diff --git a/hbase-assembly/pom.xml b/hbase-assembly/pom.xml index e703efb273e..727eb973258 100644 --- a/hbase-assembly/pom.xml +++ b/hbase-assembly/pom.xml @@ -1,6 +1,6 @@ - - 4.0.0 - - hbase - org.apache.hbase - 0.97.0-SNAPSHOT - .. - - - hbase-assembly - HBase - Assembly - - Module that does project assembly and site. + 4.0.0 + + hbase + org.apache.hbase + 0.97.0-SNAPSHOT + .. + + hbase-assembly + HBase - Assembly + + Module that does project assembly and that is all that it does. - pom - - - - maven-assembly-plugin - ${maven.assembly.version} - + pom + + + + maven-assembly-plugin + ${maven.assembly.version} + - hbase-${pom.version} + hbase-${project.version} false true - - org.codehaus.mojo - xml-maven-plugin - 1.0 - false - - - - - transform - - pre-site - - - - - - - ${basedir}/../hbase-common/src/main/resources/ - - hbase-default.xml - - ${basedir}/src/xslt/configuration_to_docbook_section.xsl - ${basedir}/target/docbkx - - - - - - - com.agilejava.docbkx - docbkx-maven-plugin - 2.0.14 - false - - - org.docbook - docbook-xml - 4.4 - runtime - - - - true - true - 100 - true - true - ${basedir}/src/docbkx/customization.xsl - 2 - yes - ${basedir}/target/docbkx - UTF-8 - - - - multipage - - generate-html - - pre-site - - true - true - ../images/ - ../css/freebsd_docbook.css - - - - onepage - - generate-html - - pre-site - - images/ - css/freebsd_docbook.css - - - - - - org.apache.maven.plugins - maven-resources-plugin - ${maven.resources.plugin.version} - - false - - - copy-javadocs - - copy-resources - - site - - target/site/apidocs - - - ${basedir}/target/apidocs - - **/** - - - - - - - copy-docbkx - - copy-resources - - site - - target/site - - - ${basedir}/target/docbkx - - **/** - - - - - - - copy-xref - - copy-resources - - site - - target/site/xref - - - ${basedir}/../target/site/xref - - **/** - - - - - - - - \ - - - - org.apache.maven.plugins - maven-site-plugin - ${maven.site.version} - false - - - - org.apache.maven.wagon - wagon-ssh - 2.2 - - - - UTF-8 - UTF-8 - ${basedir}/src/site/site.vm - - - - - - + + diff --git a/hbase-assembly/src/assembly/components.xml b/hbase-assembly/src/main/assembly/components.xml similarity index 94% rename from hbase-assembly/src/assembly/components.xml rename to hbase-assembly/src/main/assembly/components.xml index fa3281cba9b..b16b02b771e 100644 --- a/hbase-assembly/src/assembly/components.xml +++ b/hbase-assembly/src/main/assembly/components.xml @@ -25,14 +25,9 @@ - target/site + ${project.basedir}/../target/site docs - - - ${project.basedir}/../target/apidocs - docs/apidocs - ${project.basedir}/.. diff --git a/hbase-assembly/src/assembly/hadoop-one-compat.xml b/hbase-assembly/src/main/assembly/hadoop-one-compat.xml similarity index 95% rename from hbase-assembly/src/assembly/hadoop-one-compat.xml rename to hbase-assembly/src/main/assembly/hadoop-one-compat.xml index 398812bc4e8..0f9580a5562 100644 --- a/hbase-assembly/src/assembly/hadoop-one-compat.xml +++ b/hbase-assembly/src/main/assembly/hadoop-one-compat.xml @@ -26,7 +26,7 @@ tar.gz - src/assembly/components.xml + src/main/assembly/components.xml diff --git a/hbase-assembly/src/assembly/hadoop-two-compat.xml b/hbase-assembly/src/main/assembly/hadoop-two-compat.xml similarity index 96% rename from hbase-assembly/src/assembly/hadoop-two-compat.xml rename to hbase-assembly/src/main/assembly/hadoop-two-compat.xml index 4c436a534cd..f8ebcda458f 100644 --- a/hbase-assembly/src/assembly/hadoop-two-compat.xml +++ b/hbase-assembly/src/main/assembly/hadoop-two-compat.xml @@ -26,7 +26,7 @@ tar.gz - src/assembly/components.xml + src/main/assembly/components.xml diff --git a/hbase-assembly/src/assembly/src.xml b/hbase-assembly/src/main/assembly/src.xml similarity index 100% rename from hbase-assembly/src/assembly/src.xml rename to hbase-assembly/src/main/assembly/src.xml diff --git a/hbase-assembly/src/site/resources/images/hbase_logo.png b/hbase-assembly/src/site/resources/images/hbase_logo.png deleted file mode 100644 index e962ce04975..00000000000 Binary files a/hbase-assembly/src/site/resources/images/hbase_logo.png and /dev/null differ diff --git a/hbase-common/src/main/resources/hbase-default.xml b/hbase-common/src/main/resources/hbase-default.xml index e1aaf60d916..3ad54098f80 100644 --- a/hbase-common/src/main/resources/hbase-default.xml +++ b/hbase-common/src/main/resources/hbase-default.xml @@ -797,7 +797,7 @@ hbase.defaults.for.version @@@VERSION@@@ - This defaults file was compiled for version ${pom.version}. This variable is used + This defaults file was compiled for version ${project.version}. This variable is used to make sure that a user doesn't have an old version of hbase-default.xml on the classpath. diff --git a/pom.xml b/pom.xml index e233beb694c..7a40c9fc491 100644 --- a/pom.xml +++ b/pom.xml @@ -566,7 +566,6 @@ Max - org.codehaus.mojo build-helper-maven-plugin @@ -676,36 +675,47 @@ - - - org.codehaus.mojo - xml-maven-plugin - 1.0-beta-3 - + + maven-assembly-plugin + ${maven.assembly.version} + + + true + + false + + - + - maven-assembly-plugin - ${maven.assembly.version} + org.codehaus.mojo + xml-maven-plugin + 1.0 + false + + + + + transform + + pre-site + + - - true - - - - + + + + ${basedir}/hbase-common/src/main/resources/ + + hbase-default.xml + + ${basedir}/src/main/xslt/configuration_to_docbook_section.xsl + ${basedir}/target/docbkx + + + + com.agilejava.docbkx + docbkx-maven-plugin + 2.0.14 + false + + + org.docbook + docbook-xml + 4.4 + runtime + + + + ${basedir}/src/main/docbkx + true + true + 100 + true + true + ${basedir}/src/main/docbkx/customization.xsl + 2 + yes + ${basedir}/target/docbkx + UTF-8 + + + + multipage + + generate-html + + pre-site + + true + true + ../images/ + ../css/freebsd_docbook.css + + + + onepage + + generate-html + + pre-site + + images/ + css/freebsd_docbook.css - - org.apache.maven.plugins - maven-javadoc-plugin + maven-resources-plugin + ${maven.resources.plugin.version} + + false + + + copy-javadocs + + copy-resources + + site + + target/site/apidocs + + + ${basedir}/target/apidocs + + **/** + + + + + + + copy-docbkx + + copy-resources + + site + + target/site + + + ${basedir}/target/docbkx + + **/** + + + + + + + + \ + - + + org.apache.maven.plugins + maven-site-plugin + ${maven.site.version} + false + + + + org.apache.maven.wagon + wagon-ssh + 2.2 + + + + ${basedir}/src/main/site + UTF-8 + UTF-8 + ${basedir}/src/main/site/site.vm + + + ${project.build.finalName}.tar.gz @@ -1163,14 +1290,12 @@ - com.github.stephenc.findbugs findbugs-annotations ${findbugs-annotations} compile - junit @@ -1242,25 +1367,24 @@ - - - org.apache.maven.plugins - maven-surefire-plugin - - -enableassertions -Xmx1900m -Djava.security.egd=file:/dev/./urandom -Djava.net.preferIPv4Stack=true - - - java.net.preferIPv4Stack - true - - - - - + + + org.apache.maven.plugins + maven-surefire-plugin + + -enableassertions -Xmx1900m -Djava.security.egd=file:/dev/./urandom -Djava.net.preferIPv4Stack=true + + + java.net.preferIPv4Stack + true + + + + + - release @@ -1301,7 +1425,7 @@ ${hadoop-one.version} 1.4.3 hbase-hadoop1-compat - src/assembly/hadoop-one-compat.xml + src/main/assembly/hadoop-one-compat.xml @@ -1360,7 +1484,7 @@ ${hadoop-two.version} 1.6.1 hbase-hadoop2-compat - src/assembly/hadoop-two-compat.xml + src/main/assembly/hadoop-two-compat.xml @@ -1559,7 +1683,7 @@ localTests - test + test @@ -1655,9 +1779,9 @@ true true - hbase-assembly/target/site/apidocs - hbase-assembly/target/site/xref - hbase-assembly/target/site/xref + ${basedir}/target/site/apidocs + ${basedir}/target/site/xref + ${basedir}/target/site/xref **/generated/** @@ -1666,13 +1790,13 @@ - - hbase.apache.org - HBase Website at hbase.apache.org - - file:///tmp - + file:///tmp + diff --git a/hbase-assembly/src/docbkx/book.xml b/src/main/docbkx/book.xml similarity index 85% rename from hbase-assembly/src/docbkx/book.xml rename to src/main/docbkx/book.xml index 2d9001c1f80..f39132d4ca5 100644 --- a/hbase-assembly/src/docbkx/book.xml +++ b/src/main/docbkx/book.xml @@ -581,8 +581,445 @@ htable.put(put); - - + + HBase and Schema Design + A good general introduction on the strength and weaknesses modelling on + the various non-rdbms datastores is Ian Varley's Master thesis, + No Relation: The Mixed Blessings of Non-Relational Databases. + Recommended. Also, read for how HBase stores data internally. + +
+ + Schema Creation + + HBase schemas can be created or updated with + or by using HBaseAdmin in the Java API. + + Tables must be disabled when making ColumnFamily modifications, for example.. + +Configuration config = HBaseConfiguration.create(); +HBaseAdmin admin = new HBaseAdmin(conf); +String table = "myTable"; + +admin.disableTable(table); + +HColumnDescriptor cf1 = ...; +admin.addColumn(table, cf1); // adding new ColumnFamily +HColumnDescriptor cf2 = ...; +admin.modifyColumn(table, cf2); // modifying existing ColumnFamily + +admin.enableTable(table); + + See for more information about configuring client connections. + Note: online schema changes are supported in the 0.92.x codebase, but the 0.90.x codebase requires the table + to be disabled. + +
Schema Updates + When changes are made to either Tables or ColumnFamilies (e.g., region size, block size), these changes + take effect the next time there is a major compaction and the StoreFiles get re-written. + + See for more information on StoreFiles. + +
+
+
+ + On the number of column families + + + HBase currently does not do well with anything above two or three column families so keep the number + of column families in your schema low. Currently, flushing and compactions are done on a per Region basis so + if one column family is carrying the bulk of the data bringing on flushes, the adjacent families + will also be flushed though the amount of data they carry is small. When many column families the + flushing and compaction interaction can make for a bunch of needless i/o loading (To be addressed by + changing flushing and compaction to work on a per column family basis). For more information + on compactions, see . + + Try to make do with one column family if you can in your schemas. Only introduce a + second and third column family in the case where data access is usually column scoped; + i.e. you query one column family or the other but usually not both at the one time. + +
Cardinality of ColumnFamilies + Where multiple ColumnFamilies exist in a single table, be aware of the cardinality (i.e., number of rows). + If ColumnFamilyA has 1 million rows and ColumnFamilyB has 1 billion rows, ColumnFamilyA's data will likely be spread + across many, many regions (and RegionServers). This makes mass scans for ColumnFamilyA less efficient. + +
+
+
Rowkey Design +
+ + Monotonically Increasing Row Keys/Timeseries Data + + + In the HBase chapter of Tom White's book Hadoop: The Definitive Guide (O'Reilly) there is a an optimization note on watching out for a phenomenon where an import process walks in lock-step with all clients in concert pounding one of the table's regions (and thus, a single node), then moving onto the next region, etc. With monotonically increasing row-keys (i.e., using a timestamp), this will happen. See this comic by IKai Lan on why monotonically increasing row keys are problematic in BigTable-like datastores: + monotonically increasing values are bad. The pile-up on a single region brought on + by monotonically increasing keys can be mitigated by randomizing the input records to not be in sorted order, but in general it's best to avoid using a timestamp or a sequence (e.g. 1, 2, 3) as the row-key. + + + + If you do need to upload time series data into HBase, you should + study OpenTSDB as a + successful example. It has a page describing the schema it uses in + HBase. The key format in OpenTSDB is effectively [metric_type][event_timestamp], which would appear at first glance to contradict the previous advice about not using a timestamp as the key. However, the difference is that the timestamp is not in the lead position of the key, and the design assumption is that there are dozens or hundreds (or more) of different metric types. Thus, even with a continual stream of input data with a mix of metric types, the Puts are distributed across various points of regions in the table. + +
+
+ Try to minimize row and column sizes + Or why are my StoreFile indices large? + In HBase, values are always freighted with their coordinates; as a + cell value passes through the system, it'll be accompanied by its + row, column name, and timestamp - always. If your rows and column names + are large, especially compared to the size of the cell value, then + you may run up against some interesting scenarios. One such is + the case described by Marc Limotte at the tail of + HBASE-3551 + (recommended!). + Therein, the indices that are kept on HBase storefiles () + to facilitate random access may end up occupyng large chunks of the HBase + allotted RAM because the cell value coordinates are large. + Mark in the above cited comment suggests upping the block size so + entries in the store file index happen at a larger interval or + modify the table schema so it makes for smaller rows and column + names. + Compression will also make for larger indices. See + the thread a question storefileIndexSize + up on the user mailing list. + + Most of the time small inefficiencies don't matter all that much. Unfortunately, + this is a case where they do. Whatever patterns are selected for ColumnFamilies, attributes, and rowkeys they could be repeated + several billion times in your data. + See for more information on HBase stores data internally to see why this is important. +
Column Families + Try to keep the ColumnFamily names as small as possible, preferably one character (e.g. "d" for data/default). + + See for more information on HBase stores data internally to see why this is important. +
+
Attributes + Although verbose attribute names (e.g., "myVeryImportantAttribute") are easier to read, prefer shorter attribute names (e.g., "via") + to store in HBase. + + See for more information on HBase stores data internally to see why this is important. +
+
Rowkey Length + Keep them as short as is reasonable such that they can still be useful for required data access (e.g., Get vs. Scan). + A short key that is useless for data access is not better than a longer key with better get/scan properties. Expect tradeoffs + when designing rowkeys. + +
+
Byte Patterns + A long is 8 bytes. You can store an unsigned number up to 18,446,744,073,709,551,615 in those eight bytes. + If you stored this number as a String -- presuming a byte per character -- you need nearly 3x the bytes. + + Not convinced? Below is some sample code that you can run on your own. + +// long +// +long l = 1234567890L; +byte[] lb = Bytes.toBytes(l); +System.out.println("long bytes length: " + lb.length); // returns 8 + +String s = "" + l; +byte[] sb = Bytes.toBytes(s); +System.out.println("long as string length: " + sb.length); // returns 10 + +// hash +// +MessageDigest md = MessageDigest.getInstance("MD5"); +byte[] digest = md.digest(Bytes.toBytes(s)); +System.out.println("md5 digest bytes length: " + digest.length); // returns 16 + +String sDigest = new String(digest); +byte[] sbDigest = Bytes.toBytes(sDigest); +System.out.println("md5 digest as string length: " + sbDigest.length); // returns 26 + + +
+ +
+
Reverse Timestamps + A common problem in database processing is quickly finding the most recent version of a value. A technique using reverse timestamps + as a part of the key can help greatly with a special case of this problem. Also found in the HBase chapter of Tom White's book Hadoop: The Definitive Guide (O'Reilly), + the technique involves appending (Long.MAX_VALUE - timestamp) to the end of any key, e.g., [key][reverse_timestamp]. + + The most recent value for [key] in a table can be found by performing a Scan for [key] and obtaining the first record. Since HBase keys + are in sorted order, this key sorts before any older row-keys for [key] and thus is first. + + This technique would be used instead of using HBase Versioning where the intent is to hold onto all versions + "forever" (or a very long time) and at the same time quickly obtain access to any other version by using the same Scan technique. + +
+
+ Rowkeys and ColumnFamilies + Rowkeys are scoped to ColumnFamilies. Thus, the same rowkey could exist in each ColumnFamily that exists in a table without collision. + +
+
Immutability of Rowkeys + Rowkeys cannot be changed. The only way they can be "changed" in a table is if the row is deleted and then re-inserted. + This is a fairly common question on the HBase dist-list so it pays to get the rowkeys right the first time (and/or before you've + inserted a lot of data). + +
+
Relationship Between RowKeys and Region Splits + If you pre-split your table, it is critical to understand how your rowkey will be distributed across + the region boundaries. As an example of why this is important, consider the example of using displayable hex characters as the + lead position of the key (e.g., ""0000000000000000" to "ffffffffffffffff"). Running those key ranges through Bytes.split + (which is the split strategy used when creating regions in HBaseAdmin.createTable(byte[] startKey, byte[] endKey, numRegions) + for 10 regions will generate the following splits... + + + +48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 // 0 +54 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 // 6 +61 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -68 // = +68 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -126 // D +75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 72 // K +82 18 18 18 18 18 18 18 18 18 18 18 18 18 18 14 // R +88 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -44 // X +95 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -102 // _ +102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 // f + + ... (note: the lead byte is listed to the right as a comment.) Given that the first split is a '0' and the last split is an 'f', + everything is great, right? Not so fast. + + The problem is that all the data is going to pile up in the first 2 regions and the last region thus creating a "lumpy" (and + possibly "hot") region problem. To understand why, refer to an ASCII Table. + '0' is byte 48, and 'f' is byte 102, but there is a huge gap in byte values (bytes 58 to 96) that will never appear in this + keyspace because the only values are [0-9] and [a-f]. Thus, the middle regions regions will + never be used. To make pre-spliting work with this example keyspace, a custom definition of splits (i.e., and not relying on the + built-in split method) is required. + + Lesson #1: Pre-splitting tables is generally a best practice, but you need to pre-split them in such a way that all the + regions are accessible in the keyspace. While this example demonstrated the problem with a hex-key keyspace, the same problem can happen + with any keyspace. Know your data. + + Lesson #2: While generally not advisable, using hex-keys (and more generally, displayable data) can still work with pre-split + tables as long as all the created regions are accessible in the keyspace. + + To conclude this example, the following is an example of how appropriate splits can be pre-created for hex-keys:. + +public static boolean createTable(HBaseAdmin admin, HTableDescriptor table, byte[][] splits) +throws IOException { + try { + admin.createTable( table, splits ); + return true; + } catch (TableExistsException e) { + logger.info("table " + table.getNameAsString() + " already exists"); + // the table already exists... + return false; + } +} + +public static byte[][] getHexSplits(String startKey, String endKey, int numRegions) { + byte[][] splits = new byte[numRegions-1][]; + BigInteger lowestKey = new BigInteger(startKey, 16); + BigInteger highestKey = new BigInteger(endKey, 16); + BigInteger range = highestKey.subtract(lowestKey); + BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions)); + lowestKey = lowestKey.add(regionIncrement); + for(int i=0; i < numRegions-1;i++) { + BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i))); + byte[] b = String.format("%016x", key).getBytes(); + splits[i] = b; + } + return splits; +} +
+
+
+ + Number of Versions + +
Maximum Number of Versions + The maximum number of row versions to store is configured per column + family via HColumnDescriptor. + The default for max versions is 3. + This is an important parameter because as described in + section HBase does not overwrite row values, but rather + stores different values per row by time (and qualifier). Excess versions are removed during major + compactions. The number of max versions may need to be increased or decreased depending on application needs. + + It is not recommended setting the number of max versions to an exceedingly high level (e.g., hundreds or more) unless those old values are + very dear to you because this will greatly increase StoreFile size. + +
+
+ + Minimum Number of Versions + + Like maximum number of row versions, the minimum number of row versions to keep is configured per column + family via HColumnDescriptor. + The default for min versions is 0, which means the feature is disabled. + The minimum number of row versions parameter is used together with the time-to-live parameter and can be combined with the + number of row versions parameter to allow configurations such as + "keep the last T minutes worth of data, at most N versions, but keep at least M versions around" + (where M is the value for minimum number of row versions, M<N). + This parameter should only be set when time-to-live is enabled for a column family and must be less than the + number of row versions. + +
+
+
+ + Supported Datatypes + + HBase supports a "bytes-in/bytes-out" interface via Put and + Result, so anything that can be + converted to an array of bytes can be stored as a value. Input could be strings, numbers, complex objects, or even images as long as they can rendered as bytes. + + There are practical limits to the size of values (e.g., storing 10-50MB objects in HBase would probably be too much to ask); + search the mailling list for conversations on this topic. All rows in HBase conform to the datamodel, and + that includes versioning. Take that into consideration when making your design, as well as block size for the ColumnFamily. + +
+ Counters + + One supported datatype that deserves special mention are "counters" (i.e., the ability to do atomic increments of numbers). See + Increment in HTable. + + Synchronization on counters are done on the RegionServer, not in the client. + +
+
+
Joins + If you have multiple tables, don't forget to factor in the potential for into the schema design. + +
+
+ Time To Live (TTL) + ColumnFamilies can set a TTL length in seconds, and HBase will automatically delete rows once the expiration time is reached. + This applies to all versions of a row - even the current one. The TTL time encoded in the HBase for the row is specified in UTC. + + See HColumnDescriptor for more information. + +
+
+ + Keeping Deleted Cells + + ColumnFamilies can optionally keep deleted cells. That means deleted cells can still be retrieved with + Get or + Scan operations, + as long these operations have a time range specified that ends before the timestamp of any delete that would affect the cells. + This allows for point in time queries even in the presence of deletes. + + + Deleted cells are still subject to TTL and there will never be more than "maximum number of versions" deleted cells. + A new "raw" scan options returns all deleted rows and the delete markers. + + See HColumnDescriptor for more information. + +
+
+ + Secondary Indexes and Alternate Query Paths + + This section could also be titled "what if my table rowkey looks like this but I also want to query my table like that." + A common example on the dist-list is where a row-key is of the format "user-timestamp" but there are reporting requirements on activity across users for certain + time ranges. Thus, selecting by user is easy because it is in the lead position of the key, but time is not. + + There is no single answer on the best way to handle this because it depends on... + + Number of users + Data size and data arrival rate + Flexibility of reporting requirements (e.g., completely ad-hoc date selection vs. pre-configured ranges) + Desired execution speed of query (e.g., 90 seconds may be reasonable to some for an ad-hoc report, whereas it may be too long for others) + + ... and solutions are also influenced by the size of the cluster and how much processing power you have to throw at the solution. + Common techniques are in sub-sections below. This is a comprehensive, but not exhaustive, list of approaches. + + It should not be a surprise that secondary indexes require additional cluster space and processing. + This is precisely what happens in an RDBMS because the act of creating an alternate index requires both space and processing cycles to update. RBDMS products + are more advanced in this regard to handle alternative index management out of the box. However, HBase scales better at larger data volumes, so this is a feature trade-off. + + Pay attention to when implementing any of these approaches. + Additionally, see the David Butler response in this dist-list thread HBase, mail # user - Stargate+hbase + +
+ + Filter Query + + Depending on the case, it may be appropriate to use . In this case, no secondary index is created. + However, don't try a full-scan on a large table like this from an application (i.e., single-threaded client). + +
+
+ + Periodic-Update Secondary Index + + A secondary index could be created in an other table which is periodically updated via a MapReduce job. The job could be executed intra-day, but depending on + load-strategy it could still potentially be out of sync with the main data table. + See for more information. +
+
+ + Dual-Write Secondary Index + + Another strategy is to build the secondary index while publishing data to the cluster (e.g., write to data table, write to index table). + If this is approach is taken after a data table already exists, then bootstrapping will be needed for the secondary index with a MapReduce job (see ). +
+
+ + Summary Tables + + Where time-ranges are very wide (e.g., year-long report) and where the data is voluminous, summary tables are a common approach. + These would be generated with MapReduce jobs into another table. + See for more information. +
+
+ + Coprocessor Secondary Index + + Coprocessors act like RDBMS triggers. These were added in 0.92. For more information, see + +
+
+
Schema Design Smackdown + This section will describe common schema design questions that appear on the dist-list. These are + general guidelines and not laws - each application must consider its own needs. + +
Rows vs. Versions + A common question is whether one should prefer rows or HBase's built-in-versioning. The context is typically where there are + "a lot" of versions of a row to be retained (e.g., where it is significantly above the HBase default of 3 max versions). The + rows-approach would require storing a timstamp in some portion of the rowkey so that they would not overwite with each successive update. + + Preference: Rows (generally speaking). + +
+
Rows vs. Columns + Another common question is whether one should prefer rows or columns. The context is typically in extreme cases of wide + tables, such as having 1 row with 1 million attributes, or 1 million rows with 1 columns apiece. + + Preference: Rows (generally speaking). To be clear, this guideline is in the context is in extremely wide cases, not in the + standard use-case where one needs to store a few dozen or hundred columns. But there is also a middle path between these two + options, and that is "Rows as Columns." + +
+
Rows as Columns + The middle path between Rows vs. Columns is packing data that would be a separate row into columns, for certain rows. + OpenTSDB is the best example of this case where a single row represents a defined time-range, and then discrete events are treated as + columns. This approach is often more complex, and may require the additional complexity of re-writing your data, but has the + advantage of being I/O efficient. For an overview of this approach, see + Lessons Learned from OpenTSDB + from HBaseCon2012. + +
+ +
+
Operational and Performance Configuration Options + See the Performance section for more information operational and performance + schema design options, such as Bloom Filters, Table-configured regionsizes, compression, and blocksizes. + +
+ +
Constraints + HBase currently supports 'constraints' in traditional (SQL) database parlance. The advised usage for Constraints is in enforcing business rules for attributes in the table (eg. make sure values are in the range 1-10). + Constraints could also be used to enforce referential integrity, but this is strongly discouraged as it will dramatically decrease the write throughput of the tables where integrity checking is enabled. + Extensive documentation on using Constraints can be found at: Constraint since version 0.94. + +
+ +
HBase and MapReduce @@ -1738,14 +2175,14 @@ myHtd.setValue(HTableDescriptor.SPLIT_POLICY, MyCustomSplitPolicy.class.getName( - +
Online Region Merges - + Both Master and Regionserver participate in the event of online region merges. Client sends merge RPC to master, then master moves the regions together to the same regionserver where the more heavily loaded region resided, finally master - send merge request to this regionserver and regionserver run the region merges. + send merge request to this regionserver and regionserver run the region merges. Similar with process of region splits, region merges run as a local transaction on the regionserver, offlines the regions and then merges two regions on the file system, atomically delete merging regions from META and add merged region to the META, @@ -1756,7 +2193,7 @@ myHtd.setValue(HTableDescriptor.SPLIT_POLICY, MyCustomSplitPolicy.class.getName( hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME', true It's an asynchronous operation and call returns immediately without waiting merge completed. - Passing 'true' as the optional third parameter will force a merge ('force' merges regardless + Passing 'true' as the optional third parameter will force a merge ('force' merges regardless else merge will fail unless passed adjacent regions. 'force' is for expert use only)
@@ -2684,22 +3121,19 @@ hbase> describe 't1' You will find the snappy library file under the .libs directory from your Snappy build (For example /home/hbase/snappy-1.0.5/.libs/). The file is called libsnappy.so.1.x.x where 1.x.x is the version of the snappy - code you are building. You can either copy this file into your hbase lib directory -- under lib/native/PLATFORM -- - naming the file as libsnappy.so, - or simply create a symbolic link to it (See ./bin/hbase for how it does library path for native libs). + code you are building. You can either copy this file into your hbase directory under libsnappy.so name, or simply + create a symbolic link to it. The second file you need is the hadoop native library. You will find this file in your hadoop installation directory under lib/native/Linux-amd64-64/ or lib/native/Linux-i386-32/. The file you are looking for is libhadoop.so.1.x.x. - Again, you can simply copy this file or link to it from under hbase in lib/native/PLATFORM (e.g. Linux-amd64-64, etc.), - using the name libhadoop.so. + Again, you can simply copy this file or link to it, under the name libhadoop.so. At the end of the installation, you should have both libsnappy.so and libhadoop.so links or files present into - lib/native/Linux-amd64-64 or into lib/native/Linux-i386-32 (where the last part of the directory path is the - PLATFORM you built and rare running the native lib on) + lib/native/Linux-amd64-64 or into lib/native/Linux-i386-32 To point hbase at snappy support, in hbase-env.sh set export HBASE_LIBRARY_PATH=/pathtoyourhadoop/lib/native/Linux-amd64-64 diff --git a/hbase-assembly/src/docbkx/case_studies.xml b/src/main/docbkx/case_studies.xml similarity index 63% rename from hbase-assembly/src/docbkx/case_studies.xml rename to src/main/docbkx/case_studies.xml index 00230bc6d38..2e3bba0432f 100644 --- a/hbase-assembly/src/docbkx/case_studies.xml +++ b/src/main/docbkx/case_studies.xml @@ -37,8 +37,141 @@
Schema Design - See the schema design case studies here: - + +
+ List Data + The following is an exchange from the user dist-list regarding a fairly common question: + how to handle per-user list data in Apache HBase. + + *** QUESTION *** + + We're looking at how to store a large amount of (per-user) list data in +HBase, and we were trying to figure out what kind of access pattern made +the most sense. One option is store the majority of the data in a key, so +we could have something like: + + + +<FixedWidthUserName><FixedWidthValueId1>:"" (no value) +<FixedWidthUserName><FixedWidthValueId2>:"" (no value) +<FixedWidthUserName><FixedWidthValueId3>:"" (no value) + + +The other option we had was to do this entirely using: + +<FixedWidthUserName><FixedWidthPageNum0>:<FixedWidthLength><FixedIdNextPageNum><ValueId1><ValueId2><ValueId3>... +<FixedWidthUserName><FixedWidthPageNum1>:<FixedWidthLength><FixedIdNextPageNum><ValueId1><ValueId2><ValueId3>... + + +where each row would contain multiple values. +So in one case reading the first thirty values would be: + + +scan { STARTROW => 'FixedWidthUsername' LIMIT => 30} + +And in the second case it would be + +get 'FixedWidthUserName\x00\x00\x00\x00' + + +The general usage pattern would be to read only the first 30 values of +these lists, with infrequent access reading deeper into the lists. Some +users would have <= 30 total values in these lists, and some users would +have millions (i.e. power-law distribution) + + + The single-value format seems like it would take up more space on HBase, +but would offer some improved retrieval / pagination flexibility. Would +there be any significant performance advantages to be able to paginate via +gets vs paginating with scans? + + + My initial understanding was that doing a scan should be faster if our +paging size is unknown (and caching is set appropriately), but that gets +should be faster if we'll always need the same page size. I've ended up +hearing different people tell me opposite things about performance. I +assume the page sizes would be relatively consistent, so for most use cases +we could guarantee that we only wanted one page of data in the +fixed-page-length case. I would also assume that we would have infrequent +updates, but may have inserts into the middle of these lists (meaning we'd +need to update all subsequent rows). + + +Thanks for help / suggestions / follow-up questions. + + *** ANSWER *** + +If I understand you correctly, you're ultimately trying to store +triples in the form "user, valueid, value", right? E.g., something +like: + + +"user123, firstname, Paul", +"user234, lastname, Smith" + + +(But the usernames are fixed width, and the valueids are fixed width). + + +And, your access pattern is along the lines of: "for user X, list the +next 30 values, starting with valueid Y". Is that right? And these +values should be returned sorted by valueid? + + +The tl;dr version is that you should probably go with one row per +user+value, and not build a complicated intra-row pagination scheme on +your own unless you're really sure it is needed. + + +Your two options mirror a common question people have when designing +HBase schemas: should I go "tall" or "wide"? Your first schema is +"tall": each row represents one value for one user, and so there are +many rows in the table for each user; the row key is user + valueid, +and there would be (presumably) a single column qualifier that means +"the value". This is great if you want to scan over rows in sorted +order by row key (thus my question above, about whether these ids are +sorted correctly). You can start a scan at any user+valueid, read the +next 30, and be done. What you're giving up is the ability to have +transactional guarantees around all the rows for one user, but it +doesn't sound like you need that. Doing it this way is generally +recommended (see +here http://hbase.apache.org/book.html#schema.smackdown). + + +Your second option is "wide": you store a bunch of values in one row, +using different qualifiers (where the qualifier is the valueid). The +simple way to do that would be to just store ALL values for one user +in a single row. I'm guessing you jumped to the "paginated" version +because you're assuming that storing millions of columns in a single +row would be bad for performance, which may or may not be true; as +long as you're not trying to do too much in a single request, or do +things like scanning over and returning all of the cells in the row, +it shouldn't be fundamentally worse. The client has methods that allow +you to get specific slices of columns. + + +Note that neither case fundamentally uses more disk space than the +other; you're just "shifting" part of the identifying information for +a value either to the left (into the row key, in option one) or to the +right (into the column qualifiers in option 2). Under the covers, +every key/value still stores the whole row key, and column family +name. (If this is a bit confusing, take an hour and watch Lars +George's excellent video about understanding HBase schema design: +http://www.youtube.com/watch?v=_HLoH_PgrLk). + + +A manually paginated version has lots more complexities, as you note, +like having to keep track of how many things are in each page, +re-shuffling if new values are inserted, etc. That seems significantly +more complex. It might have some slight speed advantages (or +disadvantages!) at extremely high throughput, and the only way to +really know that would be to try it out. If you don't have time to +build it both ways and compare, my advice would be to start with the +simplest option (one row per user+value). Start simple and iterate! :) + + +
+
diff --git a/hbase-assembly/src/docbkx/community.xml b/src/main/docbkx/community.xml similarity index 80% rename from hbase-assembly/src/docbkx/community.xml rename to src/main/docbkx/community.xml index 075f5346908..2c09908aed9 100644 --- a/hbase-assembly/src/docbkx/community.xml +++ b/src/main/docbkx/community.xml @@ -36,7 +36,7 @@ keep elsewhere -- it should be public so it can be observed -- and you can update dev mailing list on progress. When the feature is ready for commit, 3 +1s from committers will get your feature mergedSee HBase, mail # dev - Thoughts about large feature dev branches
- +
Patch +1 Policy @@ -47,7 +47,7 @@ first to see if it works before we cast it in stone. Apache HBase is made of components. -Components have one or more s. See the 'Description' field on the +Components have one or more s. See the 'Description' field on the components JIRA page for who the current owners are by component. @@ -67,31 +67,8 @@ first pass). Any -1 on a patch by anyone vetos a patch; it cannot be committed until the justification for the -1 is addressed. -
-
- How to set fix version in JIRA on issue resolve - Here is how we agreed to set versions in JIRA when we - resolve an issue. If trunk is going to be 0.98.0 then: - - - Commit only to trunk: Mark with 0.98 - - - Commit to 0.95 and trunk : Mark with 0.98, and 0.95.x - - - Commit to 0.94.x and 0.95, and trunk: Mark with 0.98, 0.95.x, and 0.94.x - - - Commit to 89-fb: Mark with 89-fb. - - - Commit site fixes: no version - - - -
- + +
Community Roles
@@ -127,6 +104,6 @@ goals or the design toward which they are driving their component If you would like to be volunteer as a component owner, just write the dev list and we'll sign you up. Owners do not need to be committers. -
-
+ +
diff --git a/hbase-assembly/src/docbkx/configuration.xml b/src/main/docbkx/configuration.xml similarity index 99% rename from hbase-assembly/src/docbkx/configuration.xml rename to src/main/docbkx/configuration.xml index 125ade15ec0..a63efcaf0fb 100644 --- a/hbase-assembly/src/docbkx/configuration.xml +++ b/src/main/docbkx/configuration.xml @@ -669,7 +669,7 @@ stopping hbase............... Shutdown can take a moment to The generated file is a docbook section with a glossary in it--> - +
diff --git a/hbase-assembly/src/docbkx/customization.xsl b/src/main/docbkx/customization.xsl similarity index 100% rename from hbase-assembly/src/docbkx/customization.xsl rename to src/main/docbkx/customization.xsl diff --git a/hbase-assembly/src/docbkx/developer.xml b/src/main/docbkx/developer.xml similarity index 100% rename from hbase-assembly/src/docbkx/developer.xml rename to src/main/docbkx/developer.xml diff --git a/hbase-assembly/src/docbkx/external_apis.xml b/src/main/docbkx/external_apis.xml similarity index 100% rename from hbase-assembly/src/docbkx/external_apis.xml rename to src/main/docbkx/external_apis.xml diff --git a/hbase-assembly/src/docbkx/getting_started.xml b/src/main/docbkx/getting_started.xml similarity index 100% rename from hbase-assembly/src/docbkx/getting_started.xml rename to src/main/docbkx/getting_started.xml diff --git a/hbase-assembly/src/docbkx/ops_mgt.xml b/src/main/docbkx/ops_mgt.xml similarity index 100% rename from hbase-assembly/src/docbkx/ops_mgt.xml rename to src/main/docbkx/ops_mgt.xml diff --git a/hbase-assembly/src/docbkx/performance.xml b/src/main/docbkx/performance.xml similarity index 100% rename from hbase-assembly/src/docbkx/performance.xml rename to src/main/docbkx/performance.xml diff --git a/hbase-assembly/src/docbkx/preface.xml b/src/main/docbkx/preface.xml similarity index 100% rename from hbase-assembly/src/docbkx/preface.xml rename to src/main/docbkx/preface.xml diff --git a/hbase-assembly/src/docbkx/rpc.xml b/src/main/docbkx/rpc.xml similarity index 100% rename from hbase-assembly/src/docbkx/rpc.xml rename to src/main/docbkx/rpc.xml diff --git a/hbase-assembly/src/docbkx/schema_design.xml b/src/main/docbkx/schema_design.xml similarity index 100% rename from hbase-assembly/src/docbkx/schema_design.xml rename to src/main/docbkx/schema_design.xml diff --git a/hbase-assembly/src/docbkx/security.xml b/src/main/docbkx/security.xml similarity index 100% rename from hbase-assembly/src/docbkx/security.xml rename to src/main/docbkx/security.xml diff --git a/hbase-assembly/src/docbkx/shell.xml b/src/main/docbkx/shell.xml similarity index 100% rename from hbase-assembly/src/docbkx/shell.xml rename to src/main/docbkx/shell.xml diff --git a/hbase-assembly/src/docbkx/troubleshooting.xml b/src/main/docbkx/troubleshooting.xml similarity index 100% rename from hbase-assembly/src/docbkx/troubleshooting.xml rename to src/main/docbkx/troubleshooting.xml diff --git a/hbase-assembly/src/docbkx/upgrading.xml b/src/main/docbkx/upgrading.xml similarity index 74% rename from hbase-assembly/src/docbkx/upgrading.xml rename to src/main/docbkx/upgrading.xml index ad3418d9e59..d1dcdd8c0e3 100644 --- a/hbase-assembly/src/docbkx/upgrading.xml +++ b/src/main/docbkx/upgrading.xml @@ -28,58 +28,11 @@ --> Upgrading You cannot skip major verisons upgrading. If you are upgrading from - version 0.90.x to 0.94.x, you must first go from 0.90.x to 0.92.x and then go - from 0.92.x to 0.94.x. + version 0.20.x to 0.92.x, you must first go from 0.20.x to 0.90.x and then go + from 0.90.x to 0.92.x. Review , in particular the section on Hadoop version. -
- HBase version numbers - HBase has not walked a straight line where version numbers are concerned. - Since we came up out of hadoop itself, we originally tracked hadoop versioning. - Later we left hadoop versioning behind because we were moving at a different rate - to that of our parent. If you are into the arcane, checkout our old wiki page - on HBase Versioning - which tries to connect the HBase version dots. -
Odd/Even Versioning or "Development"" Series Releases - Ahead of big releases, we have been putting up preview versions to start the - feedback cycle turning-over earlier. These "Development" Series releases, - always odd-numbered, come with no guarantees, not even regards being able - to upgrade between two sequential releases (we reserve the right to break compatibility across - "Development" Series releases). Needless to say, these releases are not for - production deploys. They are a preview of what is coming in the hope that - interested parties will take the release for a test drive and flag us early if we - there are issues we've missed ahead of our rolling a production-worthy release. - - Our first "Development" Series was the 0.89 set that came out ahead of - HBase 0.90.0. HBase 0.95 is another "Development" Series that portends - HBase 0.96.0. - -
-
- Binary Compatibility - When we say two HBase versions are compatible, we mean that the versions - are wire and binary compatible. Compatible HBase versions means that - clients can talk to compatible but differently versioned servers. - It means too that you can just swap out the jars of one version and replace - them with the jars of another, compatible version and all will just work. - Unless otherwise specified, HBase point versions are binary compatible. - You can safely do rolling upgrades between binary compatible versions; i.e. - across point versions: e.g. from 0.94.5 to 0.94.6See - Does compatibility between versions also mean binary compatibility? - discussion on the hbaes dev mailing list. - . - -
-
- Rolling Upgrade between versions/Binary compatibility - Unless otherwise specified, HBase point versions are binary compatible. - you can do a rolling upgrade between hbase point versions; - for example, you can go to 0.94.6 from 0.94.5 by doing a rolling upgrade across the cluster - replacing the 0.94.5 binary with a 0.94.6 binary. - -
-
Upgrading from 0.94.x to 0.96.x The Singularity @@ -94,12 +47,7 @@
Upgrading from 0.92.x to 0.94.x - We used to think that 0.92 and 0.94 were interface compatible and that you can do a - rolling upgrade between these versions but then we figured that - HBASE-5357 Use builder pattern in HColumnDescriptor - changed method signatures so rather than return void they instead return HColumnDescriptor. This - will throw java.lang.NoSuchMethodError: org.apache.hadoop.hbase.HColumnDescriptor.setMaxVersions(I)V - .... so 0.92 and 0.94 are NOT compatible. You cannot do a rolling upgrade between them. + 0.92 and 0.94 are interface compatible. You can do a rolling upgrade between these versions.
diff --git a/hbase-assembly/src/docbkx/zookeeper.xml b/src/main/docbkx/zookeeper.xml similarity index 100% rename from hbase-assembly/src/docbkx/zookeeper.xml rename to src/main/docbkx/zookeeper.xml diff --git a/hbase-assembly/src/site/resources/css/freebsd_docbook.css b/src/main/site/resources/css/freebsd_docbook.css similarity index 100% rename from hbase-assembly/src/site/resources/css/freebsd_docbook.css rename to src/main/site/resources/css/freebsd_docbook.css diff --git a/hbase-assembly/src/site/resources/css/site.css b/src/main/site/resources/css/site.css similarity index 100% rename from hbase-assembly/src/site/resources/css/site.css rename to src/main/site/resources/css/site.css diff --git a/hbase-assembly/src/site/resources/doap_Hbase.rdf b/src/main/site/resources/doap_Hbase.rdf similarity index 100% rename from hbase-assembly/src/site/resources/doap_Hbase.rdf rename to src/main/site/resources/doap_Hbase.rdf diff --git a/hbase-assembly/src/site/resources/images/big_h_logo.svg b/src/main/site/resources/images/big_h_logo.svg similarity index 100% rename from hbase-assembly/src/site/resources/images/big_h_logo.svg rename to src/main/site/resources/images/big_h_logo.svg diff --git a/hbase-assembly/src/site/resources/images/hbase_logo.svg b/src/main/site/resources/images/hbase_logo.svg similarity index 100% rename from hbase-assembly/src/site/resources/images/hbase_logo.svg rename to src/main/site/resources/images/hbase_logo.svg diff --git a/hbase-assembly/src/site/site.vm b/src/main/site/site.vm similarity index 100% rename from hbase-assembly/src/site/site.vm rename to src/main/site/site.vm diff --git a/hbase-assembly/src/site/site.xml b/src/main/site/site.xml similarity index 96% rename from hbase-assembly/src/site/site.xml rename to src/main/site/site.xml index f3d1c91d87b..c9c8a4922f5 100644 --- a/hbase-assembly/src/site/site.xml +++ b/src/main/site/site.xml @@ -41,8 +41,6 @@ - - diff --git a/hbase-assembly/src/site/xdoc/acid-semantics.xml b/src/main/site/xdoc/acid-semantics.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/acid-semantics.xml rename to src/main/site/xdoc/acid-semantics.xml diff --git a/hbase-assembly/src/site/xdoc/bulk-loads.xml b/src/main/site/xdoc/bulk-loads.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/bulk-loads.xml rename to src/main/site/xdoc/bulk-loads.xml diff --git a/hbase-assembly/src/site/xdoc/cygwin.xml b/src/main/site/xdoc/cygwin.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/cygwin.xml rename to src/main/site/xdoc/cygwin.xml diff --git a/hbase-assembly/src/site/xdoc/index.xml b/src/main/site/xdoc/index.xml similarity index 86% rename from hbase-assembly/src/site/xdoc/index.xml rename to src/main/site/xdoc/index.xml index beab4851b5b..b4c1f817def 100644 --- a/hbase-assembly/src/site/xdoc/index.xml +++ b/src/main/site/xdoc/index.xml @@ -70,6 +70,10 @@ Apache HBase is an open-source, distributed, versioned, column-oriented store mo

February 28th, 2013 HBase Meetup at Intel Mission Campus

February 19th, 2013 Developers PowWow at HortonWorks' new digs

January 23rd, 2013 HBase Meetup at WibiData World HQ!

+

December 4th, 2012 0.96 Bug Squashing and Testing Hackathon at Cloudera, SF.

+

October 29th, 2012 HBase User Group Meetup at Wize Commerce in San Mateo.

+

October 25th, 2012 Strata/Hadoop World HBase Meetup. in NYC

+

September 11th, 2012 Contributor's Pow-Wow at HortonWorks HQ.

Old News

diff --git a/hbase-assembly/src/site/xdoc/metrics.xml b/src/main/site/xdoc/metrics.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/metrics.xml rename to src/main/site/xdoc/metrics.xml diff --git a/hbase-assembly/src/site/xdoc/old_news.xml b/src/main/site/xdoc/old_news.xml similarity index 91% rename from hbase-assembly/src/site/xdoc/old_news.xml rename to src/main/site/xdoc/old_news.xml index f7abb53b9ab..1dc3eaeb1b1 100644 --- a/hbase-assembly/src/site/xdoc/old_news.xml +++ b/src/main/site/xdoc/old_news.xml @@ -27,10 +27,6 @@
-

December 4th, 2012 0.96 Bug Squashing and Testing Hackathon at Cloudera, SF.

-

October 29th, 2012 HBase User Group Meetup at Wize Commerce in San Mateo.

-

October 25th, 2012 Strata/Hadoop World HBase Meetup. in NYC

-

September 11th, 2012 Contributor's Pow-Wow at HortonWorks HQ.

August 8th, 2012 Apache HBase 0.94.1 is available for download

June 15th, 2012 Birds-of-a-feather in San Jose, day after Hadoop Summit

May 23rd, 2012 HackConAthon in Palo Alto

diff --git a/hbase-assembly/src/site/xdoc/pseudo-distributed.xml b/src/main/site/xdoc/pseudo-distributed.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/pseudo-distributed.xml rename to src/main/site/xdoc/pseudo-distributed.xml diff --git a/hbase-assembly/src/site/xdoc/replication.xml b/src/main/site/xdoc/replication.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/replication.xml rename to src/main/site/xdoc/replication.xml diff --git a/hbase-assembly/src/site/xdoc/resources.xml b/src/main/site/xdoc/resources.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/resources.xml rename to src/main/site/xdoc/resources.xml diff --git a/hbase-assembly/src/site/xdoc/sponsors.xml b/src/main/site/xdoc/sponsors.xml similarity index 100% rename from hbase-assembly/src/site/xdoc/sponsors.xml rename to src/main/site/xdoc/sponsors.xml diff --git a/hbase-assembly/src/xslt/configuration_to_docbook_section.xsl b/src/main/xslt/configuration_to_docbook_section.xsl similarity index 100% rename from hbase-assembly/src/xslt/configuration_to_docbook_section.xsl rename to src/main/xslt/configuration_to_docbook_section.xsl