Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce2011-07-02 01:31:53 +0000
committerShawn O. Pearce2011-11-04 18:08:20 +0000
commitfa4cc2475fb127783e98ddb56b6c1fd155cd2bc4 (patch)
tree443a7f19f0890027227c049afd5c40fbd5fb8c8c /org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
parentb24a61272a991373857f9d165db33dbd0170f43a (diff)
downloadjgit-fa4cc2475fb127783e98ddb56b6c1fd155cd2bc4.tar.gz
jgit-fa4cc2475fb127783e98ddb56b6c1fd155cd2bc4.tar.xz
jgit-fa4cc2475fb127783e98ddb56b6c1fd155cd2bc4.zip
DFS: A storage layer for JGit
In practice the DHT storage layer has not been performing as well as large scale server environments want to see from a Git server. The performance of the DHT schema degrades rapidly as small changes are pushed into the repository due to the chunk size being less than 1/3 of the pushed pack size. Small chunks cause poor prefetch performance during reading, and require significantly longer prefetch lists inside of the chunk meta field to work around the small size. The DHT code is very complex (>17,000 lines of code) and is very sensitive to the underlying database round-trip time, as well as the way objects were written into the pack stream that was chunked and stored on the database. A poor pack layout (from any version of C Git prior to Junio reworking it) can cause the DHT code to be unable to enumerate the objects of the linux-2.6 repository in a completable time scale. Performing a clone from a DHT stored repository of 2 million objects takes 2 million row lookups in the DHT to locate the OBJECT_INDEX row for each object being cloned. This is very difficult for some DHTs to scale, even at 5000 rows/second the lookup stage alone takes 6 minutes (on local filesystem, this is almost too fast to bother measuring). Some servers like Apache Cassandra just fall over and cannot complete the 2 million lookups in rapid fire. On a ~400 MiB repository, the DHT schema has an extra 25 MiB of redundant data that gets downloaded to the JGit process, and that is before you consider the cost of the OBJECT_INDEX table also being fully loaded, which is at least 223 MiB of data for the linux kernel repository. In the DHT schema answering a `git clone` of the ~400 MiB linux kernel needs to load 248 MiB of "index" data from the DHT, in addition to the ~400 MiB of pack data that gets sent to the client. This is 193 MiB more data to be accessed than the native filesystem format, but it needs to come over a much smaller pipe (local Ethernet typically) than the local SATA disk drive. I also never got around to writing the "repack" support for the DHT schema, as it turns out to be fairly complex to safely repack data in the repository while also trying to minimize the amount of changes made to the database, due to very common limitations on database mutation rates.. This new DFS storage layer fixes a lot of those issues by taking the simple approach for storing relatively standard Git pack and index files on an abstract filesystem. Packs are accessed by an in-process buffer cache, similar to the WindowCache used by the local filesystem storage layer. Unlike the local file IO, there are some assumptions that the storage system has relatively high latency and no concept of "file handles". Instead it looks at the file more like HTTP byte range requests, where a read channel is a simply a thunk to trigger a read request over the network. The DFS code in this change is still abstract, it does not store on any particular filesystem, but is fairly well suited to the Amazon S3 or Apache Hadoop HDFS. Storing packs directly on HDFS rather than HBase removes a layer of abstraction, as most HBase row reads turn into an HDFS read. Most of the DFS code in this change was blatently copied from the local filesystem code. Most parts should be refactored to be shared between the two storage systems, but right now I am hesistent to do this due to how well tuned the local filesystem code currently is. Change-Id: Iec524abdf172e9ec5485d6c88ca6512cd8a6eafb
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java')
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java21
1 files changed, 21 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
index e2c23db7df..41862c7e41 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ConfigConstants.java
@@ -60,6 +60,9 @@ public class ConfigConstants {
/** The "diff" section */
public static final String CONFIG_DIFF_SECTION = "diff";
+ /** The "dfs" section */
+ public static final String CONFIG_DFS_SECTION = "dfs";
+
/** The "user" section */
public static final String CONFIG_USER_SECTION = "user";
@@ -93,6 +96,24 @@ public class ConfigConstants {
/** The "worktree" key */
public static final String CONFIG_KEY_WORKTREE = "worktree";
+ /** The "blockLimit" key */
+ public static final String CONFIG_KEY_BLOCK_LIMIT = "blockLimit";
+
+ /** The "blockSize" key */
+ public static final String CONFIG_KEY_BLOCK_SIZE = "blockSize";
+
+ /** The "readAheadLimit" key */
+ public static final String CONFIG_KEY_READ_AHEAD_LIMIT = "readAheadLimit";
+
+ /** The "readAheadThreads" key */
+ public static final String CONFIG_KEY_READ_AHEAD_THREADS = "readAheadThreads";
+
+ /** The "deltaBaseCacheLimit" key */
+ public static final String CONFIG_KEY_DELTA_BASE_CACHE_LIMIT = "deltaBaseCacheLimit";
+
+ /** The "streamFileThreshold" key */
+ public static final String CONFIG_KEY_STREAM_FILE_TRESHOLD = "streamFileThreshold";
+
/** The "remote" key */
public static final String CONFIG_KEY_REMOTE = "remote";

Back to the top