You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by pa...@apache.org on 2026/02/19 11:28:50 UTC

(hbase-site) 01/02: HBASE-29878 Update new website with new documentation

This is an automated email from the ASF dual-hosted git repository.

paksyd pushed a commit to branch asf-site-staging
in repository https://gitbox.apache.org/repos/asf/hbase-site.git

commit a23a4a12e5ce3c3bf928ab9fed747b53ed488200
Author: Dรกvid Paksy <pa...@gmail.com>
AuthorDate: Thu Feb 19 12:27:09 2026 +0100

    HBASE-29878 Update new website with new documentation
---
 __spa-fallback.html                                |    10 +-
 acid-semantics/index.html                          |    86 +-
 api/search                                         |     1 +
 api/search.data                                    |     1 +
 assets/1-snapshot-M-wgEMRv.png                     |   Bin 0 -> 125659 bytes
 assets/2-snapshots-LiQYUQGC.png                    |   Bin 0 -> 118250 bytes
 assets/Combination-D-9Ny0bQ.js                     |    41 +
 assets/KaTeX_AMS-Regular-BQhdFMY1.woff2            |   Bin 0 -> 28076 bytes
 assets/KaTeX_AMS-Regular-DMm9YOAa.woff             |   Bin 0 -> 33516 bytes
 assets/KaTeX_AMS-Regular-DRggAlZN.ttf              |   Bin 0 -> 63632 bytes
 assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf         |   Bin 0 -> 12368 bytes
 assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff        |   Bin 0 -> 7716 bytes
 assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2       |   Bin 0 -> 6912 bytes
 assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff     |   Bin 0 -> 7656 bytes
 assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2    |   Bin 0 -> 6908 bytes
 assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf      |   Bin 0 -> 12344 bytes
 assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf             |   Bin 0 -> 19584 bytes
 assets/KaTeX_Fraktur-Bold-BsDP51OF.woff            |   Bin 0 -> 13296 bytes
 assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2           |   Bin 0 -> 11348 bytes
 assets/KaTeX_Fraktur-Regular-CB_wures.ttf          |   Bin 0 -> 19572 bytes
 assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2        |   Bin 0 -> 11316 bytes
 assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff         |   Bin 0 -> 13208 bytes
 assets/KaTeX_Main-Bold-Cx986IdX.woff2              |   Bin 0 -> 25324 bytes
 assets/KaTeX_Main-Bold-Jm3AIy58.woff               |   Bin 0 -> 29912 bytes
 assets/KaTeX_Main-Bold-waoOVXN0.ttf                |   Bin 0 -> 51336 bytes
 assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2        |   Bin 0 -> 16780 bytes
 assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf          |   Bin 0 -> 32968 bytes
 assets/KaTeX_Main-BoldItalic-SpSLRI95.woff         |   Bin 0 -> 19412 bytes
 assets/KaTeX_Main-Italic-3WenGoN9.ttf              |   Bin 0 -> 33580 bytes
 assets/KaTeX_Main-Italic-BMLOBm91.woff             |   Bin 0 -> 19676 bytes
 assets/KaTeX_Main-Italic-NWA7e6Wa.woff2            |   Bin 0 -> 16988 bytes
 assets/KaTeX_Main-Regular-B22Nviop.woff2           |   Bin 0 -> 26272 bytes
 assets/KaTeX_Main-Regular-Dr94JaBh.woff            |   Bin 0 -> 30772 bytes
 assets/KaTeX_Main-Regular-ypZvNtVU.ttf             |   Bin 0 -> 53580 bytes
 assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf          |   Bin 0 -> 31196 bytes
 assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2        |   Bin 0 -> 16400 bytes
 assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff         |   Bin 0 -> 18668 bytes
 assets/KaTeX_Math-Italic-DA0__PXp.woff             |   Bin 0 -> 18748 bytes
 assets/KaTeX_Math-Italic-flOr_0UB.ttf              |   Bin 0 -> 31308 bytes
 assets/KaTeX_Math-Italic-t53AETM-.woff2            |   Bin 0 -> 16440 bytes
 assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf           |   Bin 0 -> 24504 bytes
 assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2         |   Bin 0 -> 12216 bytes
 assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff          |   Bin 0 -> 14408 bytes
 assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2       |   Bin 0 -> 12028 bytes
 assets/KaTeX_SansSerif-Italic-DN2j7dab.woff        |   Bin 0 -> 14112 bytes
 assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf         |   Bin 0 -> 22364 bytes
 assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf        |   Bin 0 -> 19436 bytes
 assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff       |   Bin 0 -> 12316 bytes
 assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2      |   Bin 0 -> 10344 bytes
 assets/KaTeX_Script-Regular-C5JkGWo-.ttf           |   Bin 0 -> 16648 bytes
 assets/KaTeX_Script-Regular-D3wIWfF6.woff2         |   Bin 0 -> 9644 bytes
 assets/KaTeX_Script-Regular-D5yQViql.woff          |   Bin 0 -> 10588 bytes
 assets/KaTeX_Size1-Regular-C195tn64.woff           |   Bin 0 -> 6496 bytes
 assets/KaTeX_Size1-Regular-Dbsnue_I.ttf            |   Bin 0 -> 12228 bytes
 assets/KaTeX_Size1-Regular-mCD8mA8B.woff2          |   Bin 0 -> 5468 bytes
 assets/KaTeX_Size2-Regular-B7gKUWhC.ttf            |   Bin 0 -> 11508 bytes
 assets/KaTeX_Size2-Regular-Dy4dx90m.woff2          |   Bin 0 -> 5208 bytes
 assets/KaTeX_Size2-Regular-oD1tc_U0.woff           |   Bin 0 -> 6188 bytes
 assets/KaTeX_Size3-Regular-CTq5MqoE.woff           |   Bin 0 -> 4420 bytes
 assets/KaTeX_Size3-Regular-DgpXs0kz.ttf            |   Bin 0 -> 7588 bytes
 assets/KaTeX_Size4-Regular-BF-4gkZK.woff           |   Bin 0 -> 5980 bytes
 assets/KaTeX_Size4-Regular-DWFBv043.ttf            |   Bin 0 -> 10364 bytes
 assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2          |   Bin 0 -> 4928 bytes
 assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff      |   Bin 0 -> 16028 bytes
 assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2     |   Bin 0 -> 13568 bytes
 assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf       |   Bin 0 -> 27556 bytes
 assets/WAL_splitting-DCT3Hgkm.png                  |   Bin 0 -> 48961 bytes
 assets/WAL_splitting-S_OUAgmz.js                   |     1 +
 assets/acid-semantics-DEgldsHV.js                  |   107 +
 assets/acl-matrix-CGfUZxnC.js                      |   189 +
 assets/adding_filters-q0nqzySF.gif                 |   Bin 0 -> 2770341 bytes
 assets/additional-topics-ss_W768g.js               |   624 +
 assets/administration-Be343mGR.js                  |   272 +
 assets/algolia-IZEDLPHE-2120h3C3.js                |     1 +
 assets/amv2-BZd-8W2P.js                            |   217 +
 assets/announcing-CLGATZs-.js                      |    74 +
 assets/app-DqYvjlOc.css                            |     1 +
 assets/asf-B_xSNWZq.js                             |    11 +
 assets/backup-and-snapshots-DywQULg4.js            |   447 +
 assets/backup-app-components-ChSULF98.js           |     1 +
 assets/backup-app-components-ZN_OfKpI.png          |   Bin 0 -> 24366 bytes
 assets/backup-cloud-appliance--qbLnXgy.js          |     1 +
 assets/backup-cloud-appliance-DQzqRFjX.png         |   Bin 0 -> 24834 bytes
 assets/backup-dedicated-cluster-BDX3WGln.png       |   Bin 0 -> 24578 bytes
 assets/backup-intra-cluster-VtQszuA-.png           |   Bin 0 -> 17348 bytes
 assets/basic-prerequisites-DOANKkJy.js             |   398 +
 assets/bc_basic-BTMl5eCr.png                       |   Bin 0 -> 239294 bytes
 assets/bc_config-Ceg8MoFC.png                      |   Bin 0 -> 124066 bytes
 assets/bc_l1-DQ3gnW8v.png                          |   Bin 0 -> 91603 bytes
 assets/bc_stats-DBz8eOUI.png                       |   Bin 0 -> 111566 bytes
 assets/building-D7JI1FBi.js                        |   495 +
 assets/bulk-data-generator-tool-DFhC9WZH.js        |   145 +
 assets/bulk-loading-Jl7zj15p.js                    |    44 +
 assets/button-CS2SuAfe.js                          |     1 +
 assets/bytebuff-allocator-stats-B7DU8asJ.png       |   Bin 0 -> 64120 bytes
 assets/bytebuff-allocator-stats-C6KiUNbS.js        |     1 +
 assets/case-studies-BPoDcA5A.js                    |   242 +
 assets/catalog-tables-DBDNW_RH.js                  |    57 +
 assets/changing_displayed_fields-CMe5Nk2W.gif      |   Bin 0 -> 2620167 bytes
 assets/changing_mode-CjAJJUmd.gif                  |   Bin 0 -> 3341347 bytes
 assets/changing_order_of_fields-0aY2WrMH.gif       |   Bin 0 -> 2879724 bytes
 assets/changing_refresh_delay-BZjQN78m.gif         |   Bin 0 -> 2292628 bytes
 assets/changing_sort_field-Ca9-_3cx.gif            |   Bin 0 -> 3434988 bytes
 assets/chunk-EPOLDU6W-B5LwAila.js                  |    26 +
 assets/chunk-OTD7MV33-qJr9DjGl.js                  |     1 +
 assets/chunk-ZMWYLUDP-oajMeTFk.js                  |     1 +
 assets/client-B5eNOW9s.js                          |   434 +
 assets/client-access-iVnBKoAb.js                   |   495 +
 assets/client-request-filters-D3rpht6K.js          |   407 +
 assets/cluster-replication-D2rcFEfx.js             |   895 +
 assets/code-of-conduct-wHEKyC02.js                 |    16 +
 assets/collapsible-DA3DUpZf.js                     |     1 +
 assets/commands-CnrbbtKl.js                        |   446 +
 assets/community-C_kYyqbI.js                       |    87 +
 assets/compression-BLaOmo6n.js                     |  1102 +
 assets/confirm-CRvfhxAV.js                         |    38 +
 assets/contributing-to-documentation-D7Yxgf9I.js   |   478 +
 assets/cp-Crzqt88_.js                              |  1555 +
 assets/createLucideIcon-BidaCVke.js                |     1 +
 assets/dark-theme-large-logo-BoBjg19n.svg          |    94 +
 assets/dark-theme-large-logo-CAKhGeGx.js           |     1 +
 assets/data-access-DNIDTwFo.js                     |  1368 +
 assets/data_block_diff_encoding-DaVDpSR3.js        |     1 +
 assets/data_block_diff_encoding-cY8klzgS.png       |   Bin 0 -> 54479 bytes
 assets/data_block_no_encoding-BRNLFT3D.png         |   Bin 0 -> 46836 bytes
 assets/data_block_prefix_encoding-DX9fSxyO.png     |   Bin 0 -> 35271 bytes
 assets/datamodel-BQZsaNKp.js                       |  1043 +
 assets/default-Do9mozlA.js                         |  2064 +
 assets/developer-guidelines-C5hlr1QB.js            |  1588 +
 assets/docs-layout-CNVvV-jP.js                     |    16 +
 assets/docs-layout-CPlZlk8X.js                     |     1 +
 assets/docs-tvoE73Lq.js                            |     4 +
 assets/downloads-B6rJlr_8.js                       |     9 +
 assets/driling_down-cB581x-U.gif                   |   Bin 0 -> 4003463 bytes
 assets/dynamic-DjWe7yMV.js                         |    90 +
 assets/empty-snapshots-CrCCrRVe.js                 |     1 +
 assets/empty-snapshots-Dz8A7Lvd.png                |   Bin 0 -> 94959 bytes
 assets/entry.client-CXriAz1o.js                    |    13 +
 assets/example-BmMxeEMY.js                         |   121 +
 assets/example-Do3_3ECZ.js                         |   249 +
 assets/export-control-BPrYZeoE.js                  |     7 +
 assets/external-apis-DaqALMua.js                   |  2216 +
 assets/external-link-jmuPj2if.js                   |     1 +
 assets/faq-BsEh4Io1.js                             |   203 +
 assets/fetch-2XFMBLBA-F2YKbHTa.js                  |     1 +
 assets/generating-documentation-BDQpiy1j.js        |     7 +
 assets/getting-involved-mL5TmMjx.js                |   272 +
 assets/getting-started-vsYq6_FY.js                 |   685 +
 assets/hbase-apis-DkEBCjc0.js                      |   196 +
 assets/hbase-history-B6jOGkyB.js                   |    10 +
 assets/hbase-incompatibilities-C3Taqpum.js         |  1011 +
 assets/hbase-mob-CWUUOAot.js                       |  1313 +
 assets/hbase-run-models-DnN688HV.js                |   202 +
 assets/hbase_replication_diagram-pmf_4kSh.jpg      |   Bin 0 -> 52298 bytes
 assets/hbtop-kkMhNlTI.js                           |   363 +
 assets/hdfs-BJ-YcWlm.js                            |    17 +
 assets/hdfs-and-zookeeper-access-jFQGS-yf.js       |     8 +
 assets/help_screen-B7e9751t.js                     |     1 +
 assets/help_screen-IyNe5Wxz.gif                    |   Bin 0 -> 930726 bytes
 assets/hfile-DV-hIcTP.png                          |   Bin 0 -> 31680 bytes
 assets/hfile-format-BImAUP4P.js                    |   554 +
 assets/hfilev2-L4pQhBIf.js                         |     1 +
 assets/hfilev2-O8X0wV-5.png                        |   Bin 0 -> 57858 bytes
 assets/home-C4IvGLOf.js                            |     1 +
 assets/ides-C0wwtuAZ.js                            |   235 +
 assets/important-CNXYVX7N.js                       |   428 +
 assets/index-BE31Pm92.js                           |     1 +
 assets/index-BKmmHxti.js                           |     1 +
 assets/index-Bha1TbQU.js                           |     5 +
 assets/index-Brr_nfBf.js                           | 48866 ++++++++++++++++
 assets/index-DJkVCgSg.js                           |     5 +
 assets/index-DKUHm2UL.js                           |    22 +
 assets/index-DXrwjGjm.js                           |     2 +
 assets/index-DnOj0pYv.js                           |    76 +
 assets/index-Dps36mP2.js                           |   168 +
 assets/index-FCA4GwU0.js                           |     1 +
 assets/index-YxOAehho.js                           |    14 +
 assets/index-lnR2ABT4.js                           |     1 +
 assets/index-vF0_8td6.js                           |     1 +
 assets/inmemory-compaction-dJoRm0c4.js             |   165 +
 assets/landing-layout-CXcQ_Wik.js                  |     1 +
 assets/large-logo-CXfkkzJH.svg                     |    89 +
 assets/link-CDX6ZyVQ.js                            |     1 +
 assets/llms-full-l0sNRNKZ.js                       |     1 +
 assets/mailing-lists-Dk5QNwFc.js                   |     3 +
 assets/manifest-3e33c58b.js                        |     1 +
 assets/mapreduce-DK_dHIAj.js                       |  1050 +
 assets/master-CuZMCYHT.js                          |   155 +
 assets/master-snapshot-CKU1gyHp.png                |   Bin 0 -> 249530 bytes
 assets/mdx-DXQ3RXga.js                             |     2 +
 assets/mdx-components-bjiyHZUo.js                  |     1 +
 assets/meta-8DXs5ugP.js                            |     1 +
 assets/meta-Ba_XQDgO.js                            |     1 +
 assets/meta-BcghAdfk.js                            |     1 +
 assets/meta-C8H8hhqv.js                            |     1 +
 assets/meta-CZc_qpXh.js                            |     1 +
 assets/meta-D6VOqHx9.js                            |     1 +
 assets/meta-DXO_jVUg.js                            |     1 +
 assets/meta-eo6CWevV.js                            |     1 +
 assets/meta-hnPTga5h.js                            |     1 +
 assets/metrics-and-monitoring-DKyCmBx7.js          |   973 +
 assets/mixedbread-RAHDVXGJ-DWAJ-1Nh.js             |     3 +
 assets/news-DoiBLu9T.js                            |     1 +
 assets/node-D1erJMJp.js                            |   287 +
 assets/offheap-overview-DTGpchw3.png               |   Bin 0 -> 64687 bytes
 assets/offheap-read-write-CUUWpqSR.js              |   437 +
 assets/orama-cloud-UZAPMPFV-DSsy8tIc.js            |     1 +
 assets/orca-DjK0iYlI.js                            |    22 +
 assets/other-info-DjsQ_xOH.js                      |    62 +
 assets/other-resources-CSwUi_64.js                 |     1 +
 assets/overview-BBL-Tau7.js                        |   303 +
 assets/overview-CFTazJ3C.js                        |    53 +
 assets/paths-hncQe2-H.js                           |   716 +
 assets/performance-5H_i_4CJ.js                     |   952 +
 assets/powered-by-hbase-CTLWcz8W.js                |     1 +
 assets/profiler-dMtotTJ_.js                        |   156 +
 assets/protobuf-DQ1FQnYU.js                        |   430 +
 assets/pv2-9G3hPv80.js                             |   234 +
 assets/region-and-capacity-DalA1LUs.js             |   654 +
 assets/region_split_process-DrwL5IoS.png           |   Bin 0 -> 338255 bytes
 assets/region_states-D4hoWYLI.png                  |   Bin 0 -> 99146 bytes
 assets/region_states-Dumv7s9S.js                   |     1 +
 assets/regions-DezkseZH.js                         |  1410 +
 assets/regionserver-CJK6VDpH.js                    |  1059 +
 assets/regionserver-sizing-Cl7SkB3P.js             |  1538 +
 assets/releasing-C6YfwdvM.js                       |   677 +
 assets/replication_overview-BAR-JHBY.js            |     1 +
 assets/replication_overview-CONFSRqj.png           |   Bin 0 -> 207537 bytes
 assets/repositories-YiqTUn3N.js                    |    18 +
 assets/rollback-DbhIPfjV.js                        |   255 +
 assets/rolling-DZTgIGiR.js                         |    22 +
 assets/root-BtA_CDVx.css                           |     1 +
 assets/root-DCifVNB4.js                            |    15 +
 assets/rpc-C-rD13aY.js                             |   366 +
 ...tiple-workloads-on-a-single-cluster-Dye-3Gcb.js |   427 +
 assets/schema-design-D3MwukXQ.js                   |    87 +
 assets/scrolling_metric_records-DdLjDZmk.gif       |   Bin 0 -> 6575199 bytes
 assets/search-default-B5qZPonW.js                  |     2 +
 assets/search-l0sNRNKZ.js                          |     1 +
 assets/serialization-B-jBEF5D.js                   |     1 +
 assets/server-build-BtA_CDVx.css                   |     1 +
 assets/shell-DvaC6xhN.js                           |   778 +
 assets/showing_and_clearing_filters-CnRYI6lf.gif   |   Bin 0 -> 1375780 bytes
 assets/snapshot-scanner-B2qsln1n.js                |   192 +
 assets/source-repository-1JSV43Td.js               |    14 +
 assets/spark-DV2PyfAf.js                           |  1306 +
 assets/sponsors-CCzZb6Wb.js                        |    12 +
 assets/sql-BQUt4WzC.js                             |     5 +
 assets/static-A2YJ5TXV-DxgpRn9-.js                 |     1 +
 assets/static-STyFaQ7a.js                          |     1 +
 assets/store-file-tracking-CX02S6Dl.js             |   262 +
 assets/sync-replication-QMgGdf41.js                |   152 +
 assets/table-rename-T2dV-wqy.js                    |    40 +
 assets/team-C0ddLOS_.js                            |     1 +
 assets/tests-DJxGTlGu.js                           |  1549 +
 assets/theme-provider-BI6ghFmW.js                  |     1 +
 assets/thrift-filter-language-Bf7i4Zyb.js          |   453 +
 assets/timeline-consistent-reads-Cfa86jEH.js       |   545 +
 assets/timeline_consistency-Bs28jTFK.js            |     1 +
 assets/timeline_consistency-WFOSacSg.png           |   Bin 0 -> 88301 bytes
 assets/tls-BZgpZHpP.js                             |   437 +
 assets/tools-BLILQGnM.js                           |  1797 +
 assets/top_screen-CWb803TC.gif                     |   Bin 0 -> 2146437 bytes
 assets/tracing-CC0Ez9il.js                         |    54 +
 assets/troubleshooting-BRcSgc0b.js                 |  2006 +
 assets/unit-testing-DeMYTE44.js                    |   639 +
 assets/updating-landing-6fHZJ6bl.js                |    11 +
 assets/user-access-BUEodRwj.js                     |   173 +
 assets/version-number-ByprZkCF.js                  |   286 +
 assets/voting-DtZEebuF.js                          |   140 +
 assets/web-ui-DGvs0Umd.js                          |   385 +
 assets/ycsb-CvQ4idTi.js                            |     8 +
 assets/zookeeper-CQIEnJ9T.js                       |   795 +
 book.html                                          |  3801 +-
 books/apache-hbase-reference-guide-dark-mode.pdf   |   Bin 0 -> 38754992 bytes
 books/apache-hbase-reference-guide.pdf             |   Bin 0 -> 38642780 bytes
 code-of-conduct/index.html                         |    34 +-
 docs-images/1-snapshot.png                         |   Bin 0 -> 125659 bytes
 docs-images/2-snapshots.png                        |   Bin 0 -> 118250 bytes
 docs-images/WAL_splitting.png                      |   Bin 0 -> 48961 bytes
 docs-images/adding_filters.gif                     |   Bin 0 -> 2770341 bytes
 docs-images/architecture.gif                       |   Bin 0 -> 15461 bytes
 docs-images/backup-app-components.png              |   Bin 0 -> 24366 bytes
 docs-images/backup-cloud-appliance.png             |   Bin 0 -> 24834 bytes
 docs-images/backup-dedicated-cluster.png           |   Bin 0 -> 24578 bytes
 docs-images/backup-intra-cluster.png               |   Bin 0 -> 17348 bytes
 docs-images/bc_basic.png                           |   Bin 0 -> 239294 bytes
 docs-images/bc_config.png                          |   Bin 0 -> 124066 bytes
 docs-images/bc_l1.png                              |   Bin 0 -> 91603 bytes
 docs-images/bc_l2_buckets.png                      |   Bin 0 -> 143801 bytes
 docs-images/bc_stats.png                           |   Bin 0 -> 111566 bytes
 docs-images/big_h_logo.png                         |   Bin 0 -> 2286 bytes
 docs-images/big_h_logo.svg                         |   139 +
 docs-images/bytebuff-allocator-stats.png           |   Bin 0 -> 64120 bytes
 docs-images/changing_displayed_fields.gif          |   Bin 0 -> 2620167 bytes
 docs-images/changing_mode.gif                      |   Bin 0 -> 3341347 bytes
 docs-images/changing_order_of_fields.gif           |   Bin 0 -> 2879724 bytes
 docs-images/changing_refresh_delay.gif             |   Bin 0 -> 2292628 bytes
 docs-images/changing_sort_field.gif                |   Bin 0 -> 3434988 bytes
 docs-images/data_block_diff_encoding.png           |   Bin 0 -> 54479 bytes
 docs-images/data_block_no_encoding.png             |   Bin 0 -> 46836 bytes
 docs-images/data_block_prefix_encoding.png         |   Bin 0 -> 35271 bytes
 docs-images/driling_down.gif                       |   Bin 0 -> 4003463 bytes
 docs-images/empty-snapshots.png                    |   Bin 0 -> 94959 bytes
 docs-images/favicon.ico                            |   Bin 0 -> 1150 bytes
 docs-images/hadoop-logo.jpg                        |   Bin 0 -> 9443 bytes
 docs-images/hbase_logo.png                         |   Bin 0 -> 2997 bytes
 docs-images/hbase_logo.svg                         |    78 +
 docs-images/hbase_logo_with_orca.png               |   Bin 0 -> 11618 bytes
 docs-images/hbase_logo_with_orca.xcf               |   Bin 0 -> 84265 bytes
 docs-images/hbase_logo_with_orca_large.png         |   Bin 0 -> 21196 bytes
 docs-images/hbase_replication_diagram.jpg          |   Bin 0 -> 52298 bytes
 docs-images/hbasecon2015.30percent.png             |   Bin 0 -> 8684 bytes
 docs-images/hbasecon2016-stack-logo.jpg            |   Bin 0 -> 32105 bytes
 docs-images/hbasecon2016-stacked.png               |   Bin 0 -> 24924 bytes
 docs-images/hbasecon2017.png                       |   Bin 0 -> 3982 bytes
 docs-images/hbaseconasia2017.png                   |   Bin 0 -> 23656 bytes
 docs-images/help_screen.gif                        |   Bin 0 -> 930726 bytes
 docs-images/hfile.png                              |   Bin 0 -> 31680 bytes
 docs-images/hfilev2.png                            |   Bin 0 -> 57858 bytes
 docs-images/jumping-orca_rotated.png               |   Bin 0 -> 52812 bytes
 docs-images/jumping-orca_rotated.xcf               |   Bin 0 -> 77560 bytes
 docs-images/jumping-orca_rotated_12percent.png     |   Bin 0 -> 2401 bytes
 docs-images/jumping-orca_rotated_25percent.png     |   Bin 0 -> 4780 bytes
 docs-images/jumping-orca_transparent_rotated.xcf   |   Bin 0 -> 135399 bytes
 docs-images/master-snapshot.png                    |   Bin 0 -> 249530 bytes
 docs-images/offheap-overview.png                   |   Bin 0 -> 64687 bytes
 docs-images/region_split_process.png               |   Bin 0 -> 338255 bytes
 docs-images/region_states.png                      |   Bin 0 -> 99146 bytes
 docs-images/replication_overview.png               |   Bin 0 -> 207537 bytes
 docs-images/scrolling_metric_records.gif           |   Bin 0 -> 6575199 bytes
 docs-images/showing_and_clearing_filters.gif       |   Bin 0 -> 1375780 bytes
 docs-images/timeline_consistency.png               |   Bin 0 -> 88301 bytes
 docs-images/top_screen.gif                         |   Bin 0 -> 2146437 bytes
 docs.data                                          |     1 +
 docs/acl-matrix.data                               |     1 +
 docs/acl-matrix/index.html                         |    77 +
 docs/amv2.data                                     |     1 +
 docs/amv2/index.html                               |   114 +
 docs/architecture.data                             |     1 +
 docs/architecture/bulk-loading.data                |     1 +
 docs/architecture/bulk-loading/index.html          |    80 +
 docs/architecture/catalog-tables.data              |     1 +
 docs/architecture/catalog-tables/index.html        |    60 +
 docs/architecture/client-request-filters.data      |     1 +
 .../architecture/client-request-filters/index.html |   199 +
 docs/architecture/client.data                      |     1 +
 docs/architecture/client/index.html                |   201 +
 docs/architecture/hbase-mob.data                   |     1 +
 docs/architecture/hbase-mob/index.html             |   491 +
 docs/architecture/hdfs.data                        |     1 +
 docs/architecture/hdfs/index.html                  |    44 +
 docs/architecture/index.html                       |    47 +
 docs/architecture/master.data                      |     1 +
 docs/architecture/master/index.html                |   103 +
 docs/architecture/overview.data                    |     1 +
 docs/architecture/overview/index.html              |    60 +
 docs/architecture/regions.data                     |     1 +
 docs/architecture/regions/index.html               |   616 +
 docs/architecture/regionserver.data                |     1 +
 docs/architecture/regionserver/index.html          |   430 +
 docs/architecture/snapshot-scanner.data            |     1 +
 docs/architecture/snapshot-scanner/index.html      |   114 +
 docs/architecture/timeline-consistent-reads.data   |     1 +
 .../timeline-consistent-reads/index.html           |   254 +
 docs/asf.data                                      |     1 +
 docs/asf/index.html                                |    42 +
 docs/backup-restore.data                           |     1 +
 docs/backup-restore/additional-topics.data         |     1 +
 docs/backup-restore/additional-topics/index.html   |   259 +
 docs/backup-restore/administration.data            |     1 +
 docs/backup-restore/administration/index.html      |   128 +
 docs/backup-restore/commands.data                  |     1 +
 docs/backup-restore/commands/index.html            |   187 +
 docs/backup-restore/index.html                     |    39 +
 docs/backup-restore/overview.data                  |     1 +
 docs/backup-restore/overview/index.html            |   150 +
 docs/building-and-developing.data                  |     1 +
 docs/building-and-developing/announcing.data       |     1 +
 docs/building-and-developing/announcing/index.html |    73 +
 docs/building-and-developing/building.data         |     1 +
 docs/building-and-developing/building/index.html   |   190 +
 .../developer-guidelines.data                      |     1 +
 .../developer-guidelines/index.html                |   593 +
 .../generating-documentation.data                  |     1 +
 .../generating-documentation/index.html            |    42 +
 docs/building-and-developing/getting-involved.data |     1 +
 .../getting-involved/index.html                    |   147 +
 docs/building-and-developing/ides.data             |     1 +
 docs/building-and-developing/ides/index.html       |   129 +
 docs/building-and-developing/index.html            |    40 +
 docs/building-and-developing/releasing.data        |     1 +
 docs/building-and-developing/releasing/index.html  |   229 +
 docs/building-and-developing/repositories.data     |     1 +
 .../repositories/index.html                        |    47 +
 docs/building-and-developing/tests.data            |     1 +
 docs/building-and-developing/tests/index.html      |   587 +
 docs/building-and-developing/updating-landing.data |     1 +
 .../updating-landing/index.html                    |    42 +
 docs/building-and-developing/voting.data           |     1 +
 docs/building-and-developing/voting/index.html     |   107 +
 docs/bulk-data-generator-tool.data                 |     1 +
 docs/bulk-data-generator-tool/index.html           |    80 +
 docs/case-studies.data                             |     1 +
 docs/case-studies/index.html                       |   134 +
 docs/community.data                                |     1 +
 docs/community/index.html                          |    63 +
 docs/compression.data                              |     1 +
 docs/compression/index.html                        |   418 +
 docs/configuration.data                            |     1 +
 docs/configuration/basic-prerequisites.data        |     1 +
 docs/configuration/basic-prerequisites/index.html  |   142 +
 docs/configuration/confirm.data                    |     1 +
 docs/configuration/confirm/index.html              |    50 +
 docs/configuration/default.data                    |     1 +
 docs/configuration/default/index.html              |   813 +
 docs/configuration/dynamic.data                    |     1 +
 docs/configuration/dynamic/index.html              |    42 +
 docs/configuration/example.data                    |     1 +
 docs/configuration/example/index.html              |    90 +
 docs/configuration/hbase-run-models.data           |     1 +
 docs/configuration/hbase-run-models/index.html     |   117 +
 docs/configuration/important.data                  |     1 +
 docs/configuration/important/index.html            |   198 +
 docs/configuration/index.html                      |    64 +
 docs/contributing-to-documentation.data            |     1 +
 docs/contributing-to-documentation/index.html      |   192 +
 docs/cp.data                                       |     1 +
 docs/cp/index.html                                 |   670 +
 docs/datamodel.data                                |     1 +
 docs/datamodel/index.html                          |   405 +
 docs/external-apis.data                            |     1 +
 docs/external-apis/index.html                      |  1035 +
 docs/faq.data                                      |     1 +
 docs/faq/index.html                                |   108 +
 docs/getting-started.data                          |     1 +
 docs/getting-started/index.html                    |   167 +
 docs/hbase-apis.data                               |     1 +
 docs/hbase-apis/index.html                         |   132 +
 docs/hbase-history.data                            |     1 +
 docs/hbase-history/index.html                      |    44 +
 docs/hbase-incompatibilities.data                  |     1 +
 docs/hbase-incompatibilities/index.html            |   359 +
 docs/hbtop.data                                    |     1 +
 docs/hbtop/index.html                              |   117 +
 docs/hfile-format.data                             |     1 +
 docs/hfile-format/index.html                       |   249 +
 docs/index.html                                    |    93 +
 docs/inmemory-compaction.data                      |     1 +
 docs/inmemory-compaction/index.html                |   100 +
 docs/mapreduce.data                                |     1 +
 docs/mapreduce/index.html                          |   442 +
 docs/offheap-read-write.data                       |     1 +
 docs/offheap-read-write/index.html                 |   183 +
 docs/operational-management.data                   |     1 +
 .../backup-and-snapshots.data                      |     1 +
 .../backup-and-snapshots/index.html                |   191 +
 .../cluster-replication.data                       |     1 +
 .../cluster-replication/index.html                 |   383 +
 docs/operational-management/index.html             |    39 +
 .../metrics-and-monitoring.data                    |     1 +
 .../metrics-and-monitoring/index.html              |   413 +
 docs/operational-management/node.data              |     1 +
 docs/operational-management/node/index.html        |   136 +
 .../region-and-capacity.data                       |     1 +
 .../region-and-capacity/index.html                 |   283 +
 ...ing-multiple-workloads-on-a-single-cluster.data |     1 +
 .../index.html                                     |   215 +
 docs/operational-management/table-rename.data      |     1 +
 .../operational-management/table-rename/index.html |    54 +
 docs/operational-management/tools.data             |     1 +
 docs/operational-management/tools/index.html       |   703 +
 docs/orca.data                                     |     1 +
 docs/orca/index.html                               |    45 +
 docs/other-info.data                               |     1 +
 docs/other-info/index.html                         |    63 +
 docs/performance.data                              |     1 +
 docs/performance/index.html                        |   386 +
 docs/profiler.data                                 |     1 +
 docs/profiler/index.html                           |   103 +
 docs/protobuf.data                                 |     1 +
 docs/protobuf/index.html                           |   195 +
 docs/pv2.data                                      |     1 +
 docs/pv2/index.html                                |   135 +
 docs/regionserver-sizing.data                      |     1 +
 docs/regionserver-sizing/index.html                |   685 +
 docs/rpc.data                                      |     1 +
 docs/rpc/index.html                                |   169 +
 docs/schema-design.data                            |     1 +
 docs/schema-design/index.html                      |    73 +
 docs/security.data                                 |     1 +
 docs/security/client-access.data                   |     1 +
 docs/security/client-access/index.html             |   239 +
 docs/security/data-access.data                     |     1 +
 docs/security/data-access/index.html               |   506 +
 docs/security/example.data                         |     1 +
 docs/security/example/index.html                   |   156 +
 docs/security/hdfs-and-zookeeper-access.data       |     1 +
 docs/security/hdfs-and-zookeeper-access/index.html |    46 +
 docs/security/index.html                           |    43 +
 docs/security/tls.data                             |     1 +
 docs/security/tls/index.html                       |   182 +
 docs/security/user-access.data                     |     1 +
 docs/security/user-access/index.html               |   104 +
 docs/security/web-ui.data                          |     1 +
 docs/security/web-ui/index.html                    |   197 +
 docs/shell.data                                    |     1 +
 docs/shell/index.html                              |   334 +
 docs/single-page.data                              |     1 +
 docs/single-page/index.html                        | 18107 ++++++
 docs/spark.data                                    |     1 +
 docs/spark/index.html                              |   579 +
 docs/sql.data                                      |     1 +
 docs/sql/index.html                                |    40 +
 docs/store-file-tracking.data                      |     1 +
 docs/store-file-tracking/index.html                |   123 +
 docs/sync-replication.data                         |     1 +
 docs/sync-replication/index.html                   |    88 +
 docs/thrift-filter-language.data                   |     1 +
 docs/thrift-filter-language/index.html             |   225 +
 docs/tracing.data                                  |     1 +
 docs/tracing/index.html                            |    56 +
 docs/troubleshooting.data                          |     1 +
 docs/troubleshooting/index.html                    |   801 +
 docs/unit-testing.data                             |     1 +
 docs/unit-testing/index.html                       |   316 +
 docs/upgrading.data                                |     1 +
 docs/upgrading/index.html                          |    40 +
 docs/upgrading/paths.data                          |     1 +
 docs/upgrading/paths/index.html                    |   327 +
 docs/upgrading/rollback.data                       |     1 +
 docs/upgrading/rollback/index.html                 |    97 +
 docs/upgrading/rolling.data                        |     1 +
 docs/upgrading/rolling/index.html                  |    45 +
 docs/upgrading/version-number.data                 |     1 +
 docs/upgrading/version-number/index.html           |   172 +
 docs/ycsb.data                                     |     1 +
 docs/ycsb/index.html                               |    41 +
 docs/zookeeper.data                                |     1 +
 docs/zookeeper/index.html                          |   337 +
 downloads/index.html                               |   119 +-
 export-control/index.html                          |    44 +
 index.html                                         |    15 +-
 llms-full.txt                                      | 56373 +++++++++++++++++++
 llms-full.txt.data                                 |     1 +
 mailing-lists/index.html                           |    81 +-
 news/index.html                                    |    15 +-
 old-book-static-files/MathJax.js                   |    19 +
 old-book-static-files/coderay-asciidoctor.css      |    87 +
 .../config/TeX-MML-AM_HTMLorMML.js                 |    19 +
 old-book-static-files/font-awesome.css             |  2337 +
 .../fonts/fontawesome-webfont.woff2                |   Bin 0 -> 77160 bytes
 old-book-static-files/hbase.css                    |   400 +
 other-resources/index.html                         |    15 +-
 powered-by-hbase/index.html                        |    15 +-
 source-repository/index.html                       |    45 +-
 sponsors/index.html                                |    34 +-
 team/index.html                                    |    15 +-
 558 files changed, 199254 insertions(+), 2134 deletions(-)

diff --git a/__spa-fallback.html b/__spa-fallback.html
index 8e25b5219ac..86ce66de9ab 100644
--- a/__spa-fallback.html
+++ b/__spa-fallback.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="/images/logo.svg"/><link rel="preload" as="font" href="/fonts/inter-latin-wght-normal.woff2" type="font/woff2" crossorigin="anonymous"/><link rel="prefetch" as="font" href="/fonts/inter-latin-wght-italic.woff2" type="font/woff2" crossorigin="anonymous"/><link rel="modulepreload" href="/assets/manifest-4b69e5a6.js"/><link rel [...]
+<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="font" href="/fonts/inter-latin-wght-normal.woff2" type="font/woff2" crossorigin="anonymous"/><link rel="prefetch" as="font" href="/fonts/inter-latin-wght-italic.woff2" type="font/woff2" crossorigin="anonymous"/><link rel="modulepreload" href="/assets/manifest-3e33c58b.js"/><link rel="modulepreload" href="/assets/entry.client-CXriAz1o.js" [...]
               (function() {
                 const theme = localStorage.getItem('theme');
                 const root = document.documentElement;
@@ -12,16 +12,16 @@
                   localStorage.setItem('theme', systemTheme);
                 }
               })();
-            </script><noscript><style>.theme-toggle-wrapper { display: none !important; }</style></noscript></head><body class="font-base"><header class="border-border/0 bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 w-full border-b backdrop-blur transition-[border] duration-200"><nav class="container mx-auto flex h-16 items-center justify-between px-4"><a class="relative z-50 flex items-center gap-3" aria-label="HBase Home" href="/" data-discover="true">< [...]
+            </script><noscript><style>.theme-toggle-wrapper { display: none !important; }</style></noscript></head><body class="font-base"><script>
               console.log(
                 "๐Ÿ’ฟ Hey developer ๐Ÿ‘‹. You can provide a way better UX than this " +
                 "when your app is loading JS modules and/or running `clientLoader` " +
                 "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " +
                 "for more information."
               );
-            </script><script>window.__reactRouterContext = {"basename":"/","future":{"v8_middleware":false,"unstable_optimizeDeps":false,"unstable_splitRouteModules":false,"unstable_subResourceIntegrity":false,"unstable_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":false,"isSpaMode":true};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThrough(new TextEncoderStream());</scr [...]
-import * as route0 from "/assets/root-7bakT4LI.js";
+            </script><script>window.__reactRouterContext = {"basename":"/","future":{"unstable_optimizeDeps":false,"unstable_subResourceIntegrity":false,"unstable_trailingSlashAwareDataRequests":false,"v8_middleware":false,"v8_splitRouteModules":false,"v8_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":false,"isSpaMode":true};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeTh [...]
+import * as route0 from "/assets/root-DCifVNB4.js";
   
   window.__reactRouterRouteModules = {"root":route0};
 
-import("/assets/entry.client-D-YQWBLI.js");</script><section id="getting-started" class="border-border/60 bg-muted/30 border-y"><div class="container mx-auto px-4 py-12 md:py-16"><div class="mb-8 text-center"><h2 class="text-3xl font-semibold tracking-tight md:text-4xl">Getting Started</h2><p class="text-muted-foreground mt-2">From download to production in a few simple steps.</p></div><div class="grid grid-cols-1 gap-4 md:grid-cols-3"><div class="border-border/60 bg-card flex flex-col r [...]
\ No newline at end of file
+import("/assets/entry.client-CXriAz1o.js");</script><!--$--><script>window.__reactRouterContext.streamController.enqueue("[{\"_1\":2,\"_3\":-5,\"_4\":-5},\"loaderData\",{},\"actionData\",\"errors\"]\n");</script><!--$--><script>window.__reactRouterContext.streamController.close();</script><!--/$--><!--/$--></body></html>
\ No newline at end of file
diff --git a/acid-semantics/index.html b/acid-semantics/index.html
index ef2eb7bd0e4..878db5b6726 100644
--- a/acid-semantics/index.html
+++ b/acid-semantics/index.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="/images/logo.svg"/><title>ACID Semantics - Apache HBase</title><meta name="description" content="Apache HBase ACID properties and guarantees specification."/><link rel="preload" as="font" href="/fonts/inter-latin-wght-normal.woff2" type="font/woff2" crossorigin="anonymous"/><link rel="prefetch" as="font" href="/fonts/inter-l [...]
+<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="image" href="/images/logo.svg"/><title>ACID Semantics - Apache HBase</title><meta name="description" content="Apache HBase ACID properties and guarantees specification."/><link rel="preload" as="font" href="/fonts/inter-latin-wght-normal.woff2" type="font/woff2" crossorigin="anonymous"/><link rel="prefetch" as="font" href="/fonts/inter-l [...]
               (function() {
                 const theme = localStorage.getItem('theme');
                 const root = document.documentElement;
@@ -12,48 +12,47 @@
                   localStorage.setItem('theme', systemTheme);
                 }
               })();
-            </script><noscript><style>.theme-toggle-wrapper { display: none !important; }</style></noscript></head><body class="font-base"><header class="border-border/0 bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 w-full border-b backdrop-blur transition-[border] duration-200"><nav class="container mx-auto flex h-16 items-center justify-between px-4"><a class="relative z-50 flex items-center gap-3" aria-label="HBase Home" href="/" data-discover="true">< [...]
-<h1 class="my-12 text-center text-4xl font-semibold tracking-tight text-balance md:text-6xl">ACID properties of HBase</h1>
-<p class="mb-4 text-base leading-7">Apache HBase (TM) is not an ACID compliant database. However, it does guarantee certain specific properties.</p>
-<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl">Definitions</h2>
-<p class="mb-4 text-base leading-7">For the sake of common vocabulary, we define the following terms:</p>
-<p class="mb-4 text-base leading-7"><strong>Atomicity</strong>
+            </script><noscript><style>.theme-toggle-wrapper { display: none !important; }</style></noscript></head><body class="font-base"><header class="border-border/0 bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-50 w-full border-b backdrop-blur transition-[border] duration-200"><nav class="container mx-auto flex h-16 items-center justify-between px-4"><a class="relative z-50 flex items-center gap-3" aria-label="HBase Home" href="/" data-discover="true">< [...]
+<p class="mb-4 text-base leading-7 wrap-anywhere">Apache HBase (TM) is not an ACID compliant database. However, it does guarantee certain specific properties.</p>
+<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl" id="definitions">Definitions</h2>
+<p class="mb-4 text-base leading-7 wrap-anywhere">For the sake of common vocabulary, we define the following terms:</p>
+<p class="mb-4 text-base leading-7 wrap-anywhere"><strong>Atomicity</strong>
 an operation is atomic if it either completes entirely or not at all</p>
-<p class="mb-4 text-base leading-7"><strong>Consistency</strong>
+<p class="mb-4 text-base leading-7 wrap-anywhere"><strong>Consistency</strong>
 all actions cause the table to transition from one valid state directly to another (eg a row will not disappear during an update, etc)</p>
-<p class="mb-4 text-base leading-7"><strong>Isolation</strong>
+<p class="mb-4 text-base leading-7 wrap-anywhere"><strong>Isolation</strong>
 an operation is isolated if it appears to complete independently of any other concurrent transaction</p>
-<p class="mb-4 text-base leading-7"><strong>Durability</strong>
+<p class="mb-4 text-base leading-7 wrap-anywhere"><strong>Durability</strong>
 any update that reports &quot;successful&quot; to the client will not be lost</p>
-<p class="mb-4 text-base leading-7"><strong>Visibility</strong>
+<p class="mb-4 text-base leading-7 wrap-anywhere"><strong>Visibility</strong>
 an update is considered visible if any subsequent read will see the update as having been committed</p>
-<p class="mb-4 text-base leading-7">The terms <em>must</em> and <em>may</em> are used as specified by RFC 2119. In short, the word &quot;must&quot; implies that, if some case exists where the statement is not true, it is a bug. The word &quot;may&quot; implies that, even if the guarantee is provided in a current release, users should not rely on it.</p>
-<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl">APIs to consider</h2>
+<p class="mb-4 text-base leading-7 wrap-anywhere">The terms <em>must</em> and <em>may</em> are used as specified by RFC 2119. In short, the word &quot;must&quot; implies that, if some case exists where the statement is not true, it is a bug. The word &quot;may&quot; implies that, even if the guarantee is provided in a current release, users should not rely on it.</p>
+<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl" id="apis-to-consider">APIs to consider</h2>
 <ul class="mb-4 ml-6 list-disc space-y-2">
-<li class="leading-7">Read APIs
+<li class="leading-7">Read APIs<!-- -->
 <ul class="mb-4 ml-6 list-disc space-y-2">
 <li class="leading-7">get</li>
 <li class="leading-7">scan</li>
 </ul>
 </li>
-<li class="leading-7">Write APIs
+<li class="leading-7">Write APIs<!-- -->
 <ul class="mb-4 ml-6 list-disc space-y-2">
 <li class="leading-7">put</li>
 <li class="leading-7">batch put</li>
 <li class="leading-7">delete</li>
 </ul>
 </li>
-<li class="leading-7">Combination (read-modify-write) APIs
+<li class="leading-7">Combination (read-modify-write) APIs<!-- -->
 <ul class="mb-4 ml-6 list-disc space-y-2">
 <li class="leading-7">incrementColumnValue</li>
 <li class="leading-7">checkAndPut</li>
 </ul>
 </li>
 </ul>
-<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl">Guarantees Provided</h2>
-<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight">Atomicity</h3>
+<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl" id="guarantees-provided">Guarantees Provided</h2>
+<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight" id="atomicity">Atomicity</h3>
 <ol class="mb-4 ml-6 list-decimal space-y-2">
-<li class="leading-7">All mutations are atomic within a row. Any put will either wholly succeed or wholly fail.[3]
+<li class="leading-7">All mutations are atomic within a row. Any put will either wholly succeed or wholly fail.[3]<!-- -->
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">An operation that returns a &quot;success&quot; code has completely succeeded.</li>
 <li class="leading-7">An operation that returns a &quot;failure&quot; code has completely failed.</li>
@@ -63,24 +62,24 @@ an update is considered visible if any subsequent read will see the update as ha
 <li class="leading-7">This is true even if the mutation crosses multiple column families within a row.</li>
 <li class="leading-7">APIs that mutate several rows will <em>not</em> be atomic across the multiple rows. For example, a multiput that operates on rows &#x27;a&#x27;,&#x27;b&#x27;, and &#x27;c&#x27; may return having mutated some but not all of the rows. In such cases, these APIs will return a list of success codes, each of which may be succeeded, failed, or timed out as described above.</li>
 <li class="leading-7">The checkAndPut API happens atomically like the typical compareAndSet (CAS) operation found in many hardware architectures.</li>
-<li class="leading-7">The order of mutations is seen to happen in a well-defined order for each row, with no interleaving. For example, if one writer issues the mutation &quot;a=1,b=1,c=1&quot; and another writer issues the mutation &quot;a=2,b=2,c=2&quot;, the row must either be &quot;a=1,b=1,c=1&quot; or &quot;a=2,b=2,c=2&quot; and must <em>not</em> be something like &quot;a=1,b=2,c=1&quot;.
+<li class="leading-7">The order of mutations is seen to happen in a well-defined order for each row, with no interleaving. For example, if one writer issues the mutation &quot;a=1,b=1,c=1&quot; and another writer issues the mutation &quot;a=2,b=2,c=2&quot;, the row must either be &quot;a=1,b=1,c=1&quot; or &quot;a=2,b=2,c=2&quot; and must <em>not</em> be something like &quot;a=1,b=2,c=1&quot;.<!-- -->
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">Please note that this is not true <em>across rows</em> for multirow batch mutations.</li>
 </ol>
 </li>
 </ol>
-<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight">Consistency and Isolation</h3>
+<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight" id="consistency-and-isolation">Consistency and Isolation</h3>
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">All rows returned via any access API will consist of a complete row that existed at some point in the table&#x27;s history.</li>
 <li class="leading-7">This is true across column families - i.e a get of a full row that occurs concurrent with some mutations 1,2,3,4,5 will return a complete row that existed at some point in time between mutation i and i+1 for some i between 1 and 5.</li>
 <li class="leading-7">The state of a row will only move forward through the history of edits to it.</li>
 </ol>
-<h4>Consistency of Scans</h4>
-<p class="mb-4 text-base leading-7">A scan is <strong>not</strong> a consistent view of a table. Scans do <strong>not</strong> exhibit <em>snapshot isolation</em>.</p>
-<p class="mb-4 text-base leading-7">Rather, scans have the following properties:</p>
+<h4 class="flex scroll-m-28 flex-row items-center gap-2" id="consistency-of-scans"><a data-card="" href="#consistency-of-scans" class="peer">Consistency of Scans</a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide size-3.5 shrink-0 text-fd-muted-foreground opacity-0 transition-opacity peer-hover:opacity-100" aria-hidden="true"><path d="M10 13a5 [...]
+<p class="mb-4 text-base leading-7 wrap-anywhere">A scan is <strong>not</strong> a consistent view of a table. Scans do <strong>not</strong> exhibit <em>snapshot isolation</em>.</p>
+<p class="mb-4 text-base leading-7 wrap-anywhere">Rather, scans have the following properties:</p>
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">Any row returned by the scan will be a consistent view (i.e. that version of the complete row existed at some point in time) [1]</li>
-<li class="leading-7">A scan will always reflect a view of the data <em>at least as new as</em> the beginning of the scan. This satisfies the visibility guarantees enumerated below.
+<li class="leading-7">A scan will always reflect a view of the data <em>at least as new as</em> the beginning of the scan. This satisfies the visibility guarantees enumerated below.<!-- -->
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">For example, if client A writes data X and then communicates via a side channel to client B, any scans started by client B will contain data at least as new as X.</li>
 <li class="leading-7">A scan <em>must</em> reflect all mutations committed prior to the construction of the scanner, and <em>may</em> reflect some mutations committed subsequent to the construction of the scanner.</li>
@@ -88,12 +87,12 @@ an update is considered visible if any subsequent read will see the update as ha
 </ol>
 </li>
 </ol>
-<p class="mb-4 text-base leading-7">Those familiar with relational databases will recognize this isolation level as &quot;read committed&quot;.</p>
-<p class="mb-4 text-base leading-7">Please note that the guarantees listed above regarding scanner consistency are referring to &quot;transaction commit time&quot;, not the &quot;timestamp&quot; field of each cell. That is to say, a scanner started at time <em>t</em> may see edits with a timestamp value greater than <em>t</em>, if those edits were committed with a &quot;forward dated&quot; timestamp before the scanner was constructed.</p>
-<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight">Visibility</h3>
+<p class="mb-4 text-base leading-7 wrap-anywhere">Those familiar with relational databases will recognize this isolation level as &quot;read committed&quot;.</p>
+<p class="mb-4 text-base leading-7 wrap-anywhere">Please note that the guarantees listed above regarding scanner consistency are referring to &quot;transaction commit time&quot;, not the &quot;timestamp&quot; field of each cell. That is to say, a scanner started at time <em>t</em> may see edits with a timestamp value greater than <em>t</em>, if those edits were committed with a &quot;forward dated&quot; timestamp before the scanner was constructed.</p>
+<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight" id="visibility">Visibility</h3>
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">When a client receives a &quot;success&quot; response for any mutation, that mutation is immediately visible to both that client and any client with whom it later communicates through side channels. [3]</li>
-<li class="leading-7">A row must never exhibit so-called &quot;time-travel&quot; properties. That is to say, if a series of mutations moves a row sequentially through a series of states, any sequence of concurrent reads will return a subsequence of those states.
+<li class="leading-7">A row must never exhibit so-called &quot;time-travel&quot; properties. That is to say, if a series of mutations moves a row sequentially through a series of states, any sequence of concurrent reads will return a subsequence of those states.<!-- -->
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">For example, if a row&#x27;s cells are mutated using the &quot;incrementColumnValue&quot; API, a client must never see the value of any cell decrease.</li>
 <li class="leading-7">This is true regardless of which read API is used to read back the mutation.</li>
@@ -101,25 +100,25 @@ an update is considered visible if any subsequent read will see the update as ha
 </li>
 <li class="leading-7">Any version of a cell that has been returned to a read operation is guaranteed to be durably stored.</li>
 </ol>
-<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight">Durability</h3>
+<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight" id="durability">Durability</h3>
 <ol class="mb-4 ml-6 list-decimal space-y-2">
 <li class="leading-7">All visible data is also durable data. That is to say, a read will never return data that has not been made durable on disk[2]</li>
 <li class="leading-7">Any operation that returns a &quot;success&quot; code (eg does not throw an exception) will be made durable.[3]</li>
 <li class="leading-7">Any operation that returns a &quot;failure&quot; code will not be made durable (subject to the Atomicity guarantees above)</li>
 <li class="leading-7">All reasonable failure scenarios will not affect any of the guarantees of this document.</li>
 </ol>
-<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight">Tunability</h3>
-<p class="mb-4 text-base leading-7">All of the above guarantees must be possible within Apache HBase. For users who would like to trade off some guarantees for performance, HBase may offer several tuning options. For example:</p>
+<h3 class="mt-8 mb-1 scroll-mt-28 text-xl font-semibold tracking-tight" id="tunability">Tunability</h3>
+<p class="mb-4 text-base leading-7 wrap-anywhere">All of the above guarantees must be possible within Apache HBase. For users who would like to trade off some guarantees for performance, HBase may offer several tuning options. For example:</p>
 <ul class="mb-4 ml-6 list-disc space-y-2">
 <li class="leading-7">Visibility may be tuned on a per-read basis to allow stale reads or time travel.</li>
 <li class="leading-7">Durability may be tuned to only flush data to disk on a periodic basis</li>
 </ul>
-<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl">More Information</h2>
-<p class="mb-4 text-base leading-7">For more information, see the <a class="text-primary underline-offset-4 hover:underline" href="https://hbase.apache.org/book.html#client">client architecture</a> or <a class="text-primary underline-offset-4 hover:underline" href="https://hbase.apache.org/book.html#datamodel">data model</a> sections in the Apache HBase Reference Guide.</p>
-<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl">Footnotes</h2>
-<p class="mb-4 text-base leading-7">[1] A consistent view is not guaranteed intra-row scanning -- i.e. fetching a portion of a row in one RPC then going back to fetch another portion of the row in a subsequent RPC. Intra-row scanning happens when you set a limit on how many values to return per Scan#next (See <a href="http://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Scan.html#setBatch(int)" target="_blank" rel="noopener noreferrer" class="text-primary inline underline-of [...]
-<p class="mb-4 text-base leading-7">[2] In the context of Apache HBase, &quot;durably on disk&quot; implies an hflush() call on the transaction log. This does not actually imply an fsync() to magnetic media, but rather just that the data has been written to the OS cache on all replicas of the log. In the case of a full datacenter power loss, it is possible that the edits are not truly durable.</p>
-<p class="mb-4 text-base leading-7">[3] Puts will either wholly succeed or wholly fail, provided that they are actually sent to the RegionServer. If the writebuffer is used, Puts will not be sent until the writebuffer is filled or it is explicitly flushed.</p></article></div><script>((storageKey2, restoreKey) => {
+<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl" id="more-information">More Information</h2>
+<p class="mb-4 text-base leading-7 wrap-anywhere">For more information, see the <a class="text-primary font-normal no-underline decoration-1 underline-offset-4 hover:underline hover:opacity-100" href="/docs/architecture/client" data-discover="true">client architecture</a> or <a class="text-primary font-normal no-underline decoration-1 underline-offset-4 hover:underline hover:opacity-100" href="/docs/datamodel" data-discover="true">data model</a> sections in the Apache HBase Reference Guide.</p>
+<h2 class="mt-12 mb-4 scroll-mt-28 text-3xl font-semibold tracking-tight md:text-4xl" id="footnotes">Footnotes</h2>
+<p class="mb-4 text-base leading-7 wrap-anywhere">[1] A consistent view is not guaranteed intra-row scanning -- i.e. fetching a portion of a row in one RPC then going back to fetch another portion of the row in a subsequent RPC. Intra-row scanning happens when you set a limit on how many values to return per Scan#next (See <a href="http://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Scan.html#setBatch(int)" target="_blank" rel="noopener noreferrer" class="text-primary inlin [...]
+<p class="mb-4 text-base leading-7 wrap-anywhere">[2] In the context of Apache HBase, &quot;durably on disk&quot; implies an hflush() call on the transaction log. This does not actually imply an fsync() to magnetic media, but rather just that the data has been written to the OS cache on all replicas of the log. In the case of a full datacenter power loss, it is possible that the edits are not truly durable.</p>
+<p class="mb-4 text-base leading-7 wrap-anywhere">[3] Puts will either wholly succeed or wholly fail, provided that they are actually sent to the RegionServer. If the writebuffer is used, Puts will not be sent until the writebuffer is filled or it is explicitly flushed.</p></article></div><section id="getting-started" class="border-border/60 bg-muted/30 border-y"><div class="container mx-auto px-4 py-12 md:py-16"><div class="mb-8 text-center"><h2 class="text-3xl font-semibold tracking-ti [...]
     if (!window.history.state || !window.history.state.key) {
       let key = Math.random().toString(32).slice(2);
       window.history.replaceState({ key }, "");
@@ -134,11 +133,12 @@ an update is considered visible if any subsequent read will see the update as ha
       console.error(error);
       sessionStorage.removeItem(storageKey2);
     }
-  })("react-router-scroll-positions", null)</script><script>window.__reactRouterContext = {"basename":"/","future":{"v8_middleware":false,"unstable_optimizeDeps":false,"unstable_splitRouteModules":false,"unstable_subResourceIntegrity":false,"unstable_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":false,"isSpaMode":false};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamController = controller;}}).pipeThroug [...]
-import * as route0 from "/assets/root-7bakT4LI.js";
-import * as route1 from "/assets/acid-semantics-C6Rlqmxk.js";
+  })("react-router-scroll-positions", null)</script><script>window.__reactRouterContext = {"basename":"/","future":{"unstable_optimizeDeps":false,"unstable_subResourceIntegrity":false,"unstable_trailingSlashAwareDataRequests":false,"v8_middleware":false,"v8_splitRouteModules":false,"v8_viteEnvironmentApi":false},"routeDiscovery":{"mode":"initial"},"ssr":false,"isSpaMode":false};window.__reactRouterContext.stream = new ReadableStream({start(controller){window.__reactRouterContext.streamCo [...]
+import * as route0 from "/assets/root-DCifVNB4.js";
+import * as route1 from "/assets/landing-layout-CXcQ_Wik.js";
+import * as route2 from "/assets/acid-semantics-DEgldsHV.js";
   
-  window.__reactRouterRouteModules = {"root":route0,"routes/acid-semantics":route1};
+  window.__reactRouterRouteModules = {"root":route0,"pages/_landing/landing-layout":route1,"routes/_landing/acid-semantics":route2};
 
-import("/assets/entry.client-D-YQWBLI.js");</script><section id="getting-started" class="border-border/60 bg-muted/30 border-y"><div class="container mx-auto px-4 py-12 md:py-16"><div class="mb-8 text-center"><h2 class="text-3xl font-semibold tracking-tight md:text-4xl">Getting Started</h2><p class="text-muted-foreground mt-2">From download to production in a few simple steps.</p></div><div class="grid grid-cols-1 gap-4 md:grid-cols-3"><div class="border-border/60 bg-card flex flex-col r [...]
+import("/assets/entry.client-CXriAz1o.js");</script><!--$?--><template id="B:0"></template><!--/$--><script id="_R_">requestAnimationFrame(function(){$RT=performance.now()});</script><div hidden id="S:0"><script>window.__reactRouterContext.streamController.enqueue("[{\"_1\":2,\"_3\":-5,\"_4\":-5},\"loaderData\",{},\"actionData\",\"errors\"]\n");</script><!--$?--><template id="B:1"></template><!--/$--></div><script>$RB=[];$RV=function(a){$RT=performance.now();for(var b=0;b<a.length;b+=2){ [...]
 $RC=function(a,b){if(b=document.getElementById(b))(a=document.getElementById(a))?(a.previousSibling.data="$~",$RB.push(a,b),2===$RB.length&&("number"!==typeof $RT?requestAnimationFrame($RV.bind(null,$RB)):(a=performance.now(),setTimeout($RV.bind(null,$RB),2300>a&&2E3<a?2300-a:$RT+300-a)))):b.parentNode.removeChild(b)};$RC("B:0","S:0")</script><div hidden id="S:1"><script>window.__reactRouterContext.streamController.close();</script></div><script>$RC("B:1","S:1")</script></body></html>
\ No newline at end of file
diff --git a/api/search b/api/search
new file mode 100644
index 00000000000..6c5bbd3ee94
--- /dev/null
+++ b/api/search
@@ -0,0 +1 @@
+{"type":"advanced","internalDocumentIDStore":{"internalIdToId":["/docs/acl-matrix","/docs/acl-matrix-0","/docs/acl-matrix-1","/docs/acl-matrix-2","/docs/acl-matrix-3","/docs/acl-matrix-4","/docs/acl-matrix-5","/docs/acl-matrix-6","/docs/acl-matrix-7","/docs/acl-matrix-8","/docs/acl-matrix-9","/docs/acl-matrix-10","/docs/acl-matrix-11","/docs/acl-matrix-12","/docs/acl-matrix-13","/docs/acl-matrix-14","/docs/acl-matrix-15","/docs/acl-matrix-16","/docs/acl-matrix-17","/docs/acl-matrix-18"," [...]
\ No newline at end of file
diff --git a/api/search.data b/api/search.data
new file mode 100644
index 00000000000..4a5f9d7cdbd
--- /dev/null
+++ b/api/search.data
@@ -0,0 +1 @@
+[{"_1":2},"routes/_api/search",{"_3":4},"data",{"_5":6,"_7":8,"_19559":19560,"_93220":220675,"_59268":271979,"_82770":350191,"_40299":86774},"type","advanced","internalDocumentIDStore",{"_9":10},"internalIdToId",[11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102, [...]
diff --git a/assets/1-snapshot-M-wgEMRv.png b/assets/1-snapshot-M-wgEMRv.png
new file mode 100644
index 00000000000..a903902b413
Binary files /dev/null and b/assets/1-snapshot-M-wgEMRv.png differ
diff --git a/assets/2-snapshots-LiQYUQGC.png b/assets/2-snapshots-LiQYUQGC.png
new file mode 100644
index 00000000000..2fd45748646
Binary files /dev/null and b/assets/2-snapshots-LiQYUQGC.png differ
diff --git a/assets/Combination-D-9Ny0bQ.js b/assets/Combination-D-9Ny0bQ.js
new file mode 100644
index 00000000000..beae2265164
--- /dev/null
+++ b/assets/Combination-D-9Ny0bQ.js
@@ -0,0 +1,41 @@
+import{r as u}from"./chunk-EPOLDU6W-B5LwAila.js";var ne=function(e){if(typeof document>"u")return null;var t=Array.isArray(e)?e[0]:e;return t.ownerDocument.body},A=new WeakMap,W=new WeakMap,B={},X=0,K=function(e){return e&&(e.host||K(e.parentNode))},ae=function(e,t){return t.map(function(r){if(e.contains(r))return r;var n=K(r);return n&&e.contains(n)?n:(console.error("aria-hidden",r,"in not contained inside",e,". Doing nothing"),null)}).filter(function(r){return!!r})},oe=function(e,t,r,n [...]
+  .`.concat(ie,` {
+   overflow: hidden `).concat(n,`;
+   padding-right: `).concat(c,"px ").concat(n,`;
+  }
+  body[`).concat(T,`] {
+    overflow: hidden `).concat(n,`;
+    overscroll-behavior: contain;
+    `).concat([t&&"position: relative ".concat(n,";"),r==="margin"&&`
+    padding-left: `.concat(a,`px;
+    padding-top: `).concat(o,`px;
+    padding-right: `).concat(l,`px;
+    margin-left:0;
+    margin-top:0;
+    margin-right: `).concat(c,"px ").concat(n,`;
+    `),r==="padding"&&"padding-right: ".concat(c,"px ").concat(n,";")].filter(Boolean).join(""),`
+  }
+  
+  .`).concat(x,` {
+    right: `).concat(c,"px ").concat(n,`;
+  }
+  
+  .`).concat(I,` {
+    margin-right: `).concat(c,"px ").concat(n,`;
+  }
+  
+  .`).concat(x," .").concat(x,` {
+    right: 0 `).concat(n,`;
+  }
+  
+  .`).concat(I," .").concat(I,` {
+    margin-right: 0 `).concat(n,`;
+  }
+  
+  body[`).concat(T,`] {
+    `).concat(ue,": ").concat(c,`px;
+  }
+`)},Z=function(){var e=parseInt(document.body.getAttribute(T)||"0",10);return isFinite(e)?e:0},Me=function(){u.useEffect(function(){return document.body.setAttribute(T,(Z()+1).toString()),function(){var e=Z()-1;e<=0?document.body.removeAttribute(T):document.body.setAttribute(T,e.toString())}},[])},Pe=function(e){var t=e.noRelative,r=e.noImportant,n=e.gapMode,a=n===void 0?"margin":n;Me();var o=u.useMemo(function(){return Re(a)},[a]);return u.createElement(ke,{styles:Ae(o,!t,a,r?"":"!impor [...]
+  .block-interactivity-`.concat(e,` {pointer-events: none;}
+  .allow-interactivity-`).concat(e,` {pointer-events: all;}
+`)},Xe=0,P=[];function Ye(e){var t=u.useRef([]),r=u.useRef([0,0]),n=u.useRef(),a=u.useState(Xe++)[0],o=u.useState(J)[0],l=u.useRef(e);u.useEffect(function(){l.current=e},[e]),u.useEffect(function(){if(e.inert){document.body.classList.add("block-interactivity-".concat(a));var i=ce([e.lockRef.current],(e.shards||[]).map(_),!0).filter(Boolean);return i.forEach(function(f){return f.classList.add("allow-interactivity-".concat(a))}),function(){document.body.classList.remove("block-interactivit [...]
diff --git a/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 b/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2
new file mode 100644
index 00000000000..0acaaff03d4
Binary files /dev/null and b/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 differ
diff --git a/assets/KaTeX_AMS-Regular-DMm9YOAa.woff b/assets/KaTeX_AMS-Regular-DMm9YOAa.woff
new file mode 100644
index 00000000000..b804d7b33a3
Binary files /dev/null and b/assets/KaTeX_AMS-Regular-DMm9YOAa.woff differ
diff --git a/assets/KaTeX_AMS-Regular-DRggAlZN.ttf b/assets/KaTeX_AMS-Regular-DRggAlZN.ttf
new file mode 100644
index 00000000000..c6f9a5e7c03
Binary files /dev/null and b/assets/KaTeX_AMS-Regular-DRggAlZN.ttf differ
diff --git a/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf b/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf
new file mode 100644
index 00000000000..9ff4a5e0442
Binary files /dev/null and b/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf differ
diff --git a/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff b/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff
new file mode 100644
index 00000000000..9759710d1d3
Binary files /dev/null and b/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff differ
diff --git a/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 b/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2
new file mode 100644
index 00000000000..f390922ecef
Binary files /dev/null and b/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 differ
diff --git a/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff b/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff
new file mode 100644
index 00000000000..9bdd534fd2b
Binary files /dev/null and b/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff differ
diff --git a/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 b/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2
new file mode 100644
index 00000000000..75344a1f98e
Binary files /dev/null and b/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 differ
diff --git a/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf b/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf
new file mode 100644
index 00000000000..f522294ff0f
Binary files /dev/null and b/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf differ
diff --git a/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf b/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf
new file mode 100644
index 00000000000..4e98259c3b5
Binary files /dev/null and b/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf differ
diff --git a/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff b/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff
new file mode 100644
index 00000000000..e7730f66275
Binary files /dev/null and b/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff differ
diff --git a/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 b/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2
new file mode 100644
index 00000000000..395f28beac2
Binary files /dev/null and b/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 differ
diff --git a/assets/KaTeX_Fraktur-Regular-CB_wures.ttf b/assets/KaTeX_Fraktur-Regular-CB_wures.ttf
new file mode 100644
index 00000000000..b8461b275fa
Binary files /dev/null and b/assets/KaTeX_Fraktur-Regular-CB_wures.ttf differ
diff --git a/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 b/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2
new file mode 100644
index 00000000000..735f6948d63
Binary files /dev/null and b/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 differ
diff --git a/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff b/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff
new file mode 100644
index 00000000000..acab069f90b
Binary files /dev/null and b/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff differ
diff --git a/assets/KaTeX_Main-Bold-Cx986IdX.woff2 b/assets/KaTeX_Main-Bold-Cx986IdX.woff2
new file mode 100644
index 00000000000..ab2ad21da6f
Binary files /dev/null and b/assets/KaTeX_Main-Bold-Cx986IdX.woff2 differ
diff --git a/assets/KaTeX_Main-Bold-Jm3AIy58.woff b/assets/KaTeX_Main-Bold-Jm3AIy58.woff
new file mode 100644
index 00000000000..f38136ac1cc
Binary files /dev/null and b/assets/KaTeX_Main-Bold-Jm3AIy58.woff differ
diff --git a/assets/KaTeX_Main-Bold-waoOVXN0.ttf b/assets/KaTeX_Main-Bold-waoOVXN0.ttf
new file mode 100644
index 00000000000..4060e627dc3
Binary files /dev/null and b/assets/KaTeX_Main-Bold-waoOVXN0.ttf differ
diff --git a/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 b/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2
new file mode 100644
index 00000000000..5931794de4a
Binary files /dev/null and b/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 differ
diff --git a/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf b/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf
new file mode 100644
index 00000000000..dc007977ee7
Binary files /dev/null and b/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf differ
diff --git a/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff b/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff
new file mode 100644
index 00000000000..67807b0bd4f
Binary files /dev/null and b/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff differ
diff --git a/assets/KaTeX_Main-Italic-3WenGoN9.ttf b/assets/KaTeX_Main-Italic-3WenGoN9.ttf
new file mode 100644
index 00000000000..0e9b0f354ad
Binary files /dev/null and b/assets/KaTeX_Main-Italic-3WenGoN9.ttf differ
diff --git a/assets/KaTeX_Main-Italic-BMLOBm91.woff b/assets/KaTeX_Main-Italic-BMLOBm91.woff
new file mode 100644
index 00000000000..6f43b594b6c
Binary files /dev/null and b/assets/KaTeX_Main-Italic-BMLOBm91.woff differ
diff --git a/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 b/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2
new file mode 100644
index 00000000000..b50920e1388
Binary files /dev/null and b/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 differ
diff --git a/assets/KaTeX_Main-Regular-B22Nviop.woff2 b/assets/KaTeX_Main-Regular-B22Nviop.woff2
new file mode 100644
index 00000000000..eb24a7ba282
Binary files /dev/null and b/assets/KaTeX_Main-Regular-B22Nviop.woff2 differ
diff --git a/assets/KaTeX_Main-Regular-Dr94JaBh.woff b/assets/KaTeX_Main-Regular-Dr94JaBh.woff
new file mode 100644
index 00000000000..21f5812968c
Binary files /dev/null and b/assets/KaTeX_Main-Regular-Dr94JaBh.woff differ
diff --git a/assets/KaTeX_Main-Regular-ypZvNtVU.ttf b/assets/KaTeX_Main-Regular-ypZvNtVU.ttf
new file mode 100644
index 00000000000..dd45e1ed2e1
Binary files /dev/null and b/assets/KaTeX_Main-Regular-ypZvNtVU.ttf differ
diff --git a/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf b/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf
new file mode 100644
index 00000000000..728ce7a1e2c
Binary files /dev/null and b/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf differ
diff --git a/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 b/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2
new file mode 100644
index 00000000000..29657023adc
Binary files /dev/null and b/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 differ
diff --git a/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff b/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff
new file mode 100644
index 00000000000..0ae390d74c9
Binary files /dev/null and b/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff differ
diff --git a/assets/KaTeX_Math-Italic-DA0__PXp.woff b/assets/KaTeX_Math-Italic-DA0__PXp.woff
new file mode 100644
index 00000000000..eb5159d4c1c
Binary files /dev/null and b/assets/KaTeX_Math-Italic-DA0__PXp.woff differ
diff --git a/assets/KaTeX_Math-Italic-flOr_0UB.ttf b/assets/KaTeX_Math-Italic-flOr_0UB.ttf
new file mode 100644
index 00000000000..70d559b4e93
Binary files /dev/null and b/assets/KaTeX_Math-Italic-flOr_0UB.ttf differ
diff --git a/assets/KaTeX_Math-Italic-t53AETM-.woff2 b/assets/KaTeX_Math-Italic-t53AETM-.woff2
new file mode 100644
index 00000000000..215c143fd78
Binary files /dev/null and b/assets/KaTeX_Math-Italic-t53AETM-.woff2 differ
diff --git a/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf b/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf
new file mode 100644
index 00000000000..2f65a8a3a6d
Binary files /dev/null and b/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf differ
diff --git a/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 b/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2
new file mode 100644
index 00000000000..cfaa3bda592
Binary files /dev/null and b/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 differ
diff --git a/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff b/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff
new file mode 100644
index 00000000000..8d47c02d940
Binary files /dev/null and b/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff differ
diff --git a/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 b/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2
new file mode 100644
index 00000000000..349c06dc609
Binary files /dev/null and b/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 differ
diff --git a/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff b/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff
new file mode 100644
index 00000000000..7e02df96362
Binary files /dev/null and b/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff differ
diff --git a/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf b/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf
new file mode 100644
index 00000000000..d5850df98ec
Binary files /dev/null and b/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf differ
diff --git a/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf b/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf
new file mode 100644
index 00000000000..537279f6bd2
Binary files /dev/null and b/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf differ
diff --git a/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff b/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff
new file mode 100644
index 00000000000..31b84829b42
Binary files /dev/null and b/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff differ
diff --git a/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 b/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2
new file mode 100644
index 00000000000..a90eea85f6f
Binary files /dev/null and b/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 differ
diff --git a/assets/KaTeX_Script-Regular-C5JkGWo-.ttf b/assets/KaTeX_Script-Regular-C5JkGWo-.ttf
new file mode 100644
index 00000000000..fd679bf374a
Binary files /dev/null and b/assets/KaTeX_Script-Regular-C5JkGWo-.ttf differ
diff --git a/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 b/assets/KaTeX_Script-Regular-D3wIWfF6.woff2
new file mode 100644
index 00000000000..b3048fc1156
Binary files /dev/null and b/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 differ
diff --git a/assets/KaTeX_Script-Regular-D5yQViql.woff b/assets/KaTeX_Script-Regular-D5yQViql.woff
new file mode 100644
index 00000000000..0e7da821eee
Binary files /dev/null and b/assets/KaTeX_Script-Regular-D5yQViql.woff differ
diff --git a/assets/KaTeX_Size1-Regular-C195tn64.woff b/assets/KaTeX_Size1-Regular-C195tn64.woff
new file mode 100644
index 00000000000..7f292d91184
Binary files /dev/null and b/assets/KaTeX_Size1-Regular-C195tn64.woff differ
diff --git a/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf b/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf
new file mode 100644
index 00000000000..871fd7d19d8
Binary files /dev/null and b/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf differ
diff --git a/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 b/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2
new file mode 100644
index 00000000000..c5a8462fbfe
Binary files /dev/null and b/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 differ
diff --git a/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf b/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf
new file mode 100644
index 00000000000..7a212caf91c
Binary files /dev/null and b/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf differ
diff --git a/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 b/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2
new file mode 100644
index 00000000000..e1bccfe2403
Binary files /dev/null and b/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 differ
diff --git a/assets/KaTeX_Size2-Regular-oD1tc_U0.woff b/assets/KaTeX_Size2-Regular-oD1tc_U0.woff
new file mode 100644
index 00000000000..d241d9be2d3
Binary files /dev/null and b/assets/KaTeX_Size2-Regular-oD1tc_U0.woff differ
diff --git a/assets/KaTeX_Size3-Regular-CTq5MqoE.woff b/assets/KaTeX_Size3-Regular-CTq5MqoE.woff
new file mode 100644
index 00000000000..e6e9b658dcf
Binary files /dev/null and b/assets/KaTeX_Size3-Regular-CTq5MqoE.woff differ
diff --git a/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf b/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf
new file mode 100644
index 00000000000..00bff3495fa
Binary files /dev/null and b/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf differ
diff --git a/assets/KaTeX_Size4-Regular-BF-4gkZK.woff b/assets/KaTeX_Size4-Regular-BF-4gkZK.woff
new file mode 100644
index 00000000000..e1ec5457664
Binary files /dev/null and b/assets/KaTeX_Size4-Regular-BF-4gkZK.woff differ
diff --git a/assets/KaTeX_Size4-Regular-DWFBv043.ttf b/assets/KaTeX_Size4-Regular-DWFBv043.ttf
new file mode 100644
index 00000000000..74f08921f00
Binary files /dev/null and b/assets/KaTeX_Size4-Regular-DWFBv043.ttf differ
diff --git a/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 b/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2
new file mode 100644
index 00000000000..680c1308507
Binary files /dev/null and b/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 differ
diff --git a/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff b/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff
new file mode 100644
index 00000000000..2432419f289
Binary files /dev/null and b/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff differ
diff --git a/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 b/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2
new file mode 100644
index 00000000000..771f1af705f
Binary files /dev/null and b/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 differ
diff --git a/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf b/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf
new file mode 100644
index 00000000000..c83252c5714
Binary files /dev/null and b/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf differ
diff --git a/assets/WAL_splitting-DCT3Hgkm.png b/assets/WAL_splitting-DCT3Hgkm.png
new file mode 100644
index 00000000000..4dbc322c3ec
Binary files /dev/null and b/assets/WAL_splitting-DCT3Hgkm.png differ
diff --git a/assets/WAL_splitting-S_OUAgmz.js b/assets/WAL_splitting-S_OUAgmz.js
new file mode 100644
index 00000000000..431bdf589c5
--- /dev/null
+++ b/assets/WAL_splitting-S_OUAgmz.js
@@ -0,0 +1 @@
+const s="/assets/region_split_process-DrwL5IoS.png",t="/assets/WAL_splitting-DCT3Hgkm.png";export{s as _,t as a};
diff --git a/assets/acid-semantics-DEgldsHV.js b/assets/acid-semantics-DEgldsHV.js
new file mode 100644
index 00000000000..53eeae77895
--- /dev/null
+++ b/assets/acid-semantics-DEgldsHV.js
@@ -0,0 +1,107 @@
+import{j as e,w as s}from"./chunk-EPOLDU6W-B5LwAila.js";import{M as a}from"./mdx-components-bjiyHZUo.js";import"./mdx-DXQ3RXga.js";import"./index-BE31Pm92.js";import"./index-lnR2ABT4.js";import"./index-FCA4GwU0.js";import"./link-CDX6ZyVQ.js";import"./external-link-jmuPj2if.js";import"./createLucideIcon-BidaCVke.js";e.jsx(e.Fragment,{children:"ACID properties of HBase"}),e.jsx(e.Fragment,{children:"Definitions"}),e.jsx(e.Fragment,{children:"APIs to consider"}),e.jsx(e.Fragment,{children:" [...]
+`,e.jsx(t.p,{children:"Apache HBase (TM) is not an ACID compliant database. However, it does guarantee certain specific properties."}),`
+`,e.jsx(t.h2,{id:"definitions",children:"Definitions"}),`
+`,e.jsx(t.p,{children:"For the sake of common vocabulary, we define the following terms:"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Atomicity"}),`
+an operation is atomic if it either completes entirely or not at all`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Consistency"}),`
+all actions cause the table to transition from one valid state directly to another (eg a row will not disappear during an update, etc)`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Isolation"}),`
+an operation is isolated if it appears to complete independently of any other concurrent transaction`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Durability"}),`
+any update that reports "successful" to the client will not be lost`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Visibility"}),`
+an update is considered visible if any subsequent read will see the update as having been committed`]}),`
+`,e.jsxs(t.p,{children:["The terms ",e.jsx(t.em,{children:"must"})," and ",e.jsx(t.em,{children:"may"}),' are used as specified by RFC 2119. In short, the word "must" implies that, if some case exists where the statement is not true, it is a bug. The word "may" implies that, even if the guarantee is provided in a current release, users should not rely on it.']}),`
+`,e.jsx(t.h2,{id:"apis-to-consider",children:"APIs to consider"}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:["Read APIs",`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"get"}),`
+`,e.jsx(t.li,{children:"scan"}),`
+`]}),`
+`]}),`
+`,e.jsxs(t.li,{children:["Write APIs",`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"put"}),`
+`,e.jsx(t.li,{children:"batch put"}),`
+`,e.jsx(t.li,{children:"delete"}),`
+`]}),`
+`]}),`
+`,e.jsxs(t.li,{children:["Combination (read-modify-write) APIs",`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"incrementColumnValue"}),`
+`,e.jsx(t.li,{children:"checkAndPut"}),`
+`]}),`
+`]}),`
+`]}),`
+`,e.jsx(t.h2,{id:"guarantees-provided",children:"Guarantees Provided"}),`
+`,e.jsx(t.h3,{id:"atomicity",children:"Atomicity"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsxs(t.li,{children:["All mutations are atomic within a row. Any put will either wholly succeed or wholly fail.[3]",`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:'An operation that returns a "success" code has completely succeeded.'}),`
+`,e.jsx(t.li,{children:'An operation that returns a "failure" code has completely failed.'}),`
+`,e.jsx(t.li,{children:"An operation that times out may have succeeded and may have failed. However, it will not have partially succeeded or failed."}),`
+`]}),`
+`]}),`
+`,e.jsx(t.li,{children:"This is true even if the mutation crosses multiple column families within a row."}),`
+`,e.jsxs(t.li,{children:["APIs that mutate several rows will ",e.jsx(t.em,{children:"not"})," be atomic across the multiple rows. For example, a multiput that operates on rows 'a','b', and 'c' may return having mutated some but not all of the rows. In such cases, these APIs will return a list of success codes, each of which may be succeeded, failed, or timed out as described above."]}),`
+`,e.jsx(t.li,{children:"The checkAndPut API happens atomically like the typical compareAndSet (CAS) operation found in many hardware architectures."}),`
+`,e.jsxs(t.li,{children:['The order of mutations is seen to happen in a well-defined order for each row, with no interleaving. For example, if one writer issues the mutation "a=1,b=1,c=1" and another writer issues the mutation "a=2,b=2,c=2", the row must either be "a=1,b=1,c=1" or "a=2,b=2,c=2" and must ',e.jsx(t.em,{children:"not"}),' be something like "a=1,b=2,c=1".',`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsxs(t.li,{children:["Please note that this is not true ",e.jsx(t.em,{children:"across rows"})," for multirow batch mutations."]}),`
+`]}),`
+`]}),`
+`]}),`
+`,e.jsx(t.h3,{id:"consistency-and-isolation",children:"Consistency and Isolation"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"All rows returned via any access API will consist of a complete row that existed at some point in the table's history."}),`
+`,e.jsx(t.li,{children:"This is true across column families - i.e a get of a full row that occurs concurrent with some mutations 1,2,3,4,5 will return a complete row that existed at some point in time between mutation i and i+1 for some i between 1 and 5."}),`
+`,e.jsx(t.li,{children:"The state of a row will only move forward through the history of edits to it."}),`
+`]}),`
+`,e.jsx(t.h4,{id:"consistency-of-scans",children:"Consistency of Scans"}),`
+`,e.jsxs(t.p,{children:["A scan is ",e.jsx(t.strong,{children:"not"})," a consistent view of a table. Scans do ",e.jsx(t.strong,{children:"not"})," exhibit ",e.jsx(t.em,{children:"snapshot isolation"}),"."]}),`
+`,e.jsx(t.p,{children:"Rather, scans have the following properties:"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"Any row returned by the scan will be a consistent view (i.e. that version of the complete row existed at some point in time) [1]"}),`
+`,e.jsxs(t.li,{children:["A scan will always reflect a view of the data ",e.jsx(t.em,{children:"at least as new as"})," the beginning of the scan. This satisfies the visibility guarantees enumerated below.",`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"For example, if client A writes data X and then communicates via a side channel to client B, any scans started by client B will contain data at least as new as X."}),`
+`,e.jsxs(t.li,{children:["A scan ",e.jsx(t.em,{children:"must"})," reflect all mutations committed prior to the construction of the scanner, and ",e.jsx(t.em,{children:"may"})," reflect some mutations committed subsequent to the construction of the scanner."]}),`
+`,e.jsxs(t.li,{children:["Scans must include ",e.jsx(t.em,{children:"all"})," data written prior to the scan (except in the case where data is subsequently mutated, in which case it ",e.jsx(t.em,{children:"may"})," reflect the mutation)"]}),`
+`]}),`
+`]}),`
+`]}),`
+`,e.jsx(t.p,{children:'Those familiar with relational databases will recognize this isolation level as "read committed".'}),`
+`,e.jsxs(t.p,{children:['Please note that the guarantees listed above regarding scanner consistency are referring to "transaction commit time", not the "timestamp" field of each cell. That is to say, a scanner started at time ',e.jsx(t.em,{children:"t"})," may see edits with a timestamp value greater than ",e.jsx(t.em,{children:"t"}),', if those edits were committed with a "forward dated" timestamp before the scanner was constructed.']}),`
+`,e.jsx(t.h3,{id:"visibility",children:"Visibility"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:'When a client receives a "success" response for any mutation, that mutation is immediately visible to both that client and any client with whom it later communicates through side channels. [3]'}),`
+`,e.jsxs(t.li,{children:['A row must never exhibit so-called "time-travel" properties. That is to say, if a series of mutations moves a row sequentially through a series of states, any sequence of concurrent reads will return a subsequence of those states.',`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:`For example, if a row's cells are mutated using the "incrementColumnValue" API, a client must never see the value of any cell decrease.`}),`
+`,e.jsx(t.li,{children:"This is true regardless of which read API is used to read back the mutation."}),`
+`]}),`
+`]}),`
+`,e.jsx(t.li,{children:"Any version of a cell that has been returned to a read operation is guaranteed to be durably stored."}),`
+`]}),`
+`,e.jsx(t.h3,{id:"durability",children:"Durability"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"All visible data is also durable data. That is to say, a read will never return data that has not been made durable on disk[2]"}),`
+`,e.jsx(t.li,{children:'Any operation that returns a "success" code (eg does not throw an exception) will be made durable.[3]'}),`
+`,e.jsx(t.li,{children:'Any operation that returns a "failure" code will not be made durable (subject to the Atomicity guarantees above)'}),`
+`,e.jsx(t.li,{children:"All reasonable failure scenarios will not affect any of the guarantees of this document."}),`
+`]}),`
+`,e.jsx(t.h3,{id:"tunability",children:"Tunability"}),`
+`,e.jsx(t.p,{children:"All of the above guarantees must be possible within Apache HBase. For users who would like to trade off some guarantees for performance, HBase may offer several tuning options. For example:"}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"Visibility may be tuned on a per-read basis to allow stale reads or time travel."}),`
+`,e.jsx(t.li,{children:"Durability may be tuned to only flush data to disk on a periodic basis"}),`
+`]}),`
+`,e.jsx(t.h2,{id:"more-information",children:"More Information"}),`
+`,e.jsxs(t.p,{children:["For more information, see the ",e.jsx(t.a,{href:"/docs/architecture/client",children:"client architecture"})," or ",e.jsx(t.a,{href:"/docs/datamodel",children:"data model"})," sections in the Apache HBase Reference Guide."]}),`
+`,e.jsx(t.h2,{id:"footnotes",children:"Footnotes"}),`
+`,e.jsxs(t.p,{children:["[1] A consistent view is not guaranteed intra-row scanning -- i.e. fetching a portion of a row in one RPC then going back to fetch another portion of the row in a subsequent RPC. Intra-row scanning happens when you set a limit on how many values to return per Scan#next (See ",e.jsx(t.a,{href:"http://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Scan.html#setBatch(int)",children:"Scan#setBatch(int)"}),")."]}),`
+`,e.jsx(t.p,{children:'[2] In the context of Apache HBase, "durably on disk" implies an hflush() call on the transaction log. This does not actually imply an fsync() to magnetic media, but rather just that the data has been written to the OS cache on all replicas of the log. In the case of a full datacenter power loss, it is possible that the edits are not truly durable.'}),`
+`,e.jsx(t.p,{children:"[3] Puts will either wholly succeed or wholly fail, provided that they are actually sent to the RegionServer. If the writebuffer is used, Puts will not be sent until the writebuffer is filled or it is explicitly flushed."})]})}function r(n={}){const{wrapper:t}=n.components||{};return t?e.jsx(t,{...n,children:e.jsx(i,{...n})}):i(n)}function o(){return e.jsx(a,{Content:r,className:"mt-12"})}function j({}){return[{title:"ACID Semantics - Apache HBase"},{name:"descript [...]
diff --git a/assets/acl-matrix-CGfUZxnC.js b/assets/acl-matrix-CGfUZxnC.js
new file mode 100644
index 00000000000..7c86c93b1e1
--- /dev/null
+++ b/assets/acl-matrix-CGfUZxnC.js
@@ -0,0 +1,189 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let n=`## Interpreting the ACL Matrix Table
+
+The following conventions are used in the ACL Matrix table:
+
+### Scopes
+
+Permissions are evaluated starting at the widest scope and working to the narrowest scope.
+
+A scope corresponds to a level of the data model. From broadest to narrowest, the scopes are as follows:
+
+#### Scopes
+
+* Global
+* Namespace (NS)
+* Table
+* Column Family (CF)
+* Column Qualifier (CQ)
+* Cell
+
+For instance, a permission granted at table level dominates any grants done at the Column Family, Column Qualifier, or cell level. The user can do what that grant implies at any location in the table. A permission granted at global scope dominates all: the user is always allowed to take that action everywhere.
+
+### Permissions
+
+Possible permissions include the following:
+
+#### Permissions
+
+* Superuser - a special user that belongs to group "supergroup" and has unlimited access
+* Admin (A)
+* Create (C)
+* Write (W)
+* Read (R)
+* Execute (X)
+
+For the most part, permissions work in an expected way, with the following caveats:
+
+**Having Write permission does not imply Read permission.**\\
+It is possible and sometimes desirable for a user to be able to write data that same user cannot read. One such example is a log-writing process.
+
+**The \`hbase:meta\` table is readable by every user, regardless of the user's other grants or restrictions.**\\
+This is a requirement for HBase to function correctly.
+
+**\`CheckAndPut\` and \`CheckAndDelete\` operations will fail if the user does not have both Write and Read permission.**\\
+**\`Increment\` and \`Append\` operations do not require Read access.**\\
+**The \`superuser\`, as the name suggests has permissions to perform all possible operations.**\\
+**And for the operations marked with \\*, the checks are done in post hook and only subset of results satisfying access checks are returned back to the user.**\\
+The following table is sorted by the interface that provides each operation.
+In case the table goes out of date, the unit tests which check for accuracy of permissions can be found in *hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java*, and the access controls themselves can be examined in *hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java*.
+
+## ACL Matrix
+
+| Interface        | Operation                           | Permissions                                                                                         |
+| ---------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------- |
+| Master           | createTable                         | superuser\\|global(C)\\|NS(C)                                                                         |
+|                  | modifyTable                         | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | deleteTable                         | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | truncateTable                       | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | addColumn                           | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | modifyColumn                        | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)\\|column(A)\\|column(C) |
+|                  | deleteColumn                        | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)\\|column(A)\\|column(C) |
+|                  | enableTable                         | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | disableTable                        | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | disableAclTable                     | Not allowed                                                                                         |
+|                  | move                                | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | assign                              | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | unassign                            | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | regionOffline                       | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | balance                             | superuser\\|global(A)                                                                                |
+|                  | balanceSwitch                       | superuser\\|global(A)                                                                                |
+|                  | shutdown                            | superuser\\|global(A)                                                                                |
+|                  | stopMaster                          | superuser\\|global(A)                                                                                |
+|                  | snapshot                            | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | listSnapshot                        | superuser\\|global(A)\\|SnapshotOwner                                                                 |
+|                  | cloneSnapshot                       | superuser\\|global(A)\\|(SnapshotOwner & TableName matches)                                           |
+|                  | restoreSnapshot                     | superuser\\|global(A)\\|SnapshotOwner & (NS(A)\\|TableOwner\\|table(A))                                 |
+|                  | deleteSnapshot                      | superuser\\|global(A)\\|SnapshotOwner                                                                 |
+|                  | createNamespace                     | superuser\\|global(A)                                                                                |
+|                  | deleteNamespace                     | superuser\\|global(A)                                                                                |
+|                  | modifyNamespace                     | superuser\\|global(A)                                                                                |
+|                  | getNamespaceDescriptor              | superuser\\|global(A)\\|NS(A)                                                                         |
+|                  | listNamespaceDescriptors\\*          | superuser\\|global(A)\\|NS(A)                                                                         |
+|                  | flushTable                          | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | getTableDescriptors\\*               | superuser\\|global(A)\\|global(C)\\|NS(A)\\|NS(C)\\|TableOwner\\|table(A)\\|table(C)                       |
+|                  | getTableNames\\*                     | superuser\\|TableOwner\\|Any global or table perm                                                     |
+|                  | setUserQuota(global level)          | superuser\\|global(A)                                                                                |
+|                  | setUserQuota(namespace level)       | superuser\\|global(A)                                                                                |
+|                  | setUserQuota(Table level)           | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | setTableQuota                       | superuser\\|global(A)\\|NS(A)\\|TableOwner\\|table(A)                                                   |
+|                  | setNamespaceQuota                   | superuser\\|global(A)                                                                                |
+|                  | addReplicationPeer                  | superuser\\|global(A)                                                                                |
+|                  | removeReplicationPeer               | superuser\\|global(A)                                                                                |
+|                  | enableReplicationPeer               | superuser\\|global(A)                                                                                |
+|                  | disableReplicationPeer              | superuser\\|global(A)                                                                                |
+|                  | getReplicationPeerConfig            | superuser\\|global(A)                                                                                |
+|                  | updateReplicationPeerConfig         | superuser\\|global(A)                                                                                |
+|                  | listReplicationPeers                | superuser\\|global(A)                                                                                |
+|                  | getClusterStatus                    | any user                                                                                            |
+| Region           | openRegion                          | superuser\\|global(A)                                                                                |
+|                  | closeRegion                         | superuser\\|global(A)                                                                                |
+|                  | flush                               | superuser\\|global(A)\\|global(C)\\|TableOwner\\|table(A)\\|table(C)                                     |
+|                  | split                               | superuser\\|global(A)\\|TableOwner\\|TableOwner\\|table(A)                                              |
+|                  | compact                             | superuser\\|global(A)\\|global(C)\\|TableOwner\\|table(A)\\|table(C)                                     |
+|                  | getClosestRowBefore                 | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | getOp                               | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | exists                              | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | put                                 | superuser\\|global(W)\\|NS(W)\\|table(W)\\|TableOwner\\|CF(W)\\|CQ(W)                                     |
+|                  | delete                              | superuser\\|global(W)\\|NS(W)\\|table(W)\\|TableOwner\\|CF(W)\\|CQ(W)                                     |
+|                  | batchMutate                         | superuser\\|global(W)\\|NS(W)\\|TableOwner\\|table(W)\\|CF(W)\\|CQ(W)                                     |
+|                  | checkAndPut                         | superuser\\|global(RW)\\|NS(RW)\\|TableOwner\\|table(RW)\\|CF(RW)\\|CQ(RW)                                |
+|                  | checkAndPutAfterRowLock             | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|Table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | checkAndDelete                      | superuser\\|global(RW)\\|NS(RW)\\|TableOwner\\|table(RW)\\|CF(RW)\\|CQ(RW)                                |
+|                  | checkAndDeleteAfterRowLock          | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | incrementColumnValue                | superuser\\|global(W)\\|NS(W)\\|TableOwner\\|table(W)\\|CF(W)\\|CQ(W)                                     |
+|                  | append                              | superuser\\|global(W)\\|NS(W)\\|TableOwner\\|table(W)\\|CF(W)\\|CQ(W)                                     |
+|                  | appendAfterRowLock                  | superuser\\|global(W)\\|NS(W)\\|TableOwner\\|table(W)\\|CF(W)\\|CQ(W)                                     |
+|                  | increment                           | superuser\\|global(W)\\|NS(W)\\|TableOwner\\|table(W)\\|CF(W)\\|CQ(W)                                     |
+|                  | incrementAfterRowLock               | superuser\\|global(W)\\|NS(W)\\|TableOwner\\|table(W)\\|CF(W)\\|CQ(W)                                     |
+|                  | scannerOpen                         | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | scannerNext                         | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | scannerClose                        | superuser\\|global(R)\\|NS(R)\\|TableOwner\\|table(R)\\|CF(R)\\|CQ(R)                                     |
+|                  | bulkLoadHFile                       | superuser\\|global(C)\\|TableOwner\\|table(C)\\|CF(C)                                                   |
+|                  | prepareBulkLoad                     | superuser\\|global(C)\\|TableOwner\\|table(C)\\|CF(C)                                                   |
+|                  | cleanupBulkLoad                     | superuser\\|global(C)\\|TableOwner\\|table(C)\\|CF(C)                                                   |
+| Endpoint         | invoke                              | superuser\\|global(X)\\|NS(X)\\|TableOwner\\|table(X)                                                   |
+| AccessController | grant(global level)                 | global(A)                                                                                           |
+|                  | grant(namespace level)              | global(A)\\|NS(A)                                                                                    |
+|                  | grant(table level)                  | global(A)\\|NS(A)\\|TableOwner\\|table(A)\\|CF(A)\\|CQ(A)                                                |
+|                  | revoke(global level)                | global(A)                                                                                           |
+|                  | revoke(namespace level)             | global(A)\\|NS(A)                                                                                    |
+|                  | revoke(table level)                 | global(A)\\|NS(A)\\|TableOwner\\|table(A)\\|CF(A)\\|CQ(A)                                                |
+|                  | getUserPermissions(global level)    | global(A)                                                                                           |
+|                  | getUserPermissions(namespace level) | global(A)\\|NS(A)                                                                                    |
+|                  | getUserPermissions(table level)     | global(A)\\|NS(A)\\|TableOwner\\|table(A)\\|CF(A)\\|CQ(A)                                                |
+|                  | hasPermission(table level)          | global(A)\\|SelfUserCheck                                                                            |
+| RegionServer     | stopRegionServer                    | superuser\\|global(A)                                                                                |
+|                  | mergeRegions                        | superuser\\|global(A)                                                                                |
+|                  | rollWALWriterRequest                | superuser\\|global(A)                                                                                |
+|                  | replicateLogEntries                 | superuser\\|global(W)                                                                                |
+| RSGroup          | addRSGroup                          | superuser\\|global(A)                                                                                |
+|                  | balanceRSGroup                      | superuser\\|global(A)                                                                                |
+|                  | getRSGroupInfo                      | superuser\\|global(A)                                                                                |
+|                  | getRSGroupInfoOfTable               | superuser\\|global(A)                                                                                |
+|                  | getRSGroupOfServer                  | superuser\\|global(A)                                                                                |
+|                  | listRSGroups                        | superuser\\|global(A)                                                                                |
+|                  | moveServers                         | superuser\\|global(A)                                                                                |
+|                  | moveServersAndTables                | superuser\\|global(A)                                                                                |
+|                  | moveTables                          | superuser\\|global(A)                                                                                |
+|                  | removeRSGroup                       | superuser\\|global(A)                                                                                |
+|                  | removeServers                       | superuser\\|global(A)                                                                                |
+`,s={title:"Access Control Matrix",description:"The following matrix shows the permission set required to perform operations in HBase. Before using the table, read through the information about how to interpret it."},i=[],o={contents:[{heading:"interpreting-the-acl-matrix-table",content:"The following conventions are used in the ACL Matrix table:"},{heading:"scopes",content:"Permissions are evaluated starting at the widest scope and working to the narrowest scope."},{heading:"scopes",con [...]
+In case the table goes out of date, the unit tests which check for accuracy of permissions can be found in hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java, and the access controls themselves can be examined in hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java.`},{heading:"acl-matrix",content:"Interface"},{heading:"acl-matrix",content:"Operation"},{heading:"acl-matrix",content:"Permissions"},{heading:"acl- [...]
+`,e.jsx(l.p,{children:"The following conventions are used in the ACL Matrix table:"}),`
+`,e.jsx(l.h3,{id:"scopes",children:"Scopes"}),`
+`,e.jsx(l.p,{children:"Permissions are evaluated starting at the widest scope and working to the narrowest scope."}),`
+`,e.jsx(l.p,{children:"A scope corresponds to a level of the data model. From broadest to narrowest, the scopes are as follows:"}),`
+`,e.jsx(l.h4,{id:"scopes-1",children:"Scopes"}),`
+`,e.jsxs(l.ul,{children:[`
+`,e.jsx(l.li,{children:"Global"}),`
+`,e.jsx(l.li,{children:"Namespace (NS)"}),`
+`,e.jsx(l.li,{children:"Table"}),`
+`,e.jsx(l.li,{children:"Column Family (CF)"}),`
+`,e.jsx(l.li,{children:"Column Qualifier (CQ)"}),`
+`,e.jsx(l.li,{children:"Cell"}),`
+`]}),`
+`,e.jsx(l.p,{children:"For instance, a permission granted at table level dominates any grants done at the Column Family, Column Qualifier, or cell level. The user can do what that grant implies at any location in the table. A permission granted at global scope dominates all: the user is always allowed to take that action everywhere."}),`
+`,e.jsx(l.h3,{id:"permissions",children:"Permissions"}),`
+`,e.jsx(l.p,{children:"Possible permissions include the following:"}),`
+`,e.jsx(l.h4,{id:"permissions-1",children:"Permissions"}),`
+`,e.jsxs(l.ul,{children:[`
+`,e.jsx(l.li,{children:'Superuser - a special user that belongs to group "supergroup" and has unlimited access'}),`
+`,e.jsx(l.li,{children:"Admin (A)"}),`
+`,e.jsx(l.li,{children:"Create (C)"}),`
+`,e.jsx(l.li,{children:"Write (W)"}),`
+`,e.jsx(l.li,{children:"Read (R)"}),`
+`,e.jsx(l.li,{children:"Execute (X)"}),`
+`]}),`
+`,e.jsx(l.p,{children:"For the most part, permissions work in an expected way, with the following caveats:"}),`
+`,e.jsxs(l.p,{children:[e.jsx(l.strong,{children:"Having Write permission does not imply Read permission."}),e.jsx(l.br,{}),`
+`,"It is possible and sometimes desirable for a user to be able to write data that same user cannot read. One such example is a log-writing process."]}),`
+`,e.jsxs(l.p,{children:[e.jsxs(l.strong,{children:["The ",e.jsx(l.code,{children:"hbase:meta"})," table is readable by every user, regardless of the user's other grants or restrictions."]}),e.jsx(l.br,{}),`
+`,"This is a requirement for HBase to function correctly."]}),`
+`,e.jsxs(l.p,{children:[e.jsxs(l.strong,{children:[e.jsx(l.code,{children:"CheckAndPut"})," and ",e.jsx(l.code,{children:"CheckAndDelete"})," operations will fail if the user does not have both Write and Read permission."]}),e.jsx(l.br,{}),`
+`,e.jsxs(l.strong,{children:[e.jsx(l.code,{children:"Increment"})," and ",e.jsx(l.code,{children:"Append"})," operations do not require Read access."]}),e.jsx(l.br,{}),`
+`,e.jsxs(l.strong,{children:["The ",e.jsx(l.code,{children:"superuser"}),", as the name suggests has permissions to perform all possible operations."]}),e.jsx(l.br,{}),`
+`,e.jsx(l.strong,{children:"And for the operations marked with *, the checks are done in post hook and only subset of results satisfying access checks are returned back to the user."}),e.jsx(l.br,{}),`
+`,`The following table is sorted by the interface that provides each operation.
+In case the table goes out of date, the unit tests which check for accuracy of permissions can be found in `,e.jsx(l.em,{children:"hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java"}),", and the access controls themselves can be examined in ",e.jsx(l.em,{children:"hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java"}),"."]}),`
+`,e.jsx(l.h2,{id:"acl-matrix",children:"ACL Matrix"}),`
+`,e.jsxs(l.table,{children:[e.jsx(l.thead,{children:e.jsxs(l.tr,{children:[e.jsx(l.th,{children:"Interface"}),e.jsx(l.th,{children:"Operation"}),e.jsx(l.th,{children:"Permissions"})]})}),e.jsxs(l.tbody,{children:[e.jsxs(l.tr,{children:[e.jsx(l.td,{children:"Master"}),e.jsx(l.td,{children:"createTable"}),e.jsx(l.td,{children:"superuser|global(C)|NS(C)"})]}),e.jsxs(l.tr,{children:[e.jsx(l.td,{}),e.jsx(l.td,{children:"modifyTable"}),e.jsx(l.td,{children:"superuser|global(A)|global(C)|NS(A)| [...]
diff --git a/assets/adding_filters-q0nqzySF.gif b/assets/adding_filters-q0nqzySF.gif
new file mode 100644
index 00000000000..4c33d530666
Binary files /dev/null and b/assets/adding_filters-q0nqzySF.gif differ
diff --git a/assets/additional-topics-ss_W768g.js b/assets/additional-topics-ss_W768g.js
new file mode 100644
index 00000000000..23f3bc976ea
--- /dev/null
+++ b/assets/additional-topics-ss_W768g.js
@@ -0,0 +1,624 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";import{_ as i}from"./backup-app-components-ChSULF98.js";let c=`
+
+## Configuration keys
+
+The backup and restore feature includes both required and optional configuration keys.
+
+### Required properties
+
+***hbase.backup.enable***: Controls whether or not the feature is enabled (Default: \`false\`). Set this value to \`true\`.
+
+***hbase.master.logcleaner.plugins***: A comma-separated list of classes invoked when cleaning logs in the HBase Master. Set
+this value to \`org.apache.hadoop.hbase.backup.master.BackupLogCleaner\` or append it to the current value.
+
+***hbase.procedure.master.classes***: A comma-separated list of classes invoked with the Procedure framework in the Master. Set
+this value to \`org.apache.hadoop.hbase.backup.master.LogRollMasterProcedureManager\` or append it to the current value.
+
+***hbase.procedure.regionserver.classes***: A comma-separated list of classes invoked with the Procedure framework in the RegionServer.
+Set this value to \`org.apache.hadoop.hbase.backup.regionserver.LogRollRegionServerProcedureManager\` or append it to the current value.
+
+***hbase.coprocessor.region.classes***: A comma-separated list of RegionObservers deployed on tables. Set this value to
+\`org.apache.hadoop.hbase.backup.BackupObserver\` or append it to the current value.
+
+***hbase.coprocessor.master.classes***: A comma-separated list of MasterObservers deployed on tables. Set this value to
+\`org.apache.hadoop.hbase.backup.BackupMasterObserver\` or append it to the current value.
+
+***hbase.master.hfilecleaner.plugins***: A comma-separated list of HFileCleaners deployed on the Master. Set this value
+to \`org.apache.hadoop.hbase.backup.BackupHFileCleaner\` or append it to the current value.
+
+### Optional properties
+
+***hbase.backup.system.ttl***: The time-to-live in seconds of data in the \`hbase:backup\` tables (default: forever). This property
+is only relevant prior to the creation of the \`hbase:backup\` table. Use the \`alter\` command in the HBase shell to modify the TTL
+when this table already exists. See the [below section](/docs/backup-restore/additional-topics#a-warning-on-file-system-growth) for more details on the impact of this
+configuration property.
+
+***hbase.backup.attempts.max***: The number of attempts to perform when taking hbase table snapshots (default: 10).
+
+***hbase.backup.attempts.pause.ms***: The amount of time to wait between failed snapshot attempts in milliseconds (default: 10000).
+
+***hbase.backup.logroll.timeout.millis***: The amount of time (in milliseconds) to wait for RegionServers to execute a WAL rolling
+in the Master's procedure framework (default: 30000).
+
+## Best Practices
+
+### Formulate a restore strategy and test it.
+
+Before you rely on a backup and restore strategy for your production environment, identify how backups must be performed,
+and more importantly, how restores must be performed. Test the plan to ensure that it is workable.
+At a minimum, store backup data from a production cluster on a different cluster or server. To further safeguard the data,
+use a backup location that is at a different physical location.
+
+If you have a unrecoverable loss of data on your primary production cluster as a result of computer system issues, you may
+be able to restore the data from a different cluster or server at the same site. However, a disaster that destroys the whole
+site renders locally stored backups useless. Consider storing the backup data and necessary resources (both computing capacity
+and operator expertise) to restore the data at a site sufficiently remote from the production site. In the case of a catastrophe
+at the whole primary site (fire, earthquake, etc.), the remote backup site can be very valuable.
+
+### Secure a full backup image first.
+
+As a baseline, you must complete a full backup of HBase data at least once before you can rely on incremental backups. The full
+backup should be stored outside of the source cluster. To ensure complete dataset recovery, you must run the restore utility
+with the option to restore baseline full backup. The full backup is the foundation of your dataset. Incremental backup data
+is applied on top of the full backup during the restore operation to return you to the point in time when backup was last taken.
+
+### Define and use backup sets for groups of tables that are logical subsets of the entire dataset.
+
+You can group tables into an object called a backup set. A backup set can save time when you have a particular group of tables
+that you expect to repeatedly back up or restore.
+
+When you create a backup set, you type table names to include in the group. The backup set includes not only groups of related
+tables, but also retains the HBase backup metadata. Afterwards, you can invoke the backup set name to indicate what tables apply
+to the command execution instead of entering all the table names individually.
+
+### Document the backup and restore strategy, and ideally log information about each backup.
+
+Document the whole process so that the knowledge base can transfer to new administrators after employee turnover. As an extra
+safety precaution, also log the calendar date, time, and other relevant details about the data of each backup. This metadata
+can potentially help locate a particular dataset in case of source cluster failure or primary site disaster. Maintain duplicate
+copies of all documentation: one copy at the production cluster site and another at the backup location or wherever it can be
+accessed by an administrator remotely from the production cluster.
+
+## Scenario: Safeguarding Application Datasets on Amazon S3
+
+This scenario describes how a hypothetical retail business uses backups to safeguard application data and then restore the dataset
+after failure.
+
+The HBase administration team uses backup sets to store data from a group of tables that have interrelated information for an
+application called green. In this example, one table contains transaction records and the other contains customer details. The
+two tables need to be backed up and be recoverable as a group.
+
+The admin team also wants to ensure daily backups occur automatically.
+
+<img alt="Tables Composing The Backup Set" src={__img0} placeholder="blur" />
+
+The following is an outline of the steps and examples of commands that are used to backup the data for the *green* application and
+to recover the data later. All commands are run when logged in as HBase superuser.
+
+* A backup set called *green\\_set* is created as an alias for both the transactions table and the customer table. The backup set can
+  be used for all operations to avoid typing each table name. The backup set name is case-sensitive and should be formed with only
+  printable characters and without spaces.
+
+  \`\`\`bash
+  $ hbase backup set add green_set transactions
+  $ hbase backup set add green_set customer
+  \`\`\`
+
+* The first backup of green\\_set data must be a full backup. The following command example shows how credentials are passed to Amazon
+  S3 and specifies the file system with the s3a: prefix.
+
+  \`\`\`bash
+  $ ACCESS_KEY=ABCDEFGHIJKLMNOPQRST
+  $ SECRET_KEY=123456789abcdefghijklmnopqrstuvwxyzABCD
+  $ sudo -u hbase hbase backup create full\\
+    s3a://$ACCESS_KEY:SECRET_KEY@prodhbasebackups/backups -s green_set
+  \`\`\`
+
+* Incremental backups should be run according to a schedule that ensures essential data recovery in the event of a catastrophe. At
+  this retail company, the HBase admin team decides that automated daily backups secures the data sufficiently. The team decides that
+  they can implement this by modifying an existing Cron job that is defined in \`/etc/crontab\`. Consequently, IT modifies the Cron job
+  by adding the following line:
+
+  \`\`\`bash
+  @daily hbase hbase backup create incremental s3a://$ACCESS_KEY:$SECRET_KEY@prodhbasebackups/backups -s green_set
+  \`\`\`
+
+* A catastrophic IT incident disables the production cluster that the green application uses. An HBase system administrator of the
+  backup cluster must restore the *green\\_set* dataset to the point in time closest to the recovery objective.
+
+  <Callout type="info">
+    If the administrator of the backup HBase cluster has the backup ID with relevant details in accessible records, the following
+    search with the \`hdfs dfs -ls\` command and manually scanning the backup ID list can be bypassed. Consider continuously maintaining
+    and protecting a detailed log of backup IDs outside the production cluster in your environment.
+  </Callout>
+
+  The HBase administrator runs the following command on the directory where backups are stored to print the list of successful backup
+  IDs on the console:
+
+  \`\`\`bash
+  hdfs dfs -ls -t /prodhbasebackups/backups
+  \`\`\`
+
+* The admin scans the list to see which backup was created at a date and time closest to the recovery objective. To do this, the
+  admin converts the calendar timestamp of the recovery point in time to Unix time because backup IDs are uniquely identified with
+  Unix time. The backup IDs are listed in reverse chronological order, meaning the most recent successful backup appears first.
+
+  The admin notices that the following line in the command output corresponds with the *green\\_set* backup that needs to be restored:
+
+  \`\`\`bash
+  /prodhbasebackups/backups/backup_1467823988425\`
+  \`\`\`
+
+* The admin restores green\\_set invoking the backup ID and the -overwrite option. The -overwrite option truncates all existing data
+  in the destination and populates the tables with data from the backup dataset. Without this flag, the backup data is appended to the
+  existing data in the destination. In this case, the admin decides to overwrite the data because it is corrupted.
+
+  \`\`\`bash
+  $ sudo -u hbase hbase restore -s green_set \\
+    s3a://$ACCESS_KEY:$SECRET_KEY@prodhbasebackups/backups backup_1467823988425 \\ -overwrite
+  \`\`\`
+
+## Security of Backup Data
+
+With this feature which makes copying data to remote locations, it's important to take a moment to clearly state the procedural
+concerns that exist around data security. Like the HBase replication feature, backup and restore provides the constructs to automatically
+copy data from within a corporate boundary to some system outside of that boundary. It is imperative when storing sensitive data that with backup and restore, much
+less any feature which extracts data from HBase, the locations to which data is being sent has undergone a security audit to ensure
+that only authenticated users are allowed to access that data.
+
+For example, with the above example of backing up data to S3, it is of the utmost importance that the proper permissions are assigned
+to the S3 bucket to ensure that only a minimum set of authorized users are allowed to access this data. Because the data is no longer
+being accessed via HBase, and its authentication and authorization controls, we must ensure that the filesystem storing that data is
+providing a comparable level of security. This is a manual step which users **must** implement on their own.
+
+## Technical Details of Incremental Backup and Restore
+
+HBase incremental backups enable more efficient capture of HBase table images than previous attempts
+at serial backup and restore solutions, such as those that only used HBase Export and Import APIs.
+Incremental backups use Write Ahead Logs (WALs) to capture the data changes since the
+previous backup was created. A WAL roll (create new WALs) is executed across all RegionServers
+to track the WALs that need to be in the backup.
+In addition to WALs, incremental backups also track bulk-loaded HFiles for tables under backup.
+
+Incremental backup gathers all WAL files generated since the last backup from the source cluster,
+converts them to HFiles in a \`.tmp\` directory under the \`BACKUP_ROOT\`, and then moves these
+HFiles to their final location under the backup root directory to form the backup image.
+It also reads bulk load records from the backup system table, forms the paths for the corresponding
+bulk-loaded HFiles, and copies those files to the backup destination.
+Bulk-loaded files are preserved (not deleted by cleaner chores) until they've been included in a
+backup (for each backup root).
+A process similar to the DistCp (distributed copy) tool is used to move the backup files to the
+target file system.
+
+When a table restore operation starts, a two-step process is initiated.
+First, the full backup is restored from the full backup image.
+Second, all HFiles from incremental backups between the last full backup and the incremental backup
+being restored (including bulk-loaded HFiles) are bulk loaded into the table using the
+HBase Bulk Load utility.
+
+You can only restore on a live HBase cluster because the data must be redistributed to complete the restore operation successfully.
+
+## A Warning on File System Growth
+
+As a reminder, incremental backups are implemented via retaining the write-ahead logs which HBase primarily uses for data durability.
+Thus, to ensure that all data needing to be included in a backup is still available in the system, the HBase backup and restore feature
+retains all write-ahead logs since the last backup until the next incremental backup is executed.
+
+Like HBase Snapshots, this can have an expectedly large impact on the HDFS usage of HBase for high volume tables. Take care in enabling
+and using the backup and restore feature, specifically with a mind to removing backup sessions when they are not actively being used.
+
+The only automated, upper-bound on retained write-ahead logs for backup and restore is based on the TTL of the \`hbase:backup\` system table which,
+as of the time this document is written, is infinite (backup table entries are never automatically deleted). This requires that administrators
+perform backups on a schedule whose frequency is relative to the amount of available space on HDFS (e.g. less available HDFS space requires
+more aggressive backup merges and deletions). As a reminder, the TTL can be altered on the \`hbase:backup\` table using the \`alter\` command
+in the HBase shell. Modifying the configuration property \`hbase.backup.system.ttl\` in hbase-site.xml after the system table exists has no effect.
+
+## Capacity Planning
+
+When designing a distributed system deployment, it is critical that some basic mathmatical rigor is executed to ensure sufficient computational
+capacity is available given the data and software requirements of the system. For this feature, the availability of network capacity is the largest
+bottleneck when estimating the performance of some implementation of backup and restore. The second most costly function is the speed at which
+data can be read/written.
+
+### Full Backups
+
+To estimate the duration of a full backup, we have to understand the general actions which are invoked:
+
+* Write-ahead log roll on each RegionServer: ones to tens of seconds per RegionServer in parallel. Relative to the load on each RegionServer.
+* Take an HBase snapshot of the table(s): tens of seconds. Relative to the number of regions and files that comprise the table.
+* Export the snapshot to the destination: see below. Relative to the size of the data and the network bandwidth to the destination.
+
+To approximate how long the final step will take, we have to make some assumptions on hardware. Be aware that these will *not* be accurate for your
+system โ€” these are numbers that your or your administrator know for your system. Let's say the speed of reading data from HDFS on a single node is
+capped at 80MB/s (across all Mappers that run on that host), a modern network interface controller (NIC) supports 10Gb/s, the top-of-rack switch can
+handle 40Gb/s, and the WAN between your clusters is 10Gb/s. This means that you can only ship data to your remote at a speed of 1.25GB/s โ€” meaning
+that 16 nodes (\`1.25 * 1024 / 80 = 16\`) participating in the ExportSnapshot should be able to fully saturate the link between clusters. With more
+nodes in the cluster, we can still saturate the network but at a lesser impact on any one node which helps ensure local SLAs are made. If the size
+of the snapshot is 10TB, this would full backup would take in the ballpark of 2.5 hours (\`10 * 1024 / 1.25 / (60 * 60) = 2.23hrs\`)
+
+As a general statement, it is very likely that the WAN bandwidth between your local cluster and the remote storage is the largest
+bottleneck to the speed of a full backup.
+
+When the concern is restricting the computational impact of backups to a "production system", the above formulas can be reused with the optional
+command-line arguments to \`hbase backup create\`: \`-b\`, \`-w\`, \`-q\`. The \`-b\` option defines the bandwidth at which each worker (Mapper) would
+write data. The \`-w\` argument limits the number of workers that would be spawned in the DistCp job. The \`-q\` allows the user to specify a YARN
+queue which can limit the specific nodes where the workers will be spawned โ€” this can quarantine the backup workers performing the copy to
+a set of non-critical nodes. Relating the \`-b\` and \`-w\` options to our earlier equations: \`-b\` would be used to restrict each node from reading
+data at the full 80MB/s and \`-w\` is used to limit the job from spawning 16 worker tasks.
+
+### Incremental Backup
+
+Like we did for full backups, we have to understand the incremental backup process to approximate its runtime and cost.
+
+* Identify new write-ahead logs since the last full or incremental backup: negligible. Apriori knowledge from the backup system table(s).
+* Read, filter, and write "minimized" HFiles equivalent to the WALs: dominated by the speed of writing data. Relative to write speed of HDFS.
+* Read bulk load records from the backup system table, form the paths for bulk-loaded HFiles, and copy them to the backup destination.
+* DistCp the HFiles to the destination: [see above](/docs/backup-restore/additional-topics#full-backups).
+
+For the second step, the dominating cost of this operation would be the re-writing the data (under the assumption that a majority of the
+data in the WAL is preserved). In this case, we can assume an aggregate write speed of 30MB/s per node. Continuing our 16-node cluster example,
+this would require approximately 15 minutes to perform this step for 50GB of data (50 \\* 1024 / 60 / 60 = 14.2). The amount of time to start the
+DistCp MapReduce job would likely dominate the actual time taken to copy the data (50 / 1.25 = 40 seconds) and can be ignored.
+
+## Limitations of the Backup and Restore Utility
+
+**Serial backup operations**\\
+Backup operations cannot be run concurrently. An operation includes actions like create, delete, restore, and merge. Only one active backup session is supported. [HBASE-16391](https://issues.apache.org/jira/browse/HBASE-16391)
+will introduce multiple-backup sessions support.
+
+**No means to cancel backups**\\
+Both backup and restore operations cannot be canceled. ([HBASE-15997](https://issues.apache.org/jira/browse/HBASE-15997), [HBASE-15998](https://issues.apache.org/jira/browse/HBASE-15998)).
+The workaround to cancel a backup would be to kill the client-side backup command (\`control-C\`), ensure all relevant MapReduce jobs have exited, and then
+run the \`hbase backup repair\` command to ensure the system backup metadata is consistent.
+
+**Backups can only be saved to a single location**\\
+Copying backup information to multiple locations is an exercise left to the user. [HBASE-15476](https://issues.apache.org/jira/browse/HBASE-15476) will
+introduce the ability to specify multiple-backup destinations intrinsically.
+
+**HBase superuser access is required**\\
+Only an HBase superuser (e.g. hbase) is allowed to perform backup/restore, can pose a problem for shared HBase installations. Current mitigations would require
+coordination with system administrators to build and deploy a backup and restore strategy ([HBASE-14138](https://issues.apache.org/jira/browse/HBASE-14138)).
+
+**Backup restoration is an online operation**\\
+To perform a restore from a backup, it requires that the HBase cluster is online as a caveat of the current implementation ([HBASE-16573](https://issues.apache.org/jira/browse/HBASE-16573)).
+
+**Some operations may fail and require re-run**\\
+The HBase backup feature is primarily client driven. While there is the standard HBase retry logic built into the HBase Connection, persistent errors in executing operations
+may propagate back to the client (e.g. snapshot failure due to region splits). The backup implementation should be moved from client-side into the ProcedureV2 framework
+in the future which would provide additional robustness around transient/retryable failures. The \`hbase backup repair\` command is meant to correct states which the system
+cannot automatically detect and recover from.
+
+**Avoidance of declaration of public API**\\
+While the Java API to interact with this feature exists and its implementation is separated from an interface, insufficient rigor has been applied to determine if
+it is exactly what we intend to ship to users. As such, it is marked as for a \`Private\` audience with the expectation that, as users begin to try the feature, there
+will be modifications that would necessitate breaking compatibility ([HBASE-17517](https://issues.apache.org/jira/browse/HBASE-17517)).
+
+**Lack of global metrics for backup and restore**\\
+Individual backup and restore operations contain metrics about the amount of work the operation included, but there is no centralized location (e.g. the Master UI)
+which present information for consumption ([HBASE-16565](https://issues.apache.org/jira/browse/HBASE-16565)).
+`,h={title:"Additional Topics",description:"Configuration keys, security considerations, and best practices for HBase backup and restore operations."},d=[{href:"/docs/backup-restore/additional-topics#a-warning-on-file-system-growth"},{href:"/docs/backup-restore/additional-topics#full-backups"},{href:"https://issues.apache.org/jira/browse/HBASE-16391"},{href:"https://issues.apache.org/jira/browse/HBASE-15997"},{href:"https://issues.apache.org/jira/browse/HBASE-15998"},{href:"https://issue [...]
+this value to org.apache.hadoop.hbase.backup.master.BackupLogCleaner or append it to the current value.`},{heading:"required-properties",content:`hbase.procedure.master.classes: A comma-separated list of classes invoked with the Procedure framework in the Master. Set
+this value to org.apache.hadoop.hbase.backup.master.LogRollMasterProcedureManager or append it to the current value.`},{heading:"required-properties",content:`hbase.procedure.regionserver.classes: A comma-separated list of classes invoked with the Procedure framework in the RegionServer.
+Set this value to org.apache.hadoop.hbase.backup.regionserver.LogRollRegionServerProcedureManager or append it to the current value.`},{heading:"required-properties",content:`hbase.coprocessor.region.classes: A comma-separated list of RegionObservers deployed on tables. Set this value to
+org.apache.hadoop.hbase.backup.BackupObserver or append it to the current value.`},{heading:"required-properties",content:`hbase.coprocessor.master.classes: A comma-separated list of MasterObservers deployed on tables. Set this value to
+org.apache.hadoop.hbase.backup.BackupMasterObserver or append it to the current value.`},{heading:"required-properties",content:`hbase.master.hfilecleaner.plugins: A comma-separated list of HFileCleaners deployed on the Master. Set this value
+to org.apache.hadoop.hbase.backup.BackupHFileCleaner or append it to the current value.`},{heading:"optional-properties",content:`hbase.backup.system.ttl: The time-to-live in seconds of data in the hbase:backup tables (default: forever). This property
+is only relevant prior to the creation of the hbase:backup table. Use the alter command in the HBase shell to modify the TTL
+when this table already exists. See the below section for more details on the impact of this
+configuration property.`},{heading:"optional-properties",content:"hbase.backup.attempts.max: The number of attempts to perform when taking hbase table snapshots (default: 10)."},{heading:"optional-properties",content:"hbase.backup.attempts.pause.ms: The amount of time to wait between failed snapshot attempts in milliseconds (default: 10000)."},{heading:"optional-properties",content:`hbase.backup.logroll.timeout.millis: The amount of time (in milliseconds) to wait for RegionServers to exe [...]
+in the Master's procedure framework (default: 30000).`},{heading:"formulate-a-restore-strategy-and-test-it",content:`Before you rely on a backup and restore strategy for your production environment, identify how backups must be performed,
+and more importantly, how restores must be performed. Test the plan to ensure that it is workable.
+At a minimum, store backup data from a production cluster on a different cluster or server. To further safeguard the data,
+use a backup location that is at a different physical location.`},{heading:"formulate-a-restore-strategy-and-test-it",content:`If you have a unrecoverable loss of data on your primary production cluster as a result of computer system issues, you may
+be able to restore the data from a different cluster or server at the same site. However, a disaster that destroys the whole
+site renders locally stored backups useless. Consider storing the backup data and necessary resources (both computing capacity
+and operator expertise) to restore the data at a site sufficiently remote from the production site. In the case of a catastrophe
+at the whole primary site (fire, earthquake, etc.), the remote backup site can be very valuable.`},{heading:"secure-a-full-backup-image-first",content:`As a baseline, you must complete a full backup of HBase data at least once before you can rely on incremental backups. The full
+backup should be stored outside of the source cluster. To ensure complete dataset recovery, you must run the restore utility
+with the option to restore baseline full backup. The full backup is the foundation of your dataset. Incremental backup data
+is applied on top of the full backup during the restore operation to return you to the point in time when backup was last taken.`},{heading:"define-and-use-backup-sets-for-groups-of-tables-that-are-logical-subsets-of-the-entire-dataset",content:`You can group tables into an object called a backup set. A backup set can save time when you have a particular group of tables
+that you expect to repeatedly back up or restore.`},{heading:"define-and-use-backup-sets-for-groups-of-tables-that-are-logical-subsets-of-the-entire-dataset",content:`When you create a backup set, you type table names to include in the group. The backup set includes not only groups of related
+tables, but also retains the HBase backup metadata. Afterwards, you can invoke the backup set name to indicate what tables apply
+to the command execution instead of entering all the table names individually.`},{heading:"document-the-backup-and-restore-strategy-and-ideally-log-information-about-each-backup",content:`Document the whole process so that the knowledge base can transfer to new administrators after employee turnover. As an extra
+safety precaution, also log the calendar date, time, and other relevant details about the data of each backup. This metadata
+can potentially help locate a particular dataset in case of source cluster failure or primary site disaster. Maintain duplicate
+copies of all documentation: one copy at the production cluster site and another at the backup location or wherever it can be
+accessed by an administrator remotely from the production cluster.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`This scenario describes how a hypothetical retail business uses backups to safeguard application data and then restore the dataset
+after failure.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`The HBase administration team uses backup sets to store data from a group of tables that have interrelated information for an
+application called green. In this example, one table contains transaction records and the other contains customer details. The
+two tables need to be backed up and be recoverable as a group.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:"The admin team also wants to ensure daily backups occur automatically."},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`The following is an outline of the steps and examples of commands that are used to backup the data for the green application and
+to recover the data later. All commands are run when logged in as HBase superuser.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`A backup set called green_set is created as an alias for both the transactions table and the customer table. The backup set can
+be used for all operations to avoid typing each table name. The backup set name is case-sensitive and should be formed with only
+printable characters and without spaces.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`The first backup of green_set data must be a full backup. The following command example shows how credentials are passed to Amazon
+S3 and specifies the file system with the s3a: prefix.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`Incremental backups should be run according to a schedule that ensures essential data recovery in the event of a catastrophe. At
+this retail company, the HBase admin team decides that automated daily backups secures the data sufficiently. The team decides that
+they can implement this by modifying an existing Cron job that is defined in /etc/crontab. Consequently, IT modifies the Cron job
+by adding the following line:`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`A catastrophic IT incident disables the production cluster that the green application uses. An HBase system administrator of the
+backup cluster must restore the green_set dataset to the point in time closest to the recovery objective.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:"type: info"},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`If the administrator of the backup HBase cluster has the backup ID with relevant details in accessible records, the following
+search with the hdfs dfs -ls command and manually scanning the backup ID list can be bypassed. Consider continuously maintaining
+and protecting a detailed log of backup IDs outside the production cluster in your environment.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`The HBase administrator runs the following command on the directory where backups are stored to print the list of successful backup
+IDs on the console:`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`The admin scans the list to see which backup was created at a date and time closest to the recovery objective. To do this, the
+admin converts the calendar timestamp of the recovery point in time to Unix time because backup IDs are uniquely identified with
+Unix time. The backup IDs are listed in reverse chronological order, meaning the most recent successful backup appears first.`},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:"The admin notices that the following line in the command output corresponds with the green_set backup that needs to be restored:"},{heading:"scenario-safeguarding-application-datasets-on-amazon-s3",content:`The admin restores green_set invoking the backup ID and the -overwrite option. Th [...]
+in the destination and populates the tables with data from the backup dataset. Without this flag, the backup data is appended to the
+existing data in the destination. In this case, the admin decides to overwrite the data because it is corrupted.`},{heading:"security-of-backup-data",content:`With this feature which makes copying data to remote locations, it's important to take a moment to clearly state the procedural
+concerns that exist around data security. Like the HBase replication feature, backup and restore provides the constructs to automatically
+copy data from within a corporate boundary to some system outside of that boundary. It is imperative when storing sensitive data that with backup and restore, much
+less any feature which extracts data from HBase, the locations to which data is being sent has undergone a security audit to ensure
+that only authenticated users are allowed to access that data.`},{heading:"security-of-backup-data",content:`For example, with the above example of backing up data to S3, it is of the utmost importance that the proper permissions are assigned
+to the S3 bucket to ensure that only a minimum set of authorized users are allowed to access this data. Because the data is no longer
+being accessed via HBase, and its authentication and authorization controls, we must ensure that the filesystem storing that data is
+providing a comparable level of security. This is a manual step which users must implement on their own.`},{heading:"technical-details-of-incremental-backup-and-restore",content:`HBase incremental backups enable more efficient capture of HBase table images than previous attempts
+at serial backup and restore solutions, such as those that only used HBase Export and Import APIs.
+Incremental backups use Write Ahead Logs (WALs) to capture the data changes since the
+previous backup was created. A WAL roll (create new WALs) is executed across all RegionServers
+to track the WALs that need to be in the backup.
+In addition to WALs, incremental backups also track bulk-loaded HFiles for tables under backup.`},{heading:"technical-details-of-incremental-backup-and-restore",content:`Incremental backup gathers all WAL files generated since the last backup from the source cluster,
+converts them to HFiles in a .tmp directory under the BACKUP_ROOT, and then moves these
+HFiles to their final location under the backup root directory to form the backup image.
+It also reads bulk load records from the backup system table, forms the paths for the corresponding
+bulk-loaded HFiles, and copies those files to the backup destination.
+Bulk-loaded files are preserved (not deleted by cleaner chores) until they've been included in a
+backup (for each backup root).
+A process similar to the DistCp (distributed copy) tool is used to move the backup files to the
+target file system.`},{heading:"technical-details-of-incremental-backup-and-restore",content:`When a table restore operation starts, a two-step process is initiated.
+First, the full backup is restored from the full backup image.
+Second, all HFiles from incremental backups between the last full backup and the incremental backup
+being restored (including bulk-loaded HFiles) are bulk loaded into the table using the
+HBase Bulk Load utility.`},{heading:"technical-details-of-incremental-backup-and-restore",content:"You can only restore on a live HBase cluster because the data must be redistributed to complete the restore operation successfully."},{heading:"a-warning-on-file-system-growth",content:`As a reminder, incremental backups are implemented via retaining the write-ahead logs which HBase primarily uses for data durability.
+Thus, to ensure that all data needing to be included in a backup is still available in the system, the HBase backup and restore feature
+retains all write-ahead logs since the last backup until the next incremental backup is executed.`},{heading:"a-warning-on-file-system-growth",content:`Like HBase Snapshots, this can have an expectedly large impact on the HDFS usage of HBase for high volume tables. Take care in enabling
+and using the backup and restore feature, specifically with a mind to removing backup sessions when they are not actively being used.`},{heading:"a-warning-on-file-system-growth",content:`The only automated, upper-bound on retained write-ahead logs for backup and restore is based on the TTL of the hbase:backup system table which,
+as of the time this document is written, is infinite (backup table entries are never automatically deleted). This requires that administrators
+perform backups on a schedule whose frequency is relative to the amount of available space on HDFS (e.g. less available HDFS space requires
+more aggressive backup merges and deletions). As a reminder, the TTL can be altered on the hbase:backup table using the alter command
+in the HBase shell. Modifying the configuration property hbase.backup.system.ttl in hbase-site.xml after the system table exists has no effect.`},{heading:"capacity-planning",content:`When designing a distributed system deployment, it is critical that some basic mathmatical rigor is executed to ensure sufficient computational
+capacity is available given the data and software requirements of the system. For this feature, the availability of network capacity is the largest
+bottleneck when estimating the performance of some implementation of backup and restore. The second most costly function is the speed at which
+data can be read/written.`},{heading:"full-backups",content:"To estimate the duration of a full backup, we have to understand the general actions which are invoked:"},{heading:"full-backups",content:"Write-ahead log roll on each RegionServer: ones to tens of seconds per RegionServer in parallel. Relative to the load on each RegionServer."},{heading:"full-backups",content:"Take an HBase snapshot of the table(s): tens of seconds. Relative to the number of regions and files that comprise th [...]
+system โ€” these are numbers that your or your administrator know for your system. Let's say the speed of reading data from HDFS on a single node is
+capped at 80MB/s (across all Mappers that run on that host), a modern network interface controller (NIC) supports 10Gb/s, the top-of-rack switch can
+handle 40Gb/s, and the WAN between your clusters is 10Gb/s. This means that you can only ship data to your remote at a speed of 1.25GB/s โ€” meaning
+that 16 nodes (1.25 * 1024 / 80 = 16) participating in the ExportSnapshot should be able to fully saturate the link between clusters. With more
+nodes in the cluster, we can still saturate the network but at a lesser impact on any one node which helps ensure local SLAs are made. If the size
+of the snapshot is 10TB, this would full backup would take in the ballpark of 2.5 hours (10 * 1024 / 1.25 / (60 * 60) = 2.23hrs)`},{heading:"full-backups",content:`As a general statement, it is very likely that the WAN bandwidth between your local cluster and the remote storage is the largest
+bottleneck to the speed of a full backup.`},{heading:"full-backups",content:`When the concern is restricting the computational impact of backups to a "production system", the above formulas can be reused with the optional
+command-line arguments to hbase backup create: -b, -w, -q. The -b option defines the bandwidth at which each worker (Mapper) would
+write data. The -w argument limits the number of workers that would be spawned in the DistCp job. The -q allows the user to specify a YARN
+queue which can limit the specific nodes where the workers will be spawned โ€” this can quarantine the backup workers performing the copy to
+a set of non-critical nodes. Relating the -b and -w options to our earlier equations: -b would be used to restrict each node from reading
+data at the full 80MB/s and -w is used to limit the job from spawning 16 worker tasks.`},{heading:"incremental-backup",content:"Like we did for full backups, we have to understand the incremental backup process to approximate its runtime and cost."},{heading:"incremental-backup",content:"Identify new write-ahead logs since the last full or incremental backup: negligible. Apriori knowledge from the backup system table(s)."},{heading:"incremental-backup",content:'Read, filter, and write "m [...]
+data in the WAL is preserved). In this case, we can assume an aggregate write speed of 30MB/s per node. Continuing our 16-node cluster example,
+this would require approximately 15 minutes to perform this step for 50GB of data (50 * 1024 / 60 / 60 = 14.2). The amount of time to start the
+DistCp MapReduce job would likely dominate the actual time taken to copy the data (50 / 1.25 = 40 seconds) and can be ignored.`},{heading:"limitations-of-the-backup-and-restore-utility",content:`Serial backup operationsBackup operations cannot be run concurrently. An operation includes actions like create, delete, restore, and merge. Only one active backup session is supported. HBASE-16391
+will introduce multiple-backup sessions support.`},{heading:"limitations-of-the-backup-and-restore-utility",content:`No means to cancel backupsBoth backup and restore operations cannot be canceled. (HBASE-15997, HBASE-15998).
+The workaround to cancel a backup would be to kill the client-side backup command (control-C), ensure all relevant MapReduce jobs have exited, and then
+run the hbase backup repair command to ensure the system backup metadata is consistent.`},{heading:"limitations-of-the-backup-and-restore-utility",content:`Backups can only be saved to a single locationCopying backup information to multiple locations is an exercise left to the user. HBASE-15476 will
+introduce the ability to specify multiple-backup destinations intrinsically.`},{heading:"limitations-of-the-backup-and-restore-utility",content:`HBase superuser access is requiredOnly an HBase superuser (e.g. hbase) is allowed to perform backup/restore, can pose a problem for shared HBase installations. Current mitigations would require
+coordination with system administrators to build and deploy a backup and restore strategy (HBASE-14138).`},{heading:"limitations-of-the-backup-and-restore-utility",content:"Backup restoration is an online operationTo perform a restore from a backup, it requires that the HBase cluster is online as a caveat of the current implementation (HBASE-16573)."},{heading:"limitations-of-the-backup-and-restore-utility",content:`Some operations may fail and require re-runThe HBase backup feature is p [...]
+may propagate back to the client (e.g. snapshot failure due to region splits). The backup implementation should be moved from client-side into the ProcedureV2 framework
+in the future which would provide additional robustness around transient/retryable failures. The hbase backup repair command is meant to correct states which the system
+cannot automatically detect and recover from.`},{heading:"limitations-of-the-backup-and-restore-utility",content:`Avoidance of declaration of public APIWhile the Java API to interact with this feature exists and its implementation is separated from an interface, insufficient rigor has been applied to determine if
+it is exactly what we intend to ship to users. As such, it is marked as for a Private audience with the expectation that, as users begin to try the feature, there
+will be modifications that would necessitate breaking compatibility (HBASE-17517).`},{heading:"limitations-of-the-backup-and-restore-utility",content:`Lack of global metrics for backup and restoreIndividual backup and restore operations contain metrics about the amount of work the operation included, but there is no centralized location (e.g. the Master UI)
+which present information for consumption (HBASE-16565).`}],headings:[{id:"configuration-keys",content:"Configuration keys"},{id:"required-properties",content:"Required properties"},{id:"optional-properties",content:"Optional properties"},{id:"best-practices",content:"Best Practices"},{id:"formulate-a-restore-strategy-and-test-it",content:"Formulate a restore strategy and test it."},{id:"secure-a-full-backup-image-first",content:"Secure a full backup image first."},{id:"define-and-use-ba [...]
+`,e.jsx(t.p,{children:"The backup and restore feature includes both required and optional configuration keys."}),`
+`,e.jsx(t.h3,{id:"required-properties",children:"Required properties"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.backup.enable"})}),": Controls whether or not the feature is enabled (Default: ",e.jsx(t.code,{children:"false"}),"). Set this value to ",e.jsx(t.code,{children:"true"}),"."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.master.logcleaner.plugins"})}),`: A comma-separated list of classes invoked when cleaning logs in the HBase Master. Set
+this value to `,e.jsx(t.code,{children:"org.apache.hadoop.hbase.backup.master.BackupLogCleaner"})," or append it to the current value."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.procedure.master.classes"})}),`: A comma-separated list of classes invoked with the Procedure framework in the Master. Set
+this value to `,e.jsx(t.code,{children:"org.apache.hadoop.hbase.backup.master.LogRollMasterProcedureManager"})," or append it to the current value."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.procedure.regionserver.classes"})}),`: A comma-separated list of classes invoked with the Procedure framework in the RegionServer.
+Set this value to `,e.jsx(t.code,{children:"org.apache.hadoop.hbase.backup.regionserver.LogRollRegionServerProcedureManager"})," or append it to the current value."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.coprocessor.region.classes"})}),`: A comma-separated list of RegionObservers deployed on tables. Set this value to
+`,e.jsx(t.code,{children:"org.apache.hadoop.hbase.backup.BackupObserver"})," or append it to the current value."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.coprocessor.master.classes"})}),`: A comma-separated list of MasterObservers deployed on tables. Set this value to
+`,e.jsx(t.code,{children:"org.apache.hadoop.hbase.backup.BackupMasterObserver"})," or append it to the current value."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.master.hfilecleaner.plugins"})}),`: A comma-separated list of HFileCleaners deployed on the Master. Set this value
+to `,e.jsx(t.code,{children:"org.apache.hadoop.hbase.backup.BackupHFileCleaner"})," or append it to the current value."]}),`
+`,e.jsx(t.h3,{id:"optional-properties",children:"Optional properties"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.backup.system.ttl"})}),": The time-to-live in seconds of data in the ",e.jsx(t.code,{children:"hbase:backup"}),` tables (default: forever). This property
+is only relevant prior to the creation of the `,e.jsx(t.code,{children:"hbase:backup"})," table. Use the ",e.jsx(t.code,{children:"alter"}),` command in the HBase shell to modify the TTL
+when this table already exists. See the `,e.jsx(t.a,{href:"/docs/backup-restore/additional-topics#a-warning-on-file-system-growth",children:"below section"}),` for more details on the impact of this
+configuration property.`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.backup.attempts.max"})}),": The number of attempts to perform when taking hbase table snapshots (default: 10)."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.backup.attempts.pause.ms"})}),": The amount of time to wait between failed snapshot attempts in milliseconds (default: 10000)."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"hbase.backup.logroll.timeout.millis"})}),`: The amount of time (in milliseconds) to wait for RegionServers to execute a WAL rolling
+in the Master's procedure framework (default: 30000).`]}),`
+`,e.jsx(t.h2,{id:"best-practices",children:"Best Practices"}),`
+`,e.jsx(t.h3,{id:"formulate-a-restore-strategy-and-test-it",children:"Formulate a restore strategy and test it."}),`
+`,e.jsx(t.p,{children:`Before you rely on a backup and restore strategy for your production environment, identify how backups must be performed,
+and more importantly, how restores must be performed. Test the plan to ensure that it is workable.
+At a minimum, store backup data from a production cluster on a different cluster or server. To further safeguard the data,
+use a backup location that is at a different physical location.`}),`
+`,e.jsx(t.p,{children:`If you have a unrecoverable loss of data on your primary production cluster as a result of computer system issues, you may
+be able to restore the data from a different cluster or server at the same site. However, a disaster that destroys the whole
+site renders locally stored backups useless. Consider storing the backup data and necessary resources (both computing capacity
+and operator expertise) to restore the data at a site sufficiently remote from the production site. In the case of a catastrophe
+at the whole primary site (fire, earthquake, etc.), the remote backup site can be very valuable.`}),`
+`,e.jsx(t.h3,{id:"secure-a-full-backup-image-first",children:"Secure a full backup image first."}),`
+`,e.jsx(t.p,{children:`As a baseline, you must complete a full backup of HBase data at least once before you can rely on incremental backups. The full
+backup should be stored outside of the source cluster. To ensure complete dataset recovery, you must run the restore utility
+with the option to restore baseline full backup. The full backup is the foundation of your dataset. Incremental backup data
+is applied on top of the full backup during the restore operation to return you to the point in time when backup was last taken.`}),`
+`,e.jsx(t.h3,{id:"define-and-use-backup-sets-for-groups-of-tables-that-are-logical-subsets-of-the-entire-dataset",children:"Define and use backup sets for groups of tables that are logical subsets of the entire dataset."}),`
+`,e.jsx(t.p,{children:`You can group tables into an object called a backup set. A backup set can save time when you have a particular group of tables
+that you expect to repeatedly back up or restore.`}),`
+`,e.jsx(t.p,{children:`When you create a backup set, you type table names to include in the group. The backup set includes not only groups of related
+tables, but also retains the HBase backup metadata. Afterwards, you can invoke the backup set name to indicate what tables apply
+to the command execution instead of entering all the table names individually.`}),`
+`,e.jsx(t.h3,{id:"document-the-backup-and-restore-strategy-and-ideally-log-information-about-each-backup",children:"Document the backup and restore strategy, and ideally log information about each backup."}),`
+`,e.jsx(t.p,{children:`Document the whole process so that the knowledge base can transfer to new administrators after employee turnover. As an extra
+safety precaution, also log the calendar date, time, and other relevant details about the data of each backup. This metadata
+can potentially help locate a particular dataset in case of source cluster failure or primary site disaster. Maintain duplicate
+copies of all documentation: one copy at the production cluster site and another at the backup location or wherever it can be
+accessed by an administrator remotely from the production cluster.`}),`
+`,e.jsx(t.h2,{id:"scenario-safeguarding-application-datasets-on-amazon-s3",children:"Scenario: Safeguarding Application Datasets on Amazon S3"}),`
+`,e.jsx(t.p,{children:`This scenario describes how a hypothetical retail business uses backups to safeguard application data and then restore the dataset
+after failure.`}),`
+`,e.jsx(t.p,{children:`The HBase administration team uses backup sets to store data from a group of tables that have interrelated information for an
+application called green. In this example, one table contains transaction records and the other contains customer details. The
+two tables need to be backed up and be recoverable as a group.`}),`
+`,e.jsx(t.p,{children:"The admin team also wants to ensure daily backups occur automatically."}),`
+`,e.jsx(t.p,{children:e.jsx(t.img,{alt:"Tables Composing The Backup Set",src:i,placeholder:"blur"})}),`
+`,e.jsxs(t.p,{children:["The following is an outline of the steps and examples of commands that are used to backup the data for the ",e.jsx(t.em,{children:"green"}),` application and
+to recover the data later. All commands are run when logged in as HBase superuser.`]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:[`
+`,e.jsxs(t.p,{children:["A backup set called ",e.jsx(t.em,{children:"green_set"}),` is created as an alias for both the transactions table and the customer table. The backup set can
+be used for all operations to avoid typing each table name. The backup set name is case-sensitive and should be formed with only
+printable characters and without spaces.`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.span,{className:"line",children:[e.jsx(t.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hbase"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" backup"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" set"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children: [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsx(t.p,{children:`The first backup of green_set data must be a full backup. The following command example shows how credentials are passed to Amazon
+S3 and specifies the file system with the s3a: prefix.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.span,{className:"line",children:[e.jsx(t.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" SECRET_KEY=123456789abcdefghijklmnopqrstuvwxyzABCD"})]}),`
+`,e.jsxs(t.span,{className:"line",children:[e.jsx(t.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" sudo"}),e.jsx(t.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -u"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hbase"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" h [...]
+`,e.jsxs(t.span,{className:"line",children:[e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  s3a://"}),e.jsx(t.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"$ACCESS_KEY"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:":SECRET_KEY@prodhbasebackups/backups"}),e.jsx(t.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -s"}),e.jsx(t.span,{style:{"--shiki-light":"#032 [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsxs(t.p,{children:[`Incremental backups should be run according to a schedule that ensures essential data recovery in the event of a catastrophe. At
+this retail company, the HBase admin team decides that automated daily backups secures the data sufficiently. The team decides that
+they can implement this by modifying an existing Cron job that is defined in `,e.jsx(t.code,{children:"/etc/crontab"}),`. Consequently, IT modifies the Cron job
+by adding the following line:`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsxs(t.p,{children:[`A catastrophic IT incident disables the production cluster that the green application uses. An HBase system administrator of the
+backup cluster must restore the `,e.jsx(t.em,{children:"green_set"})," dataset to the point in time closest to the recovery objective."]}),`
+`,e.jsx(s,{type:"info",children:e.jsxs(t.p,{children:[`If the administrator of the backup HBase cluster has the backup ID with relevant details in accessible records, the following
+search with the `,e.jsx(t.code,{children:"hdfs dfs -ls"}),` command and manually scanning the backup ID list can be bypassed. Consider continuously maintaining
+and protecting a detailed log of backup IDs outside the production cluster in your environment.`]})}),`
+`,e.jsx(t.p,{children:`The HBase administrator runs the following command on the directory where backups are stored to print the list of successful backup
+IDs on the console:`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsx(t.p,{children:`The admin scans the list to see which backup was created at a date and time closest to the recovery objective. To do this, the
+admin converts the calendar timestamp of the recovery point in time to Unix time because backup IDs are uniquely identified with
+Unix time. The backup IDs are listed in reverse chronological order, meaning the most recent successful backup appears first.`}),`
+`,e.jsxs(t.p,{children:["The admin notices that the following line in the command output corresponds with the ",e.jsx(t.em,{children:"green_set"})," backup that needs to be restored:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsx(t.p,{children:`The admin restores green_set invoking the backup ID and the -overwrite option. The -overwrite option truncates all existing data
+in the destination and populates the tables with data from the backup dataset. Without this flag, the backup data is appended to the
+existing data in the destination. In this case, the admin decides to overwrite the data because it is corrupted.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.span,{className:"line",children:[e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  s3a://"}),e.jsx(t.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"$ACCESS_KEY"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:":"}),e.jsx(t.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"$SECRET_KEY"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBF [...]
+`]}),`
+`]}),`
+`,e.jsx(t.h2,{id:"security-of-backup-data",children:"Security of Backup Data"}),`
+`,e.jsx(t.p,{children:`With this feature which makes copying data to remote locations, it's important to take a moment to clearly state the procedural
+concerns that exist around data security. Like the HBase replication feature, backup and restore provides the constructs to automatically
+copy data from within a corporate boundary to some system outside of that boundary. It is imperative when storing sensitive data that with backup and restore, much
+less any feature which extracts data from HBase, the locations to which data is being sent has undergone a security audit to ensure
+that only authenticated users are allowed to access that data.`}),`
+`,e.jsxs(t.p,{children:[`For example, with the above example of backing up data to S3, it is of the utmost importance that the proper permissions are assigned
+to the S3 bucket to ensure that only a minimum set of authorized users are allowed to access this data. Because the data is no longer
+being accessed via HBase, and its authentication and authorization controls, we must ensure that the filesystem storing that data is
+providing a comparable level of security. This is a manual step which users `,e.jsx(t.strong,{children:"must"})," implement on their own."]}),`
+`,e.jsx(t.h2,{id:"technical-details-of-incremental-backup-and-restore",children:"Technical Details of Incremental Backup and Restore"}),`
+`,e.jsx(t.p,{children:`HBase incremental backups enable more efficient capture of HBase table images than previous attempts
+at serial backup and restore solutions, such as those that only used HBase Export and Import APIs.
+Incremental backups use Write Ahead Logs (WALs) to capture the data changes since the
+previous backup was created. A WAL roll (create new WALs) is executed across all RegionServers
+to track the WALs that need to be in the backup.
+In addition to WALs, incremental backups also track bulk-loaded HFiles for tables under backup.`}),`
+`,e.jsxs(t.p,{children:[`Incremental backup gathers all WAL files generated since the last backup from the source cluster,
+converts them to HFiles in a `,e.jsx(t.code,{children:".tmp"})," directory under the ",e.jsx(t.code,{children:"BACKUP_ROOT"}),`, and then moves these
+HFiles to their final location under the backup root directory to form the backup image.
+It also reads bulk load records from the backup system table, forms the paths for the corresponding
+bulk-loaded HFiles, and copies those files to the backup destination.
+Bulk-loaded files are preserved (not deleted by cleaner chores) until they've been included in a
+backup (for each backup root).
+A process similar to the DistCp (distributed copy) tool is used to move the backup files to the
+target file system.`]}),`
+`,e.jsx(t.p,{children:`When a table restore operation starts, a two-step process is initiated.
+First, the full backup is restored from the full backup image.
+Second, all HFiles from incremental backups between the last full backup and the incremental backup
+being restored (including bulk-loaded HFiles) are bulk loaded into the table using the
+HBase Bulk Load utility.`}),`
+`,e.jsx(t.p,{children:"You can only restore on a live HBase cluster because the data must be redistributed to complete the restore operation successfully."}),`
+`,e.jsx(t.h2,{id:"a-warning-on-file-system-growth",children:"A Warning on File System Growth"}),`
+`,e.jsx(t.p,{children:`As a reminder, incremental backups are implemented via retaining the write-ahead logs which HBase primarily uses for data durability.
+Thus, to ensure that all data needing to be included in a backup is still available in the system, the HBase backup and restore feature
+retains all write-ahead logs since the last backup until the next incremental backup is executed.`}),`
+`,e.jsx(t.p,{children:`Like HBase Snapshots, this can have an expectedly large impact on the HDFS usage of HBase for high volume tables. Take care in enabling
+and using the backup and restore feature, specifically with a mind to removing backup sessions when they are not actively being used.`}),`
+`,e.jsxs(t.p,{children:["The only automated, upper-bound on retained write-ahead logs for backup and restore is based on the TTL of the ",e.jsx(t.code,{children:"hbase:backup"}),` system table which,
+as of the time this document is written, is infinite (backup table entries are never automatically deleted). This requires that administrators
+perform backups on a schedule whose frequency is relative to the amount of available space on HDFS (e.g. less available HDFS space requires
+more aggressive backup merges and deletions). As a reminder, the TTL can be altered on the `,e.jsx(t.code,{children:"hbase:backup"})," table using the ",e.jsx(t.code,{children:"alter"}),` command
+in the HBase shell. Modifying the configuration property `,e.jsx(t.code,{children:"hbase.backup.system.ttl"})," in hbase-site.xml after the system table exists has no effect."]}),`
+`,e.jsx(t.h2,{id:"capacity-planning",children:"Capacity Planning"}),`
+`,e.jsx(t.p,{children:`When designing a distributed system deployment, it is critical that some basic mathmatical rigor is executed to ensure sufficient computational
+capacity is available given the data and software requirements of the system. For this feature, the availability of network capacity is the largest
+bottleneck when estimating the performance of some implementation of backup and restore. The second most costly function is the speed at which
+data can be read/written.`}),`
+`,e.jsx(t.h3,{id:"full-backups",children:"Full Backups"}),`
+`,e.jsx(t.p,{children:"To estimate the duration of a full backup, we have to understand the general actions which are invoked:"}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"Write-ahead log roll on each RegionServer: ones to tens of seconds per RegionServer in parallel. Relative to the load on each RegionServer."}),`
+`,e.jsx(t.li,{children:"Take an HBase snapshot of the table(s): tens of seconds. Relative to the number of regions and files that comprise the table."}),`
+`,e.jsx(t.li,{children:"Export the snapshot to the destination: see below. Relative to the size of the data and the network bandwidth to the destination."}),`
+`]}),`
+`,e.jsxs(t.p,{children:["To approximate how long the final step will take, we have to make some assumptions on hardware. Be aware that these will ",e.jsx(t.em,{children:"not"}),` be accurate for your
+system โ€” these are numbers that your or your administrator know for your system. Let's say the speed of reading data from HDFS on a single node is
+capped at 80MB/s (across all Mappers that run on that host), a modern network interface controller (NIC) supports 10Gb/s, the top-of-rack switch can
+handle 40Gb/s, and the WAN between your clusters is 10Gb/s. This means that you can only ship data to your remote at a speed of 1.25GB/s โ€” meaning
+that 16 nodes (`,e.jsx(t.code,{children:"1.25 * 1024 / 80 = 16"}),`) participating in the ExportSnapshot should be able to fully saturate the link between clusters. With more
+nodes in the cluster, we can still saturate the network but at a lesser impact on any one node which helps ensure local SLAs are made. If the size
+of the snapshot is 10TB, this would full backup would take in the ballpark of 2.5 hours (`,e.jsx(t.code,{children:"10 * 1024 / 1.25 / (60 * 60) = 2.23hrs"}),")"]}),`
+`,e.jsx(t.p,{children:`As a general statement, it is very likely that the WAN bandwidth between your local cluster and the remote storage is the largest
+bottleneck to the speed of a full backup.`}),`
+`,e.jsxs(t.p,{children:[`When the concern is restricting the computational impact of backups to a "production system", the above formulas can be reused with the optional
+command-line arguments to `,e.jsx(t.code,{children:"hbase backup create"}),": ",e.jsx(t.code,{children:"-b"}),", ",e.jsx(t.code,{children:"-w"}),", ",e.jsx(t.code,{children:"-q"}),". The ",e.jsx(t.code,{children:"-b"}),` option defines the bandwidth at which each worker (Mapper) would
+write data. The `,e.jsx(t.code,{children:"-w"})," argument limits the number of workers that would be spawned in the DistCp job. The ",e.jsx(t.code,{children:"-q"}),` allows the user to specify a YARN
+queue which can limit the specific nodes where the workers will be spawned โ€” this can quarantine the backup workers performing the copy to
+a set of non-critical nodes. Relating the `,e.jsx(t.code,{children:"-b"})," and ",e.jsx(t.code,{children:"-w"})," options to our earlier equations: ",e.jsx(t.code,{children:"-b"}),` would be used to restrict each node from reading
+data at the full 80MB/s and `,e.jsx(t.code,{children:"-w"})," is used to limit the job from spawning 16 worker tasks."]}),`
+`,e.jsx(t.h3,{id:"incremental-backup",children:"Incremental Backup"}),`
+`,e.jsx(t.p,{children:"Like we did for full backups, we have to understand the incremental backup process to approximate its runtime and cost."}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"Identify new write-ahead logs since the last full or incremental backup: negligible. Apriori knowledge from the backup system table(s)."}),`
+`,e.jsx(t.li,{children:'Read, filter, and write "minimized" HFiles equivalent to the WALs: dominated by the speed of writing data. Relative to write speed of HDFS.'}),`
+`,e.jsx(t.li,{children:"Read bulk load records from the backup system table, form the paths for bulk-loaded HFiles, and copy them to the backup destination."}),`
+`,e.jsxs(t.li,{children:["DistCp the HFiles to the destination: ",e.jsx(t.a,{href:"/docs/backup-restore/additional-topics#full-backups",children:"see above"}),"."]}),`
+`]}),`
+`,e.jsx(t.p,{children:`For the second step, the dominating cost of this operation would be the re-writing the data (under the assumption that a majority of the
+data in the WAL is preserved). In this case, we can assume an aggregate write speed of 30MB/s per node. Continuing our 16-node cluster example,
+this would require approximately 15 minutes to perform this step for 50GB of data (50 * 1024 / 60 / 60 = 14.2). The amount of time to start the
+DistCp MapReduce job would likely dominate the actual time taken to copy the data (50 / 1.25 = 40 seconds) and can be ignored.`}),`
+`,e.jsx(t.h2,{id:"limitations-of-the-backup-and-restore-utility",children:"Limitations of the Backup and Restore Utility"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Serial backup operations"}),e.jsx(t.br,{}),`
+`,"Backup operations cannot be run concurrently. An operation includes actions like create, delete, restore, and merge. Only one active backup session is supported. ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-16391",children:"HBASE-16391"}),`
+will introduce multiple-backup sessions support.`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"No means to cancel backups"}),e.jsx(t.br,{}),`
+`,"Both backup and restore operations cannot be canceled. (",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-15997",children:"HBASE-15997"}),", ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-15998",children:"HBASE-15998"}),`).
+The workaround to cancel a backup would be to kill the client-side backup command (`,e.jsx(t.code,{children:"control-C"}),`), ensure all relevant MapReduce jobs have exited, and then
+run the `,e.jsx(t.code,{children:"hbase backup repair"})," command to ensure the system backup metadata is consistent."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Backups can only be saved to a single location"}),e.jsx(t.br,{}),`
+`,"Copying backup information to multiple locations is an exercise left to the user. ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-15476",children:"HBASE-15476"}),` will
+introduce the ability to specify multiple-backup destinations intrinsically.`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"HBase superuser access is required"}),e.jsx(t.br,{}),`
+`,`Only an HBase superuser (e.g. hbase) is allowed to perform backup/restore, can pose a problem for shared HBase installations. Current mitigations would require
+coordination with system administrators to build and deploy a backup and restore strategy (`,e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-14138",children:"HBASE-14138"}),")."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Backup restoration is an online operation"}),e.jsx(t.br,{}),`
+`,"To perform a restore from a backup, it requires that the HBase cluster is online as a caveat of the current implementation (",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-16573",children:"HBASE-16573"}),")."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Some operations may fail and require re-run"}),e.jsx(t.br,{}),`
+`,`The HBase backup feature is primarily client driven. While there is the standard HBase retry logic built into the HBase Connection, persistent errors in executing operations
+may propagate back to the client (e.g. snapshot failure due to region splits). The backup implementation should be moved from client-side into the ProcedureV2 framework
+in the future which would provide additional robustness around transient/retryable failures. The `,e.jsx(t.code,{children:"hbase backup repair"}),` command is meant to correct states which the system
+cannot automatically detect and recover from.`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Avoidance of declaration of public API"}),e.jsx(t.br,{}),`
+`,`While the Java API to interact with this feature exists and its implementation is separated from an interface, insufficient rigor has been applied to determine if
+it is exactly what we intend to ship to users. As such, it is marked as for a `,e.jsx(t.code,{children:"Private"}),` audience with the expectation that, as users begin to try the feature, there
+will be modifications that would necessitate breaking compatibility (`,e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-17517",children:"HBASE-17517"}),")."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Lack of global metrics for backup and restore"}),e.jsx(t.br,{}),`
+`,`Individual backup and restore operations contain metrics about the amount of work the operation included, but there is no centralized location (e.g. the Master UI)
+which present information for consumption (`,e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-16565",children:"HBASE-16565"}),")."]})]})}function b(a={}){const{wrapper:t}=a.components||{};return t?e.jsx(t,{...a,children:e.jsx(n,{...a})}):n(a)}function o(a,t){throw new Error("Expected component `"+a+"` to be defined: you likely forgot to import, pass, or provide it.")}export{c as _markdown,b as default,d as extractedReferences,h as frontmatter,u as structuredData,p as toc};
diff --git a/assets/administration-Be343mGR.js b/assets/administration-Be343mGR.js
new file mode 100644
index 00000000000..befcf11ce36
--- /dev/null
+++ b/assets/administration-Be343mGR.js
@@ -0,0 +1,272 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let l=`The \`hbase backup\` command has several subcommands that help with administering backup images as they accumulate. Most production
+environments require recurring backups, so it is necessary to have utilities to help manage the data of the backup repository.
+Some subcommands enable you to find information that can help identify backups that are relevant in a search for particular data.
+You can also delete backup images.
+
+The following list details each \`hbase backup subcommand\` that can help administer backups. Run the full command-subcommand line as
+the HBase superuser.
+
+### Managing Backup Progress
+
+You can monitor a running backup in another terminal session by running the *hbase backup progress* command and specifying the backup ID as an argument.
+
+For example, run the following command as hbase superuser to view the progress of a backup
+
+\`\`\`bash
+$ hbase backup progress <backup_id>
+\`\`\`
+
+#### Positional Command-Line Arguments
+
+***backup\\_id***\\
+Specifies the backup that you want to monitor by seeing the progress information. The backupId is case-sensitive.
+
+#### Named Command-Line Arguments
+
+None.
+
+#### Example usage
+
+\`\`\`bash
+hbase backup progress backupId_1467823988425
+\`\`\`
+
+### Managing Backup History
+
+This command displays a log of backup sessions. The information for each session includes backup ID, type (full or incremental), the tables
+in the backup, status, and start and end time. Specify the number of backup sessions to display with the optional -n argument.
+
+\`\`\`bash
+$ hbase backup history <backup_id>
+\`\`\`
+
+#### Positional Command-Line Arguments
+
+***backup\\_id***\\
+Specifies the backup that you want to monitor by seeing the progress information. The backupId is case-sensitive.
+
+#### Named Command-Line Arguments
+
+***-n \\<num\\_records>***\\
+(Optional) The maximum number of backup records (Default: 10).
+
+***-p \\<backup\\_root\\_path>***\\
+The full filesystem URI of where backup images are stored.
+
+***-s \\<backup\\_set\\_name>***\\
+The name of the backup set to obtain history for. Mutually exclusive with the *-t* option.
+
+***-t \\<table\\_name>***\\
+The name of table to obtain history for. Mutually exclusive with the *-s* option.
+
+#### Example usage
+
+\`\`\`bash
+$ hbase backup history
+$ hbase backup history -n 20
+$ hbase backup history -t WebIndexRecords
+\`\`\`
+
+### Describing a Backup Image
+
+This command can be used to obtain information about a specific backup image.
+
+\`\`\`bash
+$ hbase backup describe <backup_id>
+\`\`\`
+
+#### Positional Command-Line Arguments
+
+***backup\\_id***
+The ID of the backup image to describe.
+
+#### Named Command-Line Arguments
+
+None.
+
+#### Example usage
+
+\`\`\`bash
+$ hbase backup describe backupId_1467823988425
+\`\`\`
+
+### Deleting Backup Images
+
+The \`hbase backup delete\` command deletes backup images that are no longer needed.
+
+#### Syntax
+
+\`\`\`bash
+$ hbase backup delete -l <backup_id1,backup_id2,...>
+$ hbase backup delete -k <days>
+\`\`\`
+
+#### Named Command-Line Arguments
+
+***-l \\<backup\\_id1,backup\\_id2,...>***\\
+Comma-separated list of backup IDs to delete.
+
+***-k \\<days>***\\
+Deletes all backup images completed more than the specified number of days ago.
+
+<Callout type="info">
+  These options are **mutually exclusive**. Only one of \`-l\` or \`-k\` may be used at a time.
+</Callout>
+
+#### Example Usage
+
+Delete specific backup images by ID:
+
+\`\`\`bash
+$ hbase backup delete -l backupId_1467823988425,backupId_1467824989999
+\`\`\`
+
+Delete all backup images older than 30 days:
+
+\`\`\`bash
+$ hbase backup delete -k 30
+\`\`\`
+
+<Callout type="warn">
+  * Deleting a backup may affect all following incremental backups (in the same backup root) up to
+    the next full backup. For example, if you take a full backup every 2 weeks and
+    daily incremental backups, running \`hbase backup delete -k 7\` when the full backup is older than
+    7 days will effectively remove the data for all subsequent incremental backups.
+    The backup IDs may still be listed, but their data will be gone.
+
+  * If the most recent backup is an incremental backup and you delete it,
+    you should run a **full backup** next.
+    Running another incremental backup immediately after may result in missing data in the
+    backup image. (See [HBASE-28084](https://issues.apache.org/jira/browse/HBASE-28084))
+</Callout>
+
+### Backup Repair Command
+
+This command attempts to correct any inconsistencies in persisted backup metadata which exists as
+the result of software errors or unhandled failure scenarios. While the backup implementation tries
+to correct all errors on its own, this tool may be necessary in the cases where the system cannot
+automatically recover on its own.
+
+\`\`\`bash
+$ hbase backup repair
+\`\`\`
+
+#### Positional Command-Line Arguments
+
+None.
+
+#### Named Command-Line Arguments
+
+None.
+
+#### Example usage
+
+\`\`\`bash
+$ hbase backup repair
+\`\`\`
+`,h={title:"Administration of Backup Images",description:"Managing HBase backup images including listing, describing, deleting, and merging backup sets for efficient storage."},c=[{href:"https://issues.apache.org/jira/browse/HBASE-28084"}],d={contents:[{heading:void 0,content:`The hbase backup command has several subcommands that help with administering backup images as they accumulate. Most production
+environments require recurring backups, so it is necessary to have utilities to help manage the data of the backup repository.
+Some subcommands enable you to find information that can help identify backups that are relevant in a search for particular data.
+You can also delete backup images.`},{heading:void 0,content:`The following list details each hbase backup subcommand that can help administer backups. Run the full command-subcommand line as
+the HBase superuser.`},{heading:"managing-backup-progress",content:"You can monitor a running backup in another terminal session by running the hbase backup progress command and specifying the backup ID as an argument."},{heading:"managing-backup-progress",content:"For example, run the following command as hbase superuser to view the progress of a backup"},{heading:"backup-restore-administation-managing-backup-progress-positional-command-line-arguments",content:"backup_idSpecifies the ba [...]
+in the backup, status, and start and end time. Specify the number of backup sessions to display with the optional -n argument.`},{heading:"backup-restore-administation-managing-backup-history-positional-command-line-arguments",content:"backup_idSpecifies the backup that you want to monitor by seeing the progress information. The backupId is case-sensitive."},{heading:"backup-restore-administation-managing-backup-history-named-command-line-arguments",content:"-n <num_records>(Optional) Th [...]
+The ID of the backup image to describe.`},{heading:"backup-restore-administation-describing-a-backup-image-named-command-line-arguments",content:"None."},{heading:"deleting-backup-images",content:"The hbase backup delete command deletes backup images that are no longer needed."},{heading:"backup-restore-administation-deleting-backup-images-named-command-line-arguments",content:"-l <backup_id1,backup_id2,...>Comma-separated list of backup IDs to delete."},{heading:"backup-restore-administ [...]
+the next full backup. For example, if you take a full backup every 2 weeks and
+daily incremental backups, running hbase backup delete -k 7 when the full backup is older than
+7 days will effectively remove the data for all subsequent incremental backups.
+The backup IDs may still be listed, but their data will be gone.`},{heading:"backup-restore-administation-deleting-backup-images-example-usage",content:`If the most recent backup is an incremental backup and you delete it,
+you should run a full backup next.
+Running another incremental backup immediately after may result in missing data in the
+backup image. (See HBASE-28084)`},{heading:"backup-repair-command",content:`This command attempts to correct any inconsistencies in persisted backup metadata which exists as
+the result of software errors or unhandled failure scenarios. While the backup implementation tries
+to correct all errors on its own, this tool may be necessary in the cases where the system cannot
+automatically recover on its own.`},{heading:"backup-restore-administation-backup-repair-command-positional-command-line-arguments",content:"None."},{heading:"backup-restore-administation-backup-repair-command-named-command-line-arguments",content:"None."}],headings:[{id:"managing-backup-progress",content:"Managing Backup Progress"},{id:"backup-restore-administation-managing-backup-progress-positional-command-line-arguments",content:"Positional Command-Line Arguments"},{id:"backup-restor [...]
+environments require recurring backups, so it is necessary to have utilities to help manage the data of the backup repository.
+Some subcommands enable you to find information that can help identify backups that are relevant in a search for particular data.
+You can also delete backup images.`]}),`
+`,e.jsxs(i.p,{children:["The following list details each ",e.jsx(i.code,{children:"hbase backup subcommand"}),` that can help administer backups. Run the full command-subcommand line as
+the HBase superuser.`]}),`
+`,e.jsx(i.h3,{id:"managing-backup-progress",children:"Managing Backup Progress"}),`
+`,e.jsxs(i.p,{children:["You can monitor a running backup in another terminal session by running the ",e.jsx(i.em,{children:"hbase backup progress"})," command and specifying the backup ID as an argument."]}),`
+`,e.jsx(i.p,{children:"For example, run the following command as hbase superuser to view the progress of a backup"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"backup-restore-administation-managing-backup-progress-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"backup_id"})}),e.jsx(i.br,{}),`
+`,"Specifies the backup that you want to monitor by seeing the progress information. The backupId is case-sensitive."]}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-manging-backup-progress-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsx(i.p,{children:"None."}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-manging-backup-progress-example-usage",children:"Example usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h3,{id:"managing-backup-history",children:"Managing Backup History"}),`
+`,e.jsx(i.p,{children:`This command displays a log of backup sessions. The information for each session includes backup ID, type (full or incremental), the tables
+in the backup, status, and start and end time. Specify the number of backup sessions to display with the optional -n argument.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"backup-restore-administation-managing-backup-history-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"backup_id"})}),e.jsx(i.br,{}),`
+`,"Specifies the backup that you want to monitor by seeing the progress information. The backupId is case-sensitive."]}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-managing-backup-history-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"-n <num_records>"})}),e.jsx(i.br,{}),`
+`,"(Optional) The maximum number of backup records (Default: 10)."]}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"-p <backup_root_path>"})}),e.jsx(i.br,{}),`
+`,"The full filesystem URI of where backup images are stored."]}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"-s <backup_set_name>"})}),e.jsx(i.br,{}),`
+`,"The name of the backup set to obtain history for. Mutually exclusive with the ",e.jsx(i.em,{children:"-t"})," option."]}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"-t <table_name>"})}),e.jsx(i.br,{}),`
+`,"The name of table to obtain history for. Mutually exclusive with the ",e.jsx(i.em,{children:"-s"})," option."]}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-managing-backup-history-example-usage",children:"Example usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hbase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" backup"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" history"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},child [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hbase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" backup"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" history"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},child [...]
+`,e.jsx(i.h3,{id:"describing-a-backup-image",children:"Describing a Backup Image"}),`
+`,e.jsx(i.p,{children:"This command can be used to obtain information about a specific backup image."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"backup-restore-administation-describing-a-backup-image-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"backup_id"})}),`
+The ID of the backup image to describe.`]}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-describing-a-backup-image-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsx(i.p,{children:"None."}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-describing-a-backup-image-example-usage",children:"Example usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h3,{id:"deleting-backup-images",children:"Deleting Backup Images"}),`
+`,e.jsxs(i.p,{children:["The ",e.jsx(i.code,{children:"hbase backup delete"})," command deletes backup images that are no longer needed."]}),`
+`,e.jsx(i.h4,{id:"syntax",children:"Syntax"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hbase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" backup"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" delete"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},childr [...]
+`,e.jsx(i.h4,{id:"backup-restore-administation-deleting-backup-images-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"-l <backup_id1,backup_id2,...>"})}),e.jsx(i.br,{}),`
+`,"Comma-separated list of backup IDs to delete."]}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.strong,{children:e.jsx(i.em,{children:"-k <days>"})}),e.jsx(i.br,{}),`
+`,"Deletes all backup images completed more than the specified number of days ago."]}),`
+`,e.jsx(n,{type:"info",children:e.jsxs(i.p,{children:["These options are ",e.jsx(i.strong,{children:"mutually exclusive"}),". Only one of ",e.jsx(i.code,{children:"-l"})," or ",e.jsx(i.code,{children:"-k"})," may be used at a time."]})}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-deleting-backup-images-example-usage",children:"Example Usage"}),`
+`,e.jsx(i.p,{children:"Delete specific backup images by ID:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.p,{children:"Delete all backup images older than 30 days:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(n,{type:"warn",children:e.jsxs(i.ul,{children:[`
+`,e.jsxs(i.li,{children:[`
+`,e.jsxs(i.p,{children:[`Deleting a backup may affect all following incremental backups (in the same backup root) up to
+the next full backup. For example, if you take a full backup every 2 weeks and
+daily incremental backups, running `,e.jsx(i.code,{children:"hbase backup delete -k 7"}),` when the full backup is older than
+7 days will effectively remove the data for all subsequent incremental backups.
+The backup IDs may still be listed, but their data will be gone.`]}),`
+`]}),`
+`,e.jsxs(i.li,{children:[`
+`,e.jsxs(i.p,{children:[`If the most recent backup is an incremental backup and you delete it,
+you should run a `,e.jsx(i.strong,{children:"full backup"}),` next.
+Running another incremental backup immediately after may result in missing data in the
+backup image. (See `,e.jsx(i.a,{href:"https://issues.apache.org/jira/browse/HBASE-28084",children:"HBASE-28084"}),")"]}),`
+`]}),`
+`]})}),`
+`,e.jsx(i.h3,{id:"backup-repair-command",children:"Backup Repair Command"}),`
+`,e.jsx(i.p,{children:`This command attempts to correct any inconsistencies in persisted backup metadata which exists as
+the result of software errors or unhandled failure scenarios. While the backup implementation tries
+to correct all errors on its own, this tool may be necessary in the cases where the system cannot
+automatically recover on its own.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"backup-restore-administation-backup-repair-command-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsx(i.p,{children:"None."}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-backup-repair-command-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsx(i.p,{children:"None."}),`
+`,e.jsx(i.h4,{id:"backup-restore-administation-backup-repair-command-example-usage",children:"Example usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
diff --git a/assets/algolia-IZEDLPHE-2120h3C3.js b/assets/algolia-IZEDLPHE-2120h3C3.js
new file mode 100644
index 00000000000..51a172200df
--- /dev/null
+++ b/assets/algolia-IZEDLPHE-2120h3C3.js
@@ -0,0 +1 @@
+import{c as l}from"./chunk-OTD7MV33-qJr9DjGl.js";function h(e){const n=[],r=new Set;for(const t of e)r.has(t.url)||(r.add(t.url),n.push({id:t.url,type:"page",breadcrumbs:t.breadcrumbs,url:t.url,content:t.title})),n.push({id:t.objectID,type:t.content===t.section?"heading":"text",url:t.section_id?`${t.url}#${t.section_id}`:t.url,content:t.content});return n}async function g(e,{indexName:n,onSearch:r,client:t,locale:o,tag:s}){if(e.trim().length===0)return[];const c=r?await r(e,s,o):await t. [...]
diff --git a/assets/amv2-BZd-8W2P.js b/assets/amv2-BZd-8W2P.js
new file mode 100644
index 00000000000..5abf01c45a2
--- /dev/null
+++ b/assets/amv2-BZd-8W2P.js
@@ -0,0 +1,217 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let r=`The AMv2 project is a redo of Assignment in an attempt at addressing the root cause of many of our operational issues in production, namely slow assignment and problematic accounting such that Regions are misplaced stuck offline in the notorious *Regions-In-Transition (RIT)* limbo state.
+
+Below are notes for devs on key aspects of AMv2 in no particular order.
+
+## Background
+
+Assignment in HBase 1.x has been problematic in operation. It is not hard to see why. Region state is kept at the other end of an RPC in ZooKeeper (Terminal states โ€” i.e. OPEN or CLOSED โ€” are published to the *hbase:meta* table). In HBase-1.x.x, state has multiple writers with Master and RegionServers all able to make state edits concurrently (in *hbase:meta* table and out on ZooKeeper). If clocks are awry or watchers missed, state changes can be skipped or overwritten. Locking of HBase  [...]
+
+AMv2 (AssignmentManager Version 2) is a refactor ([HBASE-14350](https://issues.apache.org/jira/browse/HBASE-14350)) of the hbase-1.x AssignmentManager putting it up on a [ProcedureV2 (HBASE-12439)](https://issues.apache.org/jira/browse/HBASE-12439) basis. ProcedureV2 (Pv2), is an awkwardly named system that allows describing and running multi-step state machines. It is performant and persists all state to a Store which is recoverable post crash. See the companion chapter on [Procedure Fr [...]
+
+In AMv2, all assignment, crash handling, splits and merges are recast as Procedures(v2). ZooKeeper is purged from the mix. As before, the final assignment state gets published to *hbase:meta* for non-Master participants to read (all-clients) with intermediate state kept in the local Pv2 WAL-based 'store' but only the active Master, a single-writer, evolves state. The Master's in-memory cluster image is the authority and if disagreement, RegionServers are forced to comply. Pv2 adds shared [...]
+
+This redo of AM atop of a purposed, performant state machine with all operations taking on the common Procedure form with a single state writer only moves our AM to a new level of resilience and scale.
+
+## New System
+
+Each Region Assign or Unassign of a Region is now a Procedure. A Move (Region) Procedure is a compound of Procedures; it is the running of an Unassign Procedure followed by an Assign Procedure. The Move Procedure spawns the Assign and Unassign in series and then waits on their completions.
+
+And so on. ServerCrashProcedure spawns the WAL splitting tasks and then the reassign of all regions that were hosted on the crashed server as subprocedures.
+
+AMv2 Procedures are run by the Master in a ProcedureExecutor instance. All Procedures make use of utility provided by the Pv2 framework.
+
+For example, Procedures persist each state transition to the frameworks' Procedure Store. The default implementation is done as a WAL kept on HDFS. On crash, we reopen the Store and rerun all WALs of Procedure transitions to put the Assignment State Machine back into the attitude it had just before crash. We then continue Procedure execution.
+
+In the new system, the Master is the Authority on all things Assign. Previous we were ambiguous; e.g. the RegionServer was in charge of Split operations. Master keeps an in-memory image of Region states and servers. If disagreement, the Master always prevails; at an extreme it will kill the RegionServer that is in disagreement.
+
+A new RegionStateStore class takes care of publishing the terminal Region state, whether OPEN or CLOSED, out to the *hbase:meta* table.
+
+RegionServers now report their run version on Connection. This version is available inside the AM for use running migrating rolling restarts.
+
+## Procedures Detail
+
+### Assign/Unassign
+
+Assign and Unassign subclass a common RegionTransitionProcedure. There can only be one RegionTransitionProcedure per region running at a time since the RTP instance takes a lock on the region. The RTP base Procedure has three steps; a store the procedure step (REGION\\_TRANSITION\\_QUEUE); a dispatch of the procedure open or close followed by a suspend waiting on the remote regionserver to report successful open or fail (REGION\\_TRANSITION\\_DISPATCH) or notification that the server fie [...]
+
+Here is how the assign of a region 56f985a727afe80a184dac75fbf6860c looks in the logs. The assign was provoked by a Server Crash (Process ID 1176 or pid=1176 which when it is the parent of a procedure, it is identified as ppid=1176). The assign is pid=1179, the second region of the two being assigned by this Server Crash.
+
+\`\`\`
+2017-05-23 12:04:24,175 INFO  [ProcExecWrkr-30] procedure2.ProcedureExecutor: Initialized subprocedures=[{pid=1178, ppid=1176, state=RUNNABLE:REGION_TRANSITION_QUEUE; AssignProcedure table=IntegrationTestBigLinkedList, region=bfd57f0b72fd3ca77e9d3c5e3ae48d76, target=ve0540.halxg.example.org,16020,1495525111232}, {pid=1179, ppid=1176, state=RUNNABLE:REGION_TRANSITION_QUEUE; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.exa [...]
+\`\`\`
+
+Next we start the assign by queuing ('registering') the Procedure with the framework.
+
+\`\`\`
+2017-05-23 12:04:24,241 INFO  [ProcExecWrkr-30] assignment.AssignProcedure: Start pid=1179, ppid=1176, state=RUNNABLE:REGION_TRANSITION_QUEUE; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.example.org,16020,1495525111232; rit=OFFLINE, location=ve0540.halxg.example.org,16020,1495525111232; forceNewPlan=false, retain=false
+\`\`\`
+
+Track the running of Procedures in logs by tracing their process id โ€” here pid=1179.
+
+Next we move to the dispatch phase where we update hbase:meta table setting the region state as OPENING on server ve540. We then dispatch an rpc to ve540 asking it to open the region. Thereafter we suspend the Assign until we get a message back from ve540 on whether it has opened the region successfully (or not).
+
+\`\`\`
+2017-05-23 12:04:24,494 INFO  [ProcExecWrkr-38] assignment.RegionStateStore: pid=1179 updating hbase:meta row=IntegrationTestBigLinkedList,H\\xE3@\\x8D\\x964\\x9D\\xDF\\x8F@9\\x0F\\xC8\\xCC\\xC2,1495566261066.56f985a727afe80a184dac75fbf6860c., regionState=OPENING, regionLocation=ve0540.halxg.example.org,16020,1495525111232
+2017-05-23 12:04:24,498 INFO  [ProcExecWrkr-38] assignment.RegionTransitionProcedure: Dispatch pid=1179, ppid=1176, state=RUNNABLE:REGION_TRANSITION_DISPATCH; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.example.org,16020,1495525111232; rit=OPENING, location=ve0540.halxg.example.org,16020,1495525111232
+\`\`\`
+
+Below we log the incoming report that the region opened successfully on ve540. The Procedure is woken up (you can tell it the procedure is running by the name of the thread, its a ProcedureExecutor thread, ProcExecWrkr-9). The woken up Procedure updates state in hbase:meta to denote the region as open on ve0540. It then reports finished and exits.
+
+\`\`\`
+2017-05-23 12:04:26,643 DEBUG [RpcServer.default.FPBQ.Fifo.handler=46,queue=1,port=16000] assignment.RegionTransitionProcedure: Received report OPENED seqId=11984985, pid=1179, ppid=1176, state=RUNNABLE:REGION_TRANSITION_DISPATCH; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.example.org,16020,1495525111232; rit=OPENING, location=ve0540.halxg.example.org,16020,1495525111232
+2017-05-23 12:04:26,643 INFO  [ProcExecWrkr-9] assignment.RegionStateStore: pid=1179 updating hbase:meta row=IntegrationTestBigLinkedList,H\\xE3@\\x8D\\x964\\x9D\\xDF\\x8F@9\\x0F\\xC8\\xCC\\xC2,1495566261066.56f985a727afe80a184dac75fbf6860c., regionState=OPEN, openSeqNum=11984985, regionLocation=ve0540.halxg.example.org,16020,1495525111232
+2017-05-23 12:04:26,836 INFO  [ProcExecWrkr-9] procedure2.ProcedureExecutor: Finish suprocedure pid=1179, ppid=1176, state=SUCCESS; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.example.org,16020,1495525111232
+\`\`\`
+
+Unassign looks similar given it is based on the base RegionTransitionProcedure. It has the same state transitions and does basically the same steps but with different state name (CLOSING, CLOSED).
+
+Most other procedures are subclasses of a Pv2 StateMachine implementation. We have both Table and Region focused StateMachines types.
+
+## UI
+
+Along the top-bar on the Master, you can now find a 'Procedures\\&Locks' tab which takes you to a page that is ugly but useful. It dumps currently running procedures and framework locks. Look at this when you can't figure what stuff is stuck; it will at least identify problematic procedures (take the pid and grep the logs...). Look for ROLLEDBACK or pids that have been RUNNING for a long time.
+
+## Logging
+
+Procedures log their process ids as pid= and their parent ids (ppid=) everywhere. Work has been done so you can grep the pid and see history of a procedure operation.
+
+## Implementation Notes
+
+In this section we note some idiosyncrasies of operation as an attempt at saving you some head-scratching.
+
+### Region Transition RPC and RS Heartbeat can arrive at \\~same time on Master
+
+Reporting Region Transition on a RegionServer is now a RPC distinct from RS heartbeating ('RegionServerServices' Service). An heartbeat and a status update can arrive at the Master at about the same time. The Master will update its internal state for a Region but this same state is checked when heartbeat processing. We may find the unexpected; i.e. a Region just reported as CLOSED so heartbeat is surprised to find region OPEN on the back of the RS report. In the new system, all slaves mu [...]
+
+To address the above, we added a lastUpdate for in-memory Master state. Let a region state have some vintage before we act on it (one second currently).
+
+### Master as RegionServer or as RegionServer that just does system tables
+
+AMv2 enforces current master branch default of HMaster carrying system tables only; i.e. the Master in an HBase cluster acts also as a RegionServer only it is the exclusive host for tables such as *hbase:meta*, *hbase:namespace*, etc., the core system tables. This is causing a couple of test failures as AMv1, though it is not supposed to, allows moving hbase:meta off Master while AMv2 does not.
+
+## New Configs
+
+These configs all need doc on when you'd change them.
+
+#### hbase.procedure.remote.dispatcher.threadpool.size \\[!toc]
+
+Defaults 128
+
+#### hbase.procedure.remote.dispatcher.delay.msec \\[!toc]
+
+Default 150ms
+
+#### hbase.procedure.remote.dispatcher.max.queue.size \\[!toc]
+
+Default 32
+
+#### hbase.regionserver.rpc.startup.waittime \\[!toc]
+
+Default 60 seconds.
+
+## Tools
+
+HBASE-15592 Print Procedure WAL Content
+
+Patch in [HBASE-18152](https://issues.apache.org/jira/browse/HBASE-18152) \\[AMv2] Corrupt Procedure WAL file; procedure data stored out of order [https://issues.apache.org/jira/secure/attachment/12871066/reading\\_bad\\_wal.patch](https://issues.apache.org/jira/secure/attachment/12871066/reading_bad_wal.patch)
+
+### MasterProcedureSchedulerPerformanceEvaluation
+
+Tool to test performance of locks and queues in procedure scheduler independently from other framework components. Run this after any substantial changes in proc system. Prints nice output:
+
+\`\`\`text
+******************************************
+Time - addBack     : 5.0600sec
+Ops/sec - addBack  : 1.9M
+Time - poll        : 19.4590sec
+Ops/sec - poll     : 501.9K
+Num Operations     : 10000000
+
+Completed          : 10000006
+Yield              : 22025876
+
+Num Tables         : 5
+Regions per table  : 10
+Operations type    : both
+Threads            : 10
+******************************************
+Raw format for scripts
+
+RESULT [num_ops=10000000, ops_type=both, num_table=5, regions_per_table=10, threads=10, num_yield=22025876, time_addback_ms=5060, time_poll_ms=19459]
+\`\`\`
+`,i={title:"AMv2 Description for Devs",description:"The AssignmentManager (AM) in HBase Master manages assignment of Regions over a cluster of RegionServers."},o=[{href:"https://issues.apache.org/jira/browse/HBASE-14350"},{href:"https://issues.apache.org/jira/browse/HBASE-12439"},{href:"/docs/pv2"},{href:"https://issues.apache.org/jira/browse/HBASE-18152"},{href:"https://issues.apache.org/jira/secure/attachment/12871066/reading_bad_wal.patch"}],c={contents:[{heading:void 0,content:"The A [...]
+`,e.jsx(t.p,{children:"Below are notes for devs on key aspects of AMv2 in no particular order."}),`
+`,e.jsx(t.h2,{id:"amv2-background",children:"Background"}),`
+`,e.jsxs(t.p,{children:["Assignment in HBase 1.x has been problematic in operation. It is not hard to see why. Region state is kept at the other end of an RPC in ZooKeeper (Terminal states โ€” i.e. OPEN or CLOSED โ€” are published to the ",e.jsx(t.em,{children:"hbase:meta"})," table). In HBase-1.x.x, state has multiple writers with Master and RegionServers all able to make state edits concurrently (in ",e.jsx(t.em,{children:"hbase:meta"})," table and out on ZooKeeper). If clocks are awry or  [...]
+`,e.jsxs(t.p,{children:["AMv2 (AssignmentManager Version 2) is a refactor (",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-14350",children:"HBASE-14350"}),") of the hbase-1.x AssignmentManager putting it up on a ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-12439",children:"ProcedureV2 (HBASE-12439)"})," basis. ProcedureV2 (Pv2), is an awkwardly named system that allows describing and running multi-step state machines. It is performant and persists all sta [...]
+`,e.jsxs(t.p,{children:["In AMv2, all assignment, crash handling, splits and merges are recast as Procedures(v2). ZooKeeper is purged from the mix. As before, the final assignment state gets published to ",e.jsx(t.em,{children:"hbase:meta"})," for non-Master participants to read (all-clients) with intermediate state kept in the local Pv2 WAL-based 'store' but only the active Master, a single-writer, evolves state. The Master's in-memory cluster image is the authority and if disagreement, [...]
+`,e.jsx(t.p,{children:"This redo of AM atop of a purposed, performant state machine with all operations taking on the common Procedure form with a single state writer only moves our AM to a new level of resilience and scale."}),`
+`,e.jsx(t.h2,{id:"new-system",children:"New System"}),`
+`,e.jsx(t.p,{children:"Each Region Assign or Unassign of a Region is now a Procedure. A Move (Region) Procedure is a compound of Procedures; it is the running of an Unassign Procedure followed by an Assign Procedure. The Move Procedure spawns the Assign and Unassign in series and then waits on their completions."}),`
+`,e.jsx(t.p,{children:"And so on. ServerCrashProcedure spawns the WAL splitting tasks and then the reassign of all regions that were hosted on the crashed server as subprocedures."}),`
+`,e.jsx(t.p,{children:"AMv2 Procedures are run by the Master in a ProcedureExecutor instance. All Procedures make use of utility provided by the Pv2 framework."}),`
+`,e.jsx(t.p,{children:"For example, Procedures persist each state transition to the frameworks' Procedure Store. The default implementation is done as a WAL kept on HDFS. On crash, we reopen the Store and rerun all WALs of Procedure transitions to put the Assignment State Machine back into the attitude it had just before crash. We then continue Procedure execution."}),`
+`,e.jsx(t.p,{children:"In the new system, the Master is the Authority on all things Assign. Previous we were ambiguous; e.g. the RegionServer was in charge of Split operations. Master keeps an in-memory image of Region states and servers. If disagreement, the Master always prevails; at an extreme it will kill the RegionServer that is in disagreement."}),`
+`,e.jsxs(t.p,{children:["A new RegionStateStore class takes care of publishing the terminal Region state, whether OPEN or CLOSED, out to the ",e.jsx(t.em,{children:"hbase:meta"})," table."]}),`
+`,e.jsx(t.p,{children:"RegionServers now report their run version on Connection. This version is available inside the AM for use running migrating rolling restarts."}),`
+`,e.jsx(t.h2,{id:"procedures-detail",children:"Procedures Detail"}),`
+`,e.jsx(t.h3,{id:"assignunassign",children:"Assign/Unassign"}),`
+`,e.jsx(t.p,{children:"Assign and Unassign subclass a common RegionTransitionProcedure. There can only be one RegionTransitionProcedure per region running at a time since the RTP instance takes a lock on the region. The RTP base Procedure has three steps; a store the procedure step (REGION_TRANSITION_QUEUE); a dispatch of the procedure open or close followed by a suspend waiting on the remote regionserver to report successful open or fail (REGION_TRANSITION_DISPATCH) or notification that [...]
+`,e.jsx(t.p,{children:"Here is how the assign of a region 56f985a727afe80a184dac75fbf6860c looks in the logs. The assign was provoked by a Server Crash (Process ID 1176 or pid=1176 which when it is the parent of a procedure, it is identified as ppid=1176). The assign is pid=1179, the second region of the two being assigned by this Server Crash."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.p,{children:"Next we start the assign by queuing ('registering') the Procedure with the framework."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.p,{children:"Track the running of Procedures in logs by tracing their process id โ€” here pid=1179."}),`
+`,e.jsx(t.p,{children:"Next we move to the dispatch phase where we update hbase:meta table setting the region state as OPENING on server ve540. We then dispatch an rpc to ve540 asking it to open the region. Thereafter we suspend the Assign until we get a message back from ve540 on whether it has opened the region successfully (or not)."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"2017-05-23 12:04:24,498 INFO  [ProcExecWrkr-38] assignment.RegionTransitionProcedure: Dispatch pid=1179, ppid=1176, state=RUNNABLE:REGION_TRANSITION_DISPATCH; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.example.org,16020,1495525111232; rit=OPENING, location=ve0540.halxg.example.org,16020,1495525111232"})})]})})}),`
+`,e.jsx(t.p,{children:"Below we log the incoming report that the region opened successfully on ve540. The Procedure is woken up (you can tell it the procedure is running by the name of the thread, its a ProcedureExecutor thread, ProcExecWrkr-9). The woken up Procedure updates state in hbase:meta to denote the region as open on ve0540. It then reports finished and exits."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"2017-05-23 12:04:26,643 INFO  [ProcExecWrkr-9] assignment.RegionStateStore: pid=1179 updating hbase:meta row=IntegrationTestBigLinkedList,H\\xE3@\\x8D\\x964\\x9D\\xDF\\x8F@9\\x0F\\xC8\\xCC\\xC2,1495566261066.56f985a727afe80a184dac75fbf6860c., regionState=OPEN, openSeqNum=11984985, regionLocation=ve0540.halxg.example.org,16020,1495525111232"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"2017-05-23 12:04:26,836 INFO  [ProcExecWrkr-9] procedure2.ProcedureExecutor: Finish suprocedure pid=1179, ppid=1176, state=SUCCESS; AssignProcedure table=IntegrationTestBigLinkedList, region=56f985a727afe80a184dac75fbf6860c, target=ve0540.halxg.example.org,16020,1495525111232"})})]})})}),`
+`,e.jsx(t.p,{children:"Unassign looks similar given it is based on the base RegionTransitionProcedure. It has the same state transitions and does basically the same steps but with different state name (CLOSING, CLOSED)."}),`
+`,e.jsx(t.p,{children:"Most other procedures are subclasses of a Pv2 StateMachine implementation. We have both Table and Region focused StateMachines types."}),`
+`,e.jsx(t.h2,{id:"amv2-ui",children:"UI"}),`
+`,e.jsx(t.p,{children:"Along the top-bar on the Master, you can now find a 'Procedures&Locks' tab which takes you to a page that is ugly but useful. It dumps currently running procedures and framework locks. Look at this when you can't figure what stuff is stuck; it will at least identify problematic procedures (take the pid and grep the logs...). Look for ROLLEDBACK or pids that have been RUNNING for a long time."}),`
+`,e.jsx(t.h2,{id:"logging",children:"Logging"}),`
+`,e.jsx(t.p,{children:"Procedures log their process ids as pid= and their parent ids (ppid=) everywhere. Work has been done so you can grep the pid and see history of a procedure operation."}),`
+`,e.jsx(t.h2,{id:"implementation-notes",children:"Implementation Notes"}),`
+`,e.jsx(t.p,{children:"In this section we note some idiosyncrasies of operation as an attempt at saving you some head-scratching."}),`
+`,e.jsx(t.h3,{id:"region-transition-rpc-and-rs-heartbeat-can-arrive-at-same-time-on-master",children:"Region Transition RPC and RS Heartbeat can arrive at ~same time on Master"}),`
+`,e.jsx(t.p,{children:"Reporting Region Transition on a RegionServer is now a RPC distinct from RS heartbeating ('RegionServerServices' Service). An heartbeat and a status update can arrive at the Master at about the same time. The Master will update its internal state for a Region but this same state is checked when heartbeat processing. We may find the unexpected; i.e. a Region just reported as CLOSED so heartbeat is surprised to find region OPEN on the back of the RS report. In the ne [...]
+`,e.jsx(t.p,{children:"To address the above, we added a lastUpdate for in-memory Master state. Let a region state have some vintage before we act on it (one second currently)."}),`
+`,e.jsx(t.h3,{id:"master-as-regionserver-or-as-regionserver-that-just-does-system-tables",children:"Master as RegionServer or as RegionServer that just does system tables"}),`
+`,e.jsxs(t.p,{children:["AMv2 enforces current master branch default of HMaster carrying system tables only; i.e. the Master in an HBase cluster acts also as a RegionServer only it is the exclusive host for tables such as ",e.jsx(t.em,{children:"hbase:meta"}),", ",e.jsx(t.em,{children:"hbase:namespace"}),", etc., the core system tables. This is causing a couple of test failures as AMv1, though it is not supposed to, allows moving hbase:meta off Master while AMv2 does not."]}),`
+`,e.jsx(t.h2,{id:"new-configs",children:"New Configs"}),`
+`,e.jsx(t.p,{children:"These configs all need doc on when you'd change them."}),`
+`,e.jsx(t.h4,{id:"hbaseprocedureremotedispatcherthreadpoolsize-toc",children:"hbase.procedure.remote.dispatcher.threadpool.size"}),`
+`,e.jsx(t.p,{children:"Defaults 128"}),`
+`,e.jsx(t.h4,{id:"hbaseprocedureremotedispatcherdelaymsec-toc",children:"hbase.procedure.remote.dispatcher.delay.msec"}),`
+`,e.jsx(t.p,{children:"Default 150ms"}),`
+`,e.jsx(t.h4,{id:"hbaseprocedureremotedispatchermaxqueuesize-toc",children:"hbase.procedure.remote.dispatcher.max.queue.size"}),`
+`,e.jsx(t.p,{children:"Default 32"}),`
+`,e.jsx(t.h4,{id:"hbaseregionserverrpcstartupwaittime-toc",children:"hbase.regionserver.rpc.startup.waittime"}),`
+`,e.jsx(t.p,{children:"Default 60 seconds."}),`
+`,e.jsx(t.h2,{id:"amv2-tools",children:"Tools"}),`
+`,e.jsx(t.p,{children:"HBASE-15592 Print Procedure WAL Content"}),`
+`,e.jsxs(t.p,{children:["Patch in ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-18152",children:"HBASE-18152"})," [AMv2] Corrupt Procedure WAL file; procedure data stored out of order ",e.jsx(t.a,{href:"https://issues.apache.org/jira/secure/attachment/12871066/reading_bad_wal.patch",children:"https://issues.apache.org/jira/secure/attachment/12871066/reading_bad_wal.patch"})]}),`
+`,e.jsx(t.h3,{id:"masterprocedureschedulerperformanceevaluation",children:"MasterProcedureSchedulerPerformanceEvaluation"}),`
+`,e.jsx(t.p,{children:"Tool to test performance of locks and queues in procedure scheduler independently from other framework components. Run this after any substantial changes in proc system. Prints nice output:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Time - addBack     : 5.0600sec"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Ops/sec - addBack  : 1.9M"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Time - poll        : 19.4590sec"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Ops/sec - poll     : 501.9K"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Num Operations     : 10000000"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Completed          : 10000006"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Yield              : 22025876"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Num Tables         : 5"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Regions per table  : 10"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Operations type    : both"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Threads            : 10"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"******************************************"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Raw format for scripts"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"RESULT [num_ops=10000000, ops_type=both, num_table=5, regions_per_table=10, threads=10, num_yield=22025876, time_addback_ms=5060, time_poll_ms=19459]"})})]})})})]})}function d(s={}){const{wrapper:t}=s.components||{};return t?e.jsx(t,{...s,children:e.jsx(n,{...s})}):n(s)}export{r as _markdown,d as default,o as extractedReferences,i as frontmatter,c as structuredData,h as toc};
diff --git a/assets/announcing-CLGATZs-.js b/assets/announcing-CLGATZs-.js
new file mode 100644
index 00000000000..f69378eb0d3
--- /dev/null
+++ b/assets/announcing-CLGATZs-.js
@@ -0,0 +1,74 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let l=`Once an RC has passed successfully and the needed artifacts have been staged for disribution, you'll need to let everyone know about our shiny new release. It's not a requirement, but to make things easier for release managers we have a template you can start with. Be sure you replace \\_version\\_ and other markers with the relevant version numbers. You should manually verify all links before sending.
+
+\`\`\`text
+The HBase team is happy to announce the immediate availability of HBase _version_.
+
+Apache HBaseโ„ข is an open-source, distributed, versioned, non-relational database.
+Apache HBase gives you low latency random access to billions of rows with
+millions of columns atop non-specialized hardware. To learn more about HBase,
+see https://hbase.apache.org/.
+
+HBase _version_ is the _nth_ minor release in the HBase _major_.x line, which aims to
+improve the stability and reliability of HBase. This release includes roughly
+XXX resolved issues not covered by previous _major_.x releases.
+
+Notable new features include:
+- List text descriptions of features that fit on one line
+- Including if JDK or Hadoop support versions changes
+- If the "stable" pointer changes, call that out
+- For those with obvious JIRA IDs, include them (HBASE-YYYYY)
+
+The full list of issues can be found in the included CHANGES.md and RELEASENOTES.md,
+or via our issue tracker:
+
+    https://s.apache.org/hbase-_version_-jira
+
+To download please follow the links and instructions on our website:
+
+    https://hbase.apache.org/downloads.html
+
+
+Question, comments, and problems are always welcome at: dev@hbase.apache.org.
+
+Thanks to all who contributed and made this release possible.
+
+Cheers,
+The HBase Dev Team
+\`\`\`
+
+You should sent this message to the following lists: [dev@hbase.apache.org](mailto:dev@hbase.apache.org), [user@hbase.apache.org](mailto:user@hbase.apache.org), [announce@apache.org](mailto:announce@apache.org). If you'd like a spot check before sending, feel free to ask via jira or the dev list.
+`,o={title:"Announcing Releases",description:"Email template and guidelines for announcing new HBase releases to the community and mailing lists."},r=[{href:"mailto:dev@hbase.apache.org"},{href:"mailto:user@hbase.apache.org"},{href:"mailto:announce@apache.org"}],t={contents:[{heading:void 0,content:"Once an RC has passed successfully and the needed artifacts have been staged for disribution, you'll need to let everyone know about our shiny new release. It's not a requirement, but to make [...]
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Apache HBaseโ„ข is an open-source, distributed, versioned, non-relational database."})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Apache HBase gives you low latency random access to billions of rows with"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"millions of columns atop non-specialized hardware. To learn more about HBase,"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"see https://hbase.apache.org/."})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"HBase _version_ is the _nth_ minor release in the HBase _major_.x line, which aims to"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"improve the stability and reliability of HBase. This release includes roughly"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"XXX resolved issues not covered by previous _major_.x releases."})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Notable new features include:"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"- List text descriptions of features that fit on one line"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"- Including if JDK or Hadoop support versions changes"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:'- If the "stable" pointer changes, call that out'})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"- For those with obvious JIRA IDs, include them (HBASE-YYYYY)"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"The full list of issues can be found in the included CHANGES.md and RELEASENOTES.md,"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"or via our issue tracker:"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"    https://s.apache.org/hbase-_version_-jira"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"To download please follow the links and instructions on our website:"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"    https://hbase.apache.org/downloads.html"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Question, comments, and problems are always welcome at: dev@hbase.apache.org."})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Thanks to all who contributed and made this release possible."})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Cheers,"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"The HBase Dev Team"})})]})})}),`
+`,e.jsxs(s.p,{children:["You should sent this message to the following lists: ",e.jsx(s.a,{href:"mailto:dev@hbase.apache.org",children:"dev@hbase.apache.org"}),", ",e.jsx(s.a,{href:"mailto:user@hbase.apache.org",children:"user@hbase.apache.org"}),", ",e.jsx(s.a,{href:"mailto:announce@apache.org",children:"announce@apache.org"}),". If you'd like a spot check before sending, feel free to ask via jira or the dev list."]})]})}function c(n={}){const{wrapper:s}=n.components||{};return s?e.jsx( [...]
diff --git a/assets/app-DqYvjlOc.css b/assets/app-DqYvjlOc.css
new file mode 100644
index 00000000000..50d5051a40f
--- /dev/null
+++ b/assets/app-DqYvjlOc.css
@@ -0,0 +1 @@
+@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-divide-y-reverse:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal [...]
diff --git a/assets/asf-B_xSNWZq.js b/assets/asf-B_xSNWZq.js
new file mode 100644
index 00000000000..d1880b237cd
--- /dev/null
+++ b/assets/asf-B_xSNWZq.js
@@ -0,0 +1,11 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let a=`## ASF Development Process
+
+See the [Apache Development Process page](https://www.apache.org/dev/#committers) for all sorts of information on how the ASF is structured (e.g., PMC, committers, contributors), to tips on contributing and getting involved, and how open-source works at ASF.
+
+## ASF Board Reporting
+
+Once a quarter, each project in the ASF portfolio submits a report to the ASF board. This is done by the HBase project lead and the committers. See [ASF board reporting](https://www.apache.org/foundation/board/reporting) for more information.
+`,s={title:"HBase and the Apache Software Foundation",description:"HBase is a project in the Apache Software Foundation and as such there are responsibilities to the ASF to ensure a healthy project."},i=[{href:"https://www.apache.org/dev/#committers"},{href:"https://www.apache.org/foundation/board/reporting"}],c={contents:[{heading:"asf-development-process",content:"See the Apache Development Process page for all sorts of information on how the ASF is structured (e.g., PMC, committers, c [...]
+`,e.jsxs(t.p,{children:["See the ",e.jsx(t.a,{href:"https://www.apache.org/dev/#committers",children:"Apache Development Process page"})," for all sorts of information on how the ASF is structured (e.g., PMC, committers, contributors), to tips on contributing and getting involved, and how open-source works at ASF."]}),`
+`,e.jsx(t.h2,{id:"asf-board-reporting",children:"ASF Board Reporting"}),`
+`,e.jsxs(t.p,{children:["Once a quarter, each project in the ASF portfolio submits a report to the ASF board. This is done by the HBase project lead and the committers. See ",e.jsx(t.a,{href:"https://www.apache.org/foundation/board/reporting",children:"ASF board reporting"})," for more information."]})]})}function d(o={}){const{wrapper:t}=o.components||{};return t?e.jsx(t,{...o,children:e.jsx(r,{...o})}):r(o)}export{a as _markdown,d as default,i as extractedReferences,s as frontmatter,c  [...]
diff --git a/assets/backup-and-snapshots-DywQULg4.js b/assets/backup-and-snapshots-DywQULg4.js
new file mode 100644
index 00000000000..446f8292304
--- /dev/null
+++ b/assets/backup-and-snapshots-DywQULg4.js
@@ -0,0 +1,447 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let h=`## HBase Backup
+
+There are two broad strategies for performing HBase backups: backing up with a full cluster shutdown, and backing up on a live cluster. Each approach has pros and cons.
+
+For additional information, see [HBase Backup Options](https://web.archive.org/web/20160110232448/http://blog.sematext.com/2011/03/11/hbase-backup-options/) over on the Sematext Blog.
+
+### Full Shutdown Backup
+
+Some environments can tolerate a periodic full shutdown of their HBase cluster, for example if it is being used a back-end analytic capacity and not serving front-end web-pages. The benefits are that the NameNode/Master are RegionServers are down, so there is no chance of missing any in-flight changes to either StoreFiles or metadata. The obvious con is that the cluster is down. The steps include:
+
+#### Stop HBase
+
+#### Distcp
+
+Distcp could be used to either copy the contents of the HBase directory in HDFS to either the same cluster in another directory, or to a different cluster.\\
+Note: Distcp works in this situation because the cluster is down and there are no in-flight edits to files. Distcp-ing of files in the HBase directory is not generally recommended on a live cluster.
+
+#### Restore (if needed)
+
+The backup of the hbase directory from HDFS is copied onto the 'real' hbase directory via distcp. The act of copying these files creates new HDFS metadata, which is why a restore of the NameNode edits from the time of the HBase backup isn't required for this kind of restore, because it's a restore (via distcp) of a specific HDFS directory (i.e., the HBase part) not the entire HDFS file-system.
+
+### Live Cluster Backup - Replication
+
+This approach assumes that there is a second cluster. See the HBase page on [replication](/docs/operational-management/cluster-replication) for more information.
+
+### Live Cluster Backup - CopyTable
+
+The [copytable](/docs/operational-management/tools#copytable) utility could either be used to copy data from one table to another on the same cluster, or to copy data to another table on another cluster.
+
+Since the cluster is up, there is a risk that edits could be missed in the copy process.
+
+### Live Cluster Backup - Export
+
+The [export](/docs/operational-management/tools#export) approach dumps the content of a table to HDFS on the same cluster. To restore the data, the [import](/docs/operational-management/tools#import) utility would be used.
+
+Since the cluster is up, there is a risk that edits could be missed in the export process. If you want to know more about HBase back-up and restore see the page on [Backup and Restore](/docs/backup-restore).
+
+## HBase Snapshots
+
+HBase Snapshots allow you to take a copy of a table (both contents and metadata)with a very small performance impact. A Snapshot is an immutable collection of table metadata and a list of HFiles that comprised the table at the time the Snapshot was taken. A "clone" of a snapshot creates a new table from that snapshot, and a "restore" of a snapshot returns the contents of a table to what it was when the snapshot was created. The "clone" and "restore" operations do not require any data to  [...]
+
+Prior to version 0.94.6, the only way to backup or to clone a table is to use CopyTable/ExportTable, or to copy all the hfiles in HDFS after disabling the table. The disadvantages of these methods are that you can degrade region server performance (Copy/Export Table) or you need to disable the table, that means no reads or writes; and this is usually unacceptable.
+
+### Configuration
+
+To turn on the snapshot support just set the \`hbase.snapshot.enabled\` property to true. (Snapshots are enabled by default in 0.95+ and off by default in 0.94.6+)
+
+\`\`\`xml
+<property>
+  <name>hbase.snapshot.enabled</name>
+  <value>true</value>
+</property>
+\`\`\`
+
+### Take a Snapshot
+
+You can take a snapshot of a table regardless of whether it is enabled or disabled. The snapshot operation doesn't involve any data copying.
+
+\`\`\`bash
+$ ./bin/hbase shell
+hbase> snapshot 'myTable', 'myTableSnapshot-122112'
+
+\`\`\`
+
+#### Take a Snapshot Without Flushing
+
+The default behavior is to perform a flush of data in memory before the snapshot is taken. This means that data in memory is included in the snapshot. In most cases, this is the desired behavior. However, if your set-up can tolerate data in memory being excluded from the snapshot, you can use the \`SKIP_FLUSH\` option of the \`snapshot\` command to disable and flushing while taking the snapshot.
+
+\`\`\`ruby
+hbase> snapshot 'mytable', 'snapshot123', {SKIP_FLUSH => true}
+\`\`\`
+
+<Callout type="warn">
+  There is no way to determine or predict whether a very concurrent insert or update will be
+  included in a given snapshot, whether flushing is enabled or disabled. A snapshot is only a
+  representation of a table during a window of time. The amount of time the snapshot operation will
+  take to reach each Region Server may vary from a few seconds to a minute, depending on the
+  resource load and speed of the hardware or network, among other factors. There is also no way to
+  know whether a given insert or update is in memory or has been flushed.
+</Callout>
+
+#### Take a Snapshot With TTL
+
+Snapshots have a lifecycle that is independent from the table from which they are created. Although data in a table may be stored with TTL the data files containing them become frozen by the snapshot. Space consumed by expired cells will not be reclaimed by normal table housekeeping like compaction. While this is expected it can be inconvenient at scale. When many snapshots are under management and the data in various tables is expired by TTL some notion of optional TTL (and optional def [...]
+
+\`\`\`ruby
+hbase> snapshot 'mytable', 'snapshot1234', {TTL => 86400}
+\`\`\`
+
+The above command creates snapshot \`snapshot1234\` with TTL of 86400 sec (24 hours) and hence, the snapshot is supposed to be cleaned up after 24 hours
+
+#### Default Snapshot TTL:
+
+* User specified default TTL with config \`hbase.master.snapshot.ttl\`
+* FOREVER if \`hbase.master.snapshot.ttl\` is not set
+
+While creating a snapshot, if TTL in seconds is not explicitly specified, the above logic will be followed to determine the TTL. If no configs are changed, the default behavior is that all snapshots will be retained forever (until manual deletion). If a different default TTL behavior is desired, \`hbase.master.snapshot.ttl\` can be set to a default TTL in seconds. Any snapshot created without an explicit TTL will take this new value.
+
+<Callout type="info">
+  If \`hbase.master.snapshot.ttl\` is set, a snapshot with an explicit \\{TTL โ‡’ 0} or \\{TTL โ‡’ -1} will also take this value. In this case, a TTL \\< -1 (such as \\{TTL โ‡’ -2}) should be used to indicate FOREVER.
+</Callout>
+
+To summarize concisely,
+
+1. Snapshot with TTL value \\< -1 will stay forever regardless of any server side config changes (until deleted manually by user).
+2. Snapshot with TTL value > 0 will be deleted automatically soon after TTL expires.
+3. Snapshot created without specifying TTL will always have TTL value represented by config \`hbase.master.snapshot.ttl\`. Default value of this config is 0, which represents: keep the snapshot forever (until deleted manually by user).
+4. From client side, TTL value 0 or -1 should never be explicitly provided because they will be treated same as snapshot without TTL (same as above point 3) and hence will use TTL as per value represented by config \`hbase.master.snapshot.ttl\`.
+
+#### Take a snapshot with custom MAX\\_FILESIZE
+
+Optionally, snapshots can be created with a custom max file size configuration that will be used by cloned tables, instead of the global \`hbase.hregion.max.filesize\` configuration property. This is mostly useful when exporting snapshots between different clusters. If the HBase cluster where the snapshot is originally taken has a much larger value set for \`hbase.hregion.max.filesize\` than one or more clusters where the snapshot is being exported to, a storm of region splits may occur  [...]
+
+\`\`\`ruby
+snapshot 'table01', 'snap01', {MAX_FILESIZE => 21474836480}
+\`\`\`
+
+#### Enable/Disable Snapshot Auto Cleanup on running cluster:
+
+By default, snapshot auto cleanup based on TTL would be enabled for any new cluster. At any point in time, if snapshot cleanup is supposed to be stopped due to some snapshot restore activity or any other reason, it is advisable to disable it using shell command:
+
+\`\`\`ruby
+hbase> snapshot_cleanup_switch false
+\`\`\`
+
+We can re-enable it using:
+
+\`\`\`ruby
+hbase> snapshot_cleanup_switch true
+\`\`\`
+
+The shell command with switch false would disable snapshot auto cleanup activity based on TTL and return the previous state of the activity(true: running already, false: disabled already)
+
+A sample output for above commands:
+
+\`\`\`text
+Previous snapshot cleanup state : true
+Took 0.0069 seconds
+=> "true"
+\`\`\`
+
+We can query whether snapshot auto cleanup is enabled for cluster using:
+
+\`\`\`ruby
+hbase> snapshot_cleanup_enabled
+\`\`\`
+
+The command would return output in true/false.
+
+### Listing Snapshots
+
+List all snapshots taken (by printing the names and relative information).
+
+\`\`\`bash
+$ ./bin/hbase shell
+hbase> list_snapshots
+\`\`\`
+
+### Deleting Snapshots
+
+You can remove a snapshot, and the files retained for that snapshot will be removed if no longer needed.
+
+\`\`\`bash
+$ ./bin/hbase shell
+hbase> delete_snapshot 'myTableSnapshot-122112'
+\`\`\`
+
+### Clone a table from snapshot
+
+From a snapshot you can create a new table (clone operation) with the same data that you had when the snapshot was taken. The clone operation, doesn't involve data copies, and a change to the cloned table doesn't impact the snapshot or the original table.
+
+\`\`\`bash
+$ ./bin/hbase shell
+hbase> clone_snapshot 'myTableSnapshot-122112', 'myNewTestTable'
+\`\`\`
+
+### Restore a snapshot
+
+The restore operation requires the table to be disabled, and the table will be restored to the state at the time when the snapshot was taken, changing both data and schema if required.
+
+\`\`\`bash
+$ ./bin/hbase shell
+hbase> disable 'myTable'
+hbase> restore_snapshot 'myTableSnapshot-122112'
+\`\`\`
+
+<Callout type="info">
+  Since Replication works at log level and snapshots at file-system level, after a restore, the
+  replicas will be in a different state from the master. If you want to use restore, you need to
+  stop replication and redo the bootstrap.
+</Callout>
+
+In case of partial data-loss due to misbehaving client, instead of a full restore that requires the table to be disabled, you can clone the table from the snapshot and use a Map-Reduce job to copy the data that you need, from the clone to the main one.
+
+### Snapshots operations and ACLs
+
+If you are using security with the AccessController Coprocessor (See [hbase.accesscontrol.configuration](/docs/security/data-access#access-control-labels-acls)), only a global administrator can take, clone, or restore a snapshot, and these actions do not capture the ACL rights. This means that restoring a table preserves the ACL rights of the existing table, while cloning a table creates a new table that has no ACL rights until the administrator adds them.
+
+### Export to another cluster
+
+The ExportSnapshot tool copies all the data related to a snapshot (hfiles, logs, snapshot metadata) to another cluster. The tool executes a Map-Reduce job, similar to distcp, to copy files between the two clusters, and since it works at file-system level the hbase cluster does not have to be online.
+
+To copy a snapshot called MySnapshot to an HBase cluster srv2 (hdfs\\:///srv2:8082/hbase) using 16 mappers:
+
+\`\`\`bash
+$ bin/hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot MySnapshot -copy-to hdfs://srv2:8082/hbase -mappers 16
+\`\`\`
+
+#### Limiting Bandwidth Consumption
+
+You can limit the bandwidth consumption when exporting a snapshot, by specifying the \`-bandwidth\` parameter, which expects an integer representing megabytes per second. The following example limits the above example to 200 MB/sec.
+
+\`\`\`bash
+$ bin/hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot MySnapshot -copy-to hdfs://srv2:8082/hbase -mappers 16 -bandwidth 200
+\`\`\`
+
+## Storing Snapshots in an Amazon S3 Bucket
+
+You can store and retrieve snapshots from Amazon S3, using the following procedure.
+
+<Callout type="info">
+  You can also store snapshots in Microsoft Azure Blob Storage. See [Storing Snapshots in Microsoft
+  Azure Blob
+  Storage](/docs/operational-management/backup-and-snapshots#storing-snapshots-in-microsoft-azure-blob-storage).
+</Callout>
+
+### Prerequisites
+
+* You must be using HBase 1.0 or higher and Hadoop 2.6.1 or higher, which is the first configuration that uses the Amazon AWS SDK.
+* You must use the \`s3a://\` protocol to connect to Amazon S3. The older \`s3n://\` and \`s3://\` protocols have various limitations and do not use the Amazon AWS SDK.
+* The \`s3a://\` URI must be configured and available on the server where you run the commands to export and restore the snapshot.
+
+After you have fulfilled the prerequisites, take the snapshot like you normally would. Afterward, you can export it using the \`org.apache.hadoop.hbase.snapshot.ExportSnapshot\` command like the one below, substituting your own \`s3a://\` path in the \`copy-from\` or \`copy-to\` directive and substituting or modifying other options as required:
+
+\`\`\`bash
+$ hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot \\
+    -snapshot MySnapshot \\
+    -copy-from hdfs://srv2:8082/hbase \\
+    -copy-to s3a://<bucket>/<namespace>/hbase \\
+    -chuser MyUser \\
+    -chgroup MyGroup \\
+    -chmod 700 \\
+    -mappers 16
+\`\`\`
+
+\`\`\`bash
+$ hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot \\
+    -snapshot MySnapshot
+    -copy-from s3a://<bucket>/<namespace>/hbase \\
+    -copy-to hdfs://srv2:8082/hbase \\
+    -chuser MyUser \\
+    -chgroup MyGroup \\
+    -chmod 700 \\
+    -mappers 16
+\`\`\`
+
+You can also use the \`org.apache.hadoop.hbase.snapshot.SnapshotInfo\` utility with the \`s3a://\` path by including the \`-remote-dir\` option.
+
+\`\`\`bash
+$ hbase org.apache.hadoop.hbase.snapshot.SnapshotInfo \\
+    -remote-dir s3a://<bucket>/<namespace>/hbase \\
+    -list-snapshots
+\`\`\`
+
+## Storing Snapshots in Microsoft Azure Blob Storage
+
+You can store snapshots in Microsoft Azure Blog Storage using the same techniques as in [Storing Snapshots in an Amazon S3 Bucket](/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket).
+
+### Prerequisites
+
+* You must be using HBase 1.2 or higher with Hadoop 2.7.1 or higher. No version of HBase supports Hadoop 2.7.0.
+* Your hosts must be configured to be aware of the Azure blob storage filesystem. See [https://hadoop.apache.org/docs/r2.7.1/hadoop-azure/index.html](https://hadoop.apache.org/docs/r2.7.1/hadoop-azure/index.html).
+
+After you meet the prerequisites, follow the instructions in [Storing Snapshots in an Amazon S3 Bucket](/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket), replacingthe protocol specifier with \`wasb://\` or \`wasbs://\`.
+
+## Storing Snapshots in Aliyun Object Storage Service
+
+You can store snapshots in Aliyun Object Storage Service(Aliyun OSS) using the same techniques as in [Storing Snapshots in an Amazon S3 Bucket](/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket).
+
+### Prerequisites
+
+* You must be using HBase 1.2 or higher with Hadoop 2.9.1 or higher.
+* Your hosts must be configured to be aware of the Aliyun oss filesystem. See [https://hadoop.apache.org/docs/stable/hadoop-aliyun/tools/hadoop-aliyun/index.html](https://hadoop.apache.org/docs/stable/hadoop-aliyun/tools/hadoop-aliyun/index.html).
+
+After you meet the prerequisites, follow the instructions in [Storing Snapshots in an Amazon S3 Bucket](/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket), replacing the protocol specifier with \`oss://\`.
+`,r={title:"Backup & Snapshots",description:"HBase backup strategies and snapshot operations for data protection, including full cluster backups and live cluster snapshots."},l=[{href:"https://web.archive.org/web/20160110232448/http://blog.sematext.com/2011/03/11/hbase-backup-options/"},{href:"/docs/operational-management/cluster-replication"},{href:"/docs/operational-management/tools#copytable"},{href:"/docs/operational-management/tools#export"},{href:"/docs/operational-management/tools [...]
+included in a given snapshot, whether flushing is enabled or disabled. A snapshot is only a
+representation of a table during a window of time. The amount of time the snapshot operation will
+take to reach each Region Server may vary from a few seconds to a minute, depending on the
+resource load and speed of the hardware or network, among other factors. There is also no way to
+know whether a given insert or update is in memory or has been flushed.`},{heading:"take-a-snapshot-with-ttl",content:"Snapshots have a lifecycle that is independent from the table from which they are created. Although data in a table may be stored with TTL the data files containing them become frozen by the snapshot. Space consumed by expired cells will not be reclaimed by normal table housekeeping like compaction. While this is expected it can be inconvenient at scale. When many snapsh [...]
+replicas will be in a different state from the master. If you want to use restore, you need to
+stop replication and redo the bootstrap.`},{heading:"restore-a-snapshot",content:"In case of partial data-loss due to misbehaving client, instead of a full restore that requires the table to be disabled, you can clone the table from the snapshot and use a Map-Reduce job to copy the data that you need, from the clone to the main one."},{heading:"snapshots-operations-and-acls",content:"If you are using security with the AccessController Coprocessor (See hbase.accesscontrol.configuration),  [...]
+Azure Blob
+Storage.`},{heading:"operational-management-backup-and-snapshots-stroing-in-s3-prerequisites",content:"You must be using HBase 1.0 or higher and Hadoop 2.6.1 or higher, which is the first configuration that uses the Amazon AWS SDK."},{heading:"operational-management-backup-and-snapshots-stroing-in-s3-prerequisites",content:"You must use the s3a:// protocol to connect to Amazon S3. The older s3n:// and s3:// protocols have various limitations and do not use the Amazon AWS SDK."},{heading: [...]
+`,e.jsx(s.p,{children:"There are two broad strategies for performing HBase backups: backing up with a full cluster shutdown, and backing up on a live cluster. Each approach has pros and cons."}),`
+`,e.jsxs(s.p,{children:["For additional information, see ",e.jsx(s.a,{href:"https://web.archive.org/web/20160110232448/http://blog.sematext.com/2011/03/11/hbase-backup-options/",children:"HBase Backup Options"})," over on the Sematext Blog."]}),`
+`,e.jsx(s.h3,{id:"full-shutdown-backup",children:"Full Shutdown Backup"}),`
+`,e.jsx(s.p,{children:"Some environments can tolerate a periodic full shutdown of their HBase cluster, for example if it is being used a back-end analytic capacity and not serving front-end web-pages. The benefits are that the NameNode/Master are RegionServers are down, so there is no chance of missing any in-flight changes to either StoreFiles or metadata. The obvious con is that the cluster is down. The steps include:"}),`
+`,e.jsx(s.h4,{id:"operational-management-backup-and-snapshots-stop-hbase",children:"Stop HBase"}),`
+`,e.jsx(s.h4,{id:"distcp",children:"Distcp"}),`
+`,e.jsxs(s.p,{children:["Distcp could be used to either copy the contents of the HBase directory in HDFS to either the same cluster in another directory, or to a different cluster.",e.jsx(s.br,{}),`
+`,"Note: Distcp works in this situation because the cluster is down and there are no in-flight edits to files. Distcp-ing of files in the HBase directory is not generally recommended on a live cluster."]}),`
+`,e.jsx(s.h4,{id:"restore-if-needed",children:"Restore (if needed)"}),`
+`,e.jsx(s.p,{children:"The backup of the hbase directory from HDFS is copied onto the 'real' hbase directory via distcp. The act of copying these files creates new HDFS metadata, which is why a restore of the NameNode edits from the time of the HBase backup isn't required for this kind of restore, because it's a restore (via distcp) of a specific HDFS directory (i.e., the HBase part) not the entire HDFS file-system."}),`
+`,e.jsx(s.h3,{id:"live-cluster-backup---replication",children:"Live Cluster Backup - Replication"}),`
+`,e.jsxs(s.p,{children:["This approach assumes that there is a second cluster. See the HBase page on ",e.jsx(s.a,{href:"/docs/operational-management/cluster-replication",children:"replication"})," for more information."]}),`
+`,e.jsx(s.h3,{id:"live-cluster-backup---copytable",children:"Live Cluster Backup - CopyTable"}),`
+`,e.jsxs(s.p,{children:["The ",e.jsx(s.a,{href:"/docs/operational-management/tools#copytable",children:"copytable"})," utility could either be used to copy data from one table to another on the same cluster, or to copy data to another table on another cluster."]}),`
+`,e.jsx(s.p,{children:"Since the cluster is up, there is a risk that edits could be missed in the copy process."}),`
+`,e.jsx(s.h3,{id:"live-cluster-backup---export",children:"Live Cluster Backup - Export"}),`
+`,e.jsxs(s.p,{children:["The ",e.jsx(s.a,{href:"/docs/operational-management/tools#export",children:"export"})," approach dumps the content of a table to HDFS on the same cluster. To restore the data, the ",e.jsx(s.a,{href:"/docs/operational-management/tools#import",children:"import"})," utility would be used."]}),`
+`,e.jsxs(s.p,{children:["Since the cluster is up, there is a risk that edits could be missed in the export process. If you want to know more about HBase back-up and restore see the page on ",e.jsx(s.a,{href:"/docs/backup-restore",children:"Backup and Restore"}),"."]}),`
+`,e.jsx(s.h2,{id:"hbase-snapshots",children:"HBase Snapshots"}),`
+`,e.jsx(s.p,{children:'HBase Snapshots allow you to take a copy of a table (both contents and metadata)with a very small performance impact. A Snapshot is an immutable collection of table metadata and a list of HFiles that comprised the table at the time the Snapshot was taken. A "clone" of a snapshot creates a new table from that snapshot, and a "restore" of a snapshot returns the contents of a table to what it was when the snapshot was created. The "clone" and "restore" operations do n [...]
+`,e.jsx(s.p,{children:"Prior to version 0.94.6, the only way to backup or to clone a table is to use CopyTable/ExportTable, or to copy all the hfiles in HDFS after disabling the table. The disadvantages of these methods are that you can degrade region server performance (Copy/Export Table) or you need to disable the table, that means no reads or writes; and this is usually unacceptable."}),`
+`,e.jsx(s.h3,{id:"operational-management-backup-and-snapshots-configuration",children:"Configuration"}),`
+`,e.jsxs(s.p,{children:["To turn on the snapshot support just set the ",e.jsx(s.code,{children:"hbase.snapshot.enabled"})," property to true. (Snapshots are enabled by default in 0.95+ and off by default in 0.94.6+)"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(s.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.snapshot.enabled</"}),e.jsx(s.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"# [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(s.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),e.jsx(s.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(s.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(s.h3,{id:"take-a-snapshot",children:"Take a Snapshot"}),`
+`,e.jsx(s.p,{children:"You can take a snapshot of a table regardless of whether it is enabled or disabled. The snapshot operation doesn't involve any data copying."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"> "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"snapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'myTable',"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},c [...]
+`,e.jsx(s.h4,{id:"take-a-snapshot-without-flushing",children:"Take a Snapshot Without Flushing"}),`
+`,e.jsxs(s.p,{children:["The default behavior is to perform a flush of data in memory before the snapshot is taken. This means that data in memory is included in the snapshot. In most cases, this is the desired behavior. However, if your set-up can tolerate data in memory being excluded from the snapshot, you can use the ",e.jsx(s.code,{children:"SKIP_FLUSH"})," option of the ",e.jsx(s.code,{children:"snapshot"})," command to disable and flushing while taking the snapshot."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(a,{type:"warn",children:e.jsx(s.p,{children:`There is no way to determine or predict whether a very concurrent insert or update will be
+included in a given snapshot, whether flushing is enabled or disabled. A snapshot is only a
+representation of a table during a window of time. The amount of time the snapshot operation will
+take to reach each Region Server may vary from a few seconds to a minute, depending on the
+resource load and speed of the hardware or network, among other factors. There is also no way to
+know whether a given insert or update is in memory or has been flushed.`})}),`
+`,e.jsx(s.h4,{id:"take-a-snapshot-with-ttl",children:"Take a Snapshot With TTL"}),`
+`,e.jsx(s.p,{children:"Snapshots have a lifecycle that is independent from the table from which they are created. Although data in a table may be stored with TTL the data files containing them become frozen by the snapshot. Space consumed by expired cells will not be reclaimed by normal table housekeeping like compaction. While this is expected it can be inconvenient at scale. When many snapshots are under management and the data in various tables is expired by TTL some notion of optiona [...]
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsxs(s.p,{children:["The above command creates snapshot ",e.jsx(s.code,{children:"snapshot1234"})," with TTL of 86400 sec (24 hours) and hence, the snapshot is supposed to be cleaned up after 24 hours"]}),`
+`,e.jsx(s.h4,{id:"default-snapshot-ttl",children:"Default Snapshot TTL:"}),`
+`,e.jsxs(s.ul,{children:[`
+`,e.jsxs(s.li,{children:["User specified default TTL with config ",e.jsx(s.code,{children:"hbase.master.snapshot.ttl"})]}),`
+`,e.jsxs(s.li,{children:["FOREVER if ",e.jsx(s.code,{children:"hbase.master.snapshot.ttl"})," is not set"]}),`
+`]}),`
+`,e.jsxs(s.p,{children:["While creating a snapshot, if TTL in seconds is not explicitly specified, the above logic will be followed to determine the TTL. If no configs are changed, the default behavior is that all snapshots will be retained forever (until manual deletion). If a different default TTL behavior is desired, ",e.jsx(s.code,{children:"hbase.master.snapshot.ttl"})," can be set to a default TTL in seconds. Any snapshot created without an explicit TTL will take this new value."]}),`
+`,e.jsx(a,{type:"info",children:e.jsxs(s.p,{children:["If ",e.jsx(s.code,{children:"hbase.master.snapshot.ttl"})," is set, a snapshot with an explicit {TTL โ‡’ 0} or {TTL โ‡’ -1} will also take this value. In this case, a TTL < -1 (such as {TTL โ‡’ -2}) should be used to indicate FOREVER."]})}),`
+`,e.jsx(s.p,{children:"To summarize concisely,"}),`
+`,e.jsxs(s.ol,{children:[`
+`,e.jsx(s.li,{children:"Snapshot with TTL value < -1 will stay forever regardless of any server side config changes (until deleted manually by user)."}),`
+`,e.jsx(s.li,{children:"Snapshot with TTL value > 0 will be deleted automatically soon after TTL expires."}),`
+`,e.jsxs(s.li,{children:["Snapshot created without specifying TTL will always have TTL value represented by config ",e.jsx(s.code,{children:"hbase.master.snapshot.ttl"}),". Default value of this config is 0, which represents: keep the snapshot forever (until deleted manually by user)."]}),`
+`,e.jsxs(s.li,{children:["From client side, TTL value 0 or -1 should never be explicitly provided because they will be treated same as snapshot without TTL (same as above point 3) and hence will use TTL as per value represented by config ",e.jsx(s.code,{children:"hbase.master.snapshot.ttl"}),"."]}),`
+`]}),`
+`,e.jsx(s.h4,{id:"take-a-snapshot-with-custom-max_filesize",children:"Take a snapshot with custom MAX_FILESIZE"}),`
+`,e.jsxs(s.p,{children:["Optionally, snapshots can be created with a custom max file size configuration that will be used by cloned tables, instead of the global ",e.jsx(s.code,{children:"hbase.hregion.max.filesize"})," configuration property. This is mostly useful when exporting snapshots between different clusters. If the HBase cluster where the snapshot is originally taken has a much larger value set for ",e.jsx(s.code,{children:"hbase.hregion.max.filesize"})," than one or more cluste [...]
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(s.h4,{id:"enabledisable-snapshot-auto-cleanup-on-running-cluster",children:"Enable/Disable Snapshot Auto Cleanup on running cluster:"}),`
+`,e.jsx(s.p,{children:"By default, snapshot auto cleanup based on TTL would be enabled for any new cluster. At any point in time, if snapshot cleanup is supposed to be stopped due to some snapshot restore activity or any other reason, it is advisable to disable it using shell command:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(s.p,{children:"We can re-enable it using:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(s.p,{children:"The shell command with switch false would disable snapshot auto cleanup activity based on TTL and return the previous state of the activity(true: running already, false: disabled already)"}),`
+`,e.jsx(s.p,{children:"A sample output for above commands:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:"Took 0.0069 seconds"})}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{children:'=> "true"'})})]})})}),`
+`,e.jsx(s.p,{children:"We can query whether snapshot auto cleanup is enabled for cluster using:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(s.p,{children:"The command would return output in true/false."}),`
+`,e.jsx(s.h3,{id:"listing-snapshots",children:"Listing Snapshots"}),`
+`,e.jsx(s.p,{children:"List all snapshots taken (by printing the names and relative information)."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"> "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"list_snapshots"})]})]})})}),`
+`,e.jsx(s.h3,{id:"deleting-snapshots",children:"Deleting Snapshots"}),`
+`,e.jsx(s.p,{children:"You can remove a snapshot, and the files retained for that snapshot will be removed if no longer needed."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"> "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"delete_snapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'myTableSnapshot-122112'"})]})]})})}),`
+`,e.jsx(s.h3,{id:"clone-a-table-from-snapshot",children:"Clone a table from snapshot"}),`
+`,e.jsx(s.p,{children:"From a snapshot you can create a new table (clone operation) with the same data that you had when the snapshot was taken. The clone operation, doesn't involve data copies, and a change to the cloned table doesn't impact the snapshot or the original table."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"> "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"clone_snapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'myTableSnapshot-122112',"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shi [...]
+`,e.jsx(s.h3,{id:"restore-a-snapshot",children:"Restore a snapshot"}),`
+`,e.jsx(s.p,{children:"The restore operation requires the table to be disabled, and the table will be restored to the state at the time when the snapshot was taken, changing both data and schema if required."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"> "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"disable"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'myTable'"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"> "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"restore_snapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'myTableSnapshot-122112'"})]})]})})}),`
+`,e.jsx(a,{type:"info",children:e.jsx(s.p,{children:`Since Replication works at log level and snapshots at file-system level, after a restore, the
+replicas will be in a different state from the master. If you want to use restore, you need to
+stop replication and redo the bootstrap.`})}),`
+`,e.jsx(s.p,{children:"In case of partial data-loss due to misbehaving client, instead of a full restore that requires the table to be disabled, you can clone the table from the snapshot and use a Map-Reduce job to copy the data that you need, from the clone to the main one."}),`
+`,e.jsx(s.h3,{id:"snapshots-operations-and-acls",children:"Snapshots operations and ACLs"}),`
+`,e.jsxs(s.p,{children:["If you are using security with the AccessController Coprocessor (See ",e.jsx(s.a,{href:"/docs/security/data-access#access-control-labels-acls",children:"hbase.accesscontrol.configuration"}),"), only a global administrator can take, clone, or restore a snapshot, and these actions do not capture the ACL rights. This means that restoring a table preserves the ACL rights of the existing table, while cloning a table creates a new table that has no ACL rights until the [...]
+`,e.jsx(s.h3,{id:"export-to-another-cluster",children:"Export to another cluster"}),`
+`,e.jsx(s.p,{children:"The ExportSnapshot tool copies all the data related to a snapshot (hfiles, logs, snapshot metadata) to another cluster. The tool executes a Map-Reduce job, similar to distcp, to copy files between the two clusters, and since it works at file-system level the hbase cluster does not have to be online."}),`
+`,e.jsx(s.p,{children:"To copy a snapshot called MySnapshot to an HBase cluster srv2 (hdfs:///srv2:8082/hbase) using 16 mappers:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(s.h4,{id:"limiting-bandwidth-consumption",children:"Limiting Bandwidth Consumption"}),`
+`,e.jsxs(s.p,{children:["You can limit the bandwidth consumption when exporting a snapshot, by specifying the ",e.jsx(s.code,{children:"-bandwidth"})," parameter, which expects an integer representing megabytes per second. The following example limits the above example to 200 MB/sec."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(s.h2,{id:"storing-snapshots-in-an-amazon-s3-bucket",children:"Storing Snapshots in an Amazon S3 Bucket"}),`
+`,e.jsx(s.p,{children:"You can store and retrieve snapshots from Amazon S3, using the following procedure."}),`
+`,e.jsx(a,{type:"info",children:e.jsxs(s.p,{children:["You can also store snapshots in Microsoft Azure Blob Storage. See ",e.jsx(s.a,{href:"/docs/operational-management/backup-and-snapshots#storing-snapshots-in-microsoft-azure-blob-storage",children:`Storing Snapshots in Microsoft
+Azure Blob
+Storage`}),"."]})}),`
+`,e.jsx(s.h3,{id:"operational-management-backup-and-snapshots-stroing-in-s3-prerequisites",children:"Prerequisites"}),`
+`,e.jsxs(s.ul,{children:[`
+`,e.jsx(s.li,{children:"You must be using HBase 1.0 or higher and Hadoop 2.6.1 or higher, which is the first configuration that uses the Amazon AWS SDK."}),`
+`,e.jsxs(s.li,{children:["You must use the ",e.jsx(s.code,{children:"s3a://"})," protocol to connect to Amazon S3. The older ",e.jsx(s.code,{children:"s3n://"})," and ",e.jsx(s.code,{children:"s3://"})," protocols have various limitations and do not use the Amazon AWS SDK."]}),`
+`,e.jsxs(s.li,{children:["The ",e.jsx(s.code,{children:"s3a://"})," URI must be configured and available on the server where you run the commands to export and restore the snapshot."]}),`
+`]}),`
+`,e.jsxs(s.p,{children:["After you have fulfilled the prerequisites, take the snapshot like you normally would. Afterward, you can export it using the ",e.jsx(s.code,{children:"org.apache.hadoop.hbase.snapshot.ExportSnapshot"})," command like the one below, substituting your own ",e.jsx(s.code,{children:"s3a://"})," path in the ",e.jsx(s.code,{children:"copy-from"})," or ",e.jsx(s.code,{children:"copy-to"})," directive and substituting or modifying other options as required:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -snapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MySnapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -copy-from"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hdfs://srv2:8082/hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -copy-to"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" s3a://"}),e.jsx(s.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"<"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"bucke"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},ch [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -chuser"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MyUser"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -chgroup"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MyGroup"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -chmod"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 700"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -mappers"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 16"})]})]})})}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -snapshot"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MySnapshot"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"    -copy-from"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" s3a://"}),e.jsx(s.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"<"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"bucke"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"}, [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -copy-to"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hdfs://srv2:8082/hbase"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -chuser"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MyUser"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -chgroup"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MyGroup"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -chmod"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 700"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" \\"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -mappers"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 16"})]})]})})}),`
+`,e.jsxs(s.p,{children:["You can also use the ",e.jsx(s.code,{children:"org.apache.hadoop.hbase.snapshot.SnapshotInfo"})," utility with the ",e.jsx(s.code,{children:"s3a://"})," path by including the ",e.jsx(s.code,{children:"-remote-dir"})," option."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -remote-dir"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" s3a://"}),e.jsx(s.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"<"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"bucke"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"} [...]
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    -list-snapshots"})})]})})}),`
+`,e.jsx(s.h2,{id:"storing-snapshots-in-microsoft-azure-blob-storage",children:"Storing Snapshots in Microsoft Azure Blob Storage"}),`
+`,e.jsxs(s.p,{children:["You can store snapshots in Microsoft Azure Blog Storage using the same techniques as in ",e.jsx(s.a,{href:"/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket",children:"Storing Snapshots in an Amazon S3 Bucket"}),"."]}),`
+`,e.jsx(s.h3,{id:"operational-management-backup-and-snapshots-stroing-in-azure-prerequisites",children:"Prerequisites"}),`
+`,e.jsxs(s.ul,{children:[`
+`,e.jsx(s.li,{children:"You must be using HBase 1.2 or higher with Hadoop 2.7.1 or higher. No version of HBase supports Hadoop 2.7.0."}),`
+`,e.jsxs(s.li,{children:["Your hosts must be configured to be aware of the Azure blob storage filesystem. See ",e.jsx(s.a,{href:"https://hadoop.apache.org/docs/r2.7.1/hadoop-azure/index.html",children:"https://hadoop.apache.org/docs/r2.7.1/hadoop-azure/index.html"}),"."]}),`
+`]}),`
+`,e.jsxs(s.p,{children:["After you meet the prerequisites, follow the instructions in ",e.jsx(s.a,{href:"/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket",children:"Storing Snapshots in an Amazon S3 Bucket"}),", replacingthe protocol specifier with ",e.jsx(s.code,{children:"wasb://"})," or ",e.jsx(s.code,{children:"wasbs://"}),"."]}),`
+`,e.jsx(s.h2,{id:"storing-snapshots-in-aliyun-object-storage-service",children:"Storing Snapshots in Aliyun Object Storage Service"}),`
+`,e.jsxs(s.p,{children:["You can store snapshots in Aliyun Object Storage Service(Aliyun OSS) using the same techniques as in ",e.jsx(s.a,{href:"/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket",children:"Storing Snapshots in an Amazon S3 Bucket"}),"."]}),`
+`,e.jsx(s.h3,{id:"operational-management-backup-and-snapshots-stroing-in-aliyun-prerequisites",children:"Prerequisites"}),`
+`,e.jsxs(s.ul,{children:[`
+`,e.jsx(s.li,{children:"You must be using HBase 1.2 or higher with Hadoop 2.9.1 or higher."}),`
+`,e.jsxs(s.li,{children:["Your hosts must be configured to be aware of the Aliyun oss filesystem. See ",e.jsx(s.a,{href:"https://hadoop.apache.org/docs/stable/hadoop-aliyun/tools/hadoop-aliyun/index.html",children:"https://hadoop.apache.org/docs/stable/hadoop-aliyun/tools/hadoop-aliyun/index.html"}),"."]}),`
+`]}),`
+`,e.jsxs(s.p,{children:["After you meet the prerequisites, follow the instructions in ",e.jsx(s.a,{href:"/docs/operational-management/backup-and-snapshots#storing-snapshots-in-an-amazon-s3-bucket",children:"Storing Snapshots in an Amazon S3 Bucket"}),", replacing the protocol specifier with ",e.jsx(s.code,{children:"oss://"}),"."]})]})}function p(t={}){const{wrapper:s}=t.components||{};return s?e.jsx(s,{...t,children:e.jsx(n,{...t})}):n(t)}function i(t,s){throw new Error("Expected compon [...]
diff --git a/assets/backup-app-components-ChSULF98.js b/assets/backup-app-components-ChSULF98.js
new file mode 100644
index 00000000000..5560110a116
--- /dev/null
+++ b/assets/backup-app-components-ChSULF98.js
@@ -0,0 +1 @@
+const p="/assets/backup-app-components-ZN_OfKpI.png";export{p as _};
diff --git a/assets/backup-app-components-ZN_OfKpI.png b/assets/backup-app-components-ZN_OfKpI.png
new file mode 100644
index 00000000000..5e403e25c6c
Binary files /dev/null and b/assets/backup-app-components-ZN_OfKpI.png differ
diff --git a/assets/backup-cloud-appliance--qbLnXgy.js b/assets/backup-cloud-appliance--qbLnXgy.js
new file mode 100644
index 00000000000..ce0a7a41516
--- /dev/null
+++ b/assets/backup-cloud-appliance--qbLnXgy.js
@@ -0,0 +1 @@
+const s="/assets/backup-intra-cluster-VtQszuA-.png",a="/assets/backup-dedicated-cluster-BDX3WGln.png",t="/assets/backup-cloud-appliance-DQzqRFjX.png";export{s as _,a,t as b};
diff --git a/assets/backup-cloud-appliance-DQzqRFjX.png b/assets/backup-cloud-appliance-DQzqRFjX.png
new file mode 100644
index 00000000000..e92e83cb26f
Binary files /dev/null and b/assets/backup-cloud-appliance-DQzqRFjX.png differ
diff --git a/assets/backup-dedicated-cluster-BDX3WGln.png b/assets/backup-dedicated-cluster-BDX3WGln.png
new file mode 100644
index 00000000000..e8aa2a2d25d
Binary files /dev/null and b/assets/backup-dedicated-cluster-BDX3WGln.png differ
diff --git a/assets/backup-intra-cluster-VtQszuA-.png b/assets/backup-intra-cluster-VtQszuA-.png
new file mode 100644
index 00000000000..0a2e085c46f
Binary files /dev/null and b/assets/backup-intra-cluster-VtQszuA-.png differ
diff --git a/assets/basic-prerequisites-DOANKkJy.js b/assets/basic-prerequisites-DOANKkJy.js
new file mode 100644
index 00000000000..b6745ccb4d8
--- /dev/null
+++ b/assets/basic-prerequisites-DOANKkJy.js
@@ -0,0 +1,398 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let r=`## Java
+
+HBase runs on the Java Virtual Machine, thus all HBase deployments require a JVM runtime.
+
+The following table summarizes the recommendations of the HBase community with respect to running on various Java versions. The โœ… symbol indicates a base level of testing and willingness to help diagnose and address issues you might run into; these are the expected deployment combinations. An entry of โš ๏ธ means that there may be challenges with this combination, and you should look for more information before deciding to pursue this as your deployment strategy. The โŒ means this combinatio [...]
+
+<Callout type="warn">
+  HBase recommends downstream users rely only on JDK releases that are marked as Long-Term Supported
+  (LTS), either from the OpenJDK project or vendors. At the time of this writing, the following JDK
+  releases are NOT LTS releases and are NOT tested or advocated for use by the Apache HBase
+  community: JDK9, JDK10, JDK12, JDK13, and JDK14. Community discussion around this decision is
+  recorded on [HBASE-20264](https://issues.apache.org/jira/browse/HBASE-20264).
+</Callout>
+
+<Callout type="tip">
+  At this time, all testing performed by the Apache HBase project runs on the HotSpot variant of the
+  JVM. When selecting your JDK distribution, please take this into consideration.
+</Callout>
+
+**Java support by release line**
+
+| HBase Version | JDK 6 | JDK 7 | JDK 8 | JDK 11 | JDK 17 |
+| :-----------: | :---: | :---: | :---: | :----: | :----: |
+|   HBase 2.6   |   โŒ   |   โŒ   |   โœ…   |    โœ…   |    โœ…   |
+|   HBase 2.5   |   โŒ   |   โŒ   |   โœ…   |    โœ…   |  โš ๏ธ\\*  |
+|   HBase 2.4   |   โŒ   |   โŒ   |   โœ…   |    โœ…   |    โŒ   |
+|   HBase 2.3   |   โŒ   |   โŒ   |   โœ…   |  โš ๏ธ\\*  |    โŒ   |
+| HBase 2.0-2.2 |   โŒ   |   โŒ   |   โœ…   |    โŒ   |    โŒ   |
+|   HBase 1.2+  |   โŒ   |   โœ…   |   โœ…   |    โŒ   |    โŒ   |
+| HBase 1.0-1.1 |   โŒ   |   โœ…   |   โš ๏ธ  |    โŒ   |    โŒ   |
+|   HBase 0.98  |   โœ…   |   โœ…   |   โš ๏ธ  |    โŒ   |    โŒ   |
+|   HBase 0.94  |   โœ…   |   โœ…   |   โŒ   |    โŒ   |    โŒ   |
+
+<Callout type="warn">
+  Preliminary support for JDK11 is introduced with HBase 2.3.0, and for JDK17 is introduced with HBase 2.5.x. We will compile and run test suites with JDK11/17 in pre commit checks and nightly checks. We will mark the support as โœ… as long as we have run some ITs with the JDK version and also there are users in the community use the JDK version in real production clusters.
+
+  For JDK11/JDK17 support in HBase, please refer to [HBASE-22972](https://issues.apache.org/jira/browse/HBASE-22972) and [HBASE-26038](https://issues.apache.org/jira/browse/HBASE-26038)
+
+  For JDK11/JDK17 support in Hadoop, which may also affect HBase, please refer to [HADOOP-15338](https://issues.apache.org/jira/browse/HADOOP-15338) and [HADOOP-17177](https://issues.apache.org/jira/browse/HADOOP-17177)
+</Callout>
+
+<Callout type="info">
+  You must set \`JAVA_HOME\` on each node of your cluster. *hbase-env.sh* provides a handy mechanism
+  to do this.
+</Callout>
+
+### Operating System Utilities
+
+#### ssh
+
+HBase uses the Secure Shell (ssh) command and utilities extensively to communicate between cluster nodes. Each server in the cluster must be running \`ssh\` so that the Hadoop and HBase daemons can be managed. You must be able to connect to all nodes via SSH, including the local node, from the Master as well as any backup Master, using a shared key rather than a password. You can see the basic methodology for such a set-up in Linux or Unix systems at "[Procedure: Configure Passwordless S [...]
+
+#### DNS
+
+HBase uses the local hostname to self-report its IP address.
+
+#### NTP
+
+The clocks on cluster nodes should be synchronized. A small amount of variation is acceptable, but larger amounts of skew can cause erratic and unexpected behavior. Time synchronization is one of the first things to check if you see unexplained problems in your cluster. It is recommended that you run a Network Time Protocol (NTP) service, or another time-synchronization mechanism on your cluster and that all nodes look to the same service for time synchronization. See the [Basic NTP Conf [...]
+
+#### Limits on Number of Files and Processes (ulimit)
+
+Apache HBase is a database. It requires the ability to open a large number of files at once. Many Linux distributions limit the number of files a single user is allowed to open to \`1024\` (or \`256\` on older versions of OS X). You can check this limit on your servers by running the command \`ulimit -n\` when logged in as the user which runs HBase. See [the Troubleshooting section](/docs/troubleshooting#javaioioexceptiontoo-many-open-files) for some of the problems you may experience if [...]
+
+\`\`\`text
+2010-04-06 03:04:37,542 INFO org.apache.hadoop.hdfs.DFSClient: Exception increateBlockOutputStream java.io.EOFException
+2010-04-06 03:04:37,542 INFO org.apache.hadoop.hdfs.DFSClient: Abandoning block blk_-6935524980745310745_1391901
+\`\`\`
+
+It is recommended to raise the ulimit to at least 10,000, but more likely 10,240, because the value is usually expressed in multiples of 1024. Each ColumnFamily has at least one StoreFile, and possibly more than six StoreFiles if the region is under load. The number of open files required depends upon the number of ColumnFamilies and the number of regions. The following is a rough formula for calculating the potential number of open files on a RegionServer.
+
+**Calculate the Potential Number of Open Files:**
+
+\`\`\`text
+(StoreFiles per ColumnFamily) x (regions per RegionServer)
+\`\`\`
+
+For example, assuming that a schema had 3 ColumnFamilies per region with an average of 3 StoreFiles per ColumnFamily, and there are 100 regions per RegionServer, the JVM will open \`3 * 3 * 100 = 900\` file descriptors, not counting open JAR files, configuration files, and others. Opening a file does not take many resources, and the risk of allowing a user to open too many files is minimal.
+
+Another related setting is the number of processes a user is allowed to run at once. In Linux and Unix, the number of processes is set using the \`ulimit -u\` command. This should not be confused with the \`nproc\` command, which controls the number of CPUs available to a given user. Under load, a \`ulimit -u\` that is too low can cause OutOfMemoryError exceptions.
+
+Configuring the maximum number of file descriptors and processes for the user who is running the HBase process is an operating system configuration, rather than an HBase configuration. It is also important to be sure that the settings are changed for the user that actually runs HBase. To see which user started HBase, and that user's ulimit configuration, look at the first line of the HBase log for that instance.
+
+#### Example: \`ulimit\` Settings on Ubuntu \\[!toc]
+
+To configure ulimit settings on Ubuntu, edit */etc/security/limits.conf*, which is a space-delimited file with four columns. Refer to the man page for *limits.conf* for details about the format of this file. In the following example, the first line sets both soft and hard limits for the number of open files (nofile) to 32768 for the operating system user with the username hadoop. The second line sets the number of processes to 32000 for the same user.
+
+\`\`\`text
+hadoop  -       nofile  32768
+hadoop  -       nproc   32000
+\`\`\`
+
+The settings are only applied if the Pluggable Authentication Module (PAM) environment is directed to use them. To configure PAM to use these limits, be sure that the */etc/pam.d/common-session* file contains the following line:
+
+\`\`\`text
+session required  pam_limits.so
+\`\`\`
+
+#### Linux Shell
+
+All of the shell scripts that come with HBase rely on the [GNU Bash](http://www.gnu.org/software/bash) shell.
+
+#### Windows
+
+Running production systems on Windows machines is not recommended.
+
+## Hadoop
+
+The following table summarizes the versions of [Hadoop](https://hadoop.apache.org) supported with each version of HBase. Older versions not appearing in this table are considered unsupported and likely missing necessary features, while newer versions are untested but may be suitable.
+
+Based on the version of HBase, you should select the most appropriate version of Hadoop. You can use Apache Hadoop, or a vendor's distribution of Hadoop. No distinction is made here. See [the Hadoop wiki](https://cwiki.apache.org/confluence/display/HADOOP2/Distributions+and+Commercial+Support) for information about vendors of Hadoop.
+
+<Callout type="tip">
+  Comparing to Hadoop 1.x, Hadoop 2.x is faster and includes features, such as short-circuit reads (see [Leveraging local data](/docs/performance#leveraging-local-data)), which will help improve your HBase random read profile. Hadoop 2.x also includes important bug fixes that will improve your overall HBase experience. HBase does not support running with earlier versions of Hadoop. See the table below for requirements specific to different HBase versions.
+
+  Today, Hadoop 3.x is recommended as the last Hadoop 2.x release 2.10.2 was released years ago, and there is no release for Hadoop 2.x for a very long time, although the Hadoop community does not officially EOL Hadoop 2.x yet.
+</Callout>
+
+Use the following legend to interpret these tables:
+
+* โœ… = Tested to be fully-functional
+* โŒ = Known to not be fully-functional, or there are [CVEs](https://hadoop.apache.org/cve_list.html) so we drop the support in newer minor releases
+* โš ๏ธ = Not tested, may/may-not function
+
+|                    | HBase-2.5.x | HBase-2.6.x |
+| ------------------ | ----------- | ----------- |
+| Hadoop-2.10.\\[0-1] | โŒ           | โŒ           |
+| Hadoop-2.10.2+     | โœ…           | โœ…           |
+| Hadoop-3.1.0       | โŒ           | โŒ           |
+| Hadoop-3.1.1+      | โŒ           | โŒ           |
+| Hadoop-3.2.\\[0-2]  | โŒ           | โŒ           |
+| Hadoop-3.2.3+      | โœ…           | โŒ           |
+| Hadoop-3.3.\\[0-1]  | โŒ           | โŒ           |
+| Hadoop-3.3.\\[2-4]  | โœ…           | โŒ           |
+| Hadoop-3.3.5+      | โœ…           | โœ…           |
+| Hadoop-3.4.0+      | โœ… (2.5.11+) | โœ… (2.6.2+)  |
+
+### Hadoop version support matrix for active release lines
+
+|               | HBase-2.3.x | HBase-2.4.x |
+| ------------- | ----------- | ----------- |
+| Hadoop-2.10.x | โœ…           | โœ…           |
+| Hadoop-3.1.0  | โŒ           | โŒ           |
+| Hadoop-3.1.1+ | โœ…           | โœ…           |
+| Hadoop-3.2.x  | โœ…           | โœ…           |
+| Hadoop-3.3.x  | โœ…           | โœ…           |
+
+### Hadoop version support matrix for EOM 2.3+ release lines
+
+|                   | HBase-2.0.x | HBase-2.1.x | HBase-2.2.x |
+| ----------------- | ----------- | ----------- | ----------- |
+| Hadoop-2.6.1+     | โœ…           | โŒ           | โŒ           |
+| Hadoop-2.7.\\[0-6] | โŒ           | โŒ           | โŒ           |
+| Hadoop-2.7.7+     | โœ…           | โœ…           | โŒ           |
+| Hadoop-2.8.\\[0-2] | โŒ           | โŒ           | โŒ           |
+| Hadoop-2.8.\\[3-4] | โœ…           | โœ…           | โŒ           |
+| Hadoop-2.8.5+     | โœ…           | โœ…           | โœ…           |
+| Hadoop-2.9.\\[0-1] | โš ๏ธ          | โŒ           | โŒ           |
+| Hadoop-2.9.2+     | โš ๏ธ          | โš ๏ธ          | โœ…           |
+| Hadoop-3.0.\\[0-2] | โŒ           | โŒ           | โŒ           |
+| Hadoop-3.0.3+     | โŒ           | โœ…           | โŒ           |
+| Hadoop-3.1.0      | โŒ           | โŒ           | โŒ           |
+| Hadoop-3.1.1+     | โŒ           | โœ…           | โœ…           |
+
+### Hadoop version support matrix for EOM 2.x release lines
+
+|                   | HBase-1.5.x | HBase-1.6.x | HBase-1.7.x |
+| ----------------- | ----------- | ----------- | ----------- |
+| Hadoop-2.7.7+     | โœ…           | โŒ           | โŒ           |
+| Hadoop-2.8.\\[0-4] | โŒ           | โŒ           | โŒ           |
+| Hadoop-2.8.5+     | โœ…           | โœ…           | โœ…           |
+| Hadoop-2.9.\\[0-1] | โŒ           | โŒ           | โŒ           |
+| Hadoop-2.9.2+     | โœ…           | โœ…           | โœ…           |
+| Hadoop-2.10.x     | โš ๏ธ          | โœ…           | โœ…           |
+
+### Hadoop version support matrix for EOM 1.5+ release lines
+
+|               | HBase-1.0.x (Hadoop 1.x is NOT supported) | HBase-1.1.x | HBase-1.2.x | HBase-1.3.x | HBase-1.4.x |
+| ------------- | ----------------------------------------- | ----------- | ----------- | ----------- | ----------- |
+| Hadoop-2.4.x  | โœ…                                         | โœ…           | โœ…           | โœ…           | โŒ           |
+| Hadoop-2.5.x  | โœ…                                         | โœ…           | โœ…           | โœ…           | โŒ           |
+| Hadoop-2.6.0  | โŒ                                         | โŒ           | โŒ           | โŒ           | โŒ           |
+| Hadoop-2.6.1+ | โš ๏ธ                                        | โš ๏ธ          | โœ…           | โœ…           | โŒ           |
+| Hadoop-2.7.0  | โŒ                                         | โŒ           | โŒ           | โŒ           | โŒ           |
+| Hadoop-2.7.1+ | โš ๏ธ                                        | โš ๏ธ          | โœ…           | โœ…           | โœ…           |
+
+### Hadoop version support matrix for EOM 1.x release lines
+
+|                    | HBase-0.92.x | HBase-0.94.x | HBase-0.96.x | HBase-0.98.x (Support for Hadoop 1.1+ is deprecated.) |
+| ------------------ | ------------ | ------------ | ------------ | ----------------------------------------------------- |
+| Hadoop-0.20.205    | โœ…            | โŒ            | โŒ            | โŒ                                                     |
+| Hadoop-0.22.x      | โœ…            | โŒ            | โŒ            | โŒ                                                     |
+| Hadoop-1.0.x       | โŒ            | โŒ            | โŒ            | โŒ                                                     |
+| Hadoop-1.1.x       | โš ๏ธ           | โœ…            | โœ…            | โš ๏ธ                                                    |
+| Hadoop-0.23.x      | โŒ            | โœ…            | โš ๏ธ           | โŒ                                                     |
+| Hadoop-2.0.x-alpha | โŒ            | โš ๏ธ           | โŒ            | โŒ                                                     |
+| Hadoop-2.1.0-beta  | โŒ            | โš ๏ธ           | โœ…            | โŒ                                                     |
+| Hadoop-2.2.0       | โŒ            | โš ๏ธ           | โœ…            | โœ…                                                     |
+| Hadoop-2.3.x       | โŒ            | โš ๏ธ           | โœ…            | โœ…                                                     |
+| Hadoop-2.4.x       | โŒ            | โš ๏ธ           | โœ…            | โœ…                                                     |
+| Hadoop-2.5.x       | โŒ            | โš ๏ธ           | โœ…            | โœ…                                                     |
+
+### Hadoop version support matrix for EOM pre-1.0 release lines
+
+<Callout type="idea">
+  Starting around the time of Hadoop version 2.7.0, the Hadoop PMC got into the habit of calling out
+  new minor releases on their major version 2 release line as not stable / production ready. As
+  such, HBase expressly advises downstream users to avoid running on top of these releases. Note
+  that additionally the 2.8.1 release was given the same caveat by the Hadoop PMC. For reference,
+  see the release announcements for [Apache Hadoop
+  2.7.0](https://s.apache.org/hadoop-2.7.0-announcement), [Apache Hadoop
+  2.8.0](https://s.apache.org/hadoop-2.8.0-announcement), [Apache Hadoop
+  2.8.1](https://s.apache.org/hadoop-2.8.1-announcement), and [Apache Hadoop
+  2.9.0](https://s.apache.org/hadoop-2.9.0-announcement).
+</Callout>
+
+<Callout type="idea">
+  The Hadoop PMC called out the 3.1.0 release as not stable / production ready. As such, HBase
+  expressly advises downstream users to avoid running on top of this release. For reference, see the
+  [release announcement for Hadoop 3.1.0](https://s.apache.org/hadoop-3.1.0-announcement).
+</Callout>
+
+<Callout type="info">
+  Because HBase depends on Hadoop, it bundles Hadoop jars under its *lib* directory. The bundled
+  jars are ONLY for use in stand-alone mode. In distributed mode, it is *critical* that the version
+  of Hadoop that is out on your cluster match what is under HBase. Replace the hadoop jars found in
+  the HBase lib directory with the equivalent hadoop jars from the version you are running on your
+  cluster to avoid version mismatch issues. Make sure you replace the jars under HBase across your
+  whole cluster. Hadoop version mismatch issues have various manifestations. Check for mismatch if
+  HBase appears hung.
+</Callout>
+
+### Hadoop 3 Support for the HBase Binary Releases and Maven Artifacts
+
+For HBase 2.5.1 and earlier, the official HBase binary releases and Maven artifacts were built with Hadoop 2.x.
+
+Starting with HBase 2.5.2, HBase provides binary releases and Maven artifacts built with both Hadoop 2.x and Hadoop 3.x. The Hadoop 2 artifacts do not have any version suffix, the Hadoop 3 artifacts add the \`-hadoop-3\` suffix to the version. i.e. \`hbase-2.5.2-bin.tar.gz.asc\` is the Binary release built with Hadoop2, and \`hbase-2.5.2-hadoop3-bin.tar.gz\` is the release built with Hadoop 3.
+
+### Hadoop 3 version policy
+
+Each HBase release has a default Hadoop 3 version. This is used when the Hadoop 3 version is not specified during build, and for building the official binary releases and artifacts. Generally when a new minor version is released (i.e. 2.5.0) the default version is set to the latest supported Hadoop 3 version at the start of the release process.
+
+Up to HBase 2.5.10 and 2.6.1 even if HBase added support for newer Hadoop 3 releases in a patch release, the default Hadoop 3 version (and the one used in the official binary releases) was not updated. This simplified upgrading, but meant that HBase releases often included old unfixed CVEs both from Hadoop and Hadoop's dependencies, even when newer Hadoop releases with fixes were available.
+
+Starting with HBase 2.5.11 and 2.6.2, the default Hadoop 3 version is always set to the latest supported Hadoop 3 version, and is also used for the \`-hadoop3\` binary releases and artifacts. This will drastically reduce the number of known CVEs shipped in the HBase binary releases, and make sure that all fixes and improvements in Hadoop are included.
+
+### \`dfs.datanode.max.transfer.threads\`
+
+An HDFS DataNode has an upper bound on the number of files that it will serve at any one time. Before doing any loading, make sure you have configured Hadoop's *conf/hdfs-site.xml*, setting the \`dfs.datanode.max.transfer.threads\` value to at least the following:
+
+\`\`\`xml
+<property>
+  <name>dfs.datanode.max.transfer.threads</name>
+  <value>4096</value>
+</property>
+\`\`\`
+
+Be sure to restart your HDFS after making the above configuration.
+
+Not having this configuration in place makes for strange-looking failures. One manifestation is a complaint about missing blocks. For example:
+
+\`\`\`text
+10/12/08 20:10:31 INFO hdfs.DFSClient: Could not obtain block
+          blk_XXXXXXXXXXXXXXXXXXXXXX_YYYYYYYY from any node: java.io.IOException: No live nodes
+          contain current block. Will get new block locations from namenode and retry...
+\`\`\`
+
+See also [Case Studies](/docs/case-studies#case-study-4-maxtransferthreads-config) and note that this property was previously known as \`dfs.datanode.max.xcievers\` (e.g. [Hadoop HDFS: Deceived by Xciever](http://ccgtech.blogspot.com/2010/02/hadoop-hdfs-deceived-by-xciever.html)).
+
+## ZooKeeper Requirements
+
+An Apache ZooKeeper quorum is required. The exact version depends on your version of HBase, though the minimum ZooKeeper version is 3.4.x due to the \`useMulti\` feature made default in 1.0.0 (see [HBASE-16598](https://issues.apache.org/jira/browse/HBASE-16598)).
+`,d={title:"Basic Prerequisites",description:"This section lists required services and some required system configuration."},h=[{href:"https://issues.apache.org/jira/browse/HBASE-20264"},{href:"https://issues.apache.org/jira/browse/HBASE-22972"},{href:"https://issues.apache.org/jira/browse/HBASE-26038"},{href:"https://issues.apache.org/jira/browse/HADOOP-15338"},{href:"https://issues.apache.org/jira/browse/HADOOP-17177"},{href:"/docs/getting-started#procedure-configure-passwordless-ssh-a [...]
+(LTS), either from the OpenJDK project or vendors. At the time of this writing, the following JDK
+releases are NOT LTS releases and are NOT tested or advocated for use by the Apache HBase
+community: JDK9, JDK10, JDK12, JDK13, and JDK14. Community discussion around this decision is
+recorded on HBASE-20264.`},{heading:"configuration-basic-prerequisites-java",content:"type: tip"},{heading:"configuration-basic-prerequisites-java",content:`At this time, all testing performed by the Apache HBase project runs on the HotSpot variant of the
+JVM. When selecting your JDK distribution, please take this into consideration.`},{heading:"configuration-basic-prerequisites-java",content:"Java support by release line"},{heading:"configuration-basic-prerequisites-java",content:"HBase Version"},{heading:"configuration-basic-prerequisites-java",content:"JDK 6"},{heading:"configuration-basic-prerequisites-java",content:"JDK 7"},{heading:"configuration-basic-prerequisites-java",content:"JDK 8"},{heading:"configuration-basic-prerequisites- [...]
+to do this.`},{heading:"ssh",content:'HBase uses the Secure Shell (ssh) command and utilities extensively to communicate between cluster nodes. Each server in the cluster must be running ssh so that the Hadoop and HBase daemons can be managed. You must be able to connect to all nodes via SSH, including the local node, from the Master as well as any backup Master, using a shared key rather than a password. You can see the basic methodology for such a set-up in Linux or Unix systems at "Pr [...]
+new minor releases on their major version 2 release line as not stable / production ready. As
+such, HBase expressly advises downstream users to avoid running on top of these releases. Note
+that additionally the 2.8.1 release was given the same caveat by the Hadoop PMC. For reference,
+see the release announcements for Apache Hadoop
+2.7.0, Apache Hadoop
+2.8.0, Apache Hadoop
+2.8.1, and Apache Hadoop
+2.9.0.`},{heading:"hadoop-version-support-matrix-for-eom-pre-10-release-lines",content:"type: idea"},{heading:"hadoop-version-support-matrix-for-eom-pre-10-release-lines",content:`The Hadoop PMC called out the 3.1.0 release as not stable / production ready. As such, HBase
+expressly advises downstream users to avoid running on top of this release. For reference, see the
+release announcement for Hadoop 3.1.0.`},{heading:"hadoop-version-support-matrix-for-eom-pre-10-release-lines",content:"type: info"},{heading:"hadoop-version-support-matrix-for-eom-pre-10-release-lines",content:`Because HBase depends on Hadoop, it bundles Hadoop jars under its lib directory. The bundled
+jars are ONLY for use in stand-alone mode. In distributed mode, it is critical that the version
+of Hadoop that is out on your cluster match what is under HBase. Replace the hadoop jars found in
+the HBase lib directory with the equivalent hadoop jars from the version you are running on your
+cluster to avoid version mismatch issues. Make sure you replace the jars under HBase across your
+whole cluster. Hadoop version mismatch issues have various manifestations. Check for mismatch if
+HBase appears hung.`},{heading:"hadoop-3-support-for-the-hbase-binary-releases-and-maven-artifacts",content:"For HBase 2.5.1 and earlier, the official HBase binary releases and Maven artifacts were built with Hadoop 2.x."},{heading:"hadoop-3-support-for-the-hbase-binary-releases-and-maven-artifacts",content:"Starting with HBase 2.5.2, HBase provides binary releases and Maven artifacts built with both Hadoop 2.x and Hadoop 3.x. The Hadoop 2 artifacts do not have any version suffix, the Ha [...]
+`,e.jsx(o.p,{children:"HBase runs on the Java Virtual Machine, thus all HBase deployments require a JVM runtime."}),`
+`,e.jsx(o.p,{children:"The following table summarizes the recommendations of the HBase community with respect to running on various Java versions. The โœ… symbol indicates a base level of testing and willingness to help diagnose and address issues you might run into; these are the expected deployment combinations. An entry of โš ๏ธ means that there may be challenges with this combination, and you should look for more information before deciding to pursue this as your deployment strategy. The  [...]
+`,e.jsx(n,{type:"warn",children:e.jsxs(o.p,{children:[`HBase recommends downstream users rely only on JDK releases that are marked as Long-Term Supported
+(LTS), either from the OpenJDK project or vendors. At the time of this writing, the following JDK
+releases are NOT LTS releases and are NOT tested or advocated for use by the Apache HBase
+community: JDK9, JDK10, JDK12, JDK13, and JDK14. Community discussion around this decision is
+recorded on `,e.jsx(o.a,{href:"https://issues.apache.org/jira/browse/HBASE-20264",children:"HBASE-20264"}),"."]})}),`
+`,e.jsx(n,{type:"tip",children:e.jsx(o.p,{children:`At this time, all testing performed by the Apache HBase project runs on the HotSpot variant of the
+JVM. When selecting your JDK distribution, please take this into consideration.`})}),`
+`,e.jsx(o.p,{children:e.jsx(o.strong,{children:"Java support by release line"})}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{style:{textAlign:"center"},children:"HBase Version"}),e.jsx(o.th,{style:{textAlign:"center"},children:"JDK 6"}),e.jsx(o.th,{style:{textAlign:"center"},children:"JDK 7"}),e.jsx(o.th,{style:{textAlign:"center"},children:"JDK 8"}),e.jsx(o.th,{style:{textAlign:"center"},children:"JDK 11"}),e.jsx(o.th,{style:{textAlign:"center"},children:"JDK 17"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx [...]
+`,e.jsxs(n,{type:"warn",children:[e.jsx(o.p,{children:"Preliminary support for JDK11 is introduced with HBase 2.3.0, and for JDK17 is introduced with HBase 2.5.x. We will compile and run test suites with JDK11/17 in pre commit checks and nightly checks. We will mark the support as โœ… as long as we have run some ITs with the JDK version and also there are users in the community use the JDK version in real production clusters."}),e.jsxs(o.p,{children:["For JDK11/JDK17 support in HBase, plea [...]
+`,e.jsx(n,{type:"info",children:e.jsxs(o.p,{children:["You must set ",e.jsx(o.code,{children:"JAVA_HOME"})," on each node of your cluster. ",e.jsx(o.em,{children:"hbase-env.sh"}),` provides a handy mechanism
+to do this.`]})}),`
+`,e.jsx(o.h3,{id:"operating-system-utilities",children:"Operating System Utilities"}),`
+`,e.jsx(o.h4,{id:"ssh",children:"ssh"}),`
+`,e.jsxs(o.p,{children:["HBase uses the Secure Shell (ssh) command and utilities extensively to communicate between cluster nodes. Each server in the cluster must be running ",e.jsx(o.code,{children:"ssh"}),' so that the Hadoop and HBase daemons can be managed. You must be able to connect to all nodes via SSH, including the local node, from the Master as well as any backup Master, using a shared key rather than a password. You can see the basic methodology for such a set-up in Linux or U [...]
+`,e.jsx(o.h4,{id:"dns",children:"DNS"}),`
+`,e.jsx(o.p,{children:"HBase uses the local hostname to self-report its IP address."}),`
+`,e.jsx(o.h4,{id:"ntp",children:"NTP"}),`
+`,e.jsxs(o.p,{children:["The clocks on cluster nodes should be synchronized. A small amount of variation is acceptable, but larger amounts of skew can cause erratic and unexpected behavior. Time synchronization is one of the first things to check if you see unexplained problems in your cluster. It is recommended that you run a Network Time Protocol (NTP) service, or another time-synchronization mechanism on your cluster and that all nodes look to the same service for time synchronization [...]
+`,e.jsx(o.h4,{id:"limits-on-number-of-files-and-processes-ulimit",children:"Limits on Number of Files and Processes (ulimit)"}),`
+`,e.jsxs(o.p,{children:["Apache HBase is a database. It requires the ability to open a large number of files at once. Many Linux distributions limit the number of files a single user is allowed to open to ",e.jsx(o.code,{children:"1024"})," (or ",e.jsx(o.code,{children:"256"})," on older versions of OS X). You can check this limit on your servers by running the command ",e.jsx(o.code,{children:"ulimit -n"})," when logged in as the user which runs HBase. See ",e.jsx(o.a,{href:"/docs/troub [...]
+`,e.jsx(e.Fragment,{children:e.jsx(o.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(o.span,{className:"line",children:e.jsx(o.span,{children:"2010-04-06 03:04:37,542 INFO org.apache.hadoop.hdfs.DFSClient: Abandoning block blk_-6935524980745310745_1391901"})})]})})}),`
+`,e.jsx(o.p,{children:"It is recommended to raise the ulimit to at least 10,000, but more likely 10,240, because the value is usually expressed in multiples of 1024. Each ColumnFamily has at least one StoreFile, and possibly more than six StoreFiles if the region is under load. The number of open files required depends upon the number of ColumnFamilies and the number of regions. The following is a rough formula for calculating the potential number of open files on a RegionServer."}),`
+`,e.jsx(o.p,{children:e.jsx(o.strong,{children:"Calculate the Potential Number of Open Files:"})}),`
+`,e.jsx(e.Fragment,{children:e.jsx(o.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(o.p,{children:["For example, assuming that a schema had 3 ColumnFamilies per region with an average of 3 StoreFiles per ColumnFamily, and there are 100 regions per RegionServer, the JVM will open ",e.jsx(o.code,{children:"3 * 3 * 100 = 900"})," file descriptors, not counting open JAR files, configuration files, and others. Opening a file does not take many resources, and the risk of allowing a user to open too many files is minimal."]}),`
+`,e.jsxs(o.p,{children:["Another related setting is the number of processes a user is allowed to run at once. In Linux and Unix, the number of processes is set using the ",e.jsx(o.code,{children:"ulimit -u"})," command. This should not be confused with the ",e.jsx(o.code,{children:"nproc"})," command, which controls the number of CPUs available to a given user. Under load, a ",e.jsx(o.code,{children:"ulimit -u"})," that is too low can cause OutOfMemoryError exceptions."]}),`
+`,e.jsx(o.p,{children:"Configuring the maximum number of file descriptors and processes for the user who is running the HBase process is an operating system configuration, rather than an HBase configuration. It is also important to be sure that the settings are changed for the user that actually runs HBase. To see which user started HBase, and that user's ulimit configuration, look at the first line of the HBase log for that instance."}),`
+`,e.jsxs(o.h4,{id:"example-ulimit-settings-on-ubuntu-toc",children:["Example: ",e.jsx(o.code,{children:"ulimit"})," Settings on Ubuntu"]}),`
+`,e.jsxs(o.p,{children:["To configure ulimit settings on Ubuntu, edit ",e.jsx(o.em,{children:"/etc/security/limits.conf"}),", which is a space-delimited file with four columns. Refer to the man page for ",e.jsx(o.em,{children:"limits.conf"})," for details about the format of this file. In the following example, the first line sets both soft and hard limits for the number of open files (nofile) to 32768 for the operating system user with the username hadoop. The second line sets the numbe [...]
+`,e.jsx(e.Fragment,{children:e.jsx(o.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(o.span,{className:"line",children:e.jsx(o.span,{children:"hadoop  -       nproc   32000"})})]})})}),`
+`,e.jsxs(o.p,{children:["The settings are only applied if the Pluggable Authentication Module (PAM) environment is directed to use them. To configure PAM to use these limits, be sure that the ",e.jsx(o.em,{children:"/etc/pam.d/common-session"})," file contains the following line:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(o.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(o.h4,{id:"linux-shell",children:"Linux Shell"}),`
+`,e.jsxs(o.p,{children:["All of the shell scripts that come with HBase rely on the ",e.jsx(o.a,{href:"http://www.gnu.org/software/bash",children:"GNU Bash"})," shell."]}),`
+`,e.jsx(o.h4,{id:"windows",children:"Windows"}),`
+`,e.jsx(o.p,{children:"Running production systems on Windows machines is not recommended."}),`
+`,e.jsx(o.h2,{id:"hadoop",children:"Hadoop"}),`
+`,e.jsxs(o.p,{children:["The following table summarizes the versions of ",e.jsx(o.a,{href:"https://hadoop.apache.org",children:"Hadoop"})," supported with each version of HBase. Older versions not appearing in this table are considered unsupported and likely missing necessary features, while newer versions are untested but may be suitable."]}),`
+`,e.jsxs(o.p,{children:["Based on the version of HBase, you should select the most appropriate version of Hadoop. You can use Apache Hadoop, or a vendor's distribution of Hadoop. No distinction is made here. See ",e.jsx(o.a,{href:"https://cwiki.apache.org/confluence/display/HADOOP2/Distributions+and+Commercial+Support",children:"the Hadoop wiki"})," for information about vendors of Hadoop."]}),`
+`,e.jsxs(n,{type:"tip",children:[e.jsxs(o.p,{children:["Comparing to Hadoop 1.x, Hadoop 2.x is faster and includes features, such as short-circuit reads (see ",e.jsx(o.a,{href:"/docs/performance#leveraging-local-data",children:"Leveraging local data"}),"), which will help improve your HBase random read profile. Hadoop 2.x also includes important bug fixes that will improve your overall HBase experience. HBase does not support running with earlier versions of Hadoop. See the table below f [...]
+`,e.jsx(o.p,{children:"Use the following legend to interpret these tables:"}),`
+`,e.jsxs(o.ul,{children:[`
+`,e.jsx(o.li,{children:"โœ… = Tested to be fully-functional"}),`
+`,e.jsxs(o.li,{children:["โŒ = Known to not be fully-functional, or there are ",e.jsx(o.a,{href:"https://hadoop.apache.org/cve_list.html",children:"CVEs"})," so we drop the support in newer minor releases"]}),`
+`,e.jsx(o.li,{children:"โš ๏ธ = Not tested, may/may-not function"}),`
+`]}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{}),e.jsx(o.th,{children:"HBase-2.5.x"}),e.jsx(o.th,{children:"HBase-2.6.x"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.10.[0-1]"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:"โŒ"})]}),e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.10.2+"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โœ…"})]}),e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-3. [...]
+`,e.jsx(o.h3,{id:"hadoop-version-support-matrix-for-active-release-lines",children:"Hadoop version support matrix for active release lines"}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{}),e.jsx(o.th,{children:"HBase-2.3.x"}),e.jsx(o.th,{children:"HBase-2.4.x"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.10.x"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โœ…"})]}),e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-3.1.0"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:"โŒ"})]}),e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-3.1.1+"} [...]
+`,e.jsx(o.h3,{id:"hadoop-version-support-matrix-for-eom-23-release-lines",children:"Hadoop version support matrix for EOM 2.3+ release lines"}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{}),e.jsx(o.th,{children:"HBase-2.0.x"}),e.jsx(o.th,{children:"HBase-2.1.x"}),e.jsx(o.th,{children:"HBase-2.2.x"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.6.1+"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:"โŒ"})]}),e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.7.[0-6]"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:" [...]
+`,e.jsx(o.h3,{id:"hadoop-version-support-matrix-for-eom-2x-release-lines",children:"Hadoop version support matrix for EOM 2.x release lines"}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{}),e.jsx(o.th,{children:"HBase-1.5.x"}),e.jsx(o.th,{children:"HBase-1.6.x"}),e.jsx(o.th,{children:"HBase-1.7.x"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.7.7+"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:"โŒ"})]}),e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.8.[0-4]"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:" [...]
+`,e.jsx(o.h3,{id:"hadoop-version-support-matrix-for-eom-15-release-lines",children:"Hadoop version support matrix for EOM 1.5+ release lines"}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{}),e.jsx(o.th,{children:"HBase-1.0.x (Hadoop 1.x is NOT supported)"}),e.jsx(o.th,{children:"HBase-1.1.x"}),e.jsx(o.th,{children:"HBase-1.2.x"}),e.jsx(o.th,{children:"HBase-1.3.x"}),e.jsx(o.th,{children:"HBase-1.4.x"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-2.4.x"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{ch [...]
+`,e.jsx(o.h3,{id:"hadoop-version-support-matrix-for-eom-1x-release-lines",children:"Hadoop version support matrix for EOM 1.x release lines"}),`
+`,e.jsxs(o.table,{children:[e.jsx(o.thead,{children:e.jsxs(o.tr,{children:[e.jsx(o.th,{}),e.jsx(o.th,{children:"HBase-0.92.x"}),e.jsx(o.th,{children:"HBase-0.94.x"}),e.jsx(o.th,{children:"HBase-0.96.x"}),e.jsx(o.th,{children:"HBase-0.98.x (Support for Hadoop 1.1+ is deprecated.)"})]})}),e.jsxs(o.tbody,{children:[e.jsxs(o.tr,{children:[e.jsx(o.td,{children:"Hadoop-0.20.205"}),e.jsx(o.td,{children:"โœ…"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:"โŒ"}),e.jsx(o.td,{children:"โŒ"})]}),e.j [...]
+`,e.jsx(o.h3,{id:"hadoop-version-support-matrix-for-eom-pre-10-release-lines",children:"Hadoop version support matrix for EOM pre-1.0 release lines"}),`
+`,e.jsx(n,{type:"idea",children:e.jsxs(o.p,{children:[`Starting around the time of Hadoop version 2.7.0, the Hadoop PMC got into the habit of calling out
+new minor releases on their major version 2 release line as not stable / production ready. As
+such, HBase expressly advises downstream users to avoid running on top of these releases. Note
+that additionally the 2.8.1 release was given the same caveat by the Hadoop PMC. For reference,
+see the release announcements for `,e.jsx(o.a,{href:"https://s.apache.org/hadoop-2.7.0-announcement",children:`Apache Hadoop
+2.7.0`}),", ",e.jsx(o.a,{href:"https://s.apache.org/hadoop-2.8.0-announcement",children:`Apache Hadoop
+2.8.0`}),", ",e.jsx(o.a,{href:"https://s.apache.org/hadoop-2.8.1-announcement",children:`Apache Hadoop
+2.8.1`}),", and ",e.jsx(o.a,{href:"https://s.apache.org/hadoop-2.9.0-announcement",children:`Apache Hadoop
+2.9.0`}),"."]})}),`
+`,e.jsx(n,{type:"idea",children:e.jsxs(o.p,{children:[`The Hadoop PMC called out the 3.1.0 release as not stable / production ready. As such, HBase
+expressly advises downstream users to avoid running on top of this release. For reference, see the
+`,e.jsx(o.a,{href:"https://s.apache.org/hadoop-3.1.0-announcement",children:"release announcement for Hadoop 3.1.0"}),"."]})}),`
+`,e.jsx(n,{type:"info",children:e.jsxs(o.p,{children:["Because HBase depends on Hadoop, it bundles Hadoop jars under its ",e.jsx(o.em,{children:"lib"}),` directory. The bundled
+jars are ONLY for use in stand-alone mode. In distributed mode, it is `,e.jsx(o.em,{children:"critical"}),` that the version
+of Hadoop that is out on your cluster match what is under HBase. Replace the hadoop jars found in
+the HBase lib directory with the equivalent hadoop jars from the version you are running on your
+cluster to avoid version mismatch issues. Make sure you replace the jars under HBase across your
+whole cluster. Hadoop version mismatch issues have various manifestations. Check for mismatch if
+HBase appears hung.`]})}),`
+`,e.jsx(o.h3,{id:"hadoop-3-support-for-the-hbase-binary-releases-and-maven-artifacts",children:"Hadoop 3 Support for the HBase Binary Releases and Maven Artifacts"}),`
+`,e.jsx(o.p,{children:"For HBase 2.5.1 and earlier, the official HBase binary releases and Maven artifacts were built with Hadoop 2.x."}),`
+`,e.jsxs(o.p,{children:["Starting with HBase 2.5.2, HBase provides binary releases and Maven artifacts built with both Hadoop 2.x and Hadoop 3.x. The Hadoop 2 artifacts do not have any version suffix, the Hadoop 3 artifacts add the ",e.jsx(o.code,{children:"-hadoop-3"})," suffix to the version. i.e. ",e.jsx(o.code,{children:"hbase-2.5.2-bin.tar.gz.asc"})," is the Binary release built with Hadoop2, and ",e.jsx(o.code,{children:"hbase-2.5.2-hadoop3-bin.tar.gz"})," is the release built with [...]
+`,e.jsx(o.h3,{id:"hadoop-3-version-policy",children:"Hadoop 3 version policy"}),`
+`,e.jsx(o.p,{children:"Each HBase release has a default Hadoop 3 version. This is used when the Hadoop 3 version is not specified during build, and for building the official binary releases and artifacts. Generally when a new minor version is released (i.e. 2.5.0) the default version is set to the latest supported Hadoop 3 version at the start of the release process."}),`
+`,e.jsx(o.p,{children:"Up to HBase 2.5.10 and 2.6.1 even if HBase added support for newer Hadoop 3 releases in a patch release, the default Hadoop 3 version (and the one used in the official binary releases) was not updated. This simplified upgrading, but meant that HBase releases often included old unfixed CVEs both from Hadoop and Hadoop's dependencies, even when newer Hadoop releases with fixes were available."}),`
+`,e.jsxs(o.p,{children:["Starting with HBase 2.5.11 and 2.6.2, the default Hadoop 3 version is always set to the latest supported Hadoop 3 version, and is also used for the ",e.jsx(o.code,{children:"-hadoop3"})," binary releases and artifacts. This will drastically reduce the number of known CVEs shipped in the HBase binary releases, and make sure that all fixes and improvements in Hadoop are included."]}),`
+`,e.jsx(o.h3,{id:"dfsdatanodemaxtransferthreads",children:e.jsx(o.code,{children:"dfs.datanode.max.transfer.threads"})}),`
+`,e.jsxs(o.p,{children:["An HDFS DataNode has an upper bound on the number of files that it will serve at any one time. Before doing any loading, make sure you have configured Hadoop's ",e.jsx(o.em,{children:"conf/hdfs-site.xml"}),", setting the ",e.jsx(o.code,{children:"dfs.datanode.max.transfer.threads"})," value to at least the following:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(o.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(o.span,{className:"line",children:[e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(o.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">dfs.datanode.max.transfer.threads</"}),e.jsx(o.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shi [...]
+`,e.jsxs(o.span,{className:"line",children:[e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(o.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">4096</"}),e.jsx(o.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,e.jsxs(o.span,{className:"line",children:[e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(o.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(o.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(o.p,{children:"Be sure to restart your HDFS after making the above configuration."}),`
+`,e.jsx(o.p,{children:"Not having this configuration in place makes for strange-looking failures. One manifestation is a complaint about missing blocks. For example:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(o.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(o.span,{className:"line",children:e.jsx(o.span,{children:"          blk_XXXXXXXXXXXXXXXXXXXXXX_YYYYYYYY from any node: java.io.IOException: No live nodes"})}),`
+`,e.jsx(o.span,{className:"line",children:e.jsx(o.span,{children:"          contain current block. Will get new block locations from namenode and retry..."})})]})})}),`
+`,e.jsxs(o.p,{children:["See also ",e.jsx(o.a,{href:"/docs/case-studies#case-study-4-maxtransferthreads-config",children:"Case Studies"})," and note that this property was previously known as ",e.jsx(o.code,{children:"dfs.datanode.max.xcievers"})," (e.g. ",e.jsx(o.a,{href:"http://ccgtech.blogspot.com/2010/02/hadoop-hdfs-deceived-by-xciever.html",children:"Hadoop HDFS: Deceived by Xciever"}),")."]}),`
+`,e.jsx(o.h2,{id:"zookeeper-requirements",children:"ZooKeeper Requirements"}),`
+`,e.jsxs(o.p,{children:["An Apache ZooKeeper quorum is required. The exact version depends on your version of HBase, though the minimum ZooKeeper version is 3.4.x due to the ",e.jsx(o.code,{children:"useMulti"})," feature made default in 1.0.0 (see ",e.jsx(o.a,{href:"https://issues.apache.org/jira/browse/HBASE-16598",children:"HBASE-16598"}),")."]})]})}function p(s={}){const{wrapper:o}=s.components||{};return o?e.jsx(o,{...s,children:e.jsx(t,{...s})}):t(s)}function i(s,o){throw new Error [...]
diff --git a/assets/bc_basic-BTMl5eCr.png b/assets/bc_basic-BTMl5eCr.png
new file mode 100644
index 00000000000..231de9332bc
Binary files /dev/null and b/assets/bc_basic-BTMl5eCr.png differ
diff --git a/assets/bc_config-Ceg8MoFC.png b/assets/bc_config-Ceg8MoFC.png
new file mode 100644
index 00000000000..53250cf6d43
Binary files /dev/null and b/assets/bc_config-Ceg8MoFC.png differ
diff --git a/assets/bc_l1-DQ3gnW8v.png b/assets/bc_l1-DQ3gnW8v.png
new file mode 100644
index 00000000000..36d7e551385
Binary files /dev/null and b/assets/bc_l1-DQ3gnW8v.png differ
diff --git a/assets/bc_stats-DBz8eOUI.png b/assets/bc_stats-DBz8eOUI.png
new file mode 100644
index 00000000000..d8c63841a5b
Binary files /dev/null and b/assets/bc_stats-DBz8eOUI.png differ
diff --git a/assets/building-D7JI1FBi.js b/assets/building-D7JI1FBi.js
new file mode 100644
index 00000000000..0512f2d80ad
--- /dev/null
+++ b/assets/building-D7JI1FBi.js
@@ -0,0 +1,495 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let l=`## Basic Compile
+
+HBase is compiled using Maven. You must use at least Maven 3.0.4. To check your Maven version, run
+the command \`mvn -version\`.
+
+### JDK Version Requirements
+
+HBase has Java version compiler requirements that vary by release branch. At compilation time,
+HBase has the same version requirements as it does for runtime. See [Java](/docs/configuration/basic-prerequisites#configuration-basic-prerequisites-java) for a complete
+support matrix of Java version by HBase version.
+
+### Maven Build Commands
+
+All commands are executed from the local HBase project directory.
+
+#### Package
+
+The simplest command to compile HBase from its java source code is to use the \`package\` target, which builds JARs with the compiled files.
+
+\`\`\`bash
+mvn package -DskipTests
+\`\`\`
+
+Or, to clean up before compiling:
+
+\`\`\`bash
+mvn clean package -DskipTests
+\`\`\`
+
+With Eclipse set up as explained above in [Eclipse](/docs/building-and-developing#eclipse), you can also use the **Build** command in Eclipse.
+To create the full installable HBase package takes a little bit more work, so read on.
+
+#### Compile
+
+The \`compile\` target does not create the JARs with the compiled files.
+
+\`\`\`bash
+mvn compile
+\`\`\`
+
+\`\`\`bash
+mvn clean compile
+\`\`\`
+
+#### Install
+
+To install the JARs in your *\\~/.m2/* directory, use the \`install\` target.
+
+\`\`\`bash
+mvn install
+\`\`\`
+
+\`\`\`bash
+mvn clean install
+\`\`\`
+
+\`\`\`bash
+mvn clean install -DskipTests
+\`\`\`
+
+#### Building HBase 2.x on Apple Silicon
+
+Building a non-master branch requires protoc 2.5.0 binary which is not available for Apple Silicon.
+HBASE-27741 added a workaround to the build to fall back to osx-x86\\_64 version of protoc automatically by \`apple-silicon-workaround\` Maven profile.
+The intention is that this change will permit the build to proceed with the x86 version of \`protoc\`, making use of the Rosetta instruction translation service built into the OS.
+If you'd like to provide and make use of your own aarch\\_64 \`protoc\`, you can disable this profile on the command line by adding \`-P'!apple-silicon-workaround'\`, or through configuration in your \`settings.xml\`.
+
+You can use the following commands to build protoc on your Apple Silicon machine.
+
+\`\`\`bash
+curl -sSL https://github.com/protocolbuffers/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz | tar zx -
+cd protobuf-2.5.0
+curl -L -O https://gist.githubusercontent.com/liusheng/64aee1b27de037f8b9ccf1873b82c413/raw/118c2fce733a9a62a03281753572a45b6efb8639/protobuf-2.5.0-arm64.patch
+patch -p1 < protobuf-2.5.0-arm64.patch
+./configure --disable-shared
+make
+mvn install:install-file -DgroupId=com.google.protobuf -DartifactId=protoc -Dversion=2.5.0 -Dclassifier=osx-aarch_64 -Dpackaging=exe -Dfile=src/protoc
+\`\`\`
+
+### Running all or individual Unit Tests
+
+See the [Running tests](/docs/building-and-developing/tests#running-tests) section in [Unit Tests](/docs/building-and-developing/tests#building-and-developing-unit-tests)
+
+### Building against various Hadoop versions
+
+HBase supports building against Apache Hadoop versions: 2.y and 3.y (early release artifacts).
+Exactly which version of Hadoop is used by default varies by release branch. See the section
+[Hadoop](/docs/configuration/basic-prerequisites#hadoop) for the complete breakdown of supported Hadoop version by HBase release.
+
+The mechanism for selecting a Hadoop version at build time is identical across all releases. Which
+version of Hadoop is default varies. We manage Hadoop major version selection by way of Maven
+profiles. Due to the peculiarities of Maven profile mutual exclusion, the profile that builds
+against a particular Hadoop version is activated by setting a property, *not* the usual profile
+activation. Hadoop version profile activation is summarized by the following table.
+
+#### Hadoop Profile Activation by HBase Release
+
+|            | Hadoop2 Activation  | Hadoop3 Activation     |
+| ---------- | ------------------- | ---------------------- |
+| HBase 1.3+ | *active by default* | \`-Dhadoop.profile=3.0\` |
+| HBase 3.0+ | *not supported*     | *active by default*    |
+
+<Callout type="warn">
+  Please note that where a profile is active by default, \`hadoop.profile\` must NOT be provided.
+</Callout>
+
+Once the Hadoop major version profile is activated, the exact Hadoop version can be
+specified by overriding the appropriate property value. For Hadoop2 versions, the property name
+is \`hadoop-two.version\`. With Hadoop3 versions, the property name is \`hadoop-three.version\`.
+
+#### Example 1: Building HBase 1.7 against Hadoop 2.10.0
+
+For example, to build HBase 1.7 against Hadoop 2.10.0, the profile is set for Hadoop2 by default,
+so only \`hadoop-two.version\` must be specified:
+
+\`\`\`bash
+git checkout branch-1
+mvn -Dhadoop-two.version=2.10.0 ...
+\`\`\`
+
+#### Example 2: Building HBase 2.3 or 2.4 against Hadoop 3.4.0-SNAPSHOT
+
+This is how a developer might check the compatibility of HBase 2.3 or 2.4 against an unreleased
+Hadoop version (currently 3.4). Both the Hadoop3 profile and version must be specified:
+
+\`\`\`bash
+git checkout branch-2.4
+mvn -Dhadoop.profile=3.0 -Dhadoop-three.version=3.4.0-SNAPSHOT ...
+\`\`\`
+
+#### Example 3: Building HBase 3.0 against Hadoop 3.4.0-SNAPSHOT
+
+The same developer might want also to check the development version of HBase (currently 3.0)
+against the development version of Hadoop (currently 3.4). In this case, the Hadoop3 profile is
+active by default, so only \`hadoop-three.version\` must be specified:
+
+\`\`\`bash
+git checkout master
+mvn -Dhadoop-three.version=3.4.0-SNAPSHOT ...
+\`\`\`
+
+### Building with JDK11 and Hadoop3
+
+HBase manages JDK-specific build settings using Maven profiles. The profile appropriate to the JDK
+in use is automatically activated. Building and running on JDK8 supports both Hadoop2 and Hadoop3.
+For JDK11, only Hadoop3 is supported. Thus, the Hadoop3 profile must be active when building on
+JDK11, and the artifacts used when running HBase on JDK11 must be compiled against Hadoop3.
+Furthermore, the JDK11 profile requires a minimum Hadoop version of 3.2.0. This value is specified
+by the JDK11 profile, but it can be overridden using the \`hadoop-three.version\` property as normal.
+For details on Hadoop profile activation by HBase branch, see
+[Building against various Hadoop versions](/docs/building-and-developing/building#building-against-various-hadoop-versions). See [Java](/docs/configuration/basic-prerequisites#configuration-basic-prerequisites-java) for a complete
+support matrix of Java version by HBase version.
+
+#### Example 1: Building HBase 2.3 or 2.4 with JDK11
+
+To build HBase 2.3 or 2.4 with JDK11, the Hadoop3 profile must be activated explicitly.
+
+\`\`\`bash
+git checkout branch-2.4
+JAVA_HOME=/usr/lib/jvm/java-11 mvn -Dhadoop.profile=3.0 ...
+\`\`\`
+
+#### Example 2: Building HBase 3.0 with JDK11
+
+For HBase 3.0, the Hadoop3 profile is active by default, no additional properties need be
+specified.
+
+\`\`\`bash
+git checkout master
+JAVA_HOME=/usr/lib/jvm/java-11 mvn ...
+\`\`\`
+
+### Building and testing in an IDE with JDK11 and Hadoop3
+
+Continuing the discussion from the [earlier section](/docs/building-and-developing/building#building-with-jdk11-and-hadoop3), building and
+testing with JDK11 and Hadoop3 within an IDE may require additional configuration. Specifically,
+make sure the JVM version used by the IDE is a JDK11, the active JDK Maven profile is for JDK11,
+and the Maven profile for JDK8 is NOT active. Likewise, ensure the Hadoop3 Maven profile is active
+and the Hadoop2 Maven profile is NOT active.
+
+### Build Protobuf
+
+You may need to change the protobuf definitions that reside in the *hbase-protocol* module or other modules.
+
+Previous to hbase-2.0.0, protobuf definition files were sprinkled across all hbase modules but now all
+to do with protobuf must reside in the hbase-protocol module; we are trying to contain our protobuf
+use so we can freely change versions without upsetting any downstream project use of protobuf.
+
+The protobuf files are located in *hbase-protocol/src/main/protobuf*.
+For the change to be effective, you will need to regenerate the classes.
+
+\`\`\`bash
+mvn package -pl hbase-protocol -am
+\`\`\`
+
+Similarly, protobuf definitions for internal use are located in the *hbase-protocol-shaded* module.
+
+\`\`\`bash
+mvn package -pl hbase-protocol-shaded -am
+\`\`\`
+
+Typically, protobuf code generation is done using the native \`protoc\` binary. In our build we use a maven plugin for
+convenience; however, the plugin may not be able to retrieve appropriate binaries for all platforms. If you find yourself
+on a platform where protoc fails, you will have to compile protoc from source, and run it independent of our maven build.
+You can disable the inline code generation by specifying \`-Dprotoc.skip\` in your maven arguments, allowing your build to proceed further.
+
+<Callout type="info">
+  If you need to manually generate your protobuf files, you should not use \`clean\` in subsequent
+  maven calls, as that will delete the newly generated files.
+</Callout>
+
+Read the *hbase-protocol/README.txt* for more details
+
+### Build Thrift
+
+You may need to change the thrift definitions that reside in the *hbase-thrift* module or other modules.
+
+The thrift files are located in *hbase-thrift/src/main/resources*.
+For the change to be effective, you will need to regenerate the classes.
+You can use maven profile \`compile-thrift\` to do this.
+
+\`\`\`bash
+mvn compile -Pcompile-thrift
+\`\`\`
+
+You may also want to define \`thrift.path\` for the thrift binary, using the following command:
+
+\`\`\`bash
+mvn compile -Pcompile-thrift -Dthrift.path=/opt/local/bin/thrift
+\`\`\`
+
+### Build a Tarball
+
+You can build a tarball without going through the release process described in [Releasing Apache HBase](/docs/building-and-developing/releasing), by running the following command:
+
+\`\`\`bash
+mvn -DskipTests clean install && mvn -DskipTests package assembly:single
+\`\`\`
+
+The distribution tarball is built in \`hbase-assembly/target/hbase-<version>-bin.tar.gz\`.
+
+You can install or deploy the tarball by having the assembly:single goal before install or deploy in the maven command:
+
+\`\`\`bash
+mvn -DskipTests package assembly:single install
+\`\`\`
+
+\`\`\`bash
+mvn -DskipTests package assembly:single deploy
+\`\`\`
+
+### Build Gotchas
+
+#### Maven Site failure
+
+If you see \`Unable to find resource 'VM_global_library.vm'\`, ignore it.
+It's not an error.
+It is [officially ugly](https://issues.apache.org/jira/browse/MSITE-286) though.
+
+## Build On Linux Aarch64
+
+HBase runs on both Windows and UNIX-like systems, and it should run on any platform
+that runs a supported version of Java. This should include JVMs on x86\\_64 and aarch64.
+The documentation below describes how to build hbase on aarch64 platform.
+
+### Set Environment Variables
+
+Manually install Java and Maven on aarch64 servers if they are not installed,
+and set environment variables. For example:
+
+\`\`\`bash
+export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-arm64
+export MAVEN_HOME=/opt/maven
+export PATH=\${MAVEN_HOME}/bin:\${JAVA_HOME}/bin:\${PATH}
+\`\`\`
+
+### Use Protobuf Supported On Aarch64
+
+Now HBase uses protobuf of two versions. Version '3.11.4' of protobuf that hbase uses
+internally and version '2.5.0' as external usage.
+Package protoc-2.5.0 does not work on aarch64 platform, we should add maven
+profile '-Paarch64' when building. It downloads protoc-2.5.0 package from maven
+repository which we made on aarch64 platform locally.
+
+\`\`\`bash
+mvn clean install -Paarch64 -DskipTests
+\`\`\`
+
+<Callout type="info">
+  Protobuf is released with aarch64 protoc since version '3.5.0', and we are planning to upgrade
+  protobuf later, then we don't have to add the profile '-Paarch64' anymore.
+</Callout>
+`,r={title:"Building Apache HBase",description:"Maven build commands, JDK requirements, Hadoop version selection, and building HBase from source including protobuf and thrift generation."},h=[{href:"/docs/configuration/basic-prerequisites#configuration-basic-prerequisites-java"},{href:"/docs/building-and-developing#eclipse"},{href:"/docs/building-and-developing/tests#running-tests"},{href:"/docs/building-and-developing/tests#building-and-developing-unit-tests"},{href:"/docs/configuration [...]
+the command mvn -version.`},{heading:"building-basic-compile-jdk-version-requirements",content:`HBase has Java version compiler requirements that vary by release branch. At compilation time,
+HBase has the same version requirements as it does for runtime. See Java for a complete
+support matrix of Java version by HBase version.`},{heading:"maven-build-commands",content:"All commands are executed from the local HBase project directory."},{heading:"package",content:"The simplest command to compile HBase from its java source code is to use the package target, which builds JARs with the compiled files."},{heading:"package",content:"Or, to clean up before compiling:"},{heading:"package",content:`With Eclipse set up as explained above in Eclipse, you can also use the B [...]
+To create the full installable HBase package takes a little bit more work, so read on.`},{heading:"compile",content:"The compile target does not create the JARs with the compiled files."},{heading:"install",content:"To install the JARs in your ~/.m2/ directory, use the install target."},{heading:"building-hbase-2x-on-apple-silicon",content:`Building a non-master branch requires protoc 2.5.0 binary which is not available for Apple Silicon.
+HBASE-27741 added a workaround to the build to fall back to osx-x86_64 version of protoc automatically by apple-silicon-workaround Maven profile.
+The intention is that this change will permit the build to proceed with the x86 version of protoc, making use of the Rosetta instruction translation service built into the OS.
+If you'd like to provide and make use of your own aarch_64 protoc, you can disable this profile on the command line by adding -P'!apple-silicon-workaround', or through configuration in your settings.xml.`},{heading:"building-hbase-2x-on-apple-silicon",content:"You can use the following commands to build protoc on your Apple Silicon machine."},{heading:"running-all-or-individual-unit-tests",content:"See the Running tests section in Unit Tests"},{heading:"building-against-various-hadoop-ve [...]
+Exactly which version of Hadoop is used by default varies by release branch. See the section
+Hadoop for the complete breakdown of supported Hadoop version by HBase release.`},{heading:"building-against-various-hadoop-versions",content:`The mechanism for selecting a Hadoop version at build time is identical across all releases. Which
+version of Hadoop is default varies. We manage Hadoop major version selection by way of Maven
+profiles. Due to the peculiarities of Maven profile mutual exclusion, the profile that builds
+against a particular Hadoop version is activated by setting a property, not the usual profile
+activation. Hadoop version profile activation is summarized by the following table.`},{heading:"hadoop-profile-activation-by-hbase-release",content:"Hadoop2 Activation"},{heading:"hadoop-profile-activation-by-hbase-release",content:"Hadoop3 Activation"},{heading:"hadoop-profile-activation-by-hbase-release",content:"HBase 1.3+"},{heading:"hadoop-profile-activation-by-hbase-release",content:"active by default"},{heading:"hadoop-profile-activation-by-hbase-release",content:"-Dhadoop.profile [...]
+specified by overriding the appropriate property value. For Hadoop2 versions, the property name
+is hadoop-two.version. With Hadoop3 versions, the property name is hadoop-three.version.`},{heading:"example-1-building-hbase-17-against-hadoop-2100",content:`For example, to build HBase 1.7 against Hadoop 2.10.0, the profile is set for Hadoop2 by default,
+so only hadoop-two.version must be specified:`},{heading:"example-2-building-hbase-23-or-24-against-hadoop-340-snapshot",content:`This is how a developer might check the compatibility of HBase 2.3 or 2.4 against an unreleased
+Hadoop version (currently 3.4). Both the Hadoop3 profile and version must be specified:`},{heading:"example-3-building-hbase-30-against-hadoop-340-snapshot",content:`The same developer might want also to check the development version of HBase (currently 3.0)
+against the development version of Hadoop (currently 3.4). In this case, the Hadoop3 profile is
+active by default, so only hadoop-three.version must be specified:`},{heading:"building-with-jdk11-and-hadoop3",content:`HBase manages JDK-specific build settings using Maven profiles. The profile appropriate to the JDK
+in use is automatically activated. Building and running on JDK8 supports both Hadoop2 and Hadoop3.
+For JDK11, only Hadoop3 is supported. Thus, the Hadoop3 profile must be active when building on
+JDK11, and the artifacts used when running HBase on JDK11 must be compiled against Hadoop3.
+Furthermore, the JDK11 profile requires a minimum Hadoop version of 3.2.0. This value is specified
+by the JDK11 profile, but it can be overridden using the hadoop-three.version property as normal.
+For details on Hadoop profile activation by HBase branch, see
+Building against various Hadoop versions. See Java for a complete
+support matrix of Java version by HBase version.`},{heading:"example-1-building-hbase-23-or-24-with-jdk11",content:"To build HBase 2.3 or 2.4 with JDK11, the Hadoop3 profile must be activated explicitly."},{heading:"example-2-building-hbase-30-with-jdk11",content:`For HBase 3.0, the Hadoop3 profile is active by default, no additional properties need be
+specified.`},{heading:"building-and-testing-in-an-ide-with-jdk11-and-hadoop3",content:`Continuing the discussion from the earlier section, building and
+testing with JDK11 and Hadoop3 within an IDE may require additional configuration. Specifically,
+make sure the JVM version used by the IDE is a JDK11, the active JDK Maven profile is for JDK11,
+and the Maven profile for JDK8 is NOT active. Likewise, ensure the Hadoop3 Maven profile is active
+and the Hadoop2 Maven profile is NOT active.`},{heading:"build-protobuf",content:"You may need to change the protobuf definitions that reside in the hbase-protocol module or other modules."},{heading:"build-protobuf",content:`Previous to hbase-2.0.0, protobuf definition files were sprinkled across all hbase modules but now all
+to do with protobuf must reside in the hbase-protocol module; we are trying to contain our protobuf
+use so we can freely change versions without upsetting any downstream project use of protobuf.`},{heading:"build-protobuf",content:`The protobuf files are located in hbase-protocol/src/main/protobuf.
+For the change to be effective, you will need to regenerate the classes.`},{heading:"build-protobuf",content:"Similarly, protobuf definitions for internal use are located in the hbase-protocol-shaded module."},{heading:"build-protobuf",content:`Typically, protobuf code generation is done using the native protoc binary. In our build we use a maven plugin for
+convenience; however, the plugin may not be able to retrieve appropriate binaries for all platforms. If you find yourself
+on a platform where protoc fails, you will have to compile protoc from source, and run it independent of our maven build.
+You can disable the inline code generation by specifying -Dprotoc.skip in your maven arguments, allowing your build to proceed further.`},{heading:"build-protobuf",content:"type: info"},{heading:"build-protobuf",content:`If you need to manually generate your protobuf files, you should not use clean in subsequent
+maven calls, as that will delete the newly generated files.`},{heading:"build-protobuf",content:"Read the hbase-protocol/README.txt for more details"},{heading:"build-thrift",content:"You may need to change the thrift definitions that reside in the hbase-thrift module or other modules."},{heading:"build-thrift",content:`The thrift files are located in hbase-thrift/src/main/resources.
+For the change to be effective, you will need to regenerate the classes.
+You can use maven profile compile-thrift to do this.`},{heading:"build-thrift",content:"You may also want to define thrift.path for the thrift binary, using the following command:"},{heading:"build-a-tarball",content:"You can build a tarball without going through the release process described in Releasing Apache HBase, by running the following command:"},{heading:"build-a-tarball",content:"The distribution tarball is built in hbase-assembly/target/hbase-<version>-bin.tar.gz."},{heading:" [...]
+It's not an error.
+It is officially ugly though.`},{heading:"build-on-linux-aarch64",content:`HBase runs on both Windows and UNIX-like systems, and it should run on any platform
+that runs a supported version of Java. This should include JVMs on x86_64 and aarch64.
+The documentation below describes how to build hbase on aarch64 platform.`},{heading:"set-environment-variables",content:`Manually install Java and Maven on aarch64 servers if they are not installed,
+and set environment variables. For example:`},{heading:"use-protobuf-supported-on-aarch64",content:`Now HBase uses protobuf of two versions. Version '3.11.4' of protobuf that hbase uses
+internally and version '2.5.0' as external usage.
+Package protoc-2.5.0 does not work on aarch64 platform, we should add maven
+profile '-Paarch64' when building. It downloads protoc-2.5.0 package from maven
+repository which we made on aarch64 platform locally.`},{heading:"use-protobuf-supported-on-aarch64",content:"type: info"},{heading:"use-protobuf-supported-on-aarch64",content:`Protobuf is released with aarch64 protoc since version '3.5.0', and we are planning to upgrade
+protobuf later, then we don't have to add the profile '-Paarch64' anymore.`}],headings:[{id:"basic-compile",content:"Basic Compile"},{id:"building-basic-compile-jdk-version-requirements",content:"JDK Version Requirements"},{id:"maven-build-commands",content:"Maven Build Commands"},{id:"package",content:"Package"},{id:"compile",content:"Compile"},{id:"install",content:"Install"},{id:"building-hbase-2x-on-apple-silicon",content:"Building HBase 2.x on Apple Silicon"},{id:"running-all-or-ind [...]
+`,e.jsxs(i.p,{children:[`HBase is compiled using Maven. You must use at least Maven 3.0.4. To check your Maven version, run
+the command `,e.jsx(i.code,{children:"mvn -version"}),"."]}),`
+`,e.jsx(i.h3,{id:"building-basic-compile-jdk-version-requirements",children:"JDK Version Requirements"}),`
+`,e.jsxs(i.p,{children:[`HBase has Java version compiler requirements that vary by release branch. At compilation time,
+HBase has the same version requirements as it does for runtime. See `,e.jsx(i.a,{href:"/docs/configuration/basic-prerequisites#configuration-basic-prerequisites-java",children:"Java"}),` for a complete
+support matrix of Java version by HBase version.`]}),`
+`,e.jsx(i.h3,{id:"maven-build-commands",children:"Maven Build Commands"}),`
+`,e.jsx(i.p,{children:"All commands are executed from the local HBase project directory."}),`
+`,e.jsx(i.h4,{id:"package",children:"Package"}),`
+`,e.jsxs(i.p,{children:["The simplest command to compile HBase from its java source code is to use the ",e.jsx(i.code,{children:"package"})," target, which builds JARs with the compiled files."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.p,{children:"Or, to clean up before compiling:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.p,{children:["With Eclipse set up as explained above in ",e.jsx(i.a,{href:"/docs/building-and-developing#eclipse",children:"Eclipse"}),", you can also use the ",e.jsx(i.strong,{children:"Build"}),` command in Eclipse.
+To create the full installable HBase package takes a little bit more work, so read on.`]}),`
+`,e.jsx(i.h4,{id:"compile",children:"Compile"}),`
+`,e.jsxs(i.p,{children:["The ",e.jsx(i.code,{children:"compile"})," target does not create the JARs with the compiled files."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"install",children:"Install"}),`
+`,e.jsxs(i.p,{children:["To install the JARs in your ",e.jsx(i.em,{children:"~/.m2/"})," directory, use the ",e.jsx(i.code,{children:"install"})," target."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"building-hbase-2x-on-apple-silicon",children:"Building HBase 2.x on Apple Silicon"}),`
+`,e.jsxs(i.p,{children:[`Building a non-master branch requires protoc 2.5.0 binary which is not available for Apple Silicon.
+HBASE-27741 added a workaround to the build to fall back to osx-x86_64 version of protoc automatically by `,e.jsx(i.code,{children:"apple-silicon-workaround"}),` Maven profile.
+The intention is that this change will permit the build to proceed with the x86 version of `,e.jsx(i.code,{children:"protoc"}),`, making use of the Rosetta instruction translation service built into the OS.
+If you'd like to provide and make use of your own aarch_64 `,e.jsx(i.code,{children:"protoc"}),", you can disable this profile on the command line by adding ",e.jsx(i.code,{children:"-P'!apple-silicon-workaround'"}),", or through configuration in your ",e.jsx(i.code,{children:"settings.xml"}),"."]}),`
+`,e.jsx(i.p,{children:"You can use the following commands to build protoc on your Apple Silicon machine."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"cd"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" protobuf-2.5.0"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"curl"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -L"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -O"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" https://gist.githubusercontent.com/liusheng/64aee1b27de037f8b9ccf1873b82c413/raw/118c2fce733a [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"patch"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -p1"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" protobuf-2.5.0-arm64.patch"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"./configure"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" --disable-shared"})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"make"})}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"mvn"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" install:install-file"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -DgroupId=com.google.protobuf"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -DartifactId=protoc"}),e.jsx(i.span,{style:{"--sh [...]
+`,e.jsx(i.h3,{id:"running-all-or-individual-unit-tests",children:"Running all or individual Unit Tests"}),`
+`,e.jsxs(i.p,{children:["See the ",e.jsx(i.a,{href:"/docs/building-and-developing/tests#running-tests",children:"Running tests"})," section in ",e.jsx(i.a,{href:"/docs/building-and-developing/tests#building-and-developing-unit-tests",children:"Unit Tests"})]}),`
+`,e.jsx(i.h3,{id:"building-against-various-hadoop-versions",children:"Building against various Hadoop versions"}),`
+`,e.jsxs(i.p,{children:[`HBase supports building against Apache Hadoop versions: 2.y and 3.y (early release artifacts).
+Exactly which version of Hadoop is used by default varies by release branch. See the section
+`,e.jsx(i.a,{href:"/docs/configuration/basic-prerequisites#hadoop",children:"Hadoop"})," for the complete breakdown of supported Hadoop version by HBase release."]}),`
+`,e.jsxs(i.p,{children:[`The mechanism for selecting a Hadoop version at build time is identical across all releases. Which
+version of Hadoop is default varies. We manage Hadoop major version selection by way of Maven
+profiles. Due to the peculiarities of Maven profile mutual exclusion, the profile that builds
+against a particular Hadoop version is activated by setting a property, `,e.jsx(i.em,{children:"not"}),` the usual profile
+activation. Hadoop version profile activation is summarized by the following table.`]}),`
+`,e.jsx(i.h4,{id:"hadoop-profile-activation-by-hbase-release",children:"Hadoop Profile Activation by HBase Release"}),`
+`,e.jsxs(i.table,{children:[e.jsx(i.thead,{children:e.jsxs(i.tr,{children:[e.jsx(i.th,{}),e.jsx(i.th,{children:"Hadoop2 Activation"}),e.jsx(i.th,{children:"Hadoop3 Activation"})]})}),e.jsxs(i.tbody,{children:[e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"HBase 1.3+"}),e.jsx(i.td,{children:e.jsx(i.em,{children:"active by default"})}),e.jsx(i.td,{children:e.jsx(i.code,{children:"-Dhadoop.profile=3.0"})})]}),e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"HBase 3.0+"}),e.jsx(i.td,{children:e.js [...]
+`,e.jsx(s,{type:"warn",children:e.jsxs(i.p,{children:["Please note that where a profile is active by default, ",e.jsx(i.code,{children:"hadoop.profile"})," must NOT be provided."]})}),`
+`,e.jsxs(i.p,{children:[`Once the Hadoop major version profile is activated, the exact Hadoop version can be
+specified by overriding the appropriate property value. For Hadoop2 versions, the property name
+is `,e.jsx(i.code,{children:"hadoop-two.version"}),". With Hadoop3 versions, the property name is ",e.jsx(i.code,{children:"hadoop-three.version"}),"."]}),`
+`,e.jsx(i.h4,{id:"example-1-building-hbase-17-against-hadoop-2100",children:"Example 1: Building HBase 1.7 against Hadoop 2.10.0"}),`
+`,e.jsxs(i.p,{children:[`For example, to build HBase 1.7 against Hadoop 2.10.0, the profile is set for Hadoop2 by default,
+so only `,e.jsx(i.code,{children:"hadoop-two.version"})," must be specified:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"mvn"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -Dhadoop-two.version=2.10.0"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ..."})]})]})})}),`
+`,e.jsx(i.h4,{id:"example-2-building-hbase-23-or-24-against-hadoop-340-snapshot",children:"Example 2: Building HBase 2.3 or 2.4 against Hadoop 3.4.0-SNAPSHOT"}),`
+`,e.jsx(i.p,{children:`This is how a developer might check the compatibility of HBase 2.3 or 2.4 against an unreleased
+Hadoop version (currently 3.4). Both the Hadoop3 profile and version must be specified:`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"mvn"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -Dhadoop.profile=3.0"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -Dhadoop-three.version=3.4.0-SNAPSHOT"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ..."})]})]})})}),`
+`,e.jsx(i.h4,{id:"example-3-building-hbase-30-against-hadoop-340-snapshot",children:"Example 3: Building HBase 3.0 against Hadoop 3.4.0-SNAPSHOT"}),`
+`,e.jsxs(i.p,{children:[`The same developer might want also to check the development version of HBase (currently 3.0)
+against the development version of Hadoop (currently 3.4). In this case, the Hadoop3 profile is
+active by default, so only `,e.jsx(i.code,{children:"hadoop-three.version"})," must be specified:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"mvn"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -Dhadoop-three.version=3.4.0-SNAPSHOT"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ..."})]})]})})}),`
+`,e.jsx(i.h3,{id:"building-with-jdk11-and-hadoop3",children:"Building with JDK11 and Hadoop3"}),`
+`,e.jsxs(i.p,{children:[`HBase manages JDK-specific build settings using Maven profiles. The profile appropriate to the JDK
+in use is automatically activated. Building and running on JDK8 supports both Hadoop2 and Hadoop3.
+For JDK11, only Hadoop3 is supported. Thus, the Hadoop3 profile must be active when building on
+JDK11, and the artifacts used when running HBase on JDK11 must be compiled against Hadoop3.
+Furthermore, the JDK11 profile requires a minimum Hadoop version of 3.2.0. This value is specified
+by the JDK11 profile, but it can be overridden using the `,e.jsx(i.code,{children:"hadoop-three.version"}),` property as normal.
+For details on Hadoop profile activation by HBase branch, see
+`,e.jsx(i.a,{href:"/docs/building-and-developing/building#building-against-various-hadoop-versions",children:"Building against various Hadoop versions"}),". See ",e.jsx(i.a,{href:"/docs/configuration/basic-prerequisites#configuration-basic-prerequisites-java",children:"Java"}),` for a complete
+support matrix of Java version by HBase version.`]}),`
+`,e.jsx(i.h4,{id:"example-1-building-hbase-23-or-24-with-jdk11",children:"Example 1: Building HBase 2.3 or 2.4 with JDK11"}),`
+`,e.jsx(i.p,{children:"To build HBase 2.3 or 2.4 with JDK11, the Hadoop3 profile must be activated explicitly."}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"JAVA_HOME"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"/usr/lib/jvm/java-11"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" mvn"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79 [...]
+`,e.jsx(i.h4,{id:"example-2-building-hbase-30-with-jdk11",children:"Example 2: Building HBase 3.0 with JDK11"}),`
+`,e.jsx(i.p,{children:`For HBase 3.0, the Hadoop3 profile is active by default, no additional properties need be
+specified.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"JAVA_HOME"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"/usr/lib/jvm/java-11"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" mvn"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9E [...]
+`,e.jsx(i.h3,{id:"building-and-testing-in-an-ide-with-jdk11-and-hadoop3",children:"Building and testing in an IDE with JDK11 and Hadoop3"}),`
+`,e.jsxs(i.p,{children:["Continuing the discussion from the ",e.jsx(i.a,{href:"/docs/building-and-developing/building#building-with-jdk11-and-hadoop3",children:"earlier section"}),`, building and
+testing with JDK11 and Hadoop3 within an IDE may require additional configuration. Specifically,
+make sure the JVM version used by the IDE is a JDK11, the active JDK Maven profile is for JDK11,
+and the Maven profile for JDK8 is NOT active. Likewise, ensure the Hadoop3 Maven profile is active
+and the Hadoop2 Maven profile is NOT active.`]}),`
+`,e.jsx(i.h3,{id:"build-protobuf",children:"Build Protobuf"}),`
+`,e.jsxs(i.p,{children:["You may need to change the protobuf definitions that reside in the ",e.jsx(i.em,{children:"hbase-protocol"})," module or other modules."]}),`
+`,e.jsx(i.p,{children:`Previous to hbase-2.0.0, protobuf definition files were sprinkled across all hbase modules but now all
+to do with protobuf must reside in the hbase-protocol module; we are trying to contain our protobuf
+use so we can freely change versions without upsetting any downstream project use of protobuf.`}),`
+`,e.jsxs(i.p,{children:["The protobuf files are located in ",e.jsx(i.em,{children:"hbase-protocol/src/main/protobuf"}),`.
+For the change to be effective, you will need to regenerate the classes.`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.p,{children:["Similarly, protobuf definitions for internal use are located in the ",e.jsx(i.em,{children:"hbase-protocol-shaded"})," module."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.p,{children:["Typically, protobuf code generation is done using the native ",e.jsx(i.code,{children:"protoc"}),` binary. In our build we use a maven plugin for
+convenience; however, the plugin may not be able to retrieve appropriate binaries for all platforms. If you find yourself
+on a platform where protoc fails, you will have to compile protoc from source, and run it independent of our maven build.
+You can disable the inline code generation by specifying `,e.jsx(i.code,{children:"-Dprotoc.skip"})," in your maven arguments, allowing your build to proceed further."]}),`
+`,e.jsx(s,{type:"info",children:e.jsxs(i.p,{children:["If you need to manually generate your protobuf files, you should not use ",e.jsx(i.code,{children:"clean"}),` in subsequent
+maven calls, as that will delete the newly generated files.`]})}),`
+`,e.jsxs(i.p,{children:["Read the ",e.jsx(i.em,{children:"hbase-protocol/README.txt"})," for more details"]}),`
+`,e.jsx(i.h3,{id:"build-thrift",children:"Build Thrift"}),`
+`,e.jsxs(i.p,{children:["You may need to change the thrift definitions that reside in the ",e.jsx(i.em,{children:"hbase-thrift"})," module or other modules."]}),`
+`,e.jsxs(i.p,{children:["The thrift files are located in ",e.jsx(i.em,{children:"hbase-thrift/src/main/resources"}),`.
+For the change to be effective, you will need to regenerate the classes.
+You can use maven profile `,e.jsx(i.code,{children:"compile-thrift"})," to do this."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.p,{children:["You may also want to define ",e.jsx(i.code,{children:"thrift.path"})," for the thrift binary, using the following command:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h3,{id:"build-a-tarball",children:"Build a Tarball"}),`
+`,e.jsxs(i.p,{children:["You can build a tarball without going through the release process described in ",e.jsx(i.a,{href:"/docs/building-and-developing/releasing",children:"Releasing Apache HBase"}),", by running the following command:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.p,{children:["The distribution tarball is built in ",e.jsx(i.code,{children:"hbase-assembly/target/hbase-<version>-bin.tar.gz"}),"."]}),`
+`,e.jsx(i.p,{children:"You can install or deploy the tarball by having the assembly:single goal before install or deploy in the maven command:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h3,{id:"build-gotchas",children:"Build Gotchas"}),`
+`,e.jsx(i.h4,{id:"maven-site-failure",children:"Maven Site failure"}),`
+`,e.jsxs(i.p,{children:["If you see ",e.jsx(i.code,{children:"Unable to find resource 'VM_global_library.vm'"}),`, ignore it.
+It's not an error.
+It is `,e.jsx(i.a,{href:"https://issues.apache.org/jira/browse/MSITE-286",children:"officially ugly"})," though."]}),`
+`,e.jsx(i.h2,{id:"build-on-linux-aarch64",children:"Build On Linux Aarch64"}),`
+`,e.jsx(i.p,{children:`HBase runs on both Windows and UNIX-like systems, and it should run on any platform
+that runs a supported version of Java. This should include JVMs on x86_64 and aarch64.
+The documentation below describes how to build hbase on aarch64 platform.`}),`
+`,e.jsx(i.h3,{id:"set-environment-variables",children:"Set Environment Variables"}),`
+`,e.jsx(i.p,{children:`Manually install Java and Maven on aarch64 servers if they are not installed,
+and set environment variables. For example:`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"export"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" MAVEN_HOME"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"/opt/maven"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"export"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" PATH"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"${MAVEN_HOME}/bin:${JAVA_HOME}/bin:${PATH}"})]})]})})}),`
+`,e.jsx(i.h3,{id:"use-protobuf-supported-on-aarch64",children:"Use Protobuf Supported On Aarch64"}),`
+`,e.jsx(i.p,{children:`Now HBase uses protobuf of two versions. Version '3.11.4' of protobuf that hbase uses
+internally and version '2.5.0' as external usage.
+Package protoc-2.5.0 does not work on aarch64 platform, we should add maven
+profile '-Paarch64' when building. It downloads protoc-2.5.0 package from maven
+repository which we made on aarch64 platform locally.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(s,{type:"info",children:e.jsx(i.p,{children:`Protobuf is released with aarch64 protoc since version '3.5.0', and we are planning to upgrade
+protobuf later, then we don't have to add the profile '-Paarch64' anymore.`})})]})}function p(n={}){const{wrapper:i}=n.components||{};return i?e.jsx(i,{...n,children:e.jsx(a,{...n})}):a(n)}function t(n,i){throw new Error("Expected component `"+n+"` to be defined: you likely forgot to import, pass, or provide it.")}export{l as _markdown,p as default,h as extractedReferences,r as frontmatter,d as structuredData,c as toc};
diff --git a/assets/bulk-data-generator-tool-DFhC9WZH.js b/assets/bulk-data-generator-tool-DFhC9WZH.js
new file mode 100644
index 00000000000..9441688821a
--- /dev/null
+++ b/assets/bulk-data-generator-tool-DFhC9WZH.js
@@ -0,0 +1,145 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let t=`## Usage
+
+\`\`\`bash
+usage: hbase org.apache.hadoop.hbase.util.bulkdatagenerator.BulkDataGeneratorTool <OPTIONS> [-D<property=value>]*
+ -d,--delete-if-exist         If it's set, the table will be deleted if already exist.
+ -h,--help                    Show help message for the tool
+ -mc,--mapper-count <arg>     The number of mapper containers to be launched.
+ -o,--table-options <arg>     Table options to be set while creating the table.
+ -r,--rows-per-mapper <arg>   The number of rows to be generated PER mapper.
+ -sc,--split-count <arg>      The number of regions/pre-splits to be created for the table.
+ -t,--table <arg>             The table name for which data need to be generated.
+\`\`\`
+
+Examples:
+
+\`\`\`bash
+hbase org.apache.hadoop.hbase.util.bulkdatagenerator.BulkDataGeneratorTool -t TEST_TABLE -mc 10 -r 100 -sc 10
+
+hbase org.apache.hadoop.hbase.util.bulkdatagenerator.BulkDataGeneratorTool -t TEST_TABLE -mc 10 -r 100 -sc 10 -d -o "BACKUP=false,NORMALIZATION_ENABLED=false"
+
+hbase org.apache.hadoop.hbase.util.bulkdatagenerator.BulkDataGeneratorTool -t TEST_TABLE -mc 10 -r 100 -sc 10 -Dmapreduce.map.memory.mb=8192
+\`\`\`
+
+## Overview
+
+### Table Schema
+
+Tool generates a HBase table with single column family, i.e. **cf** and 9 columns i.e.
+
+\`\`\`
+ORG_ID, TOOL_EVENT_ID, EVENT_ID, VEHICLE_ID, SPEED, LATITUDE, LONGITUDE, LOCATION, TIMESTAMP
+\`\`\`
+
+with row key as
+
+\`\`\`
+<TOOL_EVENT_ID>:<ORGANIZATION_ID>
+\`\`\`
+
+### Table Creation
+
+Tool creates a pre-splited HBase Table having "**split-count**" splits (i.e. **split-count** + 1 regions) with sequential 6 digit region boundary prefix.
+Example: If a table is generated with "**split-count**" as 10, it will have (10+1) regions with following start-end keys.
+
+\`\`\`
+(-000001, 000001-000002, 000002-000003, ...., 000009-000010, 0000010-)
+\`\`\`
+
+### Data Generation
+
+Tool creates and run a MR job to generate the HFiles, which are bulk loaded to table regions via \`org.apache.hadoop.hbase.tool.BulkLoadHFilesTool\`.
+The number of mappers is defined in input as "**mapper-count**". Each mapper generates "**records-per-mapper**" rows.
+
+\`org.apache.hadoop.hbase.util.bulkdatageneratorBulkDataGeneratorRecordReader\` ensures that each record generated by mapper is associated with index (added to the key) ranging from 1 to "**records-per-mapper**".
+
+The TOOL\\_EVENT\\_ID column for each row has a 6 digit prefix as
+
+\`\`\`
+(index) mod ("split-count" + 1)
+\`\`\`
+
+Example, if 10 records are to be generated by each mapper and "**split-count**" is 4, the TOOL\\_EVENT\\_IDs for each record will have a prefix as
+
+| Record Index | TOOL\\_EVENT\\_ID's first six characters |
+| ------------ | -------------------------------------- |
+| 1            | 000001                                 |
+| 2            | 000002                                 |
+| 3            | 000003                                 |
+| 4            | 000004                                 |
+| 5            | 000000                                 |
+| 6            | 000001                                 |
+| 7            | 000002                                 |
+| 8            | 000003                                 |
+| 9            | 000004                                 |
+| 10           | 000005                                 |
+
+Since TOOL\\_EVENT\\_ID is first attribute of row key and table region boundaries are also having start-end keys as 6 digit sequential prefixes, this ensures that each mapper generates (nearly) same number of rows for each region, making the data uniformly distributed.
+TOOL\\_EVENT\\_ID suffix and other columns of the row are populated with random data.
+
+Number of rows generated is
+
+\`\`\`
+rows-per-mapper * mapper-count
+\`\`\`
+
+Size of each rows is (approximately)
+
+\`\`\`
+850 B
+\`\`\`
+
+### Experiments
+
+These results are from a 11 node cluster having HBase and Hadoop service running within self-managed test environment
+
+| Data Size | Time to Generate Data (mins) |
+| --------- | ---------------------------- |
+| 100 GB    | 6 minutes                    |
+| 340 GB    | 13 minutes                   |
+| 3.5 TB    | 3 hours 10 minutes           |
+`,r={title:"Bulk Data Generator Tool",description:"This is a random data generator tool for HBase tables leveraging Hbase bulk load. It can create pre-splited HBase table and the generated data is uniformly distributed to all the regions of the table."},h=[],l={contents:[{heading:"bulk-data-generator-tool-usage",content:"Examples:"},{heading:"table-schema",content:"Tool generates a HBase table with single column family, i.e. cf and 9 columns i.e."},{heading:"table-schema",content:"with r [...]
+Example: If a table is generated with "split-count" as 10, it will have (10+1) regions with following start-end keys.`},{heading:"data-generation",content:`Tool creates and run a MR job to generate the HFiles, which are bulk loaded to table regions via org.apache.hadoop.hbase.tool.BulkLoadHFilesTool.
+The number of mappers is defined in input as "mapper-count". Each mapper generates "records-per-mapper" rows.`},{heading:"data-generation",content:'org.apache.hadoop.hbase.util.bulkdatageneratorBulkDataGeneratorRecordReader ensures that each record generated by mapper is associated with index (added to the key) ranging from 1 to "records-per-mapper".'},{heading:"data-generation",content:"The TOOL_EVENT_ID column for each row has a 6 digit prefix as"},{heading:"data-generation",content:'E [...]
+TOOL_EVENT_ID suffix and other columns of the row are populated with random data.`},{heading:"data-generation",content:"Number of rows generated is"},{heading:"data-generation",content:"Size of each rows is (approximately)"},{heading:"experiments",content:"These results are from a 11 node cluster having HBase and Hadoop service running within self-managed test environment"},{heading:"experiments",content:"Data Size"},{heading:"experiments",content:"Time to Generate Data (mins)"},{heading [...]
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -d,--delete-if-exist"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"         If"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" it's set, the table will be deleted if already exist."})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -h,--help                    Show help message for the tool"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -mc,--mapper-count <arg>     The number of mapper containers to be launched."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -o,--table-options <arg>     Table options to be set while creating the table."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -r,--rows-per-mapper <arg>   The number of rows to be generated PER mapper."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -sc,--split-count <arg>      The number of regions/pre-splits to be created for the table."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -t,--table <arg>             The table name for which data need to be generated."})})]})})}),`
+`,e.jsx(i.p,{children:"Examples:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" org.apache.hadoop.hbase.util.bulkdatagenerator.BulkDataGeneratorTool"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -t"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" TEST_TABLE"}),e.jsx(i.span [...]
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hbase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" org.apache.hadoop.hbase.util.bulkdatagenerator.BulkDataGeneratorTool"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -t"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" TEST_TABLE"}),e.jsx(i.span [...]
+`,e.jsx(i.h2,{id:"bulk-data-generator-tool-overview",children:"Overview"}),`
+`,e.jsx(i.h3,{id:"table-schema",children:"Table Schema"}),`
+`,e.jsxs(i.p,{children:["Tool generates a HBase table with single column family, i.e. ",e.jsx(i.strong,{children:"cf"})," and 9 columns i.e."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.p,{children:"with row key as"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.h3,{id:"table-creation",children:"Table Creation"}),`
+`,e.jsxs(i.p,{children:['Tool creates a pre-splited HBase Table having "',e.jsx(i.strong,{children:"split-count"}),'" splits (i.e. ',e.jsx(i.strong,{children:"split-count"}),` + 1 regions) with sequential 6 digit region boundary prefix.
+Example: If a table is generated with "`,e.jsx(i.strong,{children:"split-count"}),'" as 10, it will have (10+1) regions with following start-end keys.']}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.h3,{id:"data-generation",children:"Data Generation"}),`
+`,e.jsxs(i.p,{children:["Tool creates and run a MR job to generate the HFiles, which are bulk loaded to table regions via ",e.jsx(i.code,{children:"org.apache.hadoop.hbase.tool.BulkLoadHFilesTool"}),`.
+The number of mappers is defined in input as "`,e.jsx(i.strong,{children:"mapper-count"}),'". Each mapper generates "',e.jsx(i.strong,{children:"records-per-mapper"}),'" rows.']}),`
+`,e.jsxs(i.p,{children:[e.jsx(i.code,{children:"org.apache.hadoop.hbase.util.bulkdatageneratorBulkDataGeneratorRecordReader"}),' ensures that each record generated by mapper is associated with index (added to the key) ranging from 1 to "',e.jsx(i.strong,{children:"records-per-mapper"}),'".']}),`
+`,e.jsx(i.p,{children:"The TOOL_EVENT_ID column for each row has a 6 digit prefix as"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.p,{children:['Example, if 10 records are to be generated by each mapper and "',e.jsx(i.strong,{children:"split-count"}),'" is 4, the TOOL_EVENT_IDs for each record will have a prefix as']}),`
+`,e.jsxs(i.table,{children:[e.jsx(i.thead,{children:e.jsxs(i.tr,{children:[e.jsx(i.th,{children:"Record Index"}),e.jsx(i.th,{children:"TOOL_EVENT_ID's first six characters"})]})}),e.jsxs(i.tbody,{children:[e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"1"}),e.jsx(i.td,{children:"000001"})]}),e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"2"}),e.jsx(i.td,{children:"000002"})]}),e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"3"}),e.jsx(i.td,{children:"000003"})]}),e.jsxs(i.tr,{children:[e.jsx(i. [...]
+`,e.jsx(i.p,{children:`Since TOOL_EVENT_ID is first attribute of row key and table region boundaries are also having start-end keys as 6 digit sequential prefixes, this ensures that each mapper generates (nearly) same number of rows for each region, making the data uniformly distributed.
+TOOL_EVENT_ID suffix and other columns of the row are populated with random data.`}),`
+`,e.jsx(i.p,{children:"Number of rows generated is"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.p,{children:"Size of each rows is (approximately)"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.h3,{id:"experiments",children:"Experiments"}),`
+`,e.jsx(i.p,{children:"These results are from a 11 node cluster having HBase and Hadoop service running within self-managed test environment"}),`
+`,e.jsxs(i.table,{children:[e.jsx(i.thead,{children:e.jsxs(i.tr,{children:[e.jsx(i.th,{children:"Data Size"}),e.jsx(i.th,{children:"Time to Generate Data (mins)"})]})}),e.jsxs(i.tbody,{children:[e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"100 GB"}),e.jsx(i.td,{children:"6 minutes"})]}),e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"340 GB"}),e.jsx(i.td,{children:"13 minutes"})]}),e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"3.5 TB"}),e.jsx(i.td,{children:"3 hours 10 minutes"})]})]})]})]}) [...]
diff --git a/assets/bulk-loading-Jl7zj15p.js b/assets/bulk-loading-Jl7zj15p.js
new file mode 100644
index 00000000000..1f7c6a95f28
--- /dev/null
+++ b/assets/bulk-loading-Jl7zj15p.js
@@ -0,0 +1,44 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let s="## Overview\n\nHBase includes several methods of loading data into tables. The most straightforward method is to either use the `TableOutputFormat` class from a MapReduce job, or use the normal client APIs; however, these are not always the most efficient methods.\n\nThe bulk load feature uses a MapReduce job to output table data in HBase's internal data format, and then directly load the generated StoreFiles into a running cluster. [...]
+client configuration only once, so if source cluster FS client configuration files are updated,
+every peer(s) cluster RS must be restarted to reload the configuration.`}],headings:[{id:"bulk-loading-overview",content:"Overview"},{id:"bulk-load-architecture",content:"Bulk Load Architecture"},{id:"preparing-data-via-a-mapreduce-job",content:"Preparing data via a MapReduce job"},{id:"completing-the-data-load",content:"Completing the data load"},{id:"bulk-loading-see-also",content:"See Also"},{id:"advanced-usage",content:"Advanced Usage"},{id:"adopting-stray-data",content:"'Adopting' S [...]
+`,e.jsxs(t.p,{children:["HBase includes several methods of loading data into tables. The most straightforward method is to either use the ",e.jsx(t.code,{children:"TableOutputFormat"})," class from a MapReduce job, or use the normal client APIs; however, these are not always the most efficient methods."]}),`
+`,e.jsx(t.p,{children:"The bulk load feature uses a MapReduce job to output table data in HBase's internal data format, and then directly load the generated StoreFiles into a running cluster. Using bulk load will use less CPU and network resources than loading via the HBase API."}),`
+`,e.jsx(t.h2,{id:"bulk-load-architecture",children:"Bulk Load Architecture"}),`
+`,e.jsx(t.p,{children:"The HBase bulk load process consists of two main steps."}),`
+`,e.jsx(t.h3,{id:"preparing-data-via-a-mapreduce-job",children:"Preparing data via a MapReduce job"}),`
+`,e.jsxs(t.p,{children:["The first step of a bulk load is to generate HBase data files (StoreFiles) from a MapReduce job using ",e.jsx(t.code,{children:"HFileOutputFormat2"}),". This output format writes out data in HBase's internal storage format so that they can be later loaded efficiently into the cluster."]}),`
+`,e.jsxs(t.p,{children:["In order to function efficiently, ",e.jsx(t.code,{children:"HFileOutputFormat2"})," must be configured such that each output HFile fits within a single region. In order to do this, jobs whose output will be bulk loaded into HBase use Hadoop's ",e.jsx(t.code,{children:"TotalOrderPartitioner"})," class to partition the map output into disjoint ranges of the key space, corresponding to the key ranges of the regions in the table."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"HFileOutputFormat2"})," includes a convenience function, ",e.jsx(t.code,{children:"configureIncrementalLoad()"}),", which automatically sets up a ",e.jsx(t.code,{children:"TotalOrderPartitioner"})," based on the current region boundaries of a table."]}),`
+`,e.jsx(t.h3,{id:"completing-the-data-load",children:"Completing the data load"}),`
+`,e.jsxs(t.p,{children:["After a data import has been prepared, either by using the ",e.jsx(t.code,{children:"importtsv"})," tool with the โ€œimporttsv.bulk.outputโ€ option or by some other MapReduce job using the ",e.jsx(t.code,{children:"HFileOutputFormat"}),", the ",e.jsx(t.code,{children:"completebulkload"})," tool is used to import the data into the running cluster. This command line tool iterates through the prepared data files, and for each one determines the region the file belongs  [...]
+`,e.jsxs(t.p,{children:["If the region boundaries have changed during the course of bulk load preparation, or between the preparation and completion steps, the ",e.jsx(t.code,{children:"completebulkload"})," utility will automatically split the data files into pieces corresponding to the new boundaries. This process is not optimally efficient, so users should take care to minimize the delay between preparing a bulk load and importing it into the cluster, especially if other clients are s [...]
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.p,{children:["The ",e.jsx(t.code,{children:"-c config-file"})," option can be used to specify a file containing the appropriate hbase parameters (e.g., hbase-site.xml) if not supplied already on the CLASSPATH (In addition, the CLASSPATH must contain the directory that has the zookeeper configuration file if zookeeper is NOT managed by HBase)."]}),`
+`,e.jsx(t.h2,{id:"bulk-loading-see-also",children:"See Also"}),`
+`,e.jsxs(t.p,{children:["For more information about the referenced utilities, see ",e.jsx(t.a,{href:"/docs/operational-management/tools#importtsv",children:"ImportTsv"})," and ",e.jsx(t.a,{href:"/docs/operational-management/tools#completebulkload",children:"CompleteBulkLoad"}),"."]}),`
+`,e.jsxs(t.p,{children:["See ",e.jsx(t.a,{href:"http://blog.cloudera.com/blog/2013/09/how-to-use-hbase-bulk-loading-and-why/",children:"How-to: Use HBase Bulk Loading, and Why"})," for an old blog post on loading."]}),`
+`,e.jsx(t.h2,{id:"advanced-usage",children:"Advanced Usage"}),`
+`,e.jsxs(t.p,{children:["Although the ",e.jsx(t.code,{children:"importtsv"})," tool is useful in many cases, advanced users may want to generate data programmatically, or import data from other formats. To get started doing so, dig into ",e.jsx(t.code,{children:"ImportTsv.java"})," and check the JavaDoc for HFileOutputFormat."]}),`
+`,e.jsxs(t.p,{children:["The import step of the bulk load can also be done programmatically. See the ",e.jsx(t.code,{children:"LoadIncrementalHFiles"})," class for more information."]}),`
+`,e.jsx(t.h3,{id:"adopting-stray-data",children:"'Adopting' Stray Data"}),`
+`,e.jsxs(t.p,{children:["Should an HBase cluster lose account of regions or files during an outage or error, you can use the ",e.jsx(t.code,{children:"completebulkload"})," tool to add back the dropped data. HBase operator tooling such as ",e.jsx(t.a,{href:"https://github.com/apache/hbase-operator-tools/tree/master/hbase-hbck2",children:"HBCK2"})," or the reporting added to the Master's UI under the ",e.jsx(t.code,{children:"HBCK Report"})," (Since HBase 2.0.6/2.1.6/2.2.1) can identify s [...]
+`,e.jsxs(t.p,{children:["Before you begin the 'adoption', ensure the ",e.jsx(t.code,{children:"hbase:meta"})," table is in a healthy state. Run the ",e.jsx(t.code,{children:"CatalogJanitor"})," by executing the ",e.jsx(t.code,{children:"catalogjanitor_run"})," command on the HBase shell. When finished, check the ",e.jsx(t.code,{children:"HBCK Report"})," page on the Master UI. Work on fixing any inconsistencies, holes, or overlaps found before proceeding. The ",e.jsx(t.code,{children:"hb [...]
+`,e.jsxs(t.p,{children:["The ",e.jsx(t.code,{children:"completebulkload"})," tool takes a directory and a ",e.jsx(t.code,{children:"tablename"}),". The directory has subdirectories named for column families of the targeted ",e.jsx(t.code,{children:"tablename"}),". In these subdirectories are ",e.jsx(t.code,{children:"hfiles"})," to load. Given this structure, you can pass errant region directories (and the table name to which the region directory belongs) and the tool will bring the data [...]
+`,e.jsxs(t.p,{children:["For example, presuming a directory at the top level in HDFS named ",e.jsx(t.code,{children:"eb3352fb5c9c9a05feeb2caba101e1cc"})," has data we need to re-add to the HBase ",e.jsx(t.code,{children:"TestTable"}),":"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.p,{children:["After it successfully completes, any files that were in ",e.jsx(t.code,{children:"eb3352fb5c9c9a05feeb2caba101e1cc"})," have been moved under hbase and the ",e.jsx(t.code,{children:"eb3352fb5c9c9a05feeb2caba101e1cc"})," directory can be deleted (Check content before and after by running ",e.jsx(t.code,{children:"ls -r"})," on the HDFS directory)."]}),`
+`,e.jsx(t.h2,{id:"bulk-loading-replication",children:"Bulk Loading Replication"}),`
+`,e.jsxs(t.p,{children:["HBASE-13153 adds replication support for bulk loaded HFiles, available since HBase 1.3/2.0. This feature is enabled by setting ",e.jsx(t.code,{children:"hbase.replication.bulkload.enabled"})," to ",e.jsx(t.code,{children:"true"})," (default is ",e.jsx(t.code,{children:"false"}),"). You also need to copy the source cluster configuration files to the destination cluster."]}),`
+`,e.jsx(t.p,{children:"Additional configurations are required too:"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"hbase.replication.source.fs.conf.provider"}),e.jsx(t.br,{}),`
+`,"This defines the class which loads the source cluster file system client configuration in the destination cluster. This should be configured for all the RS in the destination cluster. Default is ",e.jsx(t.code,{children:"org.apache.hadoop.hbase.replication.regionserver.DefaultSourceFSConfigurationProvider"}),"."]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"hbase.replication.conf.dir"}),e.jsx(t.br,{}),`
+`,"This represents the base directory where the file system client configurations of the source cluster are copied to the destination cluster. This should be configured for all the RS in the destination cluster. Default is ",e.jsx(t.code,{children:"$HBASE_CONF_DIR"}),"."]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"hbase.replication.cluster.id"}),e.jsx(t.br,{}),`
+`,"This configuration is required in the cluster where replication for bulk loaded data is enabled. A source cluster is uniquely identified by the destination cluster using this id. This should be configured for all the RS in the source cluster configuration file for all the RS."]}),`
+`]}),`
+`,e.jsxs(t.p,{children:["For example: If source cluster FS client configurations are copied to the destination cluster under directory ",e.jsx(t.code,{children:"/home/user/dc1/"}),", then ",e.jsx(t.code,{children:"hbase.replication.cluster.id"})," should be configured as ",e.jsx(t.code,{children:"dc1"})," and ",e.jsx(t.code,{children:"hbase.replication.conf.dir"})," as ",e.jsx(t.code,{children:"/home/user"}),"."]}),`
+`,e.jsx(a,{type:"info",children:e.jsxs(t.p,{children:[e.jsx(t.code,{children:"DefaultSourceFSConfigurationProvider"})," supports only ",e.jsx(t.code,{children:"xml"}),` type files. It loads source cluster FS
+client configuration only once, so if source cluster FS client configuration files are updated,
+every peer(s) cluster RS must be restarted to reload the configuration.`]})})]})}function u(o={}){const{wrapper:t}=o.components||{};return t?e.jsx(t,{...o,children:e.jsx(i,{...o})}):i(o)}function n(o,t){throw new Error("Expected component `"+o+"` to be defined: you likely forgot to import, pass, or provide it.")}export{s as _markdown,u as default,d as extractedReferences,l as frontmatter,c as structuredData,h as toc};
diff --git a/assets/button-CS2SuAfe.js b/assets/button-CS2SuAfe.js
new file mode 100644
index 00000000000..366c774c974
--- /dev/null
+++ b/assets/button-CS2SuAfe.js
@@ -0,0 +1 @@
+import{r as s,j as d}from"./chunk-EPOLDU6W-B5LwAila.js";import{c as m}from"./index-lnR2ABT4.js";import{c as v}from"./link-CDX6ZyVQ.js";function p(e,n){if(typeof e=="function")return e(n);e!=null&&(e.current=n)}function b(...e){return n=>{let t=!1;const o=e.map(r=>{const i=p(r,n);return!t&&typeof i=="function"&&(t=!0),i});if(t)return()=>{for(let r=0;r<o.length;r++){const i=o[r];typeof i=="function"?i():p(e[r],null)}}}}function y(e){const n=x(e),t=s.forwardRef((o,r)=>{const{children:i,...l [...]
diff --git a/assets/bytebuff-allocator-stats-B7DU8asJ.png b/assets/bytebuff-allocator-stats-B7DU8asJ.png
new file mode 100644
index 00000000000..b13362dbf49
Binary files /dev/null and b/assets/bytebuff-allocator-stats-B7DU8asJ.png differ
diff --git a/assets/bytebuff-allocator-stats-C6KiUNbS.js b/assets/bytebuff-allocator-stats-C6KiUNbS.js
new file mode 100644
index 00000000000..ee9fd20f52a
--- /dev/null
+++ b/assets/bytebuff-allocator-stats-C6KiUNbS.js
@@ -0,0 +1 @@
+const s="/assets/offheap-overview-DTGpchw3.png",a="/assets/bytebuff-allocator-stats-B7DU8asJ.png";export{s as _,a};
diff --git a/assets/case-studies-BPoDcA5A.js b/assets/case-studies-BPoDcA5A.js
new file mode 100644
index 00000000000..09e75de5071
--- /dev/null
+++ b/assets/case-studies-BPoDcA5A.js
@@ -0,0 +1,242 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let a=`## Overview
+
+This chapter will describe a variety of performance and troubleshooting case studies that can provide a useful blueprint on diagnosing Apache HBase cluster issues.
+
+For more information on Performance and Troubleshooting, see [Apache HBase Performance Tuning](/docs/performance) and [Troubleshooting and Debugging Apache HBase](/docs/troubleshooting).
+
+## Schema Design
+
+See the schema design case studies here: [Schema Design Case Studies](/docs/regionserver-sizing#schema-design-case-studies)
+
+## Performance/Troubleshooting
+
+### Case Study #1 (Performance Issue On A Single Node)
+
+#### Scenario
+
+Following a scheduled reboot, one data node began exhibiting unusual behavior.
+Routine MapReduce jobs run against HBase tables which regularly completed in five or six minutes began taking 30 or 40 minutes to finish.
+These jobs were consistently found to be waiting on map and reduce tasks assigned to the troubled data node (e.g., the slow map tasks all had the same Input Split). The situation came to a head during a distributed copy, when the copy was severely prolonged by the lagging node.
+
+#### Hardware
+
+Datanodes:
+
+* Two 12-core processors
+* Six Enterprise SATA disks
+* 24GB of RAM
+* Two bonded gigabit NICs
+
+Network:
+
+* 10 Gigabit top-of-rack switches
+* 20 Gigabit bonded interconnects between racks.
+
+#### Hypotheses
+
+**HBase "Hot Spot" Region**\\
+We hypothesized that we were experiencing a familiar point of pain: a "hot spot" region in an HBase table, where uneven key-space distribution can funnel a huge number of requests to a single HBase region, bombarding the RegionServer process and cause slow response time.
+Examination of the HBase Master status page showed that the number of HBase requests to the troubled node was almost zero.
+Further, examination of the HBase logs showed that there were no region splits, compactions, or other region transitions in progress.
+This effectively ruled out a "hot spot" as the root cause of the observed slowness.
+
+**HBase Region With Non-Local Data**\\
+Our next hypothesis was that one of the MapReduce tasks was requesting data from HBase that was not local to the DataNode, thus forcing HDFS to request data blocks from other servers over the network.
+Examination of the DataNode logs showed that there were very few blocks being requested over the network, indicating that the HBase region was correctly assigned, and that the majority of the necessary data was located on the node.
+This ruled out the possibility of non-local data causing a slowdown.
+
+**Excessive I/O Wait Due To Swapping Or An Over-Worked Or Failing Hard Disk**\\
+After concluding that the Hadoop and HBase were not likely to be the culprits, we moved on to troubleshooting the DataNode's hardware.
+Java, by design, will periodically scan its entire memory space to do garbage collection.
+If system memory is heavily overcommitted, the Linux kernel may enter a vicious cycle, using up all of its resources swapping Java heap back and forth from disk to RAM as Java tries to run garbage collection.
+Further, a failing hard disk will often retry reads and/or writes many times before giving up and returning an error.
+This can manifest as high iowait, as running processes wait for reads and writes to complete.
+Finally, a disk nearing the upper edge of its performance envelope will begin to cause iowait as it informs the kernel that it cannot accept any more data, and the kernel queues incoming data into the dirty write pool in memory.
+However, using \`vmstat(1)\` and \`free(1)\`, we could see that no swap was being used, and the amount of disk IO was only a few kilobytes per second.
+
+**Slowness Due To High Processor Usage**\\
+Next, we checked to see whether the system was performing slowly simply due to very high computational load. \`top(1)\` showed that the system load was higher than normal, but \`vmstat(1)\` and \`mpstat(1)\` showed that the amount of processor being used for actual computation was low.
+
+**Network Saturation (The Winner)**\\
+Since neither the disks nor the processors were being utilized heavily, we moved on to the performance of the network interfaces.
+The DataNode had two gigabit ethernet adapters, bonded to form an active-standby interface. \`ifconfig(8)\` showed some unusual anomalies, namely interface errors, overruns, framing errors.
+While not unheard of, these kinds of errors are exceedingly rare on modern hardware which is operating as it should:
+
+\`\`\`bash
+$ /sbin/ifconfig bond0
+bond0  Link encap:Ethernet  HWaddr 00:00:00:00:00:00
+inet addr:10.x.x.x  Bcast:10.x.x.255  Mask:255.255.255.0
+UP BROADCAST RUNNING MASTER MULTICAST  MTU:1500  Metric:1
+RX packets:2990700159 errors:12 dropped:0 overruns:1 frame:6          <--- Look Here! Errors!
+TX packets:3443518196 errors:0 dropped:0 overruns:0 carrier:0
+collisions:0 txqueuelen:0
+RX bytes:2416328868676 (2.4 TB)  TX bytes:3464991094001 (3.4 TB)
+\`\`\`
+
+These errors immediately lead us to suspect that one or more of the ethernet interfaces might have negotiated the wrong line speed.
+This was confirmed both by running an ICMP ping from an external host and observing round-trip-time in excess of 700ms, and by running \`ethtool(8)\` on the members of the bond interface and discovering that the active interface was operating at 100Mbs/, full duplex.
+
+\`\`\`bash
+$ sudo ethtool eth0
+Settings for eth0:
+Supported ports: [ TP ]
+Supported link modes:   10baseT/Half 10baseT/Full
+                       100baseT/Half 100baseT/Full
+                       1000baseT/Full
+Supports auto-negotiation: Yes
+Advertised link modes:  10baseT/Half 10baseT/Full
+                       100baseT/Half 100baseT/Full
+                       1000baseT/Full
+Advertised pause frame use: No
+Advertised auto-negotiation: Yes
+Link partner advertised link modes:  Not reported
+Link partner advertised pause frame use: No
+Link partner advertised auto-negotiation: No
+Speed: 100Mb/s                                     <--- Look Here!  Should say 1000Mb/s!
+Duplex: Full
+Port: Twisted Pair
+PHYAD: 1
+Transceiver: internal
+Auto-negotiation: on
+MDI-X: Unknown
+Supports Wake-on: umbg
+Wake-on: g
+Current message level: 0x00000003 (3)
+Link detected: yes
+\`\`\`
+
+In normal operation, the ICMP ping round trip time should be around 20ms, and the interface speed and duplex should read, "1000MB/s", and, "Full", respectively.
+
+#### Resolution
+
+After determining that the active ethernet adapter was at the incorrect speed, we used the \`ifenslave(8)\` command to make the standby interface the active interface, which yielded an immediate improvement in MapReduce performance, and a 10 times improvement in network throughput:
+
+On the next trip to the datacenter, we determined that the line speed issue was ultimately caused by a bad network cable, which was replaced.
+
+### Case Study #2 (Performance Research 2012)
+
+Investigation results of a self-described "we're not sure what's wrong, but it seems slow" problem. [http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html](http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html)
+
+### Case Study #3 (Performance Research 2010)
+
+Investigation results of general cluster performance from 2010.
+Although this research is on an older version of the codebase, this writeup is still very useful in terms of approach. [https://web.archive.org/web/20180503124332/http://hstack.org/hbase-performance-testing/](https://web.archive.org/web/20180503124332/http://hstack.org/hbase-performance-testing/)
+
+### Case Study #4 (max.transfer.threads Config)
+
+Case study of configuring \`max.transfer.threads\` (previously known as \`xcievers\`) and diagnosing errors from misconfigurations. [http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html](http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html)
+
+See also [\`dfs.datanode.max.transfer.threads\`](/docs/configuration/basic-prerequisites#dfsdatanodemaxtransferthreads).
+`,r={title:"Apache HBase Case Studies",description:"Performance and troubleshooting case studies for diagnosing Apache HBase cluster issues."},h=[{href:"/docs/performance"},{href:"/docs/troubleshooting"},{href:"/docs/regionserver-sizing#schema-design-case-studies"},{href:"http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html"},{href:"https://web.archive.org/web/20180503124332/http://hstack.org/hbase-performance-testing/"},{href:"http://www.larsgeorge.com/2012/03/ha [...]
+Routine MapReduce jobs run against HBase tables which regularly completed in five or six minutes began taking 30 or 40 minutes to finish.
+These jobs were consistently found to be waiting on map and reduce tasks assigned to the troubled data node (e.g., the slow map tasks all had the same Input Split). The situation came to a head during a distributed copy, when the copy was severely prolonged by the lagging node.`},{heading:"hardware",content:"Datanodes:"},{heading:"hardware",content:"Two 12-core processors"},{heading:"hardware",content:"Six Enterprise SATA disks"},{heading:"hardware",content:"24GB of RAM"},{heading:"hardw [...]
+Examination of the HBase Master status page showed that the number of HBase requests to the troubled node was almost zero.
+Further, examination of the HBase logs showed that there were no region splits, compactions, or other region transitions in progress.
+This effectively ruled out a "hot spot" as the root cause of the observed slowness.`},{heading:"hypotheses",content:`HBase Region With Non-Local DataOur next hypothesis was that one of the MapReduce tasks was requesting data from HBase that was not local to the DataNode, thus forcing HDFS to request data blocks from other servers over the network.
+Examination of the DataNode logs showed that there were very few blocks being requested over the network, indicating that the HBase region was correctly assigned, and that the majority of the necessary data was located on the node.
+This ruled out the possibility of non-local data causing a slowdown.`},{heading:"hypotheses",content:`Excessive I/O Wait Due To Swapping Or An Over-Worked Or Failing Hard DiskAfter concluding that the Hadoop and HBase were not likely to be the culprits, we moved on to troubleshooting the DataNode's hardware.
+Java, by design, will periodically scan its entire memory space to do garbage collection.
+If system memory is heavily overcommitted, the Linux kernel may enter a vicious cycle, using up all of its resources swapping Java heap back and forth from disk to RAM as Java tries to run garbage collection.
+Further, a failing hard disk will often retry reads and/or writes many times before giving up and returning an error.
+This can manifest as high iowait, as running processes wait for reads and writes to complete.
+Finally, a disk nearing the upper edge of its performance envelope will begin to cause iowait as it informs the kernel that it cannot accept any more data, and the kernel queues incoming data into the dirty write pool in memory.
+However, using vmstat(1) and free(1), we could see that no swap was being used, and the amount of disk IO was only a few kilobytes per second.`},{heading:"hypotheses",content:"Slowness Due To High Processor UsageNext, we checked to see whether the system was performing slowly simply due to very high computational load. top(1) showed that the system load was higher than normal, but vmstat(1) and mpstat(1) showed that the amount of processor being used for actual computation was low."},{he [...]
+The DataNode had two gigabit ethernet adapters, bonded to form an active-standby interface. ifconfig(8) showed some unusual anomalies, namely interface errors, overruns, framing errors.
+While not unheard of, these kinds of errors are exceedingly rare on modern hardware which is operating as it should:`},{heading:"hypotheses",content:`These errors immediately lead us to suspect that one or more of the ethernet interfaces might have negotiated the wrong line speed.
+This was confirmed both by running an ICMP ping from an external host and observing round-trip-time in excess of 700ms, and by running ethtool(8) on the members of the bond interface and discovering that the active interface was operating at 100Mbs/, full duplex.`},{heading:"hypotheses",content:'In normal operation, the ICMP ping round trip time should be around 20ms, and the interface speed and duplex should read, "1000MB/s", and, "Full", respectively.'},{heading:"resolution",content:"A [...]
+Although this research is on an older version of the codebase, this writeup is still very useful in terms of approach. https://web.archive.org/web/20180503124332/http://hstack.org/hbase-performance-testing/`},{heading:"case-study-4-maxtransferthreads-config",content:"Case study of configuring max.transfer.threads (previously known as xcievers) and diagnosing errors from misconfigurations. http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html"},{heading:"case-study-4-maxtransfe [...]
+`,e.jsx(s.p,{children:"This chapter will describe a variety of performance and troubleshooting case studies that can provide a useful blueprint on diagnosing Apache HBase cluster issues."}),`
+`,e.jsxs(s.p,{children:["For more information on Performance and Troubleshooting, see ",e.jsx(s.a,{href:"/docs/performance",children:"Apache HBase Performance Tuning"})," and ",e.jsx(s.a,{href:"/docs/troubleshooting",children:"Troubleshooting and Debugging Apache HBase"}),"."]}),`
+`,e.jsx(s.h2,{id:"case-studies-schema-design",children:"Schema Design"}),`
+`,e.jsxs(s.p,{children:["See the schema design case studies here: ",e.jsx(s.a,{href:"/docs/regionserver-sizing#schema-design-case-studies",children:"Schema Design Case Studies"})]}),`
+`,e.jsx(s.h2,{id:"performancetroubleshooting",children:"Performance/Troubleshooting"}),`
+`,e.jsx(s.h3,{id:"case-study-1-performance-issue-on-a-single-node",children:"Case Study #1 (Performance Issue On A Single Node)"}),`
+`,e.jsx(s.h4,{id:"scenario",children:"Scenario"}),`
+`,e.jsx(s.p,{children:`Following a scheduled reboot, one data node began exhibiting unusual behavior.
+Routine MapReduce jobs run against HBase tables which regularly completed in five or six minutes began taking 30 or 40 minutes to finish.
+These jobs were consistently found to be waiting on map and reduce tasks assigned to the troubled data node (e.g., the slow map tasks all had the same Input Split). The situation came to a head during a distributed copy, when the copy was severely prolonged by the lagging node.`}),`
+`,e.jsx(s.h4,{id:"hardware",children:"Hardware"}),`
+`,e.jsx(s.p,{children:"Datanodes:"}),`
+`,e.jsxs(s.ul,{children:[`
+`,e.jsx(s.li,{children:"Two 12-core processors"}),`
+`,e.jsx(s.li,{children:"Six Enterprise SATA disks"}),`
+`,e.jsx(s.li,{children:"24GB of RAM"}),`
+`,e.jsx(s.li,{children:"Two bonded gigabit NICs"}),`
+`]}),`
+`,e.jsx(s.p,{children:"Network:"}),`
+`,e.jsxs(s.ul,{children:[`
+`,e.jsx(s.li,{children:"10 Gigabit top-of-rack switches"}),`
+`,e.jsx(s.li,{children:"20 Gigabit bonded interconnects between racks."}),`
+`]}),`
+`,e.jsx(s.h4,{id:"hypotheses",children:"Hypotheses"}),`
+`,e.jsxs(s.p,{children:[e.jsx(s.strong,{children:'HBase "Hot Spot" Region'}),e.jsx(s.br,{}),`
+`,`We hypothesized that we were experiencing a familiar point of pain: a "hot spot" region in an HBase table, where uneven key-space distribution can funnel a huge number of requests to a single HBase region, bombarding the RegionServer process and cause slow response time.
+Examination of the HBase Master status page showed that the number of HBase requests to the troubled node was almost zero.
+Further, examination of the HBase logs showed that there were no region splits, compactions, or other region transitions in progress.
+This effectively ruled out a "hot spot" as the root cause of the observed slowness.`]}),`
+`,e.jsxs(s.p,{children:[e.jsx(s.strong,{children:"HBase Region With Non-Local Data"}),e.jsx(s.br,{}),`
+`,`Our next hypothesis was that one of the MapReduce tasks was requesting data from HBase that was not local to the DataNode, thus forcing HDFS to request data blocks from other servers over the network.
+Examination of the DataNode logs showed that there were very few blocks being requested over the network, indicating that the HBase region was correctly assigned, and that the majority of the necessary data was located on the node.
+This ruled out the possibility of non-local data causing a slowdown.`]}),`
+`,e.jsxs(s.p,{children:[e.jsx(s.strong,{children:"Excessive I/O Wait Due To Swapping Or An Over-Worked Or Failing Hard Disk"}),e.jsx(s.br,{}),`
+`,`After concluding that the Hadoop and HBase were not likely to be the culprits, we moved on to troubleshooting the DataNode's hardware.
+Java, by design, will periodically scan its entire memory space to do garbage collection.
+If system memory is heavily overcommitted, the Linux kernel may enter a vicious cycle, using up all of its resources swapping Java heap back and forth from disk to RAM as Java tries to run garbage collection.
+Further, a failing hard disk will often retry reads and/or writes many times before giving up and returning an error.
+This can manifest as high iowait, as running processes wait for reads and writes to complete.
+Finally, a disk nearing the upper edge of its performance envelope will begin to cause iowait as it informs the kernel that it cannot accept any more data, and the kernel queues incoming data into the dirty write pool in memory.
+However, using `,e.jsx(s.code,{children:"vmstat(1)"})," and ",e.jsx(s.code,{children:"free(1)"}),", we could see that no swap was being used, and the amount of disk IO was only a few kilobytes per second."]}),`
+`,e.jsxs(s.p,{children:[e.jsx(s.strong,{children:"Slowness Due To High Processor Usage"}),e.jsx(s.br,{}),`
+`,"Next, we checked to see whether the system was performing slowly simply due to very high computational load. ",e.jsx(s.code,{children:"top(1)"})," showed that the system load was higher than normal, but ",e.jsx(s.code,{children:"vmstat(1)"})," and ",e.jsx(s.code,{children:"mpstat(1)"})," showed that the amount of processor being used for actual computation was low."]}),`
+`,e.jsxs(s.p,{children:[e.jsx(s.strong,{children:"Network Saturation (The Winner)"}),e.jsx(s.br,{}),`
+`,`Since neither the disks nor the processors were being utilized heavily, we moved on to the performance of the network interfaces.
+The DataNode had two gigabit ethernet adapters, bonded to form an active-standby interface. `,e.jsx(s.code,{children:"ifconfig(8)"}),` showed some unusual anomalies, namely interface errors, overruns, framing errors.
+While not unheard of, these kinds of errors are exceedingly rare on modern hardware which is operating as it should:`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"bond0"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  Link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" encap:Ethernet"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  HWaddr"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9E [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"inet"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" addr:10.x.x.x"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  Bcast:10.x.x.255"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  Mask:255.255.255.0"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"UP"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" BROADCAST"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" RUNNING"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" MASTER"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}, [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"RX"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" packets:2990700159"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" errors:12"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" dropped:0"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dar [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"TX"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" packets:3443518196"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" errors:0"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" dropped:0"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"collisions:0"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" txqueuelen:0"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"RX"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" bytes:2416328868676"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (2.4 "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"TB"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8 [...]
+`,e.jsxs(s.p,{children:[`These errors immediately lead us to suspect that one or more of the ethernet interfaces might have negotiated the wrong line speed.
+This was confirmed both by running an ICMP ping from an external host and observing round-trip-time in excess of 700ms, and by running `,e.jsx(s.code,{children:"ethtool(8)"})," on the members of the bond interface and discovering that the active interface was operating at 100Mbs/, full duplex."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(s.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Settings"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" for"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" eth0:"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Supported"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ports:"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" [ "}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"TP"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},childr [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Supported"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" modes:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"   10baseT/Half"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"# [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                       100baseT/Half"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 100baseT/Full"})]}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                       1000baseT/Full"})}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Supports"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" auto-negotiation:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Yes"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Advertised"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" modes:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  10baseT/Half"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"# [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                       100baseT/Half"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 100baseT/Full"})]}),`
+`,e.jsx(s.span,{className:"line",children:e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                       1000baseT/Full"})}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Advertised"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" pause"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" frame"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" use:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}, [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Advertised"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" auto-negotiation:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Yes"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" partner"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" advertised"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"} [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" partner"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" advertised"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" pause"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF" [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" partner"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" advertised"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" auto-negotiation:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dar [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Speed:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 100Mb/s"}),e.jsx(s.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"                                     <"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"---"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62 [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Duplex:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Full"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Port:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Twisted"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Pair"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"PHYAD:"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 1"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Transceiver:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" internal"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Auto-negotiation:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" on"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"MDI-X:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Unknown"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Supports"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" Wake-on:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" umbg"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Wake-on:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" g"})]}),`
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Current"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" message"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" level:"}),e.jsx(s.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 0x00000003"}),e.jsx(s.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E [...]
+`,e.jsxs(s.span,{className:"line",children:[e.jsx(s.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Link"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" detected:"}),e.jsx(s.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" yes"})]})]})})}),`
+`,e.jsx(s.p,{children:'In normal operation, the ICMP ping round trip time should be around 20ms, and the interface speed and duplex should read, "1000MB/s", and, "Full", respectively.'}),`
+`,e.jsx(s.h4,{id:"resolution",children:"Resolution"}),`
+`,e.jsxs(s.p,{children:["After determining that the active ethernet adapter was at the incorrect speed, we used the ",e.jsx(s.code,{children:"ifenslave(8)"})," command to make the standby interface the active interface, which yielded an immediate improvement in MapReduce performance, and a 10 times improvement in network throughput:"]}),`
+`,e.jsx(s.p,{children:"On the next trip to the datacenter, we determined that the line speed issue was ultimately caused by a bad network cable, which was replaced."}),`
+`,e.jsx(s.h3,{id:"case-study-2-performance-research-2012",children:"Case Study #2 (Performance Research 2012)"}),`
+`,e.jsxs(s.p,{children:[`Investigation results of a self-described "we're not sure what's wrong, but it seems slow" problem. `,e.jsx(s.a,{href:"http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html",children:"http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html"})]}),`
+`,e.jsx(s.h3,{id:"case-study-3-performance-research-2010",children:"Case Study #3 (Performance Research 2010)"}),`
+`,e.jsxs(s.p,{children:[`Investigation results of general cluster performance from 2010.
+Although this research is on an older version of the codebase, this writeup is still very useful in terms of approach. `,e.jsx(s.a,{href:"https://web.archive.org/web/20180503124332/http://hstack.org/hbase-performance-testing/",children:"https://web.archive.org/web/20180503124332/http://hstack.org/hbase-performance-testing/"})]}),`
+`,e.jsx(s.h3,{id:"case-study-4-maxtransferthreads-config",children:"Case Study #4 (max.transfer.threads Config)"}),`
+`,e.jsxs(s.p,{children:["Case study of configuring ",e.jsx(s.code,{children:"max.transfer.threads"})," (previously known as ",e.jsx(s.code,{children:"xcievers"}),") and diagnosing errors from misconfigurations. ",e.jsx(s.a,{href:"http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html",children:"http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html"})]}),`
+`,e.jsxs(s.p,{children:["See also ",e.jsx(s.a,{href:"/docs/configuration/basic-prerequisites#dfsdatanodemaxtransferthreads",children:e.jsx(s.code,{children:"dfs.datanode.max.transfer.threads"})}),"."]})]})}function l(i={}){const{wrapper:s}=i.components||{};return s?e.jsx(s,{...i,children:e.jsx(n,{...i})}):n(i)}export{a as _markdown,l as default,h as extractedReferences,r as frontmatter,o as structuredData,d as toc};
diff --git a/assets/catalog-tables-DBDNW_RH.js b/assets/catalog-tables-DBDNW_RH.js
new file mode 100644
index 00000000000..67f0b3e51d5
--- /dev/null
+++ b/assets/catalog-tables-DBDNW_RH.js
@@ -0,0 +1,57 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let r=`The catalog table \`hbase:meta\` exists as an HBase table and is filtered out of the HBase shell's \`list\` command, but is in fact a table just like any other.
+
+## hbase:meta
+
+The \`hbase:meta\` table (previously called \`.META.\`) keeps a list of all regions in the system, and the location of \`hbase:meta\` is stored in ZooKeeper.
+
+The \`hbase:meta\` table structure is as follows:
+
+**Key:**
+
+* Region key of the format (\`[table],[region start key],[region id]\`)
+
+**Values:**
+
+* \`info:regioninfo\` (serialized [RegionInfo](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html) instance for this region)
+* \`info:server\` (server:port of the RegionServer containing this region)
+* \`info:serverstartcode\` (start-time of the RegionServer process containing this region)
+
+When a table is in the process of splitting, two other columns will be created, called \`info:splitA\` and \`info:splitB\`. These columns represent the two daughter regions. The values for these columns are also serialized HRegionInfo instances. After the region has been split, eventually this row will be deleted.
+
+<Callout type="info" title="Note on HRegionInfo">
+  The empty key is used to denote table start and table end. A region with an empty start key is the
+  first region in a table. If a region has both an empty start and an empty end key, it is the only
+  region in the table
+</Callout>
+
+In the (hopefully unlikely) event that programmatic processing of catalog metadata is required, see the [RegionInfo.parseFrom](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom\\(byte%5B%5D\\)) utility.
+
+## Startup Sequencing
+
+First, the location of \`hbase:meta\` is looked up in ZooKeeper. Next, \`hbase:meta\` is updated with server and startcode values.
+
+For information on region-RegionServer assignment, see [Region-RegionServer Assignment](/docs/architecture/regions#region-regionserver-assignment).
+`,h={title:"Catalog Tables",description:"Understanding hbase:meta catalog table structure, location tracking, and how HBase maintains region metadata."},l=[{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html"},{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom(byte%5B%5D)"},{href:"/docs/architecture/regions#region-regionserver-assignment"}],c={contents:[{heading:void 0,content:"The catalog table hbase: [...]
+first region in a table. If a region has both an empty start and an empty end key, it is the only
+region in the table`},{heading:"hbasemeta",content:"In the (hopefully unlikely) event that programmatic processing of catalog metadata is required, see the RegionInfo.parseFrom utility."},{heading:"startup-sequencing",content:"First, the location of hbase:meta is looked up in ZooKeeper. Next, hbase:meta is updated with server and startcode values."},{heading:"startup-sequencing",content:"For information on region-RegionServer assignment, see Region-RegionServer Assignment."}],headings:[{ [...]
+`,e.jsx(t.h2,{id:"hbasemeta",children:"hbase:meta"}),`
+`,e.jsxs(t.p,{children:["The ",e.jsx(t.code,{children:"hbase:meta"})," table (previously called ",e.jsx(t.code,{children:".META."}),") keeps a list of all regions in the system, and the location of ",e.jsx(t.code,{children:"hbase:meta"})," is stored in ZooKeeper."]}),`
+`,e.jsxs(t.p,{children:["The ",e.jsx(t.code,{children:"hbase:meta"})," table structure is as follows:"]}),`
+`,e.jsx(t.p,{children:e.jsx(t.strong,{children:"Key:"})}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:["Region key of the format (",e.jsx(t.code,{children:"[table],[region start key],[region id]"}),")"]}),`
+`]}),`
+`,e.jsx(t.p,{children:e.jsx(t.strong,{children:"Values:"})}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"info:regioninfo"})," (serialized ",e.jsx(t.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html",children:"RegionInfo"})," instance for this region)"]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"info:server"})," (server:port of the RegionServer containing this region)"]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"info:serverstartcode"})," (start-time of the RegionServer process containing this region)"]}),`
+`]}),`
+`,e.jsxs(t.p,{children:["When a table is in the process of splitting, two other columns will be created, called ",e.jsx(t.code,{children:"info:splitA"})," and ",e.jsx(t.code,{children:"info:splitB"}),". These columns represent the two daughter regions. The values for these columns are also serialized HRegionInfo instances. After the region has been split, eventually this row will be deleted."]}),`
+`,e.jsx(a,{type:"info",title:"Note on HRegionInfo",children:e.jsx(t.p,{children:`The empty key is used to denote table start and table end. A region with an empty start key is the
+first region in a table. If a region has both an empty start and an empty end key, it is the only
+region in the table`})}),`
+`,e.jsxs(t.p,{children:["In the (hopefully unlikely) event that programmatic processing of catalog metadata is required, see the ",e.jsx(t.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/RegionInfo.html#parseFrom(byte%5B%5D)",children:"RegionInfo.parseFrom"})," utility."]}),`
+`,e.jsx(t.h2,{id:"startup-sequencing",children:"Startup Sequencing"}),`
+`,e.jsxs(t.p,{children:["First, the location of ",e.jsx(t.code,{children:"hbase:meta"})," is looked up in ZooKeeper. Next, ",e.jsx(t.code,{children:"hbase:meta"})," is updated with server and startcode values."]}),`
+`,e.jsxs(t.p,{children:["For information on region-RegionServer assignment, see ",e.jsx(t.a,{href:"/docs/architecture/regions#region-regionserver-assignment",children:"Region-RegionServer Assignment"}),"."]})]})}function g(n={}){const{wrapper:t}=n.components||{};return t?e.jsx(t,{...n,children:e.jsx(o,{...n})}):o(n)}function i(n,t){throw new Error("Expected component `"+n+"` to be defined: you likely forgot to import, pass, or provide it.")}export{r as _markdown,g as default,l as extract [...]
diff --git a/assets/changing_displayed_fields-CMe5Nk2W.gif b/assets/changing_displayed_fields-CMe5Nk2W.gif
new file mode 100644
index 00000000000..5d91a096627
Binary files /dev/null and b/assets/changing_displayed_fields-CMe5Nk2W.gif differ
diff --git a/assets/changing_mode-CjAJJUmd.gif b/assets/changing_mode-CjAJJUmd.gif
new file mode 100644
index 00000000000..bf1cd5f5f6c
Binary files /dev/null and b/assets/changing_mode-CjAJJUmd.gif differ
diff --git a/assets/changing_order_of_fields-0aY2WrMH.gif b/assets/changing_order_of_fields-0aY2WrMH.gif
new file mode 100644
index 00000000000..53b56610ca9
Binary files /dev/null and b/assets/changing_order_of_fields-0aY2WrMH.gif differ
diff --git a/assets/changing_refresh_delay-BZjQN78m.gif b/assets/changing_refresh_delay-BZjQN78m.gif
new file mode 100644
index 00000000000..e22b7eba6ad
Binary files /dev/null and b/assets/changing_refresh_delay-BZjQN78m.gif differ
diff --git a/assets/changing_sort_field-Ca9-_3cx.gif b/assets/changing_sort_field-Ca9-_3cx.gif
new file mode 100644
index 00000000000..f55f19654ab
Binary files /dev/null and b/assets/changing_sort_field-Ca9-_3cx.gif differ
diff --git a/assets/chunk-EPOLDU6W-B5LwAila.js b/assets/chunk-EPOLDU6W-B5LwAila.js
new file mode 100644
index 00000000000..b2f9106efac
--- /dev/null
+++ b/assets/chunk-EPOLDU6W-B5LwAila.js
@@ -0,0 +1,26 @@
+function Ha(e,t){for(var r=0;r<t.length;r++){const n=t[r];if(typeof n!="string"&&!Array.isArray(n)){for(const a in n)if(a!=="default"&&!(a in e)){const o=Object.getOwnPropertyDescriptor(n,a);o&&Object.defineProperty(e,a,o.get?o:{enumerable:!0,get:()=>n[a]})}}}return Object.freeze(Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}))}function za(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Xt={exports:{}},ot={};var Jr;function Ba(){i [...]
+`,""):String(r.body);return{path:t,submission:{formMethod:o,formAction:i,formEncType:r.formEncType,formData:void 0,json:void 0,text:c}}}else if(r.formEncType==="application/json"){if(!ve(o))return n();try{let c=typeof r.body=="string"?JSON.parse(r.body):r.body;return{path:t,submission:{formMethod:o,formAction:i,formEncType:r.formEncType,formData:void 0,json:c,text:void 0}}}catch{return n()}}}Y(typeof FormData=="function","FormData is not available in this environment");let l,s;if(r.formD [...]
+
+Please change the parent <Route path="${R}"> to <Route path="${R==="/"?"*":`${R}/*`}">.`)}let p=Me(),g;g=p;let b=g.pathname||"/",S=b;if(h!=="/"){let R=h.replace(/^\//,"").split("/");S="/"+b.replace(/^\//,"").split("/").slice(R.length).join("/")}let E=Ie(e,{pathname:S});return oe(c||E!=null,`No routes matched location "${g.pathname}${g.search}${g.hash}" `),oe(E==null||E[E.length-1].route.element!==void 0||E[E.length-1].route.Component!==void 0||E[E.length-1].route.lazy!==void 0,`Matched l [...]
+`);t=o.pop()||"";for(const i of o)n.enqueue(i)},flush(r){t&&r.enqueue(t)}})}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var nr=typeof window<"u"?window:typeof globalThis<"u"?globalThis:void 0;function fr(e){const{hydrated:t,values:r}=this;if(typeof e=="number")return Sn.call(this,e);if(!Array.isArray(e)||!e.length)throw new SyntaxError;const n=r.length;for(const a of e)r.push(a);return t.length=r.length,Sn.call(this,n)}function Sn(e){const{hydrated:t,values:r,deferred: [...]
+              console.log(
+                "๐Ÿ’ฟ Hey developer ๐Ÿ‘‹. You can provide a way better UX than this " +
+                "when your app is loading JS modules and/or running \`clientLoader\` " +
+                "functions. Check out https://reactrouter.com/start/framework/route-module#hydratefallback " +
+                "for more information."
+              );
+            `}}))}function va(e){let t={};return Object.values(e).forEach(r=>{if(r){let n=r.parentId||"";t[n]||(t[n]=[]),t[n].push(r)}}),t}function _l(e,t,r){let n=ga(t),a=t.HydrateFallback&&(!r||e.id==="root")?t.HydrateFallback:e.id==="root"?Dl:void 0,o=t.ErrorBoundary?t.ErrorBoundary:e.id==="root"?()=>f.createElement(Ra,{error:Lr()}):void 0;return e.id==="root"&&t.Layout?{...n?{element:f.createElement(t.Layout,null,f.createElement(n,null))}:{Component:n},...o?{errorElement:f.createElem [...]
+
+To reference the meta function API, see https://remix.run/route/meta`);R.meta=L,h[c]=R,s=[...L],u=s}return f.createElement(f.Fragment,null,s.flat().map(c=>{if(!c)return null;if("tagName"in c){let{tagName:p,...g}=c;if(!Wl(p))return console.warn(`A meta object uses an invalid tagName: ${p}. Expected either 'link' or 'meta'`),null;let b=p;return f.createElement(b,{key:JSON.stringify(g),...g})}if("title"in c)return f.createElement("title",{key:"title"},String(c.title));if("charset"in c&&(c.c [...]
+${g.map((M,D)=>{let I=`route${D}`,v=t.routes[M.route.id];we(v,`Route ${M.route.id} not found in manifest`);let{clientActionModule:_,clientLoaderModule:z,clientMiddlewareModule:X,hydrateFallbackModule:V,module:ae}=v,se=[..._?[{module:_,varName:`${I}_clientAction`}]:[],...z?[{module:z,varName:`${I}_clientLoader`}]:[],...X?[{module:X,varName:`${I}_clientMiddleware`}]:[],...V?[{module:V,varName:`${I}_HydrateFallback`}]:[],{module:ae,varName:`${I}_main`}];if(se.length===1)return`import * as $ [...]
+`),Z=`const ${I} = {${se.map(G=>`...${G.varName}`).join(",")}};`;return[ne,Z].join(`
+`)}).join(`
+`)}
+  ${p?`window.__reactRouterManifest = ${JSON.stringify($l(t,l),null,2)};`:""}
+  window.__reactRouterRouteModules = {${g.map((M,D)=>`${JSON.stringify(M.route.id)}:route${D}`).join(",")}};
+
+import(${JSON.stringify(t.entry.module)});`:" ";return f.createElement(f.Fragment,null,f.createElement("script",{...e,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:R},type:void 0}),f.createElement("script",{...e,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:T},type:"module",async:!0}))},[]),S=$t||c?[]:Jl(t.entry.imports.concat(Tr(g,t,{includeHydrateFallback:!0}))),E=typeof t.sri=="object"?t.sri:{};return dr(!c,"The <Scripts /> element is a no-op when using RSC [...]
+        console.log(
+          "๐Ÿ’ฟ Hey developer ๐Ÿ‘‹. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information."
+        );
+      `}});if(Ve(e))return f.createElement(pr,{title:"Unhandled Thrown Response!"},f.createElement("h1",{style:{fontSize:"24px"}},e.status," ",e.statusText),r);let n;if(e instanceof Error)n=e;else{let a=e==null?"Unknown Error":typeof e=="object"&&"toString"in e?e.toString():JSON.stringify(e);n=new Error(a)}return f.createElement(pr,{title:"Application Error!",isOutsideRemixApp:t},f.createElement("h1",{style:{fontSize:"24px"}},"Application Error"),f.createElement("pre",{style:{padding:"2r [...]
diff --git a/assets/chunk-OTD7MV33-qJr9DjGl.js b/assets/chunk-OTD7MV33-qJr9DjGl.js
new file mode 100644
index 00000000000..913f04611da
--- /dev/null
+++ b/assets/chunk-OTD7MV33-qJr9DjGl.js
@@ -0,0 +1 @@
+function l(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function g(e){const i=e.trim();if(i.length===0)return null;const t=Array.from(new Set(i.split(/\s+/).map(n=>n.trim()).filter(Boolean)));if(t.length===0)return null;const r=t.map(l).join("|");return new RegExp(`(${r})`,"gi")}function o(e){const i=typeof e=="string"?g(e):e;return{highlight(t){if(!i)return[{type:"text",content:t}];const r=[];let n=0;for(const s of t.matchAll(i))n<s.index&&r.push({type:"text",content:t.substring(n, [...]
diff --git a/assets/chunk-ZMWYLUDP-oajMeTFk.js b/assets/chunk-ZMWYLUDP-oajMeTFk.js
new file mode 100644
index 00000000000..1af790faec5
--- /dev/null
+++ b/assets/chunk-ZMWYLUDP-oajMeTFk.js
@@ -0,0 +1 @@
+function r(i,t=!1){const o=i;for(const e in o){if(o[e]===void 0&&delete o[e],!t)continue;const n=o[e];if(typeof n=="object"&&n!==null){r(n,t);continue}if(Array.isArray(n))for(const f of n)r(f,t)}return i}export{r};
diff --git a/assets/client-B5eNOW9s.js b/assets/client-B5eNOW9s.js
new file mode 100644
index 00000000000..d155d1634d9
--- /dev/null
+++ b/assets/client-B5eNOW9s.js
@@ -0,0 +1,434 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let o=`The HBase client finds the RegionServers that are serving the particular row range of interest. It does this by querying the \`hbase:meta\` table. See [hbase:meta](/docs/architecture/catalog-tables#hbasemeta) for details. After locating the required region(s), the client contacts the RegionServer serving that region, rather than going through the master, and issues the read or write request. This information is cached in the client  [...]
+
+See [Runtime Impact](/docs/architecture/master#runtime-impact) for more information about the impact of the Master on HBase Client communication.
+
+Administrative functions are done via an instance of [Admin](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Admin.html)
+
+## Cluster Connections
+
+The API changed in HBase 1.0. For connection configuration information, see [Client configuration and dependencies connecting to an HBase cluster](/docs/configuration/default#client-configuration-and-dependencies-connecting-to-an-hbase-cluster).
+
+### API as of HBase 1.0.0
+
+It's been cleaned up and users are returned Interfaces to work against rather than particular types. In HBase 1.0, obtain a \`Connection\` object from \`ConnectionFactory\` and thereafter, get from it instances of \`Table\`, \`Admin\`, and \`RegionLocator\` on an as-need basis. When done, close the obtained instances. Finally, be sure to cleanup your \`Connection\` instance before exiting. \`Connections\` are heavyweight objects but thread-safe so you can create one for your application  [...]
+
+### API before HBase 1.0.0
+
+Instances of \`HTable\` are the way to interact with an HBase cluster earlier than 1.0.0. *[Table](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html) instances are not thread-safe*. Only one thread can use an instance of Table at any given time. When creating Table instances, it is advisable to use the same [HBaseConfiguration](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/HBaseConfiguration) instance. This will ensure sharing of ZooKeeper and so [...]
+
+\`\`\`java
+HBaseConfiguration conf = HBaseConfiguration.create();
+HTable table1 = new HTable(conf, "myTable");
+HTable table2 = new HTable(conf, "myTable");
+\`\`\`
+
+as opposed to this:
+
+\`\`\`java
+HBaseConfiguration conf1 = HBaseConfiguration.create();
+HTable table1 = new HTable(conf1, "myTable");
+HBaseConfiguration conf2 = HBaseConfiguration.create();
+HTable table2 = new HTable(conf2, "myTable");
+\`\`\`
+
+For more information about how connections are handled in the HBase client, see [ConnectionFactory](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/ConnectionFactory.html).
+
+#### Connection Pooling
+
+For applications which require high-end multithreaded access (e.g., web-servers or application servers that may serve many application threads in a single JVM), you can pre-create a \`Connection\`, as shown in the following example:
+
+**Example 24. Pre-Creating a \`Connection\`**
+
+\`\`\`java
+// Create a connection to the cluster.
+Configuration conf = HBaseConfiguration.create();
+try (Connection connection = ConnectionFactory.createConnection(conf);
+     Table table = connection.getTable(TableName.valueOf(tablename))) {
+  // use table as needed, the table returned is lightweight
+}
+\`\`\`
+
+<Callout type="warn" title="HTablePool is Deprecated">
+  Previous versions of this guide discussed \`HTablePool\`, which was deprecated in HBase 0.94, 0.95,
+  and 0.96, and removed in 0.98.1, by
+  [HBASE-6580](https://issues.apache.org/jira/browse/HBASE-6580), or \`HConnection\`, which is
+  deprecated in HBase 1.0 by \`Connection\`. Please use
+  [Connection](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Connection.html)
+  instead.
+</Callout>
+
+## WriteBuffer and Batch Methods
+
+In HBase 1.0 and later, [HTable](https://hbase.apache.org/1.4/devapidocs/org/apache/hadoop/hbase/client/HTable.html) is deprecated in favor of [Table](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html). \`Table\` does not use autoflush. To do buffered writes, use the BufferedMutator class.
+
+In HBase 2.0 and later, [HTable](https://hbase.apache.org/2.6/devapidocs/org/apache/hadoop/hbase/client/HTable.html) does not use BufferedMutator to execute the \`Put\` operation. Refer to [HBASE-18500](https://issues.apache.org/jira/browse/HBASE-18500) for more information.
+
+For additional information on write durability, review the [ACID semantics](/acid-semantics) page.
+
+For fine-grained control of batching of \`Put\`s or \`Delete\`s, see the [batch](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html#batch\\(java.util.List,java.lang.Object%5B%5D\\)) methods on Table.
+
+## Asynchronous Client
+
+It is a new API introduced in HBase 2.0 which aims to provide the ability to access HBase asynchronously.
+
+You can obtain an \`AsyncConnection\` from \`ConnectionFactory\`, and then get a asynchronous table instance from it to access HBase. When done, close the \`AsyncConnection\` instance(usually when your program exits).
+
+For the asynchronous table, most methods have the same meaning with the old \`Table\` interface, expect that the return value is wrapped with a CompletableFuture usually. We do not have any buffer here so there is no close method for asynchronous table, you do not need to close it. And it is thread safe.
+
+There are several differences for scan:
+
+* There is still a \`getScanner\` method which returns a \`ResultScanner\`. You can use it in the old way and it works like the old \`ClientAsyncPrefetchScanner\`.
+* There is a \`scanAll\` method which will return all the results at once. It aims to provide a simpler way for small scans which you want to get the whole results at once usually.
+* The Observer Pattern. There is a scan method which accepts a \`ScanResultConsumer\` as a parameter. It will pass the results to the consumer.
+
+Notice that \`AsyncTable\` interface is templatized. The template parameter specifies the type of \`ScanResultConsumerBase\` used by scans, which means the observer style scan APIs are different. The two types of scan consumers are - \`ScanResultConsumer\` and \`AdvancedScanResultConsumer\`.
+
+\`ScanResultConsumer\` needs a separate thread pool which is used to execute the callbacks registered to the returned CompletableFuture. Because the use of separate thread pool frees up RPC threads, callbacks are free to do anything. Use this if the callbacks are not quick, or when in doubt.
+
+\`AdvancedScanResultConsumer\` executes callbacks inside the framework thread. It is not allowed to do time consuming work in the callbacks else it will likely block the framework threads and cause very bad performance impact. As its name, it is designed for advanced users who want to write high performance code. See \`org.apache.hadoop.hbase.client.example.HttpProxyExample\` for how to write fully asynchronous code with it.
+
+## Asynchronous Admin
+
+You can obtain an \`AsyncConnection\` from \`ConnectionFactory\`, and then get a \`AsyncAdmin\` instance from it to access HBase. Notice that there are two \`getAdmin\` methods to get a \`AsyncAdmin\` instance. One method has one extra thread pool parameter which is used to execute callbacks. It is designed for normal users. Another method doesn't need a thread pool and all the callbacks are executed inside the framework thread so it is not allowed to do time consuming works in the callb [...]
+
+The default \`getAdmin\` methods will return a \`AsyncAdmin\` instance which use default configs. If you want to customize some configs, you can use \`getAdminBuilder\` methods to get a \`AsyncAdminBuilder\` for creating \`AsyncAdmin\` instance. Users are free to only set the configs they care about to create a new \`AsyncAdmin\` instance.
+
+For the \`AsyncAdmin\` interface, most methods have the same meaning with the old \`Admin\` interface, expect that the return value is wrapped with a CompletableFuture usually.
+
+For most admin operations, when the returned CompletableFuture is done, it means the admin operation has also been done. But for compact operation, it only means the compact request was sent to HBase and may need some time to finish the compact operation. For \`rollWALWriter\` method, it only means the rollWALWriter request was sent to the region server and may need some time to finish the \`rollWALWriter\` operation.
+
+For region name, we only accept \`byte[]\` as the parameter type and it may be a full region name or a encoded region name. For server name, we only accept \`ServerName\` as the parameter type. For table name, we only accept \`TableName\` as the parameter type. For \`list*\` operations, we only accept \`Pattern\` as the parameter type if you want to do regex matching.
+
+## External Clients
+
+Information on non-Java clients and custom protocols is covered in [Apache HBase External APIs](/docs/external-apis)
+
+## Master Registry (new as of 2.3.0)
+
+Starting from 2.5.0, MasterRegistry is deprecated. It's functionality is completely superseded by the RpcConnectionRegistry. Please see [Rpc Connection Registry (new as of 2.5.0)](/docs/architecture/client#rpc-connection-registry-new-as-of-250) for more details.
+
+Client internally works with a *connection registry* to fetch the metadata needed by connections. This connection registry implementation is responsible for fetching the following metadata.
+
+* Active master address
+* Current meta region(s) locations
+* Cluster ID (unique to this cluster)
+
+This information is needed as a part of various client operations like connection set up, scans, gets, etc. Traditionally, the connection registry implementation has been based on ZooKeeper as the source of truth and clients fetched the metadata directly from the ZooKeeper quorum. HBase 2.3.0 introduces a new connection registry implementation based on direct communication with the Masters. With this implementation, clients now fetch required metadata via master RPC end points instead of [...]
+
+* Reduce load on ZooKeeper since that is critical for cluster operation.
+* Holistic client timeout and retry configurations since the new registry brings all the client operations under HBase rpc framework.
+* Remove the ZooKeeper client dependency on HBase client library.
+
+This means:
+
+* At least a single active or stand by master is needed for cluster connection setup. Refer to [Runtime Impact](/docs/architecture/master#runtime-impact) for more details.
+* Master can be in a critical path of read/write operations, especially if the client metadata cache is empty or stale.
+* There is higher connection load on the masters that before since the clients talk directly to HMasters instead of ZooKeeper ensemble\\\`
+
+To reduce hot-spotting on a single master, all the masters (active & stand-by) expose the needed service to fetch the connection metadata. This lets the client connect to any master (not just active). Both ZooKeeper-based and Master-based connection registry implementations are available in 2.3+. For 2.x and earlier, the ZooKeeper-based implementation remains the default configuration. For 3.0.0, RpcConnectionRegistry becomes the default configuration, as the alternate to MasterRegistry.
+
+Change the connection registry implementation by updating the value configured for \`hbase.client.registry.impl\`. To explicitly enable the ZooKeeper-based registry, use
+
+\`\`\`xml
+<property>
+  <name>hbase.client.registry.impl</name>
+  <value>org.apache.hadoop.hbase.client.ZKConnectionRegistry</value>
+</property>
+\`\`\`
+
+To explicitly enable the Master-based registry, use
+
+\`\`\`xml
+<property>
+  <name>hbase.client.registry.impl</name>
+  <value>org.apache.hadoop.hbase.client.MasterRegistry</value>
+</property>
+\`\`\`
+
+### MasterRegistry RPC hedging
+
+MasterRegistry implements hedging of connection registry RPCs across active and stand-by masters. This lets the client make the same request to multiple servers and which ever responds first is returned back to the client immediately. This improves performance, especially when a subset of servers are under load. The hedging fan out size is configurable, meaning the number of requests that are hedged in a single attempt, using the configuration key *hbase.client.master\\_registry.hedged.f [...]
+
+### Additional Notes
+
+* Clients hedge the requests in a randomized order to avoid hot-spotting a single master.
+* Cluster internal connections (masters โ†” regionservers) still use ZooKeeper based connection registry.
+* Cluster internal state is still tracked in Zookeeper, hence ZK availability requirements are same as before.
+* Inter cluster replication still uses ZooKeeper based connection registry to simplify configuration management.
+
+For more implementation details, please refer to the [design doc](https://github.com/apache/hbase/tree/master/dev-support/design-docs) and [HBASE-18095](https://issues.apache.org/jira/browse/HBASE-18095).
+
+## Rpc Connection Registry (new as of 2.5.0)
+
+As said in the [Master Registry (new as of 2.3.0)](/docs/architecture/client#masterregistry-rpc-hedging) section, there are some disadvantages and limitations for MasterRegistry, especially that it puts master in the critical path of read/write operations. In order to address these problems, we introduced a more generic RpcConnectionRegistry.
+
+It is also rpc based, like MasterRegistry, with several differences
+
+1. Region server also implements the necessary rpc service, so you can config any nodes in the cluster as bootstrap nodes, not only masters
+2. Support refreshing bootstrap nodes, for spreading loads across the nodes in the cluster, and also remove the dead nodes in bootstrap nodes.
+
+To explicitly enable the rpc-based registry, use
+
+\`\`\`xml
+<property>
+  <name>hbase.client.registry.impl</name>
+  <value>org.apache.hadoop.hbase.client.RpcConnectionRegistry</value>
+</property>
+\`\`\`
+
+To configure the bootstrap nodes, use
+
+\`\`\`xml
+<property>
+  <name>hbase.client.bootstrap.servers</name>
+  <value>server1:16020,server2:16020,server3:16020</value>
+</property>
+\`\`\`
+
+If not configured, we will fallback to use master addresses as the bootstrap nodes.
+
+RpcConnectionRegistry is available in 2.5+, and becomes the default client registry implementation in 3.0.0.
+
+### RpcConnectionRegistry RPC hedging
+
+Hedged read is still supported, the configuration key is now *hbase.client.bootstrap.hedged.fanout*, and its default value is still 2.
+
+### RpcConnectionRegistry bootstrap nodes refreshing
+
+There are basically two reasons for us to refresh the bootstrap nodes
+
+* Periodically. This is for spreading loads across the nodes in the cluster. There are two configurations
+  1. *hbase.client.bootstrap.refresh\\_interval\\_secs*: the refresh interval in seconds, default 300. A value less than or equal to zero means disable refreshing.
+  2. *hbase.client.bootstrap.initial\\_refresh\\_delay\\_secs*: the initial refresh interval in seconds, the default value is 1/10 of *hbase.client.bootstrap.refresh\\_interval\\_secs*. The reason why we want to introduce a separated configuration for the delay for first refreshing is that, as end users could configure any nodes in a cluster as the initial bootstrap nodes, it is possible that different end users will configure the same machine which makes the machine over load. So we sho [...]
+
+* When there is a connection error while requesting the nodes, we will refresh immediately, to remove the dead nodes. To avoid putting too much pressure to the cluster, there is a configuration *hbase.client.bootstrap.min\\_secs\\_between\\_refreshes*, to control the minimum interval between two refreshings. The default value is 60, but notice that, if you change *hbase.client.bootstrap.refresh\\_interval\\_secs* to a small value, you need to make sure to also change *hbase.client.bootst [...]
+
+<Callout type="info">
+  (Advanced) In case of any issues with the rpc/master based registry, use the following
+  configuration to fallback to the ZooKeeper based connection registry implementation.
+</Callout>
+
+\`\`\`xml
+<property>
+  <name>hbase.client.registry.impl</name>
+  <value>org.apache.hadoop.hbase.client.ZKConnectionRegistry</value>
+</property>
+\`\`\`
+
+## Connection URI
+
+Starting from 2.7.0, we add the support for specifying the connection information for a HBase cluster through an URI, which we call a "connection URI". And we've added several methods in *ConnectionFactory* to let you get a connection to the cluster specified by the URI. It looks like:
+
+\`\`\`java
+URI uri = new URI("hbase+rpc://server1:16020,server2:16020,server3:16020");
+try (Connection conn = ConnectionFactory.createConnection(uri)) {
+  ...
+}
+\`\`\`
+
+### Supported Schemes
+
+Currently there are two schemes supported, *hbase+rpc* for *RpcConnectionRegistry* and *hbase+zk* for *ZKConnectionRegistry*. *MasterRegistry* is deprecated so we do not expose it through connection URI.
+
+For *hbase+rpc*, it looks like
+
+\`\`\`shell
+hbase+rpc://server1:16020,server2:16020,server3:16020
+\`\`\`
+
+The authority part *server1:16020,server2:16020,server3:16020* specifies the bootstrap nodes and their rpc ports, i.e, the configuration value for *hbase.client.bootstrap.servers* in the past.
+
+For *hbase+zk*, it looks like
+
+\`\`\`shell
+hbase+zk://zk1:2181,zk2:2181,zk3:2181/hbase
+\`\`\`
+
+The authority part *zk1:2181,zk2:2181,zk3:2181* is the zk quorum, i.e, the configuration value for *hbase.zookeeper.quorum* in the past. The path part */hbase* is the znode parent, i.e, the configuration value for *zookeeper.znode.parent* in the past.
+
+### Specify Configuration through URI Queries
+
+To let users fully specify the connection information through a connection URI, we support specifying configuration values through URI Queries. It looks like:
+
+\`\`\`shell
+hbase+rpc://server1:16020?hbase.client.operation.timeout=10000
+\`\`\`
+
+In this way you can set the operation timeout to 10 seconds. Notice that, the configuration values specified in the connection URI will override the ones in the configuration file.
+
+### Implement Your Own Connection Registry
+
+We use *ServiceLoader* to load different connection registry implementations, the entry point is *org.apache.hadoop.hbase.client.ConnectionRegistryURIFactory*. So if you implement your own *ConnectionRegistryURIFactory* which has a different scheme, and register it in the services file, we can load it at runtime.
+
+Connection URI is still a very new feature which has not been used extensively in production, so we do not want to expose the ability to customize *ConnectionRegistryURIFactory* yet as the API may be changed frequently in the beginning.
+
+If you really want to implement your own connection registry, you can use the above way but take your own risk.
+`,h={title:"Client",description:"HBase client architecture, connection management, metadata caching, and client-side configuration for optimal performance."},c=[{href:"/docs/architecture/catalog-tables#hbasemeta"},{href:"/docs/architecture/master#runtime-impact"},{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Admin.html"},{href:"/docs/configuration/default#client-configuration-and-dependencies-connecting-to-an-hbase-cluster"},{href:"https://hbase.apache.org/api [...]
+and 0.96, and removed in 0.98.1, by
+HBASE-6580, or HConnection, which is
+deprecated in HBase 1.0 by Connection. Please use
+Connection
+instead.`},{heading:"writebuffer-and-batch-methods",content:"In HBase 1.0 and later, HTable is deprecated in favor of Table. Table does not use autoflush. To do buffered writes, use the BufferedMutator class."},{heading:"writebuffer-and-batch-methods",content:"In HBase 2.0 and later, HTable does not use BufferedMutator to execute the Put operation. Refer to HBASE-18500 for more information."},{heading:"writebuffer-and-batch-methods",content:"For additional information on write durability [...]
+configuration to fallback to the ZooKeeper based connection registry implementation.`},{heading:"connection-uri",content:`Starting from 2.7.0, we add the support for specifying the connection information for a HBase cluster through an URI, which we call a "connection URI". And we've added several methods in ConnectionFactory to let you get a connection to the cluster specified by the URI. It looks like:`},{heading:"supported-schemes",content:"Currently there are two schemes supported, hb [...]
+`,e.jsxs(n.p,{children:["See ",e.jsx(n.a,{href:"/docs/architecture/master#runtime-impact",children:"Runtime Impact"})," for more information about the impact of the Master on HBase Client communication."]}),`
+`,e.jsxs(n.p,{children:["Administrative functions are done via an instance of ",e.jsx(n.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Admin.html",children:"Admin"})]}),`
+`,e.jsx(n.h2,{id:"cluster-connections",children:"Cluster Connections"}),`
+`,e.jsxs(n.p,{children:["The API changed in HBase 1.0. For connection configuration information, see ",e.jsx(n.a,{href:"/docs/configuration/default#client-configuration-and-dependencies-connecting-to-an-hbase-cluster",children:"Client configuration and dependencies connecting to an HBase cluster"}),"."]}),`
+`,e.jsx(n.h3,{id:"api-as-of-hbase-100",children:"API as of HBase 1.0.0"}),`
+`,e.jsxs(n.p,{children:["It's been cleaned up and users are returned Interfaces to work against rather than particular types. In HBase 1.0, obtain a ",e.jsx(n.code,{children:"Connection"})," object from ",e.jsx(n.code,{children:"ConnectionFactory"})," and thereafter, get from it instances of ",e.jsx(n.code,{children:"Table"}),", ",e.jsx(n.code,{children:"Admin"}),", and ",e.jsx(n.code,{children:"RegionLocator"})," on an as-need basis. When done, close the obtained instances. Finally, be  [...]
+`,e.jsx(n.h3,{id:"api-before-hbase-100",children:"API before HBase 1.0.0"}),`
+`,e.jsxs(n.p,{children:["Instances of ",e.jsx(n.code,{children:"HTable"})," are the way to interact with an HBase cluster earlier than 1.0.0. ",e.jsxs(n.em,{children:[e.jsx(n.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html",children:"Table"})," instances are not thread-safe"]}),". Only one thread can use an instance of Table at any given time. When creating Table instances, it is advisable to use the same ",e.jsx(n.a,{href:"https://hbase.apache.org/ [...]
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"HTable table1 "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" HTable"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"HTable table2 "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" HTable"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,e.jsx(n.p,{children:"as opposed to this:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"HTable table1 "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" HTable"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"HBaseConfiguration conf2 "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" HBaseConfiguration."}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"create"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E"," [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"HTable table2 "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" HTable"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,e.jsxs(n.p,{children:["For more information about how connections are handled in the HBase client, see ",e.jsx(n.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/ConnectionFactory.html",children:"ConnectionFactory"}),"."]}),`
+`,e.jsx(n.h4,{id:"connection-pooling",children:"Connection Pooling"}),`
+`,e.jsxs(n.p,{children:["For applications which require high-end multithreaded access (e.g., web-servers or application servers that may serve many application threads in a single JVM), you can pre-create a ",e.jsx(n.code,{children:"Connection"}),", as shown in the following example:"]}),`
+`,e.jsx(n.p,{children:e.jsxs(n.strong,{children:["Example 24. Pre-Creating a ",e.jsx(n.code,{children:"Connection"})]})}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Configuration conf "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" HBaseConfiguration."}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"create"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shik [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"try"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Connection connection "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ConnectionFactory."}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shi [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"     Table table "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" connection."}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"getTable"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark": [...]
+`,e.jsx(n.span,{className:"line",children:e.jsx(n.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"  // use table as needed, the table returned is lightweight"})}),`
+`,e.jsx(n.span,{className:"line",children:e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})})]})})}),`
+`,e.jsx(i,{type:"warn",title:"HTablePool is Deprecated",children:e.jsxs(n.p,{children:["Previous versions of this guide discussed ",e.jsx(n.code,{children:"HTablePool"}),`, which was deprecated in HBase 0.94, 0.95,
+and 0.96, and removed in 0.98.1, by
+`,e.jsx(n.a,{href:"https://issues.apache.org/jira/browse/HBASE-6580",children:"HBASE-6580"}),", or ",e.jsx(n.code,{children:"HConnection"}),`, which is
+deprecated in HBase 1.0 by `,e.jsx(n.code,{children:"Connection"}),`. Please use
+`,e.jsx(n.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Connection.html",children:"Connection"}),`
+instead.`]})}),`
+`,e.jsx(n.h2,{id:"writebuffer-and-batch-methods",children:"WriteBuffer and Batch Methods"}),`
+`,e.jsxs(n.p,{children:["In HBase 1.0 and later, ",e.jsx(n.a,{href:"https://hbase.apache.org/1.4/devapidocs/org/apache/hadoop/hbase/client/HTable.html",children:"HTable"})," is deprecated in favor of ",e.jsx(n.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html",children:"Table"}),". ",e.jsx(n.code,{children:"Table"})," does not use autoflush. To do buffered writes, use the BufferedMutator class."]}),`
+`,e.jsxs(n.p,{children:["In HBase 2.0 and later, ",e.jsx(n.a,{href:"https://hbase.apache.org/2.6/devapidocs/org/apache/hadoop/hbase/client/HTable.html",children:"HTable"})," does not use BufferedMutator to execute the ",e.jsx(n.code,{children:"Put"})," operation. Refer to ",e.jsx(n.a,{href:"https://issues.apache.org/jira/browse/HBASE-18500",children:"HBASE-18500"})," for more information."]}),`
+`,e.jsxs(n.p,{children:["For additional information on write durability, review the ",e.jsx(n.a,{href:"/acid-semantics",children:"ACID semantics"})," page."]}),`
+`,e.jsxs(n.p,{children:["For fine-grained control of batching of ",e.jsx(n.code,{children:"Put"}),"s or ",e.jsx(n.code,{children:"Delete"}),"s, see the ",e.jsx(n.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html#batch(java.util.List,java.lang.Object%5B%5D)",children:"batch"})," methods on Table."]}),`
+`,e.jsx(n.h2,{id:"asynchronous-client",children:"Asynchronous Client"}),`
+`,e.jsx(n.p,{children:"It is a new API introduced in HBase 2.0 which aims to provide the ability to access HBase asynchronously."}),`
+`,e.jsxs(n.p,{children:["You can obtain an ",e.jsx(n.code,{children:"AsyncConnection"})," from ",e.jsx(n.code,{children:"ConnectionFactory"}),", and then get a asynchronous table instance from it to access HBase. When done, close the ",e.jsx(n.code,{children:"AsyncConnection"})," instance(usually when your program exits)."]}),`
+`,e.jsxs(n.p,{children:["For the asynchronous table, most methods have the same meaning with the old ",e.jsx(n.code,{children:"Table"})," interface, expect that the return value is wrapped with a CompletableFuture usually. We do not have any buffer here so there is no close method for asynchronous table, you do not need to close it. And it is thread safe."]}),`
+`,e.jsx(n.p,{children:"There are several differences for scan:"}),`
+`,e.jsxs(n.ul,{children:[`
+`,e.jsxs(n.li,{children:["There is still a ",e.jsx(n.code,{children:"getScanner"})," method which returns a ",e.jsx(n.code,{children:"ResultScanner"}),". You can use it in the old way and it works like the old ",e.jsx(n.code,{children:"ClientAsyncPrefetchScanner"}),"."]}),`
+`,e.jsxs(n.li,{children:["There is a ",e.jsx(n.code,{children:"scanAll"})," method which will return all the results at once. It aims to provide a simpler way for small scans which you want to get the whole results at once usually."]}),`
+`,e.jsxs(n.li,{children:["The Observer Pattern. There is a scan method which accepts a ",e.jsx(n.code,{children:"ScanResultConsumer"})," as a parameter. It will pass the results to the consumer."]}),`
+`]}),`
+`,e.jsxs(n.p,{children:["Notice that ",e.jsx(n.code,{children:"AsyncTable"})," interface is templatized. The template parameter specifies the type of ",e.jsx(n.code,{children:"ScanResultConsumerBase"})," used by scans, which means the observer style scan APIs are different. The two types of scan consumers are - ",e.jsx(n.code,{children:"ScanResultConsumer"})," and ",e.jsx(n.code,{children:"AdvancedScanResultConsumer"}),"."]}),`
+`,e.jsxs(n.p,{children:[e.jsx(n.code,{children:"ScanResultConsumer"})," needs a separate thread pool which is used to execute the callbacks registered to the returned CompletableFuture. Because the use of separate thread pool frees up RPC threads, callbacks are free to do anything. Use this if the callbacks are not quick, or when in doubt."]}),`
+`,e.jsxs(n.p,{children:[e.jsx(n.code,{children:"AdvancedScanResultConsumer"})," executes callbacks inside the framework thread. It is not allowed to do time consuming work in the callbacks else it will likely block the framework threads and cause very bad performance impact. As its name, it is designed for advanced users who want to write high performance code. See ",e.jsx(n.code,{children:"org.apache.hadoop.hbase.client.example.HttpProxyExample"})," for how to write fully asynchronous c [...]
+`,e.jsx(n.h2,{id:"asynchronous-admin",children:"Asynchronous Admin"}),`
+`,e.jsxs(n.p,{children:["You can obtain an ",e.jsx(n.code,{children:"AsyncConnection"})," from ",e.jsx(n.code,{children:"ConnectionFactory"}),", and then get a ",e.jsx(n.code,{children:"AsyncAdmin"})," instance from it to access HBase. Notice that there are two ",e.jsx(n.code,{children:"getAdmin"})," methods to get a ",e.jsx(n.code,{children:"AsyncAdmin"})," instance. One method has one extra thread pool parameter which is used to execute callbacks. It is designed for normal users. Anoth [...]
+`,e.jsxs(n.p,{children:["The default ",e.jsx(n.code,{children:"getAdmin"})," methods will return a ",e.jsx(n.code,{children:"AsyncAdmin"})," instance which use default configs. If you want to customize some configs, you can use ",e.jsx(n.code,{children:"getAdminBuilder"})," methods to get a ",e.jsx(n.code,{children:"AsyncAdminBuilder"})," for creating ",e.jsx(n.code,{children:"AsyncAdmin"})," instance. Users are free to only set the configs they care about to create a new ",e.jsx(n.code, [...]
+`,e.jsxs(n.p,{children:["For the ",e.jsx(n.code,{children:"AsyncAdmin"})," interface, most methods have the same meaning with the old ",e.jsx(n.code,{children:"Admin"})," interface, expect that the return value is wrapped with a CompletableFuture usually."]}),`
+`,e.jsxs(n.p,{children:["For most admin operations, when the returned CompletableFuture is done, it means the admin operation has also been done. But for compact operation, it only means the compact request was sent to HBase and may need some time to finish the compact operation. For ",e.jsx(n.code,{children:"rollWALWriter"})," method, it only means the rollWALWriter request was sent to the region server and may need some time to finish the ",e.jsx(n.code,{children:"rollWALWriter"})," op [...]
+`,e.jsxs(n.p,{children:["For region name, we only accept ",e.jsx(n.code,{children:"byte[]"})," as the parameter type and it may be a full region name or a encoded region name. For server name, we only accept ",e.jsx(n.code,{children:"ServerName"})," as the parameter type. For table name, we only accept ",e.jsx(n.code,{children:"TableName"})," as the parameter type. For ",e.jsx(n.code,{children:"list*"})," operations, we only accept ",e.jsx(n.code,{children:"Pattern"})," as the parameter  [...]
+`,e.jsx(n.h2,{id:"external-clients",children:"External Clients"}),`
+`,e.jsxs(n.p,{children:["Information on non-Java clients and custom protocols is covered in ",e.jsx(n.a,{href:"/docs/external-apis",children:"Apache HBase External APIs"})]}),`
+`,e.jsx(n.h2,{id:"master-registry-new-as-of-230",children:"Master Registry (new as of 2.3.0)"}),`
+`,e.jsxs(n.p,{children:["Starting from 2.5.0, MasterRegistry is deprecated. It's functionality is completely superseded by the RpcConnectionRegistry. Please see ",e.jsx(n.a,{href:"/docs/architecture/client#rpc-connection-registry-new-as-of-250",children:"Rpc Connection Registry (new as of 2.5.0)"})," for more details."]}),`
+`,e.jsxs(n.p,{children:["Client internally works with a ",e.jsx(n.em,{children:"connection registry"})," to fetch the metadata needed by connections. This connection registry implementation is responsible for fetching the following metadata."]}),`
+`,e.jsxs(n.ul,{children:[`
+`,e.jsx(n.li,{children:"Active master address"}),`
+`,e.jsx(n.li,{children:"Current meta region(s) locations"}),`
+`,e.jsx(n.li,{children:"Cluster ID (unique to this cluster)"}),`
+`]}),`
+`,e.jsx(n.p,{children:"This information is needed as a part of various client operations like connection set up, scans, gets, etc. Traditionally, the connection registry implementation has been based on ZooKeeper as the source of truth and clients fetched the metadata directly from the ZooKeeper quorum. HBase 2.3.0 introduces a new connection registry implementation based on direct communication with the Masters. With this implementation, clients now fetch required metadata via master RP [...]
+`,e.jsxs(n.ul,{children:[`
+`,e.jsx(n.li,{children:"Reduce load on ZooKeeper since that is critical for cluster operation."}),`
+`,e.jsx(n.li,{children:"Holistic client timeout and retry configurations since the new registry brings all the client operations under HBase rpc framework."}),`
+`,e.jsx(n.li,{children:"Remove the ZooKeeper client dependency on HBase client library."}),`
+`]}),`
+`,e.jsx(n.p,{children:"This means:"}),`
+`,e.jsxs(n.ul,{children:[`
+`,e.jsxs(n.li,{children:["At least a single active or stand by master is needed for cluster connection setup. Refer to ",e.jsx(n.a,{href:"/docs/architecture/master#runtime-impact",children:"Runtime Impact"})," for more details."]}),`
+`,e.jsx(n.li,{children:"Master can be in a critical path of read/write operations, especially if the client metadata cache is empty or stale."}),`
+`,e.jsx(n.li,{children:"There is higher connection load on the masters that before since the clients talk directly to HMasters instead of ZooKeeper ensemble`"}),`
+`]}),`
+`,e.jsx(n.p,{children:"To reduce hot-spotting on a single master, all the masters (active & stand-by) expose the needed service to fetch the connection metadata. This lets the client connect to any master (not just active). Both ZooKeeper-based and Master-based connection registry implementations are available in 2.3+. For 2.x and earlier, the ZooKeeper-based implementation remains the default configuration. For 3.0.0, RpcConnectionRegistry becomes the default configuration, as the alter [...]
+`,e.jsxs(n.p,{children:["Change the connection registry implementation by updating the value configured for ",e.jsx(n.code,{children:"hbase.client.registry.impl"}),". To explicitly enable the ZooKeeper-based registry, use"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.registry.impl</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">org.apache.hadoop.hbase.client.ZKConnectionRegistry</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-lig [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(n.p,{children:"To explicitly enable the Master-based registry, use"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.registry.impl</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">org.apache.hadoop.hbase.client.MasterRegistry</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"# [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(n.h3,{id:"masterregistry-rpc-hedging",children:"MasterRegistry RPC hedging"}),`
+`,e.jsxs(n.p,{children:["MasterRegistry implements hedging of connection registry RPCs across active and stand-by masters. This lets the client make the same request to multiple servers and which ever responds first is returned back to the client immediately. This improves performance, especially when a subset of servers are under load. The hedging fan out size is configurable, meaning the number of requests that are hedged in a single attempt, using the configuration key ",e.jsx(n.em,{c [...]
+`,e.jsx(n.h3,{id:"additional-notes",children:"Additional Notes"}),`
+`,e.jsxs(n.ul,{children:[`
+`,e.jsx(n.li,{children:"Clients hedge the requests in a randomized order to avoid hot-spotting a single master."}),`
+`,e.jsx(n.li,{children:"Cluster internal connections (masters โ†” regionservers) still use ZooKeeper based connection registry."}),`
+`,e.jsx(n.li,{children:"Cluster internal state is still tracked in Zookeeper, hence ZK availability requirements are same as before."}),`
+`,e.jsx(n.li,{children:"Inter cluster replication still uses ZooKeeper based connection registry to simplify configuration management."}),`
+`]}),`
+`,e.jsxs(n.p,{children:["For more implementation details, please refer to the ",e.jsx(n.a,{href:"https://github.com/apache/hbase/tree/master/dev-support/design-docs",children:"design doc"})," and ",e.jsx(n.a,{href:"https://issues.apache.org/jira/browse/HBASE-18095",children:"HBASE-18095"}),"."]}),`
+`,e.jsx(n.h2,{id:"rpc-connection-registry-new-as-of-250",children:"Rpc Connection Registry (new as of 2.5.0)"}),`
+`,e.jsxs(n.p,{children:["As said in the ",e.jsx(n.a,{href:"/docs/architecture/client#masterregistry-rpc-hedging",children:"Master Registry (new as of 2.3.0)"})," section, there are some disadvantages and limitations for MasterRegistry, especially that it puts master in the critical path of read/write operations. In order to address these problems, we introduced a more generic RpcConnectionRegistry."]}),`
+`,e.jsx(n.p,{children:"It is also rpc based, like MasterRegistry, with several differences"}),`
+`,e.jsxs(n.ol,{children:[`
+`,e.jsx(n.li,{children:"Region server also implements the necessary rpc service, so you can config any nodes in the cluster as bootstrap nodes, not only masters"}),`
+`,e.jsx(n.li,{children:"Support refreshing bootstrap nodes, for spreading loads across the nodes in the cluster, and also remove the dead nodes in bootstrap nodes."}),`
+`]}),`
+`,e.jsx(n.p,{children:"To explicitly enable the rpc-based registry, use"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.registry.impl</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">org.apache.hadoop.hbase.client.RpcConnectionRegistry</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-li [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(n.p,{children:"To configure the bootstrap nodes, use"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.bootstrap.servers</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">server1:16020,server2:16020,server3:16020</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"#2429 [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(n.p,{children:"If not configured, we will fallback to use master addresses as the bootstrap nodes."}),`
+`,e.jsx(n.p,{children:"RpcConnectionRegistry is available in 2.5+, and becomes the default client registry implementation in 3.0.0."}),`
+`,e.jsx(n.h3,{id:"rpcconnectionregistry-rpc-hedging",children:"RpcConnectionRegistry RPC hedging"}),`
+`,e.jsxs(n.p,{children:["Hedged read is still supported, the configuration key is now ",e.jsx(n.em,{children:"hbase.client.bootstrap.hedged.fanout"}),", and its default value is still 2."]}),`
+`,e.jsx(n.h3,{id:"rpcconnectionregistry-bootstrap-nodes-refreshing",children:"RpcConnectionRegistry bootstrap nodes refreshing"}),`
+`,e.jsx(n.p,{children:"There are basically two reasons for us to refresh the bootstrap nodes"}),`
+`,e.jsxs(n.ul,{children:[`
+`,e.jsxs(n.li,{children:[`
+`,e.jsx(n.p,{children:"Periodically. This is for spreading loads across the nodes in the cluster. There are two configurations"}),`
+`,e.jsxs(n.ol,{children:[`
+`,e.jsxs(n.li,{children:[e.jsx(n.em,{children:"hbase.client.bootstrap.refresh_interval_secs"}),": the refresh interval in seconds, default 300. A value less than or equal to zero means disable refreshing."]}),`
+`,e.jsxs(n.li,{children:[e.jsx(n.em,{children:"hbase.client.bootstrap.initial_refresh_delay_secs"}),": the initial refresh interval in seconds, the default value is 1/10 of ",e.jsx(n.em,{children:"hbase.client.bootstrap.refresh_interval_secs"}),". The reason why we want to introduce a separated configuration for the delay for first refreshing is that, as end users could configure any nodes in a cluster as the initial bootstrap nodes, it is possible that different end users will configure [...]
+`]}),`
+`]}),`
+`,e.jsxs(n.li,{children:[`
+`,e.jsxs(n.p,{children:["When there is a connection error while requesting the nodes, we will refresh immediately, to remove the dead nodes. To avoid putting too much pressure to the cluster, there is a configuration ",e.jsx(n.em,{children:"hbase.client.bootstrap.min_secs_between_refreshes"}),", to control the minimum interval between two refreshings. The default value is 60, but notice that, if you change ",e.jsx(n.em,{children:"hbase.client.bootstrap.refresh_interval_secs"})," to a sma [...]
+`]}),`
+`]}),`
+`,e.jsx(i,{type:"info",children:e.jsx(n.p,{children:`(Advanced) In case of any issues with the rpc/master based registry, use the following
+configuration to fallback to the ZooKeeper based connection registry implementation.`})}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.registry.impl</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">org.apache.hadoop.hbase.client.ZKConnectionRegistry</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(n.span,{style:{"--shiki-lig [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(n.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(n.h2,{id:"connection-uri",children:"Connection URI"}),`
+`,e.jsxs(n.p,{children:[`Starting from 2.7.0, we add the support for specifying the connection information for a HBase cluster through an URI, which we call a "connection URI". And we've added several methods in `,e.jsx(n.em,{children:"ConnectionFactory"})," to let you get a connection to the cluster specified by the URI. It looks like:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(n.span,{className:"line",children:[e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"try"}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Connection conn "}),e.jsx(n.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ConnectionFactory."}),e.jsx(n.span,{style:{"--shiki-light":"#6F42C1","--shiki-dar [...]
+`,e.jsx(n.span,{className:"line",children:e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  ..."})}),`
+`,e.jsx(n.span,{className:"line",children:e.jsx(n.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})})]})})}),`
+`,e.jsx(n.h3,{id:"supported-schemes",children:"Supported Schemes"}),`
+`,e.jsxs(n.p,{children:["Currently there are two schemes supported, ",e.jsx(n.em,{children:"hbase+rpc"})," for ",e.jsx(n.em,{children:"RpcConnectionRegistry"})," and ",e.jsx(n.em,{children:"hbase+zk"})," for ",e.jsx(n.em,{children:"ZKConnectionRegistry"}),". ",e.jsx(n.em,{children:"MasterRegistry"})," is deprecated so we do not expose it through connection URI."]}),`
+`,e.jsxs(n.p,{children:["For ",e.jsx(n.em,{children:"hbase+rpc"}),", it looks like"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(n.p,{children:["The authority part ",e.jsx(n.em,{children:"server1:16020,server2:16020,server3:16020"})," specifies the bootstrap nodes and their rpc ports, i.e, the configuration value for ",e.jsx(n.em,{children:"hbase.client.bootstrap.servers"})," in the past."]}),`
+`,e.jsxs(n.p,{children:["For ",e.jsx(n.em,{children:"hbase+zk"}),", it looks like"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(n.p,{children:["The authority part ",e.jsx(n.em,{children:"zk1:2181,zk2:2181,zk3:2181"})," is the zk quorum, i.e, the configuration value for ",e.jsx(n.em,{children:"hbase.zookeeper.quorum"})," in the past. The path part ",e.jsx(n.em,{children:"/hbase"})," is the znode parent, i.e, the configuration value for ",e.jsx(n.em,{children:"zookeeper.znode.parent"})," in the past."]}),`
+`,e.jsx(n.h3,{id:"specify-configuration-through-uri-queries",children:"Specify Configuration through URI Queries"}),`
+`,e.jsx(n.p,{children:"To let users fully specify the connection information through a connection URI, we support specifying configuration values through URI Queries. It looks like:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(n.p,{children:"In this way you can set the operation timeout to 10 seconds. Notice that, the configuration values specified in the connection URI will override the ones in the configuration file."}),`
+`,e.jsx(n.h3,{id:"implement-your-own-connection-registry",children:"Implement Your Own Connection Registry"}),`
+`,e.jsxs(n.p,{children:["We use ",e.jsx(n.em,{children:"ServiceLoader"})," to load different connection registry implementations, the entry point is ",e.jsx(n.em,{children:"org.apache.hadoop.hbase.client.ConnectionRegistryURIFactory"}),". So if you implement your own ",e.jsx(n.em,{children:"ConnectionRegistryURIFactory"})," which has a different scheme, and register it in the services file, we can load it at runtime."]}),`
+`,e.jsxs(n.p,{children:["Connection URI is still a very new feature which has not been used extensively in production, so we do not want to expose the ability to customize ",e.jsx(n.em,{children:"ConnectionRegistryURIFactory"})," yet as the API may be changed frequently in the beginning."]}),`
+`,e.jsx(n.p,{children:"If you really want to implement your own connection registry, you can use the above way but take your own risk."})]})}function p(t={}){const{wrapper:n}=t.components||{};return n?e.jsx(n,{...t,children:e.jsx(s,{...t})}):s(t)}function a(t,n){throw new Error("Expected component `"+t+"` to be defined: you likely forgot to import, pass, or provide it.")}export{o as _markdown,p as default,c as extractedReferences,h as frontmatter,l as structuredData,d as toc};
diff --git a/assets/client-access-iVnBKoAb.js b/assets/client-access-iVnBKoAb.js
new file mode 100644
index 00000000000..dd18309335f
--- /dev/null
+++ b/assets/client-access-iVnBKoAb.js
@@ -0,0 +1,495 @@
+import{j as i}from"./chunk-EPOLDU6W-B5LwAila.js";let r=`Newer releases of Apache HBase (>= 0.92) support optional SASL authentication of clients. See also Matteo Bertozzi's article on [Understanding User Authentication and Authorization in Apache HBase](https://blog.cloudera.com/blog/2012/09/understanding-user-authentication-and-authorization-in-apache-hbase/).
+
+This describes how to set up Apache HBase and clients for connection to secure HBase resources.
+
+## Prerequisites
+
+#### Hadoop Authentication Configuration \\[!toc]
+
+To run HBase RPC with strong authentication, you must set \`hbase.security.authentication\` to \`kerberos\`. In this case, you must also set \`hadoop.security.authentication\` to \`kerberos\` in core-site.xml. Otherwise, you would be using strong authentication for HBase but not for the underlying HDFS, which would cancel out any benefit.
+
+#### Kerberos KDC \\[!toc]
+
+You need to have a working Kerberos KDC.
+
+## Server-side Configuration for Secure Operation
+
+First, refer to [security.prerequisites](/docs/security/client-access#security-client-access-prerequisites) and ensure that your underlying HDFS configuration is secure.
+
+Add the following to the \`hbase-site.xml\` file on every server machine in the cluster:
+
+\`\`\`xml
+<property>
+  <name>hbase.security.authentication</name>
+  <value>kerberos</value>
+</property>
+<property>
+  <name>hbase.security.authorization</name>
+  <value>true</value>
+</property>
+<property>
+<name>hbase.coprocessor.region.classes</name>
+  <value>org.apache.hadoop.hbase.security.token.TokenProvider</value>
+</property>
+\`\`\`
+
+A full shutdown and restart of HBase service is required when deploying these configuration changes.
+
+## Client-side Configuration for Secure Operation
+
+First, refer to [Prerequisites](/docs/security/client-access#security-client-access-prerequisites) and ensure that your underlying HDFS configuration is secure.
+
+Add the following to the \`hbase-site.xml\` file on every client:
+
+\`\`\`xml
+<property>
+  <name>hbase.security.authentication</name>
+  <value>kerberos</value>
+</property>
+\`\`\`
+
+Before 2.2.0 version, the client environment must be logged in to Kerberos from KDC or keytab via the \`kinit\` command before communication with the HBase cluster will be possible.
+
+Since 2.2.0, client can specify the following configurations in \`hbase-site.xml\`:
+
+\`\`\`xml
+<property>
+  <name>hbase.client.keytab.file</name>
+  <value>/local/path/to/client/keytab</value>
+</property>
+
+<property>
+  <name>hbase.client.keytab.principal</name>
+  <value>foo@EXAMPLE.COM</value>
+</property>
+\`\`\`
+
+Then application can automatically do the login and credential renewal jobs without client interference.
+
+It's optional feature, client, who upgrades to 2.2.0, can still keep their login and credential renewal logic already did in older version, as long as keeping \`hbase.client.keytab.file\` and \`hbase.client.keytab.principal\` are unset.
+
+Be advised that if the \`hbase.security.authentication\` in the client- and server-side site files do not match, the client will not be able to communicate with the cluster.
+
+Once HBase is configured for secure RPC it is possible to optionally configure encrypted communication. To do so, add the following to the \`hbase-site.xml\` file on every client:
+
+\`\`\`xml
+<property>
+  <name>hbase.rpc.protection</name>
+  <value>privacy</value>
+</property>
+\`\`\`
+
+This configuration property can also be set on a per-connection basis. Set it in the \`Configuration\` supplied to \`Table\`:
+
+\`\`\`java
+Configuration conf = HBaseConfiguration.create();
+Connection connection = ConnectionFactory.createConnection(conf);
+conf.set("hbase.rpc.protection", "privacy");
+try (Connection connection = ConnectionFactory.createConnection(conf);
+     Table table = connection.getTable(TableName.valueOf(tablename))) {
+  .... do your stuff
+}
+\`\`\`
+
+Expect a \\~10% performance penalty for encrypted communication.
+
+## Client-side Configuration for Secure Operation - Thrift Gateway
+
+Add the following to the \`hbase-site.xml\` file for every Thrift gateway:
+
+\`\`\`xml
+<property>
+  <name>hbase.thrift.keytab.file</name>
+  <value>/etc/hbase/conf/hbase.keytab</value>
+</property>
+<property>
+  <name>hbase.thrift.kerberos.principal</name>
+  <value>$USER/_HOST@HADOOP.LOCALDOMAIN</value>
+  <!-- TODO: This may need to be  HTTP/_HOST@<REALM> and _HOST may not work.
+   You may have  to put the concrete full hostname.
+   -->
+</property>
+<!-- Add these if you need to configure a different DNS interface from the default -->
+<property>
+  <name>hbase.thrift.dns.interface</name>
+  <value>default</value>
+</property>
+<property>
+  <name>hbase.thrift.dns.nameserver</name>
+  <value>default</value>
+</property>
+\`\`\`
+
+Substitute the appropriate credential and keytab for *\\$USER* and *\\$KEYTAB* respectively.
+
+In order to use the Thrift API principal to interact with HBase, it is also necessary to add the \`hbase.thrift.kerberos.principal\` to the \`acl\` table. For example, to give the Thrift API principal, \`thrift_server\`, administrative access, a command such as this one will suffice:
+
+\`\`\`sql
+grant 'thrift_server', 'RWCA'
+\`\`\`
+
+For more information about ACLs, please see the [Access Control Labels (ACLs)](/docs/security/data-access#access-control-labels-acls) section
+
+The Thrift gateway will authenticate with HBase using the supplied credential. No authentication will be performed by the Thrift gateway itself. All client access via the Thrift gateway will use the Thrift gateway's credential and have its privilege.
+
+## Configure the Thrift Gateway to Authenticate on Behalf of the Client
+
+[Client-side Configuration for Secure Operation - Thrift Gateway](/docs/security/client-access#client-side-configuration-for-secure-operation---thrift-gateway) describes how to authenticate a Thrift client to HBase using a fixed user. As an alternative, you can configure the Thrift gateway to authenticate to HBase on the client's behalf, and to access HBase using a proxy user. This was implemented in [HBASE-11349](https://issues.apache.org/jira/browse/HBASE-11349) for Thrift 1, and [HBAS [...]
+
+<Callout type="info">
+  If you use framed transport, you cannot yet take advantage of this feature, because SASL does not
+  work with Thrift framed transport at this time.
+</Callout>
+
+To enable it, do the following.
+
+1. Be sure Thrift is running in secure mode, by following the procedure described in [Client-side Configuration for Secure Operation - Thrift Gateway](/docs/security/client-access#client-side-configuration-for-secure-operation---thrift-gateway).
+2. Be sure that HBase is configured to allow proxy users, as described in [REST Gateway Impersonation Configuration](/docs/security/client-access#rest-gateway-impersonation-configuration).
+3. In *hbase-site.xml* for each cluster node running a Thrift gateway, set the property \`hbase.thrift.security.qop\` to one of the following three values:
+   * \`privacy\` - authentication, integrity, and confidentiality checking.
+   * \`integrity\` - authentication and integrity checking
+   * \`authentication\` - authentication checking only
+4. Restart the Thrift gateway processes for the changes to take effect. If a node is running Thrift, the output of the \`jps\` command will list a \`ThriftServer\` process. To stop Thrift on a node, run the command \`bin/hbase-daemon.sh stop thrift\`. To start Thrift on a node, run the command \`bin/hbase-daemon.sh start thrift\`.
+
+## Configure the Thrift Gateway to Use the \`doAs\` Feature
+
+[Configure the Thrift Gateway to Authenticate on Behalf of the Client](/docs/security/client-access#configure-the-thrift-gateway-to-authenticate-on-behalf-of-the-client) describes how to configure the Thrift gateway to authenticate to HBase on the client's behalf, and to access HBase using a proxy user. The limitation of this approach is that after the client is initialized with a particular set of credentials, it cannot change these credentials during the session. The \`doAs\` feature p [...]
+
+**To enable the \`doAs\` feature**, add the following to the *hbase-site.xml* file for every Thrift gateway:
+
+\`\`\`xml
+<property>
+  <name>hbase.regionserver.thrift.http</name>
+  <value>true</value>
+</property>
+<property>
+  <name>hbase.thrift.support.proxyuser</name>
+  <value>true</value>
+</property>
+\`\`\`
+
+**To allow proxy users** when using \`doAs\` impersonation, add the following to the *hbase-site.xml* file for every HBase node:
+
+\`\`\`xml
+<property>
+  <name>hadoop.security.authorization</name>
+  <value>true</value>
+</property>
+<property>
+  <name>hadoop.proxyuser.$USER.groups</name>
+  <value>$GROUPS</value>
+</property>
+<property>
+  <name>hadoop.proxyuser.$USER.hosts</name>
+  <value>$GROUPS</value>
+</property>
+\`\`\`
+
+Take a look at the [demo client](https://github.com/apache/hbase/blob/master/hbase-examples/src/main/java/org/apache/hadoop/hbase/thrift/HttpDoAsClient.java) to get an overall idea of how to use this feature in your client.
+
+## Client-side Configuration for Secure Operation - REST Gateway
+
+Add the following to the \`hbase-site.xml\` file for every REST gateway:
+
+\`\`\`xml
+<property>
+  <name>hbase.rest.keytab.file</name>
+  <value>$KEYTAB</value>
+</property>
+<property>
+  <name>hbase.rest.kerberos.principal</name>
+  <value>$USER/_HOST@HADOOP.LOCALDOMAIN</value>
+</property>
+\`\`\`
+
+Substitute the appropriate credential and keytab for *\\$USER* and *\\$KEYTAB* respectively.
+
+The REST gateway will authenticate with HBase using the supplied credential.
+
+In order to use the REST API principal to interact with HBase, it is also necessary to add the \`hbase.rest.kerberos.principal\` to the \`acl\` table. For example, to give the REST API principal, \`rest_server\`, administrative access, a command such as this one will suffice:
+
+\`\`\`sql
+grant 'rest_server', 'RWCA'
+\`\`\`
+
+For more information about ACLs, please see the [Access Control Labels (ACLs)](/docs/security/data-access#access-control-labels-acls) section
+
+HBase REST gateway supports [SPNEGO HTTP authentication](https://hadoop.apache.org/docs/stable/hadoop-auth/index.html) for client access to the gateway. To enable REST gateway Kerberos authentication for client access, add the following to the \`hbase-site.xml\` file for every REST gateway.
+
+\`\`\`xml
+<property>
+  <name>hbase.rest.support.proxyuser</name>
+  <value>true</value>
+</property>
+<property>
+  <name>hbase.rest.authentication.type</name>
+  <value>kerberos</value>
+</property>
+<property>
+  <name>hbase.rest.authentication.kerberos.principal</name>
+  <value>HTTP/_HOST@HADOOP.LOCALDOMAIN</value>
+</property>
+<property>
+  <name>hbase.rest.authentication.kerberos.keytab</name>
+  <value>$KEYTAB</value>
+</property>
+<!-- Add these if you need to configure a different DNS interface from the default -->
+<property>
+  <name>hbase.rest.dns.interface</name>
+  <value>default</value>
+</property>
+<property>
+  <name>hbase.rest.dns.nameserver</name>
+  <value>default</value>
+</property>
+\`\`\`
+
+Substitute the keytab for HTTP for *\\$KEYTAB*.
+
+HBase REST gateway supports different 'hbase.rest.authentication.type': simple, kerberos. You can also implement a custom authentication by implementing Hadoop AuthenticationHandler, then specify the full class name as 'hbase.rest.authentication.type' value. For more information, refer to [SPNEGO HTTP authentication](https://hadoop.apache.org/docs/stable/hadoop-auth/index.html).
+
+## REST Gateway Impersonation Configuration
+
+By default, the REST gateway doesn't support impersonation. It accesses the HBase on behalf of clients as the user configured as in the previous section. To the HBase server, all requests are from the REST gateway user. The actual users are unknown. You can turn on the impersonation support. With impersonation, the REST gateway user is a proxy user. The HBase server knows the actual/real user of each request. So it can apply proper authorizations.
+
+To turn on REST gateway impersonation, we need to configure HBase servers (masters and region servers) to allow proxy users; configure REST gateway to enable impersonation.
+
+To allow proxy users, add the following to the \`hbase-site.xml\` file for every HBase server:
+
+\`\`\`xml
+<property>
+  <name>hadoop.security.authorization</name>
+  <value>true</value>
+</property>
+<property>
+  <name>hadoop.proxyuser.$USER.groups</name>
+  <value>$GROUPS</value>
+</property>
+<property>
+  <name>hadoop.proxyuser.$USER.hosts</name>
+  <value>$GROUPS</value>
+</property>
+\`\`\`
+
+Substitute the REST gateway proxy user for *\\$USER*, and the allowed group list for *\\$GROUPS*.
+
+To enable REST gateway impersonation, add the following to the \`hbase-site.xml\` file for every REST gateway.
+
+\`\`\`xml
+<property>
+  <name>hbase.rest.authentication.type</name>
+  <value>kerberos</value>
+</property>
+<property>
+  <name>hbase.rest.authentication.kerberos.principal</name>
+  <value>HTTP/_HOST@HADOOP.LOCALDOMAIN</value>
+</property>
+<property>
+  <name>hbase.rest.authentication.kerberos.keytab</name>
+  <value>$KEYTAB</value>
+</property>
+\`\`\`
+
+Substitute the keytab for HTTP for *\\$KEYTAB*.
+`,l={title:"Secure Client Access to Apache HBase",description:"Configuring Kerberos-based secure authentication for HBase clients, including server and client setup procedures."},o=[{href:"https://blog.cloudera.com/blog/2012/09/understanding-user-authentication-and-authorization-in-apache-hbase/"},{href:"/docs/security/client-access#security-client-access-prerequisites"},{href:"/docs/security/client-access#security-client-access-prerequisites"},{href:"/docs/security/data-access#access-co [...]
+work with Thrift framed transport at this time.`},{heading:"configure-the-thrift-gateway-to-authenticate-on-behalf-of-the-client",content:"To enable it, do the following."},{heading:"configure-the-thrift-gateway-to-authenticate-on-behalf-of-the-client",content:"Be sure Thrift is running in secure mode, by following the procedure described in Client-side Configuration for Secure Operation - Thrift Gateway."},{heading:"configure-the-thrift-gateway-to-authenticate-on-behalf-of-the-client",c [...]
+`,i.jsx(e.p,{children:"This describes how to set up Apache HBase and clients for connection to secure HBase resources."}),`
+`,i.jsx(e.h2,{id:"security-client-access-prerequisites",children:"Prerequisites"}),`
+`,i.jsx(e.h4,{id:"hadoop-authentication-configuration-toc",children:"Hadoop Authentication Configuration"}),`
+`,i.jsxs(e.p,{children:["To run HBase RPC with strong authentication, you must set ",i.jsx(e.code,{children:"hbase.security.authentication"})," to ",i.jsx(e.code,{children:"kerberos"}),". In this case, you must also set ",i.jsx(e.code,{children:"hadoop.security.authentication"})," to ",i.jsx(e.code,{children:"kerberos"})," in core-site.xml. Otherwise, you would be using strong authentication for HBase but not for the underlying HDFS, which would cancel out any benefit."]}),`
+`,i.jsx(e.h4,{id:"kerberos-kdc-toc",children:"Kerberos KDC"}),`
+`,i.jsx(e.p,{children:"You need to have a working Kerberos KDC."}),`
+`,i.jsx(e.h2,{id:"server-side-configuration-for-secure-operation",children:"Server-side Configuration for Secure Operation"}),`
+`,i.jsxs(e.p,{children:["First, refer to ",i.jsx(e.a,{href:"/docs/security/client-access#security-client-access-prerequisites",children:"security.prerequisites"})," and ensure that your underlying HDFS configuration is secure."]}),`
+`,i.jsxs(e.p,{children:["Add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file on every server machine in the cluster:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.security.authentication</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">kerberos</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chi [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.security.authorization</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-da [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.coprocessor.region.classes</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">org.apache.hadoop.hbase.security.token.TokenProvider</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-li [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsx(e.p,{children:"A full shutdown and restart of HBase service is required when deploying these configuration changes."}),`
+`,i.jsx(e.h2,{id:"client-side-configuration-for-secure-operation",children:"Client-side Configuration for Secure Operation"}),`
+`,i.jsxs(e.p,{children:["First, refer to ",i.jsx(e.a,{href:"/docs/security/client-access#security-client-access-prerequisites",children:"Prerequisites"})," and ensure that your underlying HDFS configuration is secure."]}),`
+`,i.jsxs(e.p,{children:["Add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file on every client:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.security.authentication</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">kerberos</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chi [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Before 2.2.0 version, the client environment must be logged in to Kerberos from KDC or keytab via the ",i.jsx(e.code,{children:"kinit"})," command before communication with the HBase cluster will be possible."]}),`
+`,i.jsxs(e.p,{children:["Since 2.2.0, client can specify the following configurations in ",i.jsx(e.code,{children:"hbase-site.xml"}),":"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.keytab.file</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark": [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">/local/path/to/client/keytab</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsx(e.span,{className:"line"}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.client.keytab.principal</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">foo@EXAMPLE.COM</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsx(e.p,{children:"Then application can automatically do the login and credential renewal jobs without client interference."}),`
+`,i.jsxs(e.p,{children:["It's optional feature, client, who upgrades to 2.2.0, can still keep their login and credential renewal logic already did in older version, as long as keeping ",i.jsx(e.code,{children:"hbase.client.keytab.file"})," and ",i.jsx(e.code,{children:"hbase.client.keytab.principal"})," are unset."]}),`
+`,i.jsxs(e.p,{children:["Be advised that if the ",i.jsx(e.code,{children:"hbase.security.authentication"})," in the client- and server-side site files do not match, the client will not be able to communicate with the cluster."]}),`
+`,i.jsxs(e.p,{children:["Once HBase is configured for secure RPC it is possible to optionally configure encrypted communication. To do so, add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file on every client:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rpc.protection</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1 [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">privacy</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["This configuration property can also be set on a per-connection basis. Set it in the ",i.jsx(e.code,{children:"Configuration"})," supplied to ",i.jsx(e.code,{children:"Table"}),":"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Connection connection "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ConnectionFactory."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"createConnection"}),i.jsx(e.span,{style:{"--shiki-light":"#242 [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"conf."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"set"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'"hbase.rpc.protection"'}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"try"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Connection connection "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ConnectionFactory."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shi [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"     Table table "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" connection."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"getTable"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark": [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  .... do your stuff"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})})]})})}),`
+`,i.jsx(e.p,{children:"Expect a ~10% performance penalty for encrypted communication."}),`
+`,i.jsx(e.h2,{id:"client-side-configuration-for-secure-operation---thrift-gateway",children:"Client-side Configuration for Secure Operation - Thrift Gateway"}),`
+`,i.jsxs(e.p,{children:["Add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file for every Thrift gateway:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.thrift.keytab.file</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark": [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">/etc/hbase/conf/hbase.keytab</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.thrift.kerberos.principal</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$USER/_HOST@HADOOP.LOCALDOMAIN</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shik [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"  <!-- TODO: This may need to be  HTTP/_HOST@<REALM> and _HOST may not work."})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"   You may have  to put the concrete full hostname."})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"   -->"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"<!-- Add these if you need to configure a different DNS interface from the default -->"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.thrift.dns.interface</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">default</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.thrift.dns.nameserver</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dar [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">default</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Substitute the appropriate credential and keytab for ",i.jsx(e.em,{children:"$USER"})," and ",i.jsx(e.em,{children:"$KEYTAB"})," respectively."]}),`
+`,i.jsxs(e.p,{children:["In order to use the Thrift API principal to interact with HBase, it is also necessary to add the ",i.jsx(e.code,{children:"hbase.thrift.kerberos.principal"})," to the ",i.jsx(e.code,{children:"acl"})," table. For example, to give the Thrift API principal, ",i.jsx(e.code,{children:"thrift_server"}),", administrative access, a command such as this one will suffice:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.p,{children:["For more information about ACLs, please see the ",i.jsx(e.a,{href:"/docs/security/data-access#access-control-labels-acls",children:"Access Control Labels (ACLs)"})," section"]}),`
+`,i.jsx(e.p,{children:"The Thrift gateway will authenticate with HBase using the supplied credential. No authentication will be performed by the Thrift gateway itself. All client access via the Thrift gateway will use the Thrift gateway's credential and have its privilege."}),`
+`,i.jsx(e.h2,{id:"configure-the-thrift-gateway-to-authenticate-on-behalf-of-the-client",children:"Configure the Thrift Gateway to Authenticate on Behalf of the Client"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"/docs/security/client-access#client-side-configuration-for-secure-operation---thrift-gateway",children:"Client-side Configuration for Secure Operation - Thrift Gateway"})," describes how to authenticate a Thrift client to HBase using a fixed user. As an alternative, you can configure the Thrift gateway to authenticate to HBase on the client's behalf, and to access HBase using a proxy user. This was implemented in ",i.jsx(e.a,{href:"https://issues. [...]
+`,i.jsx(t,{type:"info",children:i.jsx(e.p,{children:`If you use framed transport, you cannot yet take advantage of this feature, because SASL does not
+work with Thrift framed transport at this time.`})}),`
+`,i.jsx(e.p,{children:"To enable it, do the following."}),`
+`,i.jsxs(e.ol,{children:[`
+`,i.jsxs(e.li,{children:["Be sure Thrift is running in secure mode, by following the procedure described in ",i.jsx(e.a,{href:"/docs/security/client-access#client-side-configuration-for-secure-operation---thrift-gateway",children:"Client-side Configuration for Secure Operation - Thrift Gateway"}),"."]}),`
+`,i.jsxs(e.li,{children:["Be sure that HBase is configured to allow proxy users, as described in ",i.jsx(e.a,{href:"/docs/security/client-access#rest-gateway-impersonation-configuration",children:"REST Gateway Impersonation Configuration"}),"."]}),`
+`,i.jsxs(e.li,{children:["In ",i.jsx(e.em,{children:"hbase-site.xml"})," for each cluster node running a Thrift gateway, set the property ",i.jsx(e.code,{children:"hbase.thrift.security.qop"})," to one of the following three values:",`
+`,i.jsxs(e.ul,{children:[`
+`,i.jsxs(e.li,{children:[i.jsx(e.code,{children:"privacy"})," - authentication, integrity, and confidentiality checking."]}),`
+`,i.jsxs(e.li,{children:[i.jsx(e.code,{children:"integrity"})," - authentication and integrity checking"]}),`
+`,i.jsxs(e.li,{children:[i.jsx(e.code,{children:"authentication"})," - authentication checking only"]}),`
+`]}),`
+`]}),`
+`,i.jsxs(e.li,{children:["Restart the Thrift gateway processes for the changes to take effect. If a node is running Thrift, the output of the ",i.jsx(e.code,{children:"jps"})," command will list a ",i.jsx(e.code,{children:"ThriftServer"})," process. To stop Thrift on a node, run the command ",i.jsx(e.code,{children:"bin/hbase-daemon.sh stop thrift"}),". To start Thrift on a node, run the command ",i.jsx(e.code,{children:"bin/hbase-daemon.sh start thrift"}),"."]}),`
+`]}),`
+`,i.jsxs(e.h2,{id:"configure-the-thrift-gateway-to-use-the-doas-feature",children:["Configure the Thrift Gateway to Use the ",i.jsx(e.code,{children:"doAs"})," Feature"]}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"/docs/security/client-access#configure-the-thrift-gateway-to-authenticate-on-behalf-of-the-client",children:"Configure the Thrift Gateway to Authenticate on Behalf of the Client"})," describes how to configure the Thrift gateway to authenticate to HBase on the client's behalf, and to access HBase using a proxy user. The limitation of this approach is that after the client is initialized with a particular set of credentials, it cannot change these  [...]
+`,i.jsxs(e.p,{children:[i.jsxs(e.strong,{children:["To enable the ",i.jsx(e.code,{children:"doAs"})," feature"]}),", add the following to the ",i.jsx(e.em,{children:"hbase-site.xml"})," file for every Thrift gateway:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.regionserver.thrift.http</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.thrift.support.proxyuser</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.strong,{children:"To allow proxy users"})," when using ",i.jsx(e.code,{children:"doAs"})," impersonation, add the following to the ",i.jsx(e.em,{children:"hbase-site.xml"})," file for every HBase node:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hadoop.security.authorization</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hadoop.proxyuser.$USER.groups</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$GROUPS</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hadoop.proxyuser.$USER.hosts</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-da [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$GROUPS</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Take a look at the ",i.jsx(e.a,{href:"https://github.com/apache/hbase/blob/master/hbase-examples/src/main/java/org/apache/hadoop/hbase/thrift/HttpDoAsClient.java",children:"demo client"})," to get an overall idea of how to use this feature in your client."]}),`
+`,i.jsx(e.h2,{id:"client-side-configuration-for-secure-operation---rest-gateway",children:"Client-side Configuration for Secure Operation - REST Gateway"}),`
+`,i.jsxs(e.p,{children:["Add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file for every REST gateway:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.keytab.file</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"# [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$KEYTAB</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.kerberos.principal</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$USER/_HOST@HADOOP.LOCALDOMAIN</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shik [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Substitute the appropriate credential and keytab for ",i.jsx(e.em,{children:"$USER"})," and ",i.jsx(e.em,{children:"$KEYTAB"})," respectively."]}),`
+`,i.jsx(e.p,{children:"The REST gateway will authenticate with HBase using the supplied credential."}),`
+`,i.jsxs(e.p,{children:["In order to use the REST API principal to interact with HBase, it is also necessary to add the ",i.jsx(e.code,{children:"hbase.rest.kerberos.principal"})," to the ",i.jsx(e.code,{children:"acl"})," table. For example, to give the REST API principal, ",i.jsx(e.code,{children:"rest_server"}),", administrative access, a command such as this one will suffice:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.p,{children:["For more information about ACLs, please see the ",i.jsx(e.a,{href:"/docs/security/data-access#access-control-labels-acls",children:"Access Control Labels (ACLs)"})," section"]}),`
+`,i.jsxs(e.p,{children:["HBase REST gateway supports ",i.jsx(e.a,{href:"https://hadoop.apache.org/docs/stable/hadoop-auth/index.html",children:"SPNEGO HTTP authentication"})," for client access to the gateway. To enable REST gateway Kerberos authentication for client access, add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file for every REST gateway."]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.support.proxyuser</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-da [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.authentication.type</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">kerberos</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chi [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.authentication.kerberos.principal</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#242 [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">HTTP/_HOST@HADOOP.LOCALDOMAIN</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.authentication.kerberos.keytab</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$KEYTAB</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"<!-- Add these if you need to configure a different DNS interface from the default -->"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.dns.interface</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark": [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">default</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.dns.nameserver</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark" [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">default</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Substitute the keytab for HTTP for ",i.jsx(e.em,{children:"$KEYTAB"}),"."]}),`
+`,i.jsxs(e.p,{children:["HBase REST gateway supports different 'hbase.rest.authentication.type': simple, kerberos. You can also implement a custom authentication by implementing Hadoop AuthenticationHandler, then specify the full class name as 'hbase.rest.authentication.type' value. For more information, refer to ",i.jsx(e.a,{href:"https://hadoop.apache.org/docs/stable/hadoop-auth/index.html",children:"SPNEGO HTTP authentication"}),"."]}),`
+`,i.jsx(e.h2,{id:"rest-gateway-impersonation-configuration",children:"REST Gateway Impersonation Configuration"}),`
+`,i.jsx(e.p,{children:"By default, the REST gateway doesn't support impersonation. It accesses the HBase on behalf of clients as the user configured as in the previous section. To the HBase server, all requests are from the REST gateway user. The actual users are unknown. You can turn on the impersonation support. With impersonation, the REST gateway user is a proxy user. The HBase server knows the actual/real user of each request. So it can apply proper authorizations."}),`
+`,i.jsx(e.p,{children:"To turn on REST gateway impersonation, we need to configure HBase servers (masters and region servers) to allow proxy users; configure REST gateway to enable impersonation."}),`
+`,i.jsxs(e.p,{children:["To allow proxy users, add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file for every HBase server:"]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hadoop.security.authorization</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">true</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hadoop.proxyuser.$USER.groups</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$GROUPS</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hadoop.proxyuser.$USER.hosts</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-da [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$GROUPS</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Substitute the REST gateway proxy user for ",i.jsx(e.em,{children:"$USER"}),", and the allowed group list for ",i.jsx(e.em,{children:"$GROUPS"}),"."]}),`
+`,i.jsxs(e.p,{children:["To enable REST gateway impersonation, add the following to the ",i.jsx(e.code,{children:"hbase-site.xml"})," file for every REST gateway."]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.authentication.type</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki- [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">kerberos</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chi [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.authentication.kerberos.principal</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#242 [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">HTTP/_HOST@HADOOP.LOCALDOMAIN</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.rest.authentication.kerberos.keytab</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">$KEYTAB</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),i.jsx(e.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,i.jsxs(e.p,{children:["Substitute the keytab for HTTP for ",i.jsx(e.em,{children:"$KEYTAB"}),"."]})]})}function k(s={}){const{wrapper:e}=s.components||{};return e?i.jsx(e,{...s,children:i.jsx(n,{...s})}):n(s)}function a(s,e){throw new Error("Expected component `"+s+"` to be defined: you likely forgot to import, pass, or provide it.")}export{r as _markdown,k as default,o as extractedReferences,l as frontmatter,c as structuredData,d as toc};
diff --git a/assets/client-request-filters-D3rpht6K.js b/assets/client-request-filters-D3rpht6K.js
new file mode 100644
index 00000000000..c99af297f7e
--- /dev/null
+++ b/assets/client-request-filters-D3rpht6K.js
@@ -0,0 +1,407 @@
+import{j as i}from"./chunk-EPOLDU6W-B5LwAila.js";let n=`[Get](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Get.html) and [Scan](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Scan.html) instances can be optionally configured with [filters](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/Filter.html) which are applied on the RegionServer.
+
+Filters can be confusing because there are many different types, and it is best to approach them by understanding the groups of Filter functionality.
+
+## Structural
+
+Structural Filters contain other Filters.
+
+### FilterList
+
+[FilterList](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/FilterList.html) represents a list of Filters with a relationship of \`FilterList.Operator.MUST_PASS_ALL\` or \`FilterList.Operator.MUST_PASS_ONE\` between the Filters. The following example shows an 'or' between two Filters (checking for either 'my value' or 'my other value' on the same attribute).
+
+\`\`\`java
+FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);
+SingleColumnValueFilter filter1 = new SingleColumnValueFilter(
+  cf,
+  column,
+  CompareOperator.EQUAL,
+  Bytes.toBytes("my value")
+  );
+list.add(filter1);
+SingleColumnValueFilter filter2 = new SingleColumnValueFilter(
+  cf,
+  column,
+  CompareOperator.EQUAL,
+  Bytes.toBytes("my other value")
+  );
+list.add(filter2);
+scan.setFilter(list);
+\`\`\`
+
+## Column Value
+
+### SingleColumnValueFilter
+
+A SingleColumnValueFilter (see: [https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html)) can be used to test column values for equivalence (\`CompareOperaor.EQUAL\`), inequality (\`CompareOperaor.NOT_EQUAL\`), or ranges (e.g., \`CompareOperaor.GREATER\`). The following is an example of testing equivalence of a column to a String value "my value"...
+
+\`\`\`java
+SingleColumnValueFilter filter = new SingleColumnValueFilter(
+  cf,
+  column,
+  CompareOperaor.EQUAL,
+  Bytes.toBytes("my value")
+  );
+scan.setFilter(filter);
+\`\`\`
+
+### ColumnValueFilter
+
+Introduced in HBase-2.0.0 version as a complementation of SingleColumnValueFilter, ColumnValueFilter gets matched cell only, while SingleColumnValueFilter gets the entire row (has other columns and values) to which the matched cell belongs. Parameters of constructor of ColumnValueFilter are the same as SingleColumnValueFilter.
+
+\`\`\`java
+ColumnValueFilter filter = new ColumnValueFilter(
+  cf,
+  column,
+  CompareOperaor.EQUAL,
+  Bytes.toBytes("my value")
+  );
+scan.setFilter(filter);
+\`\`\`
+
+Note. For simple query like "equals to a family:qualifier:value", we highly recommend to use the following way instead of using SingleColumnValueFilter or ColumnValueFilter:
+
+\`\`\`java
+Scan scan = new Scan();
+scan.addColumn(Bytes.toBytes("family"), Bytes.toBytes("qualifier"));
+ValueFilter vf = new ValueFilter(CompareOperator.EQUAL,
+  new BinaryComparator(Bytes.toBytes("value")));
+scan.setFilter(vf);
+...
+\`\`\`
+
+This scan will restrict to the specified column 'family:qualifier', avoiding scan of unrelated families and columns, which has better performance, and \`ValueFilter\` is the condition used to do the value filtering.
+
+But if query is much more complicated beyond this book, then please make your good choice case by case.
+
+## Column Value Comparators
+
+There are several Comparator classes in the Filter package that deserve special mention. These Comparators are used in concert with other Filters, such as [SingleColumnValueFilter](/docs/architecture/client-request-filters#singlecolumnvaluefilter).
+
+### RegexStringComparator
+
+[RegexStringComparator](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/RegexStringComparator.html) supports regular expressions for value comparisons.
+
+\`\`\`java
+RegexStringComparator comp = new RegexStringComparator("my.");   // any value that starts with 'my'
+SingleColumnValueFilter filter = new SingleColumnValueFilter(
+  cf,
+  column,
+  CompareOperaor.EQUAL,
+  comp
+  );
+scan.setFilter(filter);
+\`\`\`
+
+See the Oracle JavaDoc for [supported RegEx patterns in Java](http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html).
+
+### SubstringComparator
+
+[SubstringComparator](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SubstringComparator.html) can be used to determine if a given substring exists in a value. The comparison is case-insensitive.
+
+\`\`\`java
+SubstringComparator comp = new SubstringComparator("y val");   // looking for 'my value'
+SingleColumnValueFilter filter = new SingleColumnValueFilter(
+  cf,
+  column,
+  CompareOperaor.EQUAL,
+  comp
+  );
+scan.setFilter(filter);
+\`\`\`
+
+### BinaryPrefixComparator
+
+See [BinaryPrefixComparator](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryPrefixComparator.html).
+
+### BinaryComparator
+
+See [BinaryComparator](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryComparator.html).
+
+### BinaryComponentComparator
+
+[BinaryComponentComparator](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryComponentComparator.html) can be used to compare specific value at specific location with in the cell value. The comparison can be done for both ascii and binary data.
+
+\`\`\`java
+byte[] partialValue = Bytes.toBytes("partial_value");
+int partialValueOffset = 0;
+Filter partialValueFilter = new ValueFilter(CompareFilter.CompareOp.GREATER,
+        new BinaryComponentComparator(partialValue,partialValueOffset));
+\`\`\`
+
+See [HBASE-22969](https://issues.apache.org/jira/browse/HBASE-22969) for other use cases and details.
+
+## KeyValue Metadata
+
+As HBase stores data internally as KeyValue pairs, KeyValue Metadata Filters evaluate the existence of keys (i.e., ColumnFamily:Column qualifiers) for a row, as opposed to values the previous section.
+
+### FamilyFilter
+
+[FamilyFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/FamilyFilter.html) can be used to filter on the ColumnFamily. It is generally a better idea to select ColumnFamilies in the Scan than to do it with a Filter.
+
+### QualifierFilter
+
+[QualifierFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/QualifierFilter.html) can be used to filter based on Column (aka Qualifier) name.
+
+### ColumnPrefixFilter
+
+[ColumnPrefixFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/ColumnPrefixFilter.html) can be used to filter based on the lead portion of Column (aka Qualifier) names.
+
+A ColumnPrefixFilter seeks ahead to the first column matching the prefix in each row and for each involved column family. It can be used to efficiently get a subset of the columns in very wide rows.
+
+Note: The same column qualifier can be used in different column families. This filter returns all matching columns.
+
+Example: Find all columns in a row and family that start with "abc"
+
+\`\`\`java
+Table t = ...;
+byte[] row = ...;
+byte[] family = ...;
+byte[] prefix = Bytes.toBytes("abc");
+Scan scan = new Scan(row, row); // (optional) limit to one row
+scan.addFamily(family); // (optional) limit to one family
+Filter f = new ColumnPrefixFilter(prefix);
+scan.setFilter(f);
+scan.setBatch(10); // set this if there could be many columns returned
+ResultScanner rs = t.getScanner(scan);
+for (Result r = rs.next(); r != null; r = rs.next()) {
+  for (Cell cell : result.listCells()) {
+    // each cell represents a column
+  }
+}
+rs.close();
+\`\`\`
+
+### MultipleColumnPrefixFilter
+
+[MultipleColumnPrefixFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/MultipleColumnPrefixFilter.html) behaves like ColumnPrefixFilter but allows specifying multiple prefixes.
+
+Like ColumnPrefixFilter, MultipleColumnPrefixFilter efficiently seeks ahead to the first column matching the lowest prefix and also seeks past ranges of columns between prefixes. It can be used to efficiently get discontinuous sets of columns from very wide rows.
+
+Example: Find all columns in a row and family that start with "abc" or "xyz"
+
+\`\`\`java
+Table t = ...;
+byte[] row = ...;
+byte[] family = ...;
+byte[][] prefixes = new byte[][] {Bytes.toBytes("abc"), Bytes.toBytes("xyz")};
+Scan scan = new Scan(row, row); // (optional) limit to one row
+scan.addFamily(family); // (optional) limit to one family
+Filter f = new MultipleColumnPrefixFilter(prefixes);
+scan.setFilter(f);
+scan.setBatch(10); // set this if there could be many columns returned
+ResultScanner rs = t.getScanner(scan);
+for (Result r = rs.next(); r != null; r = rs.next()) {
+  for (Cell cell : result.listCells()) {
+    // each cell represents a column
+  }
+}
+rs.close();
+\`\`\`
+
+### ColumnRangeFilter
+
+A [ColumnRangeFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/ColumnRangeFilter.html) allows efficient intra row scanning.
+
+A ColumnRangeFilter can seek ahead to the first matching column for each involved column family. It can be used to efficiently get a 'slice' of the columns of a very wide row. i.e. you have a million columns in a row but you only want to look at columns bbbb-bbdd.
+
+Note: The same column qualifier can be used in different column families. This filter returns all matching columns.
+
+Example: Find all columns in a row and family between "bbbb" (inclusive) and "bbdd" (inclusive)
+
+\`\`\`java
+Table t = ...;
+byte[] row = ...;
+byte[] family = ...;
+byte[] startColumn = Bytes.toBytes("bbbb");
+byte[] endColumn = Bytes.toBytes("bbdd");
+Scan scan = new Scan(row, row); // (optional) limit to one row
+scan.addFamily(family); // (optional) limit to one family
+Filter f = new ColumnRangeFilter(startColumn, true, endColumn, true);
+scan.setFilter(f);
+scan.setBatch(10); // set this if there could be many columns returned
+ResultScanner rs = t.getScanner(scan);
+for (Result r = rs.next(); r != null; r = rs.next()) {
+  for (Cell cell : result.listCells()) {
+    // each cell represents a column
+  }
+}
+rs.close();
+\`\`\`
+
+Note: Introduced in HBase 0.92
+
+## RowKey
+
+### RowFilter
+
+It is generally a better idea to use the startRow/stopRow methods on Scan for row selection, however [RowFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/RowFilter.html) can also be used.
+
+You can supplement a scan (both bounded and unbounded) with RowFilter constructed from [BinaryComponentComparator](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryComponentComparator.html) for further filtering out or filtering in rows. See [HBASE-22969](https://issues.apache.org/jira/browse/HBASE-22969) for use cases and other details.
+
+## Utility
+
+### FirstKeyOnlyFilter
+
+This is primarily used for rowcount jobs. See [FirstKeyOnlyFilter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/FirstKeyOnlyFilter.html).
+`,t={title:"Client Request Filters",description:"Using filters with Get and Scan operations to efficiently query HBase data, including comparison, column, row, and utility filters."},r=[{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Get.html"},{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Scan.html"},{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/Filter.html"},{href:"https://hbase.apache.org/devapidocs/org/ [...]
+`,i.jsx(e.p,{children:"Filters can be confusing because there are many different types, and it is best to approach them by understanding the groups of Filter functionality."}),`
+`,i.jsx(e.h2,{id:"structural",children:"Structural"}),`
+`,i.jsx(e.p,{children:"Structural Filters contain other Filters."}),`
+`,i.jsx(e.h3,{id:"filterlist",children:"FilterList"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/FilterList.html",children:"FilterList"})," represents a list of Filters with a relationship of ",i.jsx(e.code,{children:"FilterList.Operator.MUST_PASS_ALL"})," or ",i.jsx(e.code,{children:"FilterList.Operator.MUST_PASS_ONE"})," between the Filters. The following example shows an 'or' between two Filters (checking for either 'my value' or 'my other value' on the same attribute)."]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"SingleColumnValueFilter filter1 "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" SingleColumnValueFilter"}),i.jsx(e.span,{style:{"--shiki-light":"# [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  cf,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  column,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  CompareOperator.EQUAL,"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"toBytes"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'"my value"'}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  );"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"list."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"add"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(filter1);"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"SingleColumnValueFilter filter2 "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" SingleColumnValueFilter"}),i.jsx(e.span,{style:{"--shiki-light":"# [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  cf,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  column,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  CompareOperator.EQUAL,"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"toBytes"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'"my other value"'}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4 [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  );"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"list."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"add"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(filter2);"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(list);"})]})]})})}),`
+`,i.jsx(e.h2,{id:"column-value",children:"Column Value"}),`
+`,i.jsx(e.h3,{id:"singlecolumnvaluefilter",children:"SingleColumnValueFilter"}),`
+`,i.jsxs(e.p,{children:["A SingleColumnValueFilter (see: ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html",children:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html"}),") can be used to test column values for equivalence (",i.jsx(e.code,{children:"CompareOperaor.EQUAL"}),"), inequality (",i.jsx(e.code,{children:"CompareOperaor.NOT_EQUAL"}),"), or ranges (e.g., ",i.jsx(e.code, [...]
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  cf,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  column,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  CompareOperaor.EQUAL,"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"toBytes"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'"my value"'}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  );"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(filter);"})]})]})})}),`
+`,i.jsx(e.h3,{id:"columnvaluefilter",children:"ColumnValueFilter"}),`
+`,i.jsx(e.p,{children:"Introduced in HBase-2.0.0 version as a complementation of SingleColumnValueFilter, ColumnValueFilter gets matched cell only, while SingleColumnValueFilter gets the entire row (has other columns and values) to which the matched cell belongs. Parameters of constructor of ColumnValueFilter are the same as SingleColumnValueFilter."}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  cf,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  column,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  CompareOperaor.EQUAL,"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"toBytes"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'"my value"'}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  );"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(filter);"})]})]})})}),`
+`,i.jsx(e.p,{children:'Note. For simple query like "equals to a family:qualifier:value", we highly recommend to use the following way instead of using SingleColumnValueFilter or ColumnValueFilter:'}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"addColumn"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"toBytes"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"} [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"ValueFilter vf "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" ValueFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4 [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"  new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" BinaryComparator"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"toBytes"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"# [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(vf);"})]}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"..."})})]})})}),`
+`,i.jsxs(e.p,{children:["This scan will restrict to the specified column 'family:qualifier', avoiding scan of unrelated families and columns, which has better performance, and ",i.jsx(e.code,{children:"ValueFilter"})," is the condition used to do the value filtering."]}),`
+`,i.jsx(e.p,{children:"But if query is much more complicated beyond this book, then please make your good choice case by case."}),`
+`,i.jsx(e.h2,{id:"column-value-comparators",children:"Column Value Comparators"}),`
+`,i.jsxs(e.p,{children:["There are several Comparator classes in the Filter package that deserve special mention. These Comparators are used in concert with other Filters, such as ",i.jsx(e.a,{href:"/docs/architecture/client-request-filters#singlecolumnvaluefilter",children:"SingleColumnValueFilter"}),"."]}),`
+`,i.jsx(e.h3,{id:"regexstringcomparator",children:"RegexStringComparator"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/RegexStringComparator.html",children:"RegexStringComparator"})," supports regular expressions for value comparisons."]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"SingleColumnValueFilter filter "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" SingleColumnValueFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#2 [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  cf,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  column,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  CompareOperaor.EQUAL,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  comp"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  );"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(filter);"})]})]})})}),`
+`,i.jsxs(e.p,{children:["See the Oracle JavaDoc for ",i.jsx(e.a,{href:"http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html",children:"supported RegEx patterns in Java"}),"."]}),`
+`,i.jsx(e.h3,{id:"substringcomparator",children:"SubstringComparator"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/SubstringComparator.html",children:"SubstringComparator"})," can be used to determine if a given substring exists in a value. The comparison is case-insensitive."]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"SingleColumnValueFilter filter "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" SingleColumnValueFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#2 [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  cf,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  column,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  CompareOperaor.EQUAL,"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  comp"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  );"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(filter);"})]})]})})}),`
+`,i.jsx(e.h3,{id:"binaryprefixcomparator",children:"BinaryPrefixComparator"}),`
+`,i.jsxs(e.p,{children:["See ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryPrefixComparator.html",children:"BinaryPrefixComparator"}),"."]}),`
+`,i.jsx(e.h3,{id:"binarycomparator",children:"BinaryComparator"}),`
+`,i.jsxs(e.p,{children:["See ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryComparator.html",children:"BinaryComparator"}),"."]}),`
+`,i.jsx(e.h3,{id:"binarycomponentcomparator",children:"BinaryComponentComparator"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryComponentComparator.html",children:"BinaryComponentComparator"})," can be used to compare specific value at specific location with in the cell value. The comparison can be done for both ascii and binary data."]}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"int"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" partialValueOffset "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 0"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},c [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Filter partialValueFilter "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" ValueFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-d [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"        new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" BinaryComponentComparator"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(partialValue,partialValueOffset));"})]})]})})}),`
+`,i.jsxs(e.p,{children:["See ",i.jsx(e.a,{href:"https://issues.apache.org/jira/browse/HBASE-22969",children:"HBASE-22969"})," for other use cases and details."]}),`
+`,i.jsx(e.h2,{id:"keyvalue-metadata",children:"KeyValue Metadata"}),`
+`,i.jsx(e.p,{children:"As HBase stores data internally as KeyValue pairs, KeyValue Metadata Filters evaluate the existence of keys (i.e., ColumnFamily:Column qualifiers) for a row, as opposed to values the previous section."}),`
+`,i.jsx(e.h3,{id:"familyfilter",children:"FamilyFilter"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/FamilyFilter.html",children:"FamilyFilter"})," can be used to filter on the ColumnFamily. It is generally a better idea to select ColumnFamilies in the Scan than to do it with a Filter."]}),`
+`,i.jsx(e.h3,{id:"qualifierfilter",children:"QualifierFilter"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/QualifierFilter.html",children:"QualifierFilter"})," can be used to filter based on Column (aka Qualifier) name."]}),`
+`,i.jsx(e.h3,{id:"columnprefixfilter",children:"ColumnPrefixFilter"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/ColumnPrefixFilter.html",children:"ColumnPrefixFilter"})," can be used to filter based on the lead portion of Column (aka Qualifier) names."]}),`
+`,i.jsx(e.p,{children:"A ColumnPrefixFilter seeks ahead to the first column matching the prefix in each row and for each involved column family. It can be used to efficiently get a subset of the columns in very wide rows."}),`
+`,i.jsx(e.p,{children:"Note: The same column qualifier can be used in different column families. This filter returns all matching columns."}),`
+`,i.jsx(e.p,{children:'Example: Find all columns in a row and family that start with "abc"'}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] row "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ...;"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] family "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ...;"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] prefix "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},child [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Scan scan "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" Scan"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"addFamily"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(family); "}),i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"// (optional) limit to one family"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Filter f "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" ColumnPrefixFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(f);"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setBatch"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"10"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:") [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"ResultScanner rs "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" t."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"getScanner"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"for"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Result r "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" rs."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"  for"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Cell cell "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:":"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" result."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},c [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"    // each cell represents a column"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  }"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"rs."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"close"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"();"})]})]})})}),`
+`,i.jsx(e.h3,{id:"multiplecolumnprefixfilter",children:"MultipleColumnPrefixFilter"}),`
+`,i.jsxs(e.p,{children:[i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/MultipleColumnPrefixFilter.html",children:"MultipleColumnPrefixFilter"})," behaves like ColumnPrefixFilter but allows specifying multiple prefixes."]}),`
+`,i.jsx(e.p,{children:"Like ColumnPrefixFilter, MultipleColumnPrefixFilter efficiently seeks ahead to the first column matching the lowest prefix and also seeks past ranges of columns between prefixes. It can be used to efficiently get discontinuous sets of columns from very wide rows."}),`
+`,i.jsx(e.p,{children:'Example: Find all columns in a row and family that start with "abc" or "xyz"'}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] row "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ...;"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] family "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ...;"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[][] prefixes "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},chil [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Scan scan "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" Scan"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"addFamily"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(family); "}),i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"// (optional) limit to one family"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Filter f "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" MultipleColumnPrefixFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dar [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(f);"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setBatch"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"10"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:") [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"ResultScanner rs "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" t."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"getScanner"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"for"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Result r "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" rs."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"  for"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Cell cell "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:":"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" result."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},c [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"    // each cell represents a column"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  }"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"rs."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"close"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"();"})]})]})})}),`
+`,i.jsx(e.h3,{id:"columnrangefilter",children:"ColumnRangeFilter"}),`
+`,i.jsxs(e.p,{children:["A ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/ColumnRangeFilter.html",children:"ColumnRangeFilter"})," allows efficient intra row scanning."]}),`
+`,i.jsx(e.p,{children:"A ColumnRangeFilter can seek ahead to the first matching column for each involved column family. It can be used to efficiently get a 'slice' of the columns of a very wide row. i.e. you have a million columns in a row but you only want to look at columns bbbb-bbdd."}),`
+`,i.jsx(e.p,{children:"Note: The same column qualifier can be used in different column families. This filter returns all matching columns."}),`
+`,i.jsx(e.p,{children:'Example: Find all columns in a row and family between "bbbb" (inclusive) and "bbdd" (inclusive)'}),`
+`,i.jsx(i.Fragment,{children:i.jsx(e.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] row "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ...;"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] family "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" ...;"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] startColumn "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"}, [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"byte"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"[] endColumn "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" Bytes."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},ch [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Scan scan "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" Scan"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childre [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"addFamily"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(family); "}),i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"// (optional) limit to one family"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Filter f "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" new"}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" ColumnRangeFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4 [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setFilter"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(f);"})]}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"scan."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"setBatch"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"("}),i.jsx(e.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"10"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:") [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"ResultScanner rs "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" t."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"getScanner"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"for"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Result r "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" rs."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children [...]
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"  for"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" (Cell cell "}),i.jsx(e.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:":"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" result."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},c [...]
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"    // each cell represents a column"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  }"})}),`
+`,i.jsx(e.span,{className:"line",children:i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})}),`
+`,i.jsxs(e.span,{className:"line",children:[i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"rs."}),i.jsx(e.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"close"}),i.jsx(e.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"();"})]})]})})}),`
+`,i.jsx(e.p,{children:"Note: Introduced in HBase 0.92"}),`
+`,i.jsx(e.h2,{id:"rowkey",children:"RowKey"}),`
+`,i.jsx(e.h3,{id:"rowfilter",children:"RowFilter"}),`
+`,i.jsxs(e.p,{children:["It is generally a better idea to use the startRow/stopRow methods on Scan for row selection, however ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/RowFilter.html",children:"RowFilter"})," can also be used."]}),`
+`,i.jsxs(e.p,{children:["You can supplement a scan (both bounded and unbounded) with RowFilter constructed from ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/BinaryComponentComparator.html",children:"BinaryComponentComparator"})," for further filtering out or filtering in rows. See ",i.jsx(e.a,{href:"https://issues.apache.org/jira/browse/HBASE-22969",children:"HBASE-22969"})," for use cases and other details."]}),`
+`,i.jsx(e.h2,{id:"utility",children:"Utility"}),`
+`,i.jsx(e.h3,{id:"firstkeyonlyfilter",children:"FirstKeyOnlyFilter"}),`
+`,i.jsxs(e.p,{children:["This is primarily used for rowcount jobs. See ",i.jsx(e.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/FirstKeyOnlyFilter.html",children:"FirstKeyOnlyFilter"}),"."]})]})}function c(s={}){const{wrapper:e}=s.components||{};return e?i.jsx(e,{...s,children:i.jsx(l,{...s})}):l(s)}export{n as _markdown,c as default,r as extractedReferences,t as frontmatter,h as structuredData,o as toc};
diff --git a/assets/cluster-replication-D2rcFEfx.js b/assets/cluster-replication-D2rcFEfx.js
new file mode 100644
index 00000000000..09476385aaf
--- /dev/null
+++ b/assets/cluster-replication-D2rcFEfx.js
@@ -0,0 +1,895 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";import{_ as a,a as r}from"./replication_overview-BAR-JHBY.js";let c=`
+
+
+
+## Cluster Replication
+
+HBase provides a cluster replication mechanism which allows you to keep one cluster's state synchronized with that of another cluster, using the write-ahead log (WAL) of the source cluster to propagate the changes. Some use cases for cluster replication include:
+
+* Backup and disaster recovery
+* Data aggregation
+* Geographic data distribution
+* Online data ingestion combined with offline data analytics
+
+<Callout type="info">
+  Replication is enabled at the granularity of the column family. Before enabling replication for a
+  column family, create the table and all column families to be replicated, on the destination
+  cluster.
+</Callout>
+
+<Callout type="info">
+  Replication is asynchronous as we send WAL to another cluster in background, which means that when
+  you want to do recovery through replication, you could loss some data. To address this problem, we
+  have introduced a new feature called synchronous replication. As the mechanism is a bit different
+  so we use a separated section to describe it. Please see [Synchronous
+  Replication](/docs/sync-replication).
+</Callout>
+
+<Callout type="info">
+  At present, there is compatibility problem if Replication and WAL Compression are used together.
+  If you need to use Replication, it is recommended to set the
+  \`hbase.regionserver.wal.enablecompression\` property to \`false\`. See
+  ([HBASE-26849](https://issues.apache.org/jira/browse/HBASE-26849)) for details.
+</Callout>
+
+### Replication Overview
+
+Cluster replication uses a source-push methodology. An HBase cluster can be a source (also called master or active, meaning that it is the originator of new data), a destination (also called slave or passive, meaning that it receives data via replication), or can fulfill both roles at once. Replication is asynchronous, and the goal of replication is eventual consistency. When the source receives an edit to a column family with replication enabled, that edit is propagated to all destinati [...]
+
+When data is replicated from one cluster to another, the original source of the data is tracked via a cluster ID which is part of the metadata. In HBase 0.96 and newer ([HBASE-7709](https://issues.apache.org/jira/browse/HBASE-7709)), all clusters which have already consumed the data are also tracked. This prevents replication loops.
+
+The WALs for each region server must be kept in HDFS as long as they are needed to replicate data to any slave cluster. Each region server reads from the oldest log it needs to replicate and keeps track of its progress processing WALs inside ZooKeeper to simplify failure recovery. The position marker which indicates a slave cluster's progress, as well as the queue of WALs to process, may be different for every slave cluster.
+
+The clusters participating in replication can be of different sizes. The master cluster relies on randomization to attempt to balance the stream of replication on the slave clusters. It is expected that the slave cluster has storage capacity to hold the replicated data, as well as any data it is responsible for ingesting. If a slave cluster does run out of room, or is inaccessible for other reasons, it throws an error and the master retains the WAL and retries the replication at intervals.
+
+<Callout type="warn" title="Consistency Across Replicated Clusters">
+  How your application builds on top of the HBase API matters when replication is in play. HBase's replication system provides at-least-once delivery of client edits for an enabled column family to each configured destination cluster. In the event of failure to reach a given destination, the replication system will retry sending edits in a way that might repeat a given message. HBase provides two ways of replication, one is the original replication and the other is serial replication. In [...]
+
+  The combination of these two properties (at-least-once delivery and the lack of message ordering) means that some destination clusters may end up in a different state if your application makes use of operations that are not idempotent, e.g. Increments.
+
+  To solve the problem, HBase now supports serial replication, which sends edits to destination cluster as the order of requests from client. See [Serial Replication](/docs/operational-management/cluster-replication#serial-replication).
+</Callout>
+
+<Callout type="info" title="Terminology Changes">
+  Previously, terms such as **master-master**, **master-slave**, and **cyclical** were used to
+  describe replication relationships in HBase. These terms added confusion, and have been abandoned
+  in favor of discussions about cluster topologies appropriate for different scenarios.
+</Callout>
+
+#### Cluster Topologies
+
+* A central source cluster might propagate changes out to multiple destination clusters, for failover or due to geographic distribution.
+* A source cluster might push changes to a destination cluster, which might also push its own changes back to the original cluster.
+* Many different low-latency clusters might push changes to one centralized cluster for backup or resource-intensive data analytics jobs. The processed data might then be replicated back to the low-latency clusters.
+
+Multiple levels of replication may be chained together to suit your organization's needs. The following diagram shows a hypothetical scenario. Use the arrows to follow the data paths.
+
+***Example of a Complex Cluster Replication Configuration***
+<img alt="hbase replication diagram" src={__img0} placeholder="blur" />
+
+HBase replication borrows many concepts from the **statement-based replication** design used by MySQL. Instead of SQL statements, entire WALEdits (consisting of multiple cell inserts coming from Put and Delete operations on the clients) are replicated in order to maintain atomicity.
+
+### Managing and Configuring Cluster Replication
+
+#### Cluster Configuration Overview
+
+1. Configure and start the source and destination clusters. Create tables with the same names and column families on both the source and destination clusters, so that the destination cluster knows where to store data it will receive.
+2. All hosts in the source and destination clusters should be reachable to each other.
+3. If both clusters use the same ZooKeeper cluster, you must use a different \`zookeeper.znode.parent\`, because they cannot write in the same folder.
+4. On the source cluster, in HBase Shell, add the destination cluster as a peer, using the \`add_peer\` command.
+5. On the source cluster, in HBase Shell, enable the table replication, using the \`enable_table_replication\` command.
+6. Check the logs to see if replication is taking place. If so, you will see messages like the following, coming from the ReplicationSource.
+
+\`\`\`java
+LOG.info("Replicating "+clusterId + " -> " + peerClusterId);
+\`\`\`
+
+#### Serial Replication Configuration
+
+See [Serial Replication](/docs/operational-management/cluster-replication#serial-replication)
+
+#### Cluster Management Commands
+
+**add\\_peer \`<ID>\` \`<CLUSTER_KEY>\`**\\
+Adds a replication relationship between two clusters.
+
+* ID โ€” a unique string, which must not contain a hyphen.
+* CLUSTER\\_KEY: composed using the following template, with appropriate place-holders: \`hbase.zookeeper.quorum:hbase.zookeeper.property.clientPort:zookeeper.znode.parent\`. This value can be found on the Master UI info page.
+* STATE(optional): ENABLED or DISABLED, default value is ENABLED
+
+**list\\_peers**\\
+list all replication relationships known by this cluster
+
+**enable\\_peer \`<ID>\`**\\
+Enable a previously-disabled replication relationship
+
+**disable\\_peer \`<ID>\`**\\
+Disable a replication relationship. HBase will no longer send edits to that peer cluster, but it still keeps track of all the new WALs that it will need to replicate if and when it is re-enabled. WALs are retained when enabling or disabling replication as long as peers exist.
+
+**remove\\_peer \`<ID>\`**\\
+Disable and remove a replication relationship. HBase will no longer send edits to that peer cluster or keep track of WALs.
+
+**enable\\_table\\_replication \`<TABLE_NAME>\`**\\
+Enable the table replication switch for all its column families. If the table is not found in the destination cluster then it will create one with the same name and column families.
+
+**disable\\_table\\_replication \`<TABLE_NAME>\`**\\
+Disable the table replication switch for all its column families.
+
+**peer\\_modification\\_switch \`<enable_or_disable>\`, \`<drain_procedures>\`**\\
+Enabled/Disable peer modification operations, such as adding/removing replication peers. The second parameter means whether you want to wait until all existing peer modification procedures to finish before returning when disabling peer modification.
+
+**peer\\_modification\\_enabled**\\
+Check whether peer modification is enabled.
+
+### Migrate Across Different Replication Peer Storages
+
+Starting from 2.6.0, we introduce a file system based \`ReplicationPeerStorage\`, which stores the replication peer state with files on HFile file system, instead of znodes on ZooKeeper. And we have also implemented a tool to copy replication peer state across different replication peer storages.
+
+\`\`\`bash
+./bin/hbase copyreppeers <SRC_REPLICATION_PEER_STORAGE> <DST_REPLICATION_PEER_STORAGE>
+\`\`\`
+
+To support doing the migrate online, we introduce a shell command called \`peer_modification_switch\`.
+
+\`\`\`ruby
+hbase> peer_modification_switch false, true
+\`\`\`
+
+Use the above command can disable peer modification operations. The second \`true\` means you want to wait until all the existing replication peer modification procedures to finish before returning. After disabling the peer modification, it is safe for you to copy replication peer state with the above tool, and then update all the *hbase-site.xml* files in the cluster to specify the new replication peer storage, and finally trigger an online configuration update to load the new replicati [...]
+
+## Serial Replication
+
+Note: this feature is introduced in HBase 2.1
+
+**Function of serial replication**\\
+Serial replication supports to push logs to the destination cluster in the same order as logs reach to the source cluster.
+
+### Why need serial replication?
+
+In replication of HBase, we push mutations to destination cluster by reading WAL in each region server. We have a queue for WAL files so we can read them in order of creation time. However, when region-move or RS failure occurs in source cluster, the hlog entries that are not pushed before region-move or RS-failure will be pushed by original RS(for region move) or another RS which takes over the remained hlog of dead RS(for RS failure), and the new entries for the same region(s) will be  [...]
+
+This treatment can possibly lead to data inconsistency between source and destination clusters:
+
+1. there are put and then delete written to source cluster.
+2. due to region-move / RS-failure, they are pushed by different replication-source threads to peer cluster.
+3. if delete is pushed to peer cluster before put, and flush and major-compact occurs in peer cluster before put is pushed to peer cluster, the delete is collected and the put remains in peer cluster, but in source cluster the put is masked by the delete, hence data inconsistency between source and destination clusters.
+
+### Serial replication configuration
+
+Set the serial flag to true for a repliation peer. And the default serial flag is false.
+
+* Add a new replication peer which serial flag is true
+
+  \`\`\`ruby
+  hbase> add_peer '1', CLUSTER_KEY => "server1.cie.com:2181:/hbase", SERIAL => true
+  \`\`\`
+
+* Set a replication peer's serial flag to false
+
+  \`\`\`ruby
+  hbase> set_peer_serial '1', false
+  \`\`\`
+
+* Set a replication peer's serial flag to true
+
+  \`\`\`ruby
+  hbase> set_peer_serial '1', true
+  \`\`\`
+
+The serial replication feature had been done firstly in [HBASE-9465](https://issues.apache.org/jira/browse/HBASE-9465) and then reverted and redone in [HBASE-20046](https://issues.apache.org/jira/browse/HBASE-20046). You can find more details in these issues.
+
+### Verifying Replicated Data
+
+The \`VerifyReplication\` MapReduce job, which is included in HBase, performs a systematic comparison of replicated data between two different clusters. Run the VerifyReplication job on the master cluster, supplying it with the peer ID and table name to use for validation. You can limit the verification further by specifying a time range or specific families. The job's short name is \`verifyrep\`. To run the job, use a command like the following:
+
+\`\`\`bash
+$ HADOOP_CLASSPATH=\`\${HBASE_HOME}/bin/hbase classpath\` "\${HADOOP_HOME}/bin/hadoop" jar "\${HBASE_HOME}/hbase-mapreduce-VERSION.jar" verifyrep --starttime=<timestamp> --endtime=<timestamp> --families=<myFam> <ID> <tableName>
+\`\`\`
+
+* The \`VerifyReplication\` command prints out \`GOODROWS\` and \`BADROWS\` counters to indicate rows that did and did not replicate correctly.
+
+### Detailed Information About Cluster Replication
+
+***Replication Architecture Overview***
+<img alt="replication overview" src={__img1} placeholder="blur" />
+
+#### Life of a WAL Edit
+
+A single WAL edit goes through several steps in order to be replicated to a slave cluster.
+
+1. An HBase client uses a Put or Delete operation to manipulate data in HBase.
+2. The region server writes the request to the WAL in a way allows it to be replayed if it is not written successfully.
+3. If the changed cell corresponds to a column family that is scoped for replication, the edit is added to the queue for replication.
+4. In a separate thread, the edit is read from the log, as part of a batch process. Only the KeyValues that are eligible for replication are kept. Replicable KeyValues are part of a column family whose schema is scoped GLOBAL, are not part of a catalog such as \`hbase:meta\`, did not originate from the target slave cluster, and have not already been consumed by the target slave cluster.
+5. The edit is tagged with the master's UUID and added to a buffer. When the buffer is filled, or the reader reaches the end of the file, the buffer is sent to a random region server on the slave cluster.
+6. The region server reads the edits sequentially and separates them into buffers, one buffer per table. After all edits are read, each buffer is flushed using [Table](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html), HBase's normal client. The master's UUID and the UUIDs of slaves which have already consumed the data are preserved in the edits they are applied, in order to prevent replication loops.
+7. In the master, the offset for the WAL that is currently being replicated is registered in ZooKeeper.
+8. The first three steps, where the edit is inserted, are identical.
+9. Again in a separate thread, the region server reads, filters, and edits the log edits in the same way as above. The slave region server does not answer the RPC call.
+10. The master sleeps and tries again a configurable number of times.
+11. If the slave region server is still not available, the master selects a new subset of region server to replicate to, and tries again to send the buffer of edits.
+12. Meanwhile, the WALs are rolled and stored in a queue in ZooKeeper. Logs that are **archived** by their region server, by moving them from the region server's log directory to a central log directory, will update their paths in the in-memory queue of the replicating thread.
+13. When the slave cluster is finally available, the buffer is applied in the same way as during normal processing. The master region server will then replicate the backlog of logs that accumulated during the outage.
+
+**Spreading Queue Failover Load**\\
+When replication is active, a subset of region servers in the source cluster is responsible for shipping edits to the sink. This responsibility must be failed over like all other region server functions should a process or node crash. The following configuration settings are recommended for maintaining an even distribution of replication activity over the remaining live servers in the source cluster:
+
+* Set \`replication.source.maxretriesmultiplier\` to \`300\`.
+* Set \`replication.source.sleepforretries\` to \`1\` (1 second). This value, combined with the value of \`replication.source.maxretriesmultiplier\`, causes the retry cycle to last about 5 minutes.
+* Set \`replication.sleep.before.failover\` to \`30000\` (30 seconds) in the source cluster site configuration.
+
+**Preserving Tags During Replication**\\
+By default, the codec used for replication between clusters strips tags, such as cell-level ACLs, from cells. To prevent the tags from being stripped, you can use a different codec which does not strip them. Configure \`hbase.replication.rpc.codec\` to use \`org.apache.hadoop.hbase.codec.KeyValueCodecWithTags\`, on both the source and sink RegionServers involved in the replication. This option was introduced in [HBASE-10322](https://issues.apache.org/jira/browse/HBASE-10322).
+
+#### Replication Internals
+
+**Replication State Storage**\\
+In HBASE-15867, we abstract two interfaces for storing replication state, \`ReplicationPeerStorage\` and \`ReplicationQueueStorage\`. The former one is for storing the replication peer related states, and the latter one is for storing the replication queue related states. HBASE-15867 is only half done, as although we have abstract these two interfaces, we still only have zookeeper based implementations.
+
+And in HBASE-27110, we have implemented a file system based replication peer storage, to store replication peer state on file system. Of course you can still use the zookeeper based replication peer storage.
+
+And in HBASE-27109, we have changed the replication queue storage from zookeeper based to hbase table based. See the below \`Replication Queue State\` in hbase:replication table section for more details.
+
+**Replication State in ZooKeeper**\\
+By default, the state is contained in the base node */hbase/replication*. Usually this nodes contains two child nodes, the peers znode is for storing replication peer state, and the rs znodes is for storing replication queue state. And if you choose the file system based replication peer storage, you will not see the peers znode. And starting from 3.0.0, we have moved the replication queue state to \`hbase:replication\` table (see below), so you will not see the rs znode.
+
+**The \`Peers\` Znode**\\
+The \`peers\` znode is stored in */hbase/replication/peers* by default. It consists of a list of all peer replication clusters, along with the status of each of them. The value of each peer is its cluster key, which is provided in the HBase Shell. The cluster key contains a list of ZooKeeper nodes in the cluster's quorum, the client port for the ZooKeeper quorum, and the base znode for HBase in HDFS on that cluster. Starting from 3.0.0, you can also specify connection URI as a cluster ke [...]
+
+**The \`RS\` Znode**\\
+The \`rs\` znode contains a list of WAL logs which need to be replicated. This list is divided into a set of queues organized by region server and the peer cluster the region server is shipping the logs to. The rs znode has one child znode for each region server in the cluster. The child znode name is the region server's hostname, client port, and start code. This list includes both live and dead region servers.
+
+**The hbase:replication Table**\\
+After 3.0.0, the \`Queue\` has been stored in the hbase:replication table, where the row key is \`<PeerId>-<ServerName>[/<SourceServerName>]\`, the WAL group will be the qualifier, and the serialized ReplicationGroupOffset will be the value. The ReplicationGroupOffset includes the wal file of the corresponding queue (\`<PeerId>-<ServerName>[/<SourceServerName>]\`) and its offset. Because we track replication offset per queue instead of per file, we only need to store one replication offs [...]
+
+**Other implementations for \`ReplicationPeerStorage\`**\\
+Starting from 2.6.0, we introduce a file system based \`ReplicationPeerStorage\`, which stores the replication peer state with files on HFile file system, instead of znodes on ZooKeeper. The layout is almost the same with znodes on zookeeper, the main difference is that, the HFile file system may not support atomic rename, so we use two files to store the state and when reading we will read them both and compare the timestamp to find out the newer one. So typically, you will see two peer [...]
+
+#### Choosing Region Servers to Replicate To
+
+When a master cluster region server initiates a replication source to a slave cluster, it first connects to the slave's ZooKeeper ensemble using the provided cluster key . It then scans the *rs/* directory to discover all the available sinks (region servers that are accepting incoming streams of edits to replicate) and randomly chooses a subset of them using a configured ratio which has a default value of 10%. For example, if a slave cluster has 150 machines, 15 will be chosen as potenti [...]
+
+A ZooKeeper watcher is placed on the \`$zookeeper.znode.parent/rs\` node of the slave cluster by each of the master cluster's region servers. This watch is used to monitor changes in the composition of the slave cluster. When nodes are removed from the slave cluster, or if nodes go down or come back up, the master cluster's region servers will respond by selecting a new pool of slave region servers to replicate to.
+
+#### Keeping Track of Logs(based on ZooKeeper)
+
+Each master cluster region server has its own znode in the replication znodes hierarchy. It contains one znode per peer cluster (if 5 slave clusters, 5 znodes are created), and each of these contain a queue of WALs to process. Each of these queues will track the WALs created by that region server, but they can differ in size. For example, if one slave cluster becomes unavailable for some time, the WALs should not be deleted, so they need to stay in the queue while the others are processe [...]
+
+When a source is instantiated, it contains the current WAL that the region server is writing to. During log rolling, the new file is added to the queue of each slave cluster's znode just before it is made available. This ensures that all the sources are aware that a new log exists before the region server is able to append edits into it, but this operations is now more expensive. The queue items are discarded when the replication thread cannot read more entries from a file (because it re [...]
+
+A log can be archived if it is no longer used or if the number of logs exceeds \`hbase.regionserver.maxlogs\` because the insertion rate is faster than regions are flushed. When a log is archived, the source threads are notified that the path for that log changed. If a particular source has already finished with an archived log, it will just ignore the message. If the log is in the queue, the path will be updated in memory. If the log is currently being replicated, the change will be don [...]
+
+#### Keeping Track of Logs(based on hbase table)
+
+After 3.0.0, for table based implementation, we have server name in row key, which means we will have lots of rows for a given peer.
+
+For a normal replication queue, the WAL files belong to the region server that is still alive, all the WAL files are kept in memory, so we do not need to get the WAL files from replication queue storage. And for a recovered replication queue, we could get the WAL files of the dead region server by listing the old WAL directory on HDFS. So theoretically, we do not need to store every WAL file in replication queue storage. And what's more, we store the created time(usually) in the WAL file [...]
+
+For ReplicationLogCleaner, all the files before this offset can be deleted, otherwise not.
+
+#### Reading, Filtering and Sending Edits
+
+By default, a source attempts to read from a WAL and ship log entries to a sink as quickly as possible. Speed is limited by the filtering of log entries Only KeyValues that are scoped GLOBAL and that do not belong to catalog tables will be retained. Speed is also limited by total size of the list of edits to replicate per slave, which is limited to 64 MB by default. With this configuration, a master cluster region server with three slaves would use at most 192 MB to store data to replica [...]
+
+Once the maximum size of edits has been buffered or the reader reaches the end of the WAL, the source thread stops reading and chooses at random a sink to replicate to (from the list that was generated by keeping only a subset of slave region servers). It directly issues a RPC to the chosen region server and waits for the method to return. If the RPC was successful, the source determines whether the current file has been emptied or it contains more data which needs to be read. If the fil [...]
+
+#### Cleaning Logs
+
+If replication is not enabled, the master's log-cleaning thread deletes old logs using a configured TTL. This TTL-based method does not work well with replication, because archived logs which have exceeded their TTL may still be in a queue. The default behavior is augmented so that if a log is past its TTL, the cleaning thread looks up every queue until it finds the log, while caching queues it has found. If the log is not found in any queues, the log will be deleted. The next time the c [...]
+
+<Callout type="info">
+  WALs are saved when replication is enabled or disabled as long as peers exist.
+</Callout>
+
+#### Region Server Failover
+
+When no region servers are failing, keeping track of the logs in ZooKeeper adds no value. Unfortunately, region servers do fail, and since ZooKeeper is highly available, it is useful for managing the transfer of the queues in the event of a failure. Each of the master cluster region servers keeps a watcher on every other region server, in order to be notified when one dies (just as the master does). When a failure happens, they all race to create a znode called \`lock\` inside the dead r [...]
+
+Next, the master cluster region server creates one new source thread per copied queue, and each of the source threads follows the read/filter/ship pattern. The main difference is that those queues will never receive new data, since they do not belong to their new region server. When the reader hits the end of the last log, the queue's znode is deleted and the master cluster region server closes that replication source.
+
+And starting from 2.5.0, the failover logic has been moved to SCP, where we add a SERVER\\_CRASH\\_CLAIM\\_REPLICATION\\_QUEUES step in SCP to claim the replication queues for a dead server. And starting from 3.0.0, where we changed the replication queue storage from zookeeper to table, the update to the replication queue storage is async, so we also need an extra step to add the missing replication queues before claiming.
+
+#### The replication queue claiming (based on ZooKeeper)
+
+Given a master cluster with 3 region servers replicating to a single slave with id \`2\`, the following hierarchy represents what the znodes layout could be at some point in time. The region servers' znodes all contain a \`peers\` znode which contains a single queue. The znode names in the queues represent the actual file names on HDFS in the form \`address,port.timestamp\`.
+
+\`\`\`text
+/hbase/replication/rs/
+  1.1.1.1,60020,123456780/
+    2/
+      1.1.1.1,60020.1234  (Contains a position)
+      1.1.1.1,60020.1265
+  1.1.1.2,60020,123456790/
+    2/
+      1.1.1.2,60020.1214  (Contains a position)
+      1.1.1.2,60020.1248
+      1.1.1.2,60020.1312
+  1.1.1.3,60020,    123456630/
+    2/
+      1.1.1.3,60020.1280  (Contains a position)
+\`\`\`
+
+Assume that 1.1.1.2 loses its ZooKeeper session. The survivors will race to create a lock, and, arbitrarily, 1.1.1.3 wins. It will then start transferring all the queues to its local peers znode by appending the name of the dead server. Right before 1.1.1.3 is able to clean up the old znodes, the layout will look like the following:
+
+\`\`\`text
+/hbase/replication/rs/
+  1.1.1.1,60020,123456780/
+    2/
+      1.1.1.1,60020.1234  (Contains a position)
+      1.1.1.1,60020.1265
+  1.1.1.2,60020,123456790/
+    lock
+    2/
+      1.1.1.2,60020.1214  (Contains a position)
+      1.1.1.2,60020.1248
+      1.1.1.2,60020.1312
+  1.1.1.3,60020,123456630/
+    2/
+      1.1.1.3,60020.1280  (Contains a position)
+
+    2-1.1.1.2,60020,123456790/
+      1.1.1.2,60020.1214  (Contains a position)
+      1.1.1.2,60020.1248
+      1.1.1.2,60020.1312
+\`\`\`
+
+Some time later, but before 1.1.1.3 is able to finish replicating the last WAL from 1.1.1.2, it dies too. Some new logs were also created in the normal queues. The last region server will then try to lock 1.1.1.3's znode and will begin transferring all the queues. The new layout will be:
+
+\`\`\`text
+/hbase/replication/rs/
+  1.1.1.1,60020,123456780/
+    2/
+      1.1.1.1,60020.1378  (Contains a position)
+
+    2-1.1.1.3,60020,123456630/
+      1.1.1.3,60020.1325  (Contains a position)
+      1.1.1.3,60020.1401
+
+    2-1.1.1.2,60020,123456790-1.1.1.3,60020,123456630/
+      1.1.1.2,60020.1312  (Contains a position)
+  1.1.1.3,60020,123456630/
+    lock
+    2/
+      1.1.1.3,60020.1325  (Contains a position)
+      1.1.1.3,60020.1401
+
+    2-1.1.1.2,60020,123456790/
+      1.1.1.2,60020.1312  (Contains a position)
+\`\`\`
+
+#### The replication queue claiming(based on hbase table)
+
+Given a master cluster with 3 region servers replicating to a single slave with id \`2\`, the following info represents what the storage layout of queue in the hbase:replication at some point in time. Row key is \`<PeerId>-<ServerName>[/<SourceServerName>]\`, and value is WAL && Offset.
+
+\`\`\`text
+  <PeerId>-<ServerName>[/<SourceServerName>]                        WAL && Offset
+  2-1.1.1.1,60020,123456780                            1.1.1.1,60020.1234  (Contains a position)
+  2-1.1.1.2,60020,123456790                            1.1.1.2,60020.1214  (Contains a position)
+  2-1.1.1.3,60020,123456630                            1.1.1.3,60020.1280  (Contains a position)
+\`\`\`
+
+Assume that 1.1.1.2 failed. The survivors will claim queue of that, and, arbitrarily, 1.1.1.3 wins. It will claim all the queue of 1.1.1.2, including removing the row of a replication queue, and inserting a new row(where we change the server name to the region server which claims the queue). Finally, the layout will look like the following:
+
+\`\`\`text
+  <PeerId>-<ServerName>[/<SourceServerName>]                        WAL && Offset
+  2-1.1.1.1,60020,123456780                            1.1.1.1,60020.1234  (Contains a position)
+  2-1.1.1.3,60020,123456630                            1.1.1.3,60020.1280  (Contains a position)
+  2-1.1.1.3,60020,123456630 1.1.1.2,60020,123456790    1.1.1.2,60020.1214  (Contains a position)
+\`\`\`
+
+### Replication Metrics
+
+The following metrics are exposed at the global region server level and at the peer level:
+
+\`source.sizeOfLogQueue\`\\
+number of WALs to process (excludes the one which is being processed) at the Replication source
+
+\`source.shippedOps\`\\
+number of mutations shipped
+
+\`source.logEditsRead\`\\
+number of mutations read from WALs at the replication source
+
+\`source.ageOfLastShippedOp\`\\
+age of last batch that was shipped by the replication source
+
+\`source.completedLogs\`\\
+The number of write-ahead-log files that have completed their acknowledged sending to the peer associated with this source. Increments to this metric are a part of normal operation of HBase replication.
+
+\`source.completedRecoverQueues\`\\
+The number of recovery queues this source has completed sending to the associated peer. Increments to this metric are a part of normal recovery of HBase replication in the face of failed Region Servers.
+
+\`source.uncleanlyClosedLogs\`\\
+The number of write-ahead-log files the replication system considered completed after reaching the end of readable entries in the face of an uncleanly closed file.
+
+\`source.ignoredUncleanlyClosedLogContentsInBytes\`\\
+When a write-ahead-log file is not closed cleanly, there will likely be some entry that has been partially serialized. This metric contains the number of bytes of such entries the HBase replication system believes were remaining at the end of files skipped in the face of an uncleanly closed file. Those bytes should either be in different file or represent a client write that was not acknowledged.
+
+\`source.restartedLogReading\`\\
+The number of times the HBase replication system detected that it failed to correctly parse a cleanly closed write-ahead-log file. In this circumstance, the system replays the entire log from the beginning, ensuring that no edits fail to be acknowledged by the associated peer. Increments to this metric indicate that the HBase replication system is having difficulty correctly handling failures in the underlying distributed storage system. No dataloss should occur, but you should check Reg [...]
+
+\`source.repeatedLogFileBytes\`\\
+When the HBase replication system determines that it needs to replay a given write-ahead-log file, this metric is incremented by the number of bytes the replication system believes had already been acknowledged by the associated peer prior to starting over.
+
+\`source.closedLogsWithUnknownFileLength\`\\
+Incremented when the HBase replication system believes it is at the end of a write-ahead-log file but it can not determine the length of that file in the underlying distributed storage system. Could indicate dataloss since the replication system is unable to determine if the end of readable entries lines up with the expected end of the file. You should check Region Server log files for details of the failures.
+
+### Replication Configuration Options
+
+| Option                                  | Description                                                                                                   | Default                      |
+| --------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------- |
+| zookeeper.znode.parent                  | The name of the base ZooKeeper znode used for HBase                                                           | /hbase                       |
+| zookeeper.znode.replication             | The name of the base znode used for replication                                                               | replication                  |
+| zookeeper.znode.replication.peers       | The name of the peer znode                                                                                    | peers                        |
+| zookeeper.znode.replication.peers.state | The name of peer-state znode                                                                                  | peer-state                   |
+| zookeeper.znode.replication.rs          | The name of the rs znode                                                                                      | rs                           |
+| replication.sleep.before.failover       | How many milliseconds a worker should sleep before attempting to replicate a dead region server's WAL queues. |                              |
+| replication.executor.workers            | The number of region servers a given region server should attempt to failover simultaneously.                 | 1                            |
+| hbase.replication.peer.storage.impl     | The replication peer storage implementation                                                                   | zookeeper                    |
+| hbase.replication.peers.directory       | The directory for storing replication peer state, when filesystem replication peer storage is specified       | peers                        |
+| hbase.replication.queue.table.name      | The table for storing replication queue state                                                                 | hbase:replication            |
+| hbase.replication.queue.storage.impl    | The replication queue storage implementation                                                                  | TableReplicationQueueStorage |
+
+### Monitoring Replication Status
+
+You can use the HBase Shell command \`status 'replication'\` to monitor the replication status on your cluster. The command has three variations:
+
+* \`status 'replication'\` โ€” prints the status of each source and its sinks, sorted by hostname.
+* \`status 'replication', 'source'\` โ€” prints the status for each replication source, sorted by hostname.
+* \`status 'replication', 'sink'\` โ€” prints the status for each replication sink, sorted by hostname.
+
+#### Understanding the output
+
+The command output will vary according to the state of replication. For example right after a restart and if destination peer is not reachable, no replication source threads would be running, so no metrics would get displayed:
+
+\`\`\`text
+hbase01.home:
+SOURCE: PeerID=1
+Normal Queue: 1
+No Reader/Shipper threads runnning yet.
+SINK: TimeStampStarted=1591985197350, Waiting for OPs...
+\`\`\`
+
+Under normal circumstances, a healthy, active-active replication deployment would show the following:
+
+\`\`\`text
+    hbase01.home:
+      SOURCE: PeerID=1
+         Normal Queue: 1
+           AgeOfLastShippedOp=0, TimeStampOfLastShippedOp=Fri Jun 12 18:49:23 BST 2020, SizeOfLogQueue=1, EditsReadFromLogQueue=1, OpsShippedToTarget=1, TimeStampOfNextToReplicate=Fri Jun 12 18:49:23 BST 2020, Replication Lag=0
+      SINK: TimeStampStarted=1591983663458, AgeOfLastAppliedOp=0, TimeStampsOfLastAppliedOp=Fri Jun 12 18:57:18 BST 2020
+\`\`\`
+
+The definition for each of these metrics is detailed below:
+
+| Type   | Metric Name                | Description                                                                                                                        |
+| ------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
+| Source | AgeOfLastShippedOp         | How long last successfully shipped edit took to effectively get replicated on target.                                              |
+| Source | TimeStampOfLastShippedOp   | The actual date of last successful edit shipment.                                                                                  |
+| Source | SizeOfLogQueue             | Number of wal files on this given queue.                                                                                           |
+| Source | EditsReadFromLogQueue      | How many edits have been read from this given queue since this source thread started.                                              |
+| Source | OpsShippedToTarget         | How many edits have been shipped to target since this source thread started.                                                       |
+| Source | TimeStampOfNextToReplicate | Date of the current edit been attempted to replicate.                                                                              |
+| Source | Replication Lag            | The elapsed time (in millis), since the last edit to replicate was read by this source thread and effectively replicated to target |
+| Sink   | TimeStampStarted           | Date (in millis) of when this Sink thread started.                                                                                 |
+| Sink   | AgeOfLastAppliedOp         | How long it took to apply the last successful shipped edit.                                                                        |
+| Sink   | TimeStampsOfLastAppliedOp  | Date of last successful applied edit.                                                                                              |
+
+Growing values for \`Source.TimeStampsOfLastAppliedOp\` and/or \`Source.Replication Lag\` would indicate replication delays. If those numbers keep going up, while \`Source.TimeStampOfLastShippedOp\`, \`Source.EditsReadFromLogQueue\`, \`Source.OpsShippedToTarget\` or \`Source.TimeStampOfNextToReplicate\` do not change at all, then replication flow is failing to progress, and there might be problems within clusters communication. This could also happen if replication is manually paused (vi [...]
+
+### Replication Observability Framework
+
+The core idea is to create \`replication marker rows\` periodically and insert them into WAL. These marker rows will help track the replication delays/bugs back to the \`originating region server, WAL and timestamp of occurrence\`. This tracker rows' WAL entries are interleaved with the regular table WAL entries and have a very high chance of running into the same replication delays/bugs that the user tables are seeing. Details as follows:
+
+#### REPLICATION.WALEVENTTRACKER table
+
+Create a new table called \`REPLICATION.WALEVENTTRACKER\` table and persist all the WAL events (like \`ACTIVE\`, \`ROLLING\`, \`ROLLED\`) to this table.\\
+The properties of this table are: Replication is set to 0, Block Cache is Disabled, Max versions is 1, TTL is 1 year.
+
+This table has single ColumnFamily: \`info\`\\
+\`info\` contains multiple qualifiers:
+
+* \`info:region_server_name\`
+* \`info:wal_name\`
+* \`info:timestamp\`
+* \`info:wal_state\`
+* \`info:wal_length\`
+
+Whenever we roll a WAL (\`old-wal-name\` โ†’ \`new-wal-name\`), it will create 3 rows in this table.\\
+\`<region_server_name>, <old-wal-name>, <current timestamp>, <ROLLING>, <length of old-wal-name>\`\\
+\`<region_server_name>, <old-wal-name>, <current timestamp>, <ROLLED>, <length of old-wal-name>\`\\
+\`<region_server_name>, <new-wal-name>, <current timestamp>, <ACTIVE>, 0\`
+
+**Configuration**\\
+To enable persisting WAL events, there is a configuration property: \`hbase.regionserver.wal.event.tracker.enabled\` (defaults to false)
+
+#### REPLICATION.SINK\\_TRACKER table
+
+Create a new table called \`REPLICATION.SINK_TRACKER\`.\\
+The properties of this table are: Replication is set to 0, Block Cache is Disabled, Max versions is 1, TTL is 1 year.
+
+This table has single ColumnFamily: \`info\`\\
+\`info\` contains multiple qualifiers:
+
+* \`info:region_server_name\`
+* \`info:wal_name\`
+* \`info:timestamp\`
+* \`info:offset\`
+
+**Configuration**\\
+To create the above table, there is a configuration property: \`hbase.regionserver.replication.sink.tracker.enabled\` (defaults to false)
+
+#### ReplicationMarker Chore
+
+We introduced a new chore called \`ReplicationMarkerChore\` which will create the marker rows periodically into active WAL. The marker rows has the following metadata: \`region_server_name, wal_name, timestamp and offset within WAL\`. These markers are replicated (with special handling) and they are persisted into a sink side table \`REPLICATION.SINK_TRACKER\`.
+
+**Configuration:**\\
+\`ReplicationMarkerChore\` is enabled with configuration property: \`hbase.regionserver.replication.marker.enabled\` (defaults to false) and the period at which it creates marker rows is controlled by \`hbase.regionserver.replication.marker.chore.duration\` (defaults to 30 seconds). Sink cluster can choose to process these marker rows and persist to \`REPLICATION.SINK_TRACKER\` table or it can ignore these rows. This behavior is controlled by configuration property \`hbase.regionserver.r [...]
+
+#### How to enable end-to-end feature ?
+
+To use this whole feature, we will need to enable the above configuration properties in 2 phases/releases.\\
+In first phase/release, set the following configuration properties to \`true\`:
+
+* \`hbase.regionserver.wal.event.tracker.enabled\`: This will just persist all the WAL events to REPLICATION.WALEVENTTRACKER table.
+* \`hbase.regionserver.replication.sink.tracker.enabled\`: This will create REPLICATION.SINK\\_TRACKER table and will process special marker rows coming from source cluster.
+
+In second phase/release, set the following configuration property to \`true\`:
+
+* \`hbase.regionserver.replication.marker.enabled\`: This will create marker rows periodically and sink cluster will persist these marker rows in \`REPLICATION.SINK_TRACKER\` table.
+`,d={title:"Cluster Replication",description:"Setting up and managing HBase cluster replication for disaster recovery, data aggregation, and geographic distribution of data."},p=[{href:"/docs/sync-replication"},{href:"https://issues.apache.org/jira/browse/HBASE-26849"},{href:"https://issues.apache.org/jira/browse/HBASE-7709"},{href:"/docs/operational-management/cluster-replication#serial-replication"},{href:"/docs/operational-management/cluster-replication#serial-replication"},{href:"htt [...]
+column family, create the table and all column families to be replicated, on the destination
+cluster.`},{heading:"cluster-replication",content:"type: info"},{heading:"cluster-replication",content:`Replication is asynchronous as we send WAL to another cluster in background, which means that when
+you want to do recovery through replication, you could loss some data. To address this problem, we
+have introduced a new feature called synchronous replication. As the mechanism is a bit different
+so we use a separated section to describe it. Please see Synchronous
+Replication.`},{heading:"cluster-replication",content:"type: info"},{heading:"cluster-replication",content:`At present, there is compatibility problem if Replication and WAL Compression are used together.
+If you need to use Replication, it is recommended to set the
+hbase.regionserver.wal.enablecompression property to false. See
+(HBASE-26849) for details.`},{heading:"replication-overview",content:"Cluster replication uses a source-push methodology. An HBase cluster can be a source (also called master or active, meaning that it is the originator of new data), a destination (also called slave or passive, meaning that it receives data via replication), or can fulfill both roles at once. Replication is asynchronous, and the goal of replication is eventual consistency. When the source receives an edit to a column fam [...]
+describe replication relationships in HBase. These terms added confusion, and have been abandoned
+in favor of discussions about cluster topologies appropriate for different scenarios.`},{heading:"cluster-topologies",content:"A central source cluster might propagate changes out to multiple destination clusters, for failover or due to geographic distribution."},{heading:"cluster-topologies",content:"A source cluster might push changes to a destination cluster, which might also push its own changes back to the original cluster."},{heading:"cluster-topologies",content:"Many different low [...]
+`,e.jsx(t.p,{children:"HBase provides a cluster replication mechanism which allows you to keep one cluster's state synchronized with that of another cluster, using the write-ahead log (WAL) of the source cluster to propagate the changes. Some use cases for cluster replication include:"}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"Backup and disaster recovery"}),`
+`,e.jsx(t.li,{children:"Data aggregation"}),`
+`,e.jsx(t.li,{children:"Geographic data distribution"}),`
+`,e.jsx(t.li,{children:"Online data ingestion combined with offline data analytics"}),`
+`]}),`
+`,e.jsx(n,{type:"info",children:e.jsx(t.p,{children:`Replication is enabled at the granularity of the column family. Before enabling replication for a
+column family, create the table and all column families to be replicated, on the destination
+cluster.`})}),`
+`,e.jsx(n,{type:"info",children:e.jsxs(t.p,{children:[`Replication is asynchronous as we send WAL to another cluster in background, which means that when
+you want to do recovery through replication, you could loss some data. To address this problem, we
+have introduced a new feature called synchronous replication. As the mechanism is a bit different
+so we use a separated section to describe it. Please see `,e.jsx(t.a,{href:"/docs/sync-replication",children:`Synchronous
+Replication`}),"."]})}),`
+`,e.jsx(n,{type:"info",children:e.jsxs(t.p,{children:[`At present, there is compatibility problem if Replication and WAL Compression are used together.
+If you need to use Replication, it is recommended to set the
+`,e.jsx(t.code,{children:"hbase.regionserver.wal.enablecompression"})," property to ",e.jsx(t.code,{children:"false"}),`. See
+(`,e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-26849",children:"HBASE-26849"}),") for details."]})}),`
+`,e.jsx(t.h3,{id:"replication-overview",children:"Replication Overview"}),`
+`,e.jsx(t.p,{children:"Cluster replication uses a source-push methodology. An HBase cluster can be a source (also called master or active, meaning that it is the originator of new data), a destination (also called slave or passive, meaning that it receives data via replication), or can fulfill both roles at once. Replication is asynchronous, and the goal of replication is eventual consistency. When the source receives an edit to a column family with replication enabled, that edit is prop [...]
+`,e.jsxs(t.p,{children:["When data is replicated from one cluster to another, the original source of the data is tracked via a cluster ID which is part of the metadata. In HBase 0.96 and newer (",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-7709",children:"HBASE-7709"}),"), all clusters which have already consumed the data are also tracked. This prevents replication loops."]}),`
+`,e.jsx(t.p,{children:"The WALs for each region server must be kept in HDFS as long as they are needed to replicate data to any slave cluster. Each region server reads from the oldest log it needs to replicate and keeps track of its progress processing WALs inside ZooKeeper to simplify failure recovery. The position marker which indicates a slave cluster's progress, as well as the queue of WALs to process, may be different for every slave cluster."}),`
+`,e.jsx(t.p,{children:"The clusters participating in replication can be of different sizes. The master cluster relies on randomization to attempt to balance the stream of replication on the slave clusters. It is expected that the slave cluster has storage capacity to hold the replicated data, as well as any data it is responsible for ingesting. If a slave cluster does run out of room, or is inaccessible for other reasons, it throws an error and the master retains the WAL and retries the  [...]
+`,e.jsxs(n,{type:"warn",title:"Consistency Across Replicated Clusters",children:[e.jsx(t.p,{children:"How your application builds on top of the HBase API matters when replication is in play. HBase's replication system provides at-least-once delivery of client edits for an enabled column family to each configured destination cluster. In the event of failure to reach a given destination, the replication system will retry sending edits in a way that might repeat a given message. HBase provi [...]
+`,e.jsx(n,{type:"info",title:"Terminology Changes",children:e.jsxs(t.p,{children:["Previously, terms such as ",e.jsx(t.strong,{children:"master-master"}),", ",e.jsx(t.strong,{children:"master-slave"}),", and ",e.jsx(t.strong,{children:"cyclical"}),` were used to
+describe replication relationships in HBase. These terms added confusion, and have been abandoned
+in favor of discussions about cluster topologies appropriate for different scenarios.`]})}),`
+`,e.jsx(t.h4,{id:"cluster-topologies",children:"Cluster Topologies"}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"A central source cluster might propagate changes out to multiple destination clusters, for failover or due to geographic distribution."}),`
+`,e.jsx(t.li,{children:"A source cluster might push changes to a destination cluster, which might also push its own changes back to the original cluster."}),`
+`,e.jsx(t.li,{children:"Many different low-latency clusters might push changes to one centralized cluster for backup or resource-intensive data analytics jobs. The processed data might then be replicated back to the low-latency clusters."}),`
+`]}),`
+`,e.jsx(t.p,{children:"Multiple levels of replication may be chained together to suit your organization's needs. The following diagram shows a hypothetical scenario. Use the arrows to follow the data paths."}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"Example of a Complex Cluster Replication Configuration"})}),`
+`,e.jsx(t.img,{alt:"hbase replication diagram",src:a,placeholder:"blur"})]}),`
+`,e.jsxs(t.p,{children:["HBase replication borrows many concepts from the ",e.jsx(t.strong,{children:"statement-based replication"})," design used by MySQL. Instead of SQL statements, entire WALEdits (consisting of multiple cell inserts coming from Put and Delete operations on the clients) are replicated in order to maintain atomicity."]}),`
+`,e.jsx(t.h3,{id:"managing-and-configuring-cluster-replication",children:"Managing and Configuring Cluster Replication"}),`
+`,e.jsx(t.h4,{id:"cluster-configuration-overview",children:"Cluster Configuration Overview"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"Configure and start the source and destination clusters. Create tables with the same names and column families on both the source and destination clusters, so that the destination cluster knows where to store data it will receive."}),`
+`,e.jsx(t.li,{children:"All hosts in the source and destination clusters should be reachable to each other."}),`
+`,e.jsxs(t.li,{children:["If both clusters use the same ZooKeeper cluster, you must use a different ",e.jsx(t.code,{children:"zookeeper.znode.parent"}),", because they cannot write in the same folder."]}),`
+`,e.jsxs(t.li,{children:["On the source cluster, in HBase Shell, add the destination cluster as a peer, using the ",e.jsx(t.code,{children:"add_peer"})," command."]}),`
+`,e.jsxs(t.li,{children:["On the source cluster, in HBase Shell, enable the table replication, using the ",e.jsx(t.code,{children:"enable_table_replication"})," command."]}),`
+`,e.jsx(t.li,{children:"Check the logs to see if replication is taking place. If so, you will see messages like the following, coming from the ReplicationSource."}),`
+`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.h4,{id:"serial-replication-configuration",children:"Serial Replication Configuration"}),`
+`,e.jsxs(t.p,{children:["See ",e.jsx(t.a,{href:"/docs/operational-management/cluster-replication#serial-replication",children:"Serial Replication"})]}),`
+`,e.jsx(t.h4,{id:"cluster-management-commands",children:"Cluster Management Commands"}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["add_peer ",e.jsx(t.code,{children:"<ID>"})," ",e.jsx(t.code,{children:"<CLUSTER_KEY>"})]}),e.jsx(t.br,{}),`
+`,"Adds a replication relationship between two clusters."]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:"ID โ€” a unique string, which must not contain a hyphen."}),`
+`,e.jsxs(t.li,{children:["CLUSTER_KEY: composed using the following template, with appropriate place-holders: ",e.jsx(t.code,{children:"hbase.zookeeper.quorum:hbase.zookeeper.property.clientPort:zookeeper.znode.parent"}),". This value can be found on the Master UI info page."]}),`
+`,e.jsx(t.li,{children:"STATE(optional): ENABLED or DISABLED, default value is ENABLED"}),`
+`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"list_peers"}),e.jsx(t.br,{}),`
+`,"list all replication relationships known by this cluster"]}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["enable_peer ",e.jsx(t.code,{children:"<ID>"})]}),e.jsx(t.br,{}),`
+`,"Enable a previously-disabled replication relationship"]}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["disable_peer ",e.jsx(t.code,{children:"<ID>"})]}),e.jsx(t.br,{}),`
+`,"Disable a replication relationship. HBase will no longer send edits to that peer cluster, but it still keeps track of all the new WALs that it will need to replicate if and when it is re-enabled. WALs are retained when enabling or disabling replication as long as peers exist."]}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["remove_peer ",e.jsx(t.code,{children:"<ID>"})]}),e.jsx(t.br,{}),`
+`,"Disable and remove a replication relationship. HBase will no longer send edits to that peer cluster or keep track of WALs."]}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["enable_table_replication ",e.jsx(t.code,{children:"<TABLE_NAME>"})]}),e.jsx(t.br,{}),`
+`,"Enable the table replication switch for all its column families. If the table is not found in the destination cluster then it will create one with the same name and column families."]}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["disable_table_replication ",e.jsx(t.code,{children:"<TABLE_NAME>"})]}),e.jsx(t.br,{}),`
+`,"Disable the table replication switch for all its column families."]}),`
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["peer_modification_switch ",e.jsx(t.code,{children:"<enable_or_disable>"}),", ",e.jsx(t.code,{children:"<drain_procedures>"})]}),e.jsx(t.br,{}),`
+`,"Enabled/Disable peer modification operations, such as adding/removing replication peers. The second parameter means whether you want to wait until all existing peer modification procedures to finish before returning when disabling peer modification."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"peer_modification_enabled"}),e.jsx(t.br,{}),`
+`,"Check whether peer modification is enabled."]}),`
+`,e.jsx(t.h3,{id:"migrate-across-different-replication-peer-storages",children:"Migrate Across Different Replication Peer Storages"}),`
+`,e.jsxs(t.p,{children:["Starting from 2.6.0, we introduce a file system based ",e.jsx(t.code,{children:"ReplicationPeerStorage"}),", which stores the replication peer state with files on HFile file system, instead of znodes on ZooKeeper. And we have also implemented a tool to copy replication peer state across different replication peer storages."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.p,{children:["To support doing the migrate online, we introduce a shell command called ",e.jsx(t.code,{children:"peer_modification_switch"}),"."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsxs(t.p,{children:["Use the above command can disable peer modification operations. The second ",e.jsx(t.code,{children:"true"})," means you want to wait until all the existing replication peer modification procedures to finish before returning. After disabling the peer modification, it is safe for you to copy replication peer state with the above tool, and then update all the ",e.jsx(t.em,{children:"hbase-site.xml"})," files in the cluster to specify the new replication peer storag [...]
+`,e.jsx(t.h2,{id:"serial-replication",children:"Serial Replication"}),`
+`,e.jsx(t.p,{children:"Note: this feature is introduced in HBase 2.1"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Function of serial replication"}),e.jsx(t.br,{}),`
+`,"Serial replication supports to push logs to the destination cluster in the same order as logs reach to the source cluster."]}),`
+`,e.jsx(t.h3,{id:"why-need-serial-replication",children:"Why need serial replication?"}),`
+`,e.jsx(t.p,{children:"In replication of HBase, we push mutations to destination cluster by reading WAL in each region server. We have a queue for WAL files so we can read them in order of creation time. However, when region-move or RS failure occurs in source cluster, the hlog entries that are not pushed before region-move or RS-failure will be pushed by original RS(for region move) or another RS which takes over the remained hlog of dead RS(for RS failure), and the new entries for the  [...]
+`,e.jsx(t.p,{children:"This treatment can possibly lead to data inconsistency between source and destination clusters:"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"there are put and then delete written to source cluster."}),`
+`,e.jsx(t.li,{children:"due to region-move / RS-failure, they are pushed by different replication-source threads to peer cluster."}),`
+`,e.jsx(t.li,{children:"if delete is pushed to peer cluster before put, and flush and major-compact occurs in peer cluster before put is pushed to peer cluster, the delete is collected and the put remains in peer cluster, but in source cluster the put is masked by the delete, hence data inconsistency between source and destination clusters."}),`
+`]}),`
+`,e.jsx(t.h3,{id:"serial-replication-configuration-1",children:"Serial replication configuration"}),`
+`,e.jsx(t.p,{children:"Set the serial flag to true for a repliation peer. And the default serial flag is false."}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:[`
+`,e.jsx(t.p,{children:"Add a new replication peer which serial flag is true"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsx(t.p,{children:"Set a replication peer's serial flag to false"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`]}),`
+`,e.jsxs(t.li,{children:[`
+`,e.jsx(t.p,{children:"Set a replication peer's serial flag to true"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`]}),`
+`]}),`
+`,e.jsxs(t.p,{children:["The serial replication feature had been done firstly in ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-9465",children:"HBASE-9465"})," and then reverted and redone in ",e.jsx(t.a,{href:"https://issues.apache.org/jira/browse/HBASE-20046",children:"HBASE-20046"}),". You can find more details in these issues."]}),`
+`,e.jsx(t.h3,{id:"verifying-replicated-data",children:"Verifying Replicated Data"}),`
+`,e.jsxs(t.p,{children:["The ",e.jsx(t.code,{children:"VerifyReplication"})," MapReduce job, which is included in HBase, performs a systematic comparison of replicated data between two different clusters. Run the VerifyReplication job on the master cluster, supplying it with the peer ID and table name to use for validation. You can limit the verification further by specifying a time range or specific families. The job's short name is ",e.jsx(t.code,{children:"verifyrep"}),". To run the j [...]
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:["The ",e.jsx(t.code,{children:"VerifyReplication"})," command prints out ",e.jsx(t.code,{children:"GOODROWS"})," and ",e.jsx(t.code,{children:"BADROWS"})," counters to indicate rows that did and did not replicate correctly."]}),`
+`]}),`
+`,e.jsx(t.h3,{id:"detailed-information-about-cluster-replication",children:"Detailed Information About Cluster Replication"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:e.jsx(t.em,{children:"Replication Architecture Overview"})}),`
+`,e.jsx(t.img,{alt:"replication overview",src:r,placeholder:"blur"})]}),`
+`,e.jsx(t.h4,{id:"life-of-a-wal-edit",children:"Life of a WAL Edit"}),`
+`,e.jsx(t.p,{children:"A single WAL edit goes through several steps in order to be replicated to a slave cluster."}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"An HBase client uses a Put or Delete operation to manipulate data in HBase."}),`
+`,e.jsx(t.li,{children:"The region server writes the request to the WAL in a way allows it to be replayed if it is not written successfully."}),`
+`,e.jsx(t.li,{children:"If the changed cell corresponds to a column family that is scoped for replication, the edit is added to the queue for replication."}),`
+`,e.jsxs(t.li,{children:["In a separate thread, the edit is read from the log, as part of a batch process. Only the KeyValues that are eligible for replication are kept. Replicable KeyValues are part of a column family whose schema is scoped GLOBAL, are not part of a catalog such as ",e.jsx(t.code,{children:"hbase:meta"}),", did not originate from the target slave cluster, and have not already been consumed by the target slave cluster."]}),`
+`,e.jsx(t.li,{children:"The edit is tagged with the master's UUID and added to a buffer. When the buffer is filled, or the reader reaches the end of the file, the buffer is sent to a random region server on the slave cluster."}),`
+`,e.jsxs(t.li,{children:["The region server reads the edits sequentially and separates them into buffers, one buffer per table. After all edits are read, each buffer is flushed using ",e.jsx(t.a,{href:"https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html",children:"Table"}),", HBase's normal client. The master's UUID and the UUIDs of slaves which have already consumed the data are preserved in the edits they are applied, in order to prevent replication loops."]}),`
+`,e.jsx(t.li,{children:"In the master, the offset for the WAL that is currently being replicated is registered in ZooKeeper."}),`
+`,e.jsx(t.li,{children:"The first three steps, where the edit is inserted, are identical."}),`
+`,e.jsx(t.li,{children:"Again in a separate thread, the region server reads, filters, and edits the log edits in the same way as above. The slave region server does not answer the RPC call."}),`
+`,e.jsx(t.li,{children:"The master sleeps and tries again a configurable number of times."}),`
+`,e.jsx(t.li,{children:"If the slave region server is still not available, the master selects a new subset of region server to replicate to, and tries again to send the buffer of edits."}),`
+`,e.jsxs(t.li,{children:["Meanwhile, the WALs are rolled and stored in a queue in ZooKeeper. Logs that are ",e.jsx(t.strong,{children:"archived"})," by their region server, by moving them from the region server's log directory to a central log directory, will update their paths in the in-memory queue of the replicating thread."]}),`
+`,e.jsx(t.li,{children:"When the slave cluster is finally available, the buffer is applied in the same way as during normal processing. The master region server will then replicate the backlog of logs that accumulated during the outage."}),`
+`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Spreading Queue Failover Load"}),e.jsx(t.br,{}),`
+`,"When replication is active, a subset of region servers in the source cluster is responsible for shipping edits to the sink. This responsibility must be failed over like all other region server functions should a process or node crash. The following configuration settings are recommended for maintaining an even distribution of replication activity over the remaining live servers in the source cluster:"]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:["Set ",e.jsx(t.code,{children:"replication.source.maxretriesmultiplier"})," to ",e.jsx(t.code,{children:"300"}),"."]}),`
+`,e.jsxs(t.li,{children:["Set ",e.jsx(t.code,{children:"replication.source.sleepforretries"})," to ",e.jsx(t.code,{children:"1"})," (1 second). This value, combined with the value of ",e.jsx(t.code,{children:"replication.source.maxretriesmultiplier"}),", causes the retry cycle to last about 5 minutes."]}),`
+`,e.jsxs(t.li,{children:["Set ",e.jsx(t.code,{children:"replication.sleep.before.failover"})," to ",e.jsx(t.code,{children:"30000"})," (30 seconds) in the source cluster site configuration."]}),`
+`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Preserving Tags During Replication"}),e.jsx(t.br,{}),`
+`,"By default, the codec used for replication between clusters strips tags, such as cell-level ACLs, from cells. To prevent the tags from being stripped, you can use a different codec which does not strip them. Configure ",e.jsx(t.code,{children:"hbase.replication.rpc.codec"})," to use ",e.jsx(t.code,{children:"org.apache.hadoop.hbase.codec.KeyValueCodecWithTags"}),", on both the source and sink RegionServers involved in the replication. This option was introduced in ",e.jsx(t.a,{href:"h [...]
+`,e.jsx(t.h4,{id:"replication-internals",children:"Replication Internals"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Replication State Storage"}),e.jsx(t.br,{}),`
+`,"In HBASE-15867, we abstract two interfaces for storing replication state, ",e.jsx(t.code,{children:"ReplicationPeerStorage"})," and ",e.jsx(t.code,{children:"ReplicationQueueStorage"}),". The former one is for storing the replication peer related states, and the latter one is for storing the replication queue related states. HBASE-15867 is only half done, as although we have abstract these two interfaces, we still only have zookeeper based implementations."]}),`
+`,e.jsx(t.p,{children:"And in HBASE-27110, we have implemented a file system based replication peer storage, to store replication peer state on file system. Of course you can still use the zookeeper based replication peer storage."}),`
+`,e.jsxs(t.p,{children:["And in HBASE-27109, we have changed the replication queue storage from zookeeper based to hbase table based. See the below ",e.jsx(t.code,{children:"Replication Queue State"})," in hbase:replication table section for more details."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Replication State in ZooKeeper"}),e.jsx(t.br,{}),`
+`,"By default, the state is contained in the base node ",e.jsx(t.em,{children:"/hbase/replication"}),". Usually this nodes contains two child nodes, the peers znode is for storing replication peer state, and the rs znodes is for storing replication queue state. And if you choose the file system based replication peer storage, you will not see the peers znode. And starting from 3.0.0, we have moved the replication queue state to ",e.jsx(t.code,{children:"hbase:replication"})," table (see  [...]
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["The ",e.jsx(t.code,{children:"Peers"})," Znode"]}),e.jsx(t.br,{}),`
+`,"The ",e.jsx(t.code,{children:"peers"})," znode is stored in ",e.jsx(t.em,{children:"/hbase/replication/peers"})," by default. It consists of a list of all peer replication clusters, along with the status of each of them. The value of each peer is its cluster key, which is provided in the HBase Shell. The cluster key contains a list of ZooKeeper nodes in the cluster's quorum, the client port for the ZooKeeper quorum, and the base znode for HBase in HDFS on that cluster. Starting from 3 [...]
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["The ",e.jsx(t.code,{children:"RS"})," Znode"]}),e.jsx(t.br,{}),`
+`,"The ",e.jsx(t.code,{children:"rs"})," znode contains a list of WAL logs which need to be replicated. This list is divided into a set of queues organized by region server and the peer cluster the region server is shipping the logs to. The rs znode has one child znode for each region server in the cluster. The child znode name is the region server's hostname, client port, and start code. This list includes both live and dead region servers."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"The hbase:replication Table"}),e.jsx(t.br,{}),`
+`,"After 3.0.0, the ",e.jsx(t.code,{children:"Queue"})," has been stored in the hbase:replication table, where the row key is ",e.jsx(t.code,{children:"<PeerId>-<ServerName>[/<SourceServerName>]"}),", the WAL group will be the qualifier, and the serialized ReplicationGroupOffset will be the value. The ReplicationGroupOffset includes the wal file of the corresponding queue (",e.jsx(t.code,{children:"<PeerId>-<ServerName>[/<SourceServerName>]"}),") and its offset. Because we track replicat [...]
+`,e.jsxs(t.p,{children:[e.jsxs(t.strong,{children:["Other implementations for ",e.jsx(t.code,{children:"ReplicationPeerStorage"})]}),e.jsx(t.br,{}),`
+`,"Starting from 2.6.0, we introduce a file system based ",e.jsx(t.code,{children:"ReplicationPeerStorage"}),", which stores the replication peer state with files on HFile file system, instead of znodes on ZooKeeper. The layout is almost the same with znodes on zookeeper, the main difference is that, the HFile file system may not support atomic rename, so we use two files to store the state and when reading we will read them both and compare the timestamp to find out the newer one. So ty [...]
+`,e.jsx(t.h4,{id:"choosing-region-servers-to-replicate-to",children:"Choosing Region Servers to Replicate To"}),`
+`,e.jsxs(t.p,{children:["When a master cluster region server initiates a replication source to a slave cluster, it first connects to the slave's ZooKeeper ensemble using the provided cluster key . It then scans the ",e.jsx(t.em,{children:"rs/"})," directory to discover all the available sinks (region servers that are accepting incoming streams of edits to replicate) and randomly chooses a subset of them using a configured ratio which has a default value of 10%. For example, if a slave cl [...]
+`,e.jsxs(t.p,{children:["A ZooKeeper watcher is placed on the ",e.jsx(t.code,{children:"$zookeeper.znode.parent/rs"})," node of the slave cluster by each of the master cluster's region servers. This watch is used to monitor changes in the composition of the slave cluster. When nodes are removed from the slave cluster, or if nodes go down or come back up, the master cluster's region servers will respond by selecting a new pool of slave region servers to replicate to."]}),`
+`,e.jsx(t.h4,{id:"keeping-track-of-logsbased-on-zookeeper",children:"Keeping Track of Logs(based on ZooKeeper)"}),`
+`,e.jsxs(t.p,{children:["Each master cluster region server has its own znode in the replication znodes hierarchy. It contains one znode per peer cluster (if 5 slave clusters, 5 znodes are created), and each of these contain a queue of WALs to process. Each of these queues will track the WALs created by that region server, but they can differ in size. For example, if one slave cluster becomes unavailable for some time, the WALs should not be deleted, so they need to stay in the queue whil [...]
+`,e.jsx(t.p,{children:`When a source is instantiated, it contains the current WAL that the region server is writing to. During log rolling, the new file is added to the queue of each slave cluster's znode just before it is made available. This ensures that all the sources are aware that a new log exists before the region server is able to append edits into it, but this operations is now more expensive. The queue items are discarded when the replication thread cannot read more entries fro [...]
+`,e.jsxs(t.p,{children:["A log can be archived if it is no longer used or if the number of logs exceeds ",e.jsx(t.code,{children:"hbase.regionserver.maxlogs"})," because the insertion rate is faster than regions are flushed. When a log is archived, the source threads are notified that the path for that log changed. If a particular source has already finished with an archived log, it will just ignore the message. If the log is in the queue, the path will be updated in memory. If the log i [...]
+`,e.jsx(t.h4,{id:"keeping-track-of-logsbased-on-hbase-table",children:"Keeping Track of Logs(based on hbase table)"}),`
+`,e.jsx(t.p,{children:"After 3.0.0, for table based implementation, we have server name in row key, which means we will have lots of rows for a given peer."}),`
+`,e.jsx(t.p,{children:"For a normal replication queue, the WAL files belong to the region server that is still alive, all the WAL files are kept in memory, so we do not need to get the WAL files from replication queue storage. And for a recovered replication queue, we could get the WAL files of the dead region server by listing the old WAL directory on HDFS. So theoretically, we do not need to store every WAL file in replication queue storage. And what's more, we store the created time(u [...]
+`,e.jsx(t.p,{children:"For ReplicationLogCleaner, all the files before this offset can be deleted, otherwise not."}),`
+`,e.jsx(t.h4,{id:"reading-filtering-and-sending-edits",children:"Reading, Filtering and Sending Edits"}),`
+`,e.jsx(t.p,{children:"By default, a source attempts to read from a WAL and ship log entries to a sink as quickly as possible. Speed is limited by the filtering of log entries Only KeyValues that are scoped GLOBAL and that do not belong to catalog tables will be retained. Speed is also limited by total size of the list of edits to replicate per slave, which is limited to 64 MB by default. With this configuration, a master cluster region server with three slaves would use at most 192 MB t [...]
+`,e.jsx(t.p,{children:"Once the maximum size of edits has been buffered or the reader reaches the end of the WAL, the source thread stops reading and chooses at random a sink to replicate to (from the list that was generated by keeping only a subset of slave region servers). It directly issues a RPC to the chosen region server and waits for the method to return. If the RPC was successful, the source determines whether the current file has been emptied or it contains more data which needs [...]
+`,e.jsx(t.h4,{id:"cleaning-logs",children:"Cleaning Logs"}),`
+`,e.jsx(t.p,{children:"If replication is not enabled, the master's log-cleaning thread deletes old logs using a configured TTL. This TTL-based method does not work well with replication, because archived logs which have exceeded their TTL may still be in a queue. The default behavior is augmented so that if a log is past its TTL, the cleaning thread looks up every queue until it finds the log, while caching queues it has found. If the log is not found in any queues, the log will be delet [...]
+`,e.jsx(n,{type:"info",children:e.jsx(t.p,{children:"WALs are saved when replication is enabled or disabled as long as peers exist."})}),`
+`,e.jsx(t.h4,{id:"region-server-failover",children:"Region Server Failover"}),`
+`,e.jsxs(t.p,{children:["When no region servers are failing, keeping track of the logs in ZooKeeper adds no value. Unfortunately, region servers do fail, and since ZooKeeper is highly available, it is useful for managing the transfer of the queues in the event of a failure. Each of the master cluster region servers keeps a watcher on every other region server, in order to be notified when one dies (just as the master does). When a failure happens, they all race to create a znode called " [...]
+`,e.jsx(t.p,{children:"Next, the master cluster region server creates one new source thread per copied queue, and each of the source threads follows the read/filter/ship pattern. The main difference is that those queues will never receive new data, since they do not belong to their new region server. When the reader hits the end of the last log, the queue's znode is deleted and the master cluster region server closes that replication source."}),`
+`,e.jsx(t.p,{children:"And starting from 2.5.0, the failover logic has been moved to SCP, where we add a SERVER_CRASH_CLAIM_REPLICATION_QUEUES step in SCP to claim the replication queues for a dead server. And starting from 3.0.0, where we changed the replication queue storage from zookeeper to table, the update to the replication queue storage is async, so we also need an extra step to add the missing replication queues before claiming."}),`
+`,e.jsx(t.h4,{id:"the-replication-queue-claiming-based-on-zookeeper",children:"The replication queue claiming (based on ZooKeeper)"}),`
+`,e.jsxs(t.p,{children:["Given a master cluster with 3 region servers replicating to a single slave with id ",e.jsx(t.code,{children:"2"}),", the following hierarchy represents what the znodes layout could be at some point in time. The region servers' znodes all contain a ",e.jsx(t.code,{children:"peers"})," znode which contains a single queue. The znode names in the queues represent the actual file names on HDFS in the form ",e.jsx(t.code,{children:"address,port.timestamp"}),"."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.1,60020,123456780/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.1,60020.1234  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.1,60020.1265"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.2,60020,123456790/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1214  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1248"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1312"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.3,60020,    123456630/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.3,60020.1280  (Contains a position)"})})]})})}),`
+`,e.jsx(t.p,{children:"Assume that 1.1.1.2 loses its ZooKeeper session. The survivors will race to create a lock, and, arbitrarily, 1.1.1.3 wins. It will then start transferring all the queues to its local peers znode by appending the name of the dead server. Right before 1.1.1.3 is able to clean up the old znodes, the layout will look like the following:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.1,60020,123456780/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.1,60020.1234  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.1,60020.1265"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.2,60020,123456790/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    lock"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1214  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1248"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1312"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.3,60020,123456630/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.3,60020.1280  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2-1.1.1.2,60020,123456790/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1214  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1248"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1312"})})]})})}),`
+`,e.jsx(t.p,{children:"Some time later, but before 1.1.1.3 is able to finish replicating the last WAL from 1.1.1.2, it dies too. Some new logs were also created in the normal queues. The last region server will then try to lock 1.1.1.3's znode and will begin transferring all the queues. The new layout will be:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.1,60020,123456780/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.1,60020.1378  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2-1.1.1.3,60020,123456630/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.3,60020.1325  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.3,60020.1401"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2-1.1.1.2,60020,123456790-1.1.1.3,60020,123456630/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1312  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  1.1.1.3,60020,123456630/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    lock"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.3,60020.1325  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.3,60020.1401"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"    2-1.1.1.2,60020,123456790/"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      1.1.1.2,60020.1312  (Contains a position)"})})]})})}),`
+`,e.jsx(t.h4,{id:"the-replication-queue-claimingbased-on-hbase-table",children:"The replication queue claiming(based on hbase table)"}),`
+`,e.jsxs(t.p,{children:["Given a master cluster with 3 region servers replicating to a single slave with id ",e.jsx(t.code,{children:"2"}),", the following info represents what the storage layout of queue in the hbase:replication at some point in time. Row key is ",e.jsx(t.code,{children:"<PeerId>-<ServerName>[/<SourceServerName>]"}),", and value is WAL && Offset."]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  2-1.1.1.1,60020,123456780                            1.1.1.1,60020.1234  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  2-1.1.1.2,60020,123456790                            1.1.1.2,60020.1214  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  2-1.1.1.3,60020,123456630                            1.1.1.3,60020.1280  (Contains a position)"})})]})})}),`
+`,e.jsx(t.p,{children:"Assume that 1.1.1.2 failed. The survivors will claim queue of that, and, arbitrarily, 1.1.1.3 wins. It will claim all the queue of 1.1.1.2, including removing the row of a replication queue, and inserting a new row(where we change the server name to the region server which claims the queue). Finally, the layout will look like the following:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  2-1.1.1.1,60020,123456780                            1.1.1.1,60020.1234  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  2-1.1.1.3,60020,123456630                            1.1.1.3,60020.1280  (Contains a position)"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"  2-1.1.1.3,60020,123456630 1.1.1.2,60020,123456790    1.1.1.2,60020.1214  (Contains a position)"})})]})})}),`
+`,e.jsx(t.h3,{id:"replication-metrics",children:"Replication Metrics"}),`
+`,e.jsx(t.p,{children:"The following metrics are exposed at the global region server level and at the peer level:"}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.sizeOfLogQueue"}),e.jsx(t.br,{}),`
+`,"number of WALs to process (excludes the one which is being processed) at the Replication source"]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.shippedOps"}),e.jsx(t.br,{}),`
+`,"number of mutations shipped"]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.logEditsRead"}),e.jsx(t.br,{}),`
+`,"number of mutations read from WALs at the replication source"]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.ageOfLastShippedOp"}),e.jsx(t.br,{}),`
+`,"age of last batch that was shipped by the replication source"]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.completedLogs"}),e.jsx(t.br,{}),`
+`,"The number of write-ahead-log files that have completed their acknowledged sending to the peer associated with this source. Increments to this metric are a part of normal operation of HBase replication."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.completedRecoverQueues"}),e.jsx(t.br,{}),`
+`,"The number of recovery queues this source has completed sending to the associated peer. Increments to this metric are a part of normal recovery of HBase replication in the face of failed Region Servers."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.uncleanlyClosedLogs"}),e.jsx(t.br,{}),`
+`,"The number of write-ahead-log files the replication system considered completed after reaching the end of readable entries in the face of an uncleanly closed file."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.ignoredUncleanlyClosedLogContentsInBytes"}),e.jsx(t.br,{}),`
+`,"When a write-ahead-log file is not closed cleanly, there will likely be some entry that has been partially serialized. This metric contains the number of bytes of such entries the HBase replication system believes were remaining at the end of files skipped in the face of an uncleanly closed file. Those bytes should either be in different file or represent a client write that was not acknowledged."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.restartedLogReading"}),e.jsx(t.br,{}),`
+`,"The number of times the HBase replication system detected that it failed to correctly parse a cleanly closed write-ahead-log file. In this circumstance, the system replays the entire log from the beginning, ensuring that no edits fail to be acknowledged by the associated peer. Increments to this metric indicate that the HBase replication system is having difficulty correctly handling failures in the underlying distributed storage system. No dataloss should occur, but you should check  [...]
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.repeatedLogFileBytes"}),e.jsx(t.br,{}),`
+`,"When the HBase replication system determines that it needs to replay a given write-ahead-log file, this metric is incremented by the number of bytes the replication system believes had already been acknowledged by the associated peer prior to starting over."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.code,{children:"source.closedLogsWithUnknownFileLength"}),e.jsx(t.br,{}),`
+`,"Incremented when the HBase replication system believes it is at the end of a write-ahead-log file but it can not determine the length of that file in the underlying distributed storage system. Could indicate dataloss since the replication system is unable to determine if the end of readable entries lines up with the expected end of the file. You should check Region Server log files for details of the failures."]}),`
+`,e.jsx(t.h3,{id:"replication-configuration-options",children:"Replication Configuration Options"}),`
+`,e.jsxs(t.table,{children:[e.jsx(t.thead,{children:e.jsxs(t.tr,{children:[e.jsx(t.th,{children:"Option"}),e.jsx(t.th,{children:"Description"}),e.jsx(t.th,{children:"Default"})]})}),e.jsxs(t.tbody,{children:[e.jsxs(t.tr,{children:[e.jsx(t.td,{children:"zookeeper.znode.parent"}),e.jsx(t.td,{children:"The name of the base ZooKeeper znode used for HBase"}),e.jsx(t.td,{children:"/hbase"})]}),e.jsxs(t.tr,{children:[e.jsx(t.td,{children:"zookeeper.znode.replication"}),e.jsx(t.td,{children:"The [...]
+`,e.jsx(t.h3,{id:"monitoring-replication-status",children:"Monitoring Replication Status"}),`
+`,e.jsxs(t.p,{children:["You can use the HBase Shell command ",e.jsx(t.code,{children:"status 'replication'"})," to monitor the replication status on your cluster. The command has three variations:"]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"status 'replication'"})," โ€” prints the status of each source and its sinks, sorted by hostname."]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"status 'replication', 'source'"})," โ€” prints the status for each replication source, sorted by hostname."]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"status 'replication', 'sink'"})," โ€” prints the status for each replication sink, sorted by hostname."]}),`
+`]}),`
+`,e.jsx(t.h4,{id:"understanding-the-output",children:"Understanding the output"}),`
+`,e.jsx(t.p,{children:"The command output will vary according to the state of replication. For example right after a restart and if destination peer is not reachable, no replication source threads would be running, so no metrics would get displayed:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"SOURCE: PeerID=1"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"Normal Queue: 1"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"No Reader/Shipper threads runnning yet."})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"SINK: TimeStampStarted=1591985197350, Waiting for OPs..."})})]})})}),`
+`,e.jsx(t.p,{children:"Under normal circumstances, a healthy, active-active replication deployment would show the following:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      SOURCE: PeerID=1"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"         Normal Queue: 1"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"           AgeOfLastShippedOp=0, TimeStampOfLastShippedOp=Fri Jun 12 18:49:23 BST 2020, SizeOfLogQueue=1, EditsReadFromLogQueue=1, OpsShippedToTarget=1, TimeStampOfNextToReplicate=Fri Jun 12 18:49:23 BST 2020, Replication Lag=0"})}),`
+`,e.jsx(t.span,{className:"line",children:e.jsx(t.span,{children:"      SINK: TimeStampStarted=1591983663458, AgeOfLastAppliedOp=0, TimeStampsOfLastAppliedOp=Fri Jun 12 18:57:18 BST 2020"})})]})})}),`
+`,e.jsx(t.p,{children:"The definition for each of these metrics is detailed below:"}),`
+`,e.jsxs(t.table,{children:[e.jsx(t.thead,{children:e.jsxs(t.tr,{children:[e.jsx(t.th,{children:"Type"}),e.jsx(t.th,{children:"Metric Name"}),e.jsx(t.th,{children:"Description"})]})}),e.jsxs(t.tbody,{children:[e.jsxs(t.tr,{children:[e.jsx(t.td,{children:"Source"}),e.jsx(t.td,{children:"AgeOfLastShippedOp"}),e.jsx(t.td,{children:"How long last successfully shipped edit took to effectively get replicated on target."})]}),e.jsxs(t.tr,{children:[e.jsx(t.td,{children:"Source"}),e.jsx(t.td,{ch [...]
+`,e.jsxs(t.p,{children:["Growing values for ",e.jsx(t.code,{children:"Source.TimeStampsOfLastAppliedOp"})," and/or ",e.jsx(t.code,{children:"Source.Replication Lag"})," would indicate replication delays. If those numbers keep going up, while ",e.jsx(t.code,{children:"Source.TimeStampOfLastShippedOp"}),", ",e.jsx(t.code,{children:"Source.EditsReadFromLogQueue"}),", ",e.jsx(t.code,{children:"Source.OpsShippedToTarget"})," or ",e.jsx(t.code,{children:"Source.TimeStampOfNextToReplicate"}),"  [...]
+`,e.jsx(t.h3,{id:"replication-observability-framework",children:"Replication Observability Framework"}),`
+`,e.jsxs(t.p,{children:["The core idea is to create ",e.jsx(t.code,{children:"replication marker rows"})," periodically and insert them into WAL. These marker rows will help track the replication delays/bugs back to the ",e.jsx(t.code,{children:"originating region server, WAL and timestamp of occurrence"}),". This tracker rows' WAL entries are interleaved with the regular table WAL entries and have a very high chance of running into the same replication delays/bugs that the user tables a [...]
+`,e.jsx(t.h4,{id:"replicationwaleventtracker-table",children:"REPLICATION.WALEVENTTRACKER table"}),`
+`,e.jsxs(t.p,{children:["Create a new table called ",e.jsx(t.code,{children:"REPLICATION.WALEVENTTRACKER"})," table and persist all the WAL events (like ",e.jsx(t.code,{children:"ACTIVE"}),", ",e.jsx(t.code,{children:"ROLLING"}),", ",e.jsx(t.code,{children:"ROLLED"}),") to this table.",e.jsx(t.br,{}),`
+`,"The properties of this table are: Replication is set to 0, Block Cache is Disabled, Max versions is 1, TTL is 1 year."]}),`
+`,e.jsxs(t.p,{children:["This table has single ColumnFamily: ",e.jsx(t.code,{children:"info"}),e.jsx(t.br,{}),`
+`,e.jsx(t.code,{children:"info"})," contains multiple qualifiers:"]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:region_server_name"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:wal_name"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:timestamp"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:wal_state"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:wal_length"})}),`
+`]}),`
+`,e.jsxs(t.p,{children:["Whenever we roll a WAL (",e.jsx(t.code,{children:"old-wal-name"})," โ†’ ",e.jsx(t.code,{children:"new-wal-name"}),"), it will create 3 rows in this table.",e.jsx(t.br,{}),`
+`,e.jsx(t.code,{children:"<region_server_name>, <old-wal-name>, <current timestamp>, <ROLLING>, <length of old-wal-name>"}),e.jsx(t.br,{}),`
+`,e.jsx(t.code,{children:"<region_server_name>, <old-wal-name>, <current timestamp>, <ROLLED>, <length of old-wal-name>"}),e.jsx(t.br,{}),`
+`,e.jsx(t.code,{children:"<region_server_name>, <new-wal-name>, <current timestamp>, <ACTIVE>, 0"})]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Configuration"}),e.jsx(t.br,{}),`
+`,"To enable persisting WAL events, there is a configuration property: ",e.jsx(t.code,{children:"hbase.regionserver.wal.event.tracker.enabled"})," (defaults to false)"]}),`
+`,e.jsx(t.h4,{id:"replicationsink_tracker-table",children:"REPLICATION.SINK_TRACKER table"}),`
+`,e.jsxs(t.p,{children:["Create a new table called ",e.jsx(t.code,{children:"REPLICATION.SINK_TRACKER"}),".",e.jsx(t.br,{}),`
+`,"The properties of this table are: Replication is set to 0, Block Cache is Disabled, Max versions is 1, TTL is 1 year."]}),`
+`,e.jsxs(t.p,{children:["This table has single ColumnFamily: ",e.jsx(t.code,{children:"info"}),e.jsx(t.br,{}),`
+`,e.jsx(t.code,{children:"info"})," contains multiple qualifiers:"]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:region_server_name"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:wal_name"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:timestamp"})}),`
+`,e.jsx(t.li,{children:e.jsx(t.code,{children:"info:offset"})}),`
+`]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Configuration"}),e.jsx(t.br,{}),`
+`,"To create the above table, there is a configuration property: ",e.jsx(t.code,{children:"hbase.regionserver.replication.sink.tracker.enabled"})," (defaults to false)"]}),`
+`,e.jsx(t.h4,{id:"replicationmarker-chore",children:"ReplicationMarker Chore"}),`
+`,e.jsxs(t.p,{children:["We introduced a new chore called ",e.jsx(t.code,{children:"ReplicationMarkerChore"})," which will create the marker rows periodically into active WAL. The marker rows has the following metadata: ",e.jsx(t.code,{children:"region_server_name, wal_name, timestamp and offset within WAL"}),". These markers are replicated (with special handling) and they are persisted into a sink side table ",e.jsx(t.code,{children:"REPLICATION.SINK_TRACKER"}),"."]}),`
+`,e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Configuration:"}),e.jsx(t.br,{}),`
+`,e.jsx(t.code,{children:"ReplicationMarkerChore"})," is enabled with configuration property: ",e.jsx(t.code,{children:"hbase.regionserver.replication.marker.enabled"})," (defaults to false) and the period at which it creates marker rows is controlled by ",e.jsx(t.code,{children:"hbase.regionserver.replication.marker.chore.duration"})," (defaults to 30 seconds). Sink cluster can choose to process these marker rows and persist to ",e.jsx(t.code,{children:"REPLICATION.SINK_TRACKER"})," tab [...]
+`,e.jsx(t.h4,{id:"how-to-enable-end-to-end-feature-",children:"How to enable end-to-end feature ?"}),`
+`,e.jsxs(t.p,{children:["To use this whole feature, we will need to enable the above configuration properties in 2 phases/releases.",e.jsx(t.br,{}),`
+`,"In first phase/release, set the following configuration properties to ",e.jsx(t.code,{children:"true"}),":"]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"hbase.regionserver.wal.event.tracker.enabled"}),": This will just persist all the WAL events to REPLICATION.WALEVENTTRACKER table."]}),`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"hbase.regionserver.replication.sink.tracker.enabled"}),": This will create REPLICATION.SINK_TRACKER table and will process special marker rows coming from source cluster."]}),`
+`]}),`
+`,e.jsxs(t.p,{children:["In second phase/release, set the following configuration property to ",e.jsx(t.code,{children:"true"}),":"]}),`
+`,e.jsxs(t.ul,{children:[`
+`,e.jsxs(t.li,{children:[e.jsx(t.code,{children:"hbase.regionserver.replication.marker.enabled"}),": This will create marker rows periodically and sink cluster will persist these marker rows in ",e.jsx(t.code,{children:"REPLICATION.SINK_TRACKER"})," table."]}),`
+`]})]})}function f(i={}){const{wrapper:t}=i.components||{};return t?e.jsx(t,{...i,children:e.jsx(s,{...i})}):s(i)}function o(i,t){throw new Error("Expected component `"+i+"` to be defined: you likely forgot to import, pass, or provide it.")}export{c as _markdown,f as default,p as extractedReferences,d as frontmatter,u as structuredData,g as toc};
diff --git a/assets/code-of-conduct-wHEKyC02.js b/assets/code-of-conduct-wHEKyC02.js
new file mode 100644
index 00000000000..e339324795d
--- /dev/null
+++ b/assets/code-of-conduct-wHEKyC02.js
@@ -0,0 +1,16 @@
+import{j as e,w as o}from"./chunk-EPOLDU6W-B5LwAila.js";import{M as a}from"./mdx-components-bjiyHZUo.js";import"./mdx-DXQ3RXga.js";import"./index-BE31Pm92.js";import"./index-lnR2ABT4.js";import"./index-FCA4GwU0.js";import"./link-CDX6ZyVQ.js";import"./external-link-jmuPj2if.js";import"./createLucideIcon-BidaCVke.js";e.jsx(e.Fragment,{children:"Code of Conduct"}),e.jsx(e.Fragment,{children:"Policy"}),e.jsx(e.Fragment,{children:"Diversity Statement"});function i(n){const t={a:"a",h1:"h1",h2 [...]
+`,e.jsx(t.h2,{id:"policy",children:"Policy"}),`
+`,e.jsxs(t.p,{children:["We expect participants in discussions on the HBase project mailing lists, IRC channels, and JIRA issues to abide by the Apache Software Foundation's ",e.jsx(t.a,{href:"http://apache.org/foundation/policies/conduct.html",children:"Code of Conduct"}),"."]}),`
+`,e.jsx(t.p,{children:"If you feel there has been a violation of this code, please point out your concerns publicly in a friendly and matter of fact manner. Nonverbal communication is prone to misinterpretation and misunderstanding. Everyone has bad days and sometimes says things they regret later. Someone else's communication style may clash with yours, but the difference can be amicably resolved. After pointing out your concerns please be generous upon receiving an apology."}),`
+`,e.jsx(t.p,{children:"Should there be repeated instances of code of conduct violations, or if there is an obvious and severe violation, the HBase PMC may become involved. When this happens the PMC will openly discuss the matter, most likely on the dev@hbase mailing list, and will consider taking the following actions, in order, if there is a continuing problem with an individual:"}),`
+`,e.jsxs(t.ol,{children:[`
+`,e.jsx(t.li,{children:"A friendly off-list warning;"}),`
+`,e.jsx(t.li,{children:"A friendly public warning, if the communication at issue was on list, otherwise another off-list warning;"}),`
+`,e.jsx(t.li,{children:"A three month suspension from the public mailing lists and possible operator action in the IRC channels."}),`
+`,e.jsx(t.li,{children:"A permanent ban from the public mailing lists, IRC channels, and project JIRA."}),`
+`]}),`
+`,e.jsx(t.p,{children:"For flagrant violations requiring a firm response the PMC may opt to skip early steps. No action will be taken before public discussion leading to consensus or a successful majority vote."}),`
+`,e.jsx(t.h2,{id:"diversity-statement",children:"Diversity Statement"}),`
+`,e.jsx(t.p,{children:"As a project and a community, we encourage you to participate in the HBase project in whatever capacity suits you, whether it involves development, documentation, answering questions on mailing lists, triaging issue and patch review, managing releases, or any other way that you want to help. We appreciate your contributions and the time you dedicate to the HBase project. We strive to recognize the work of participants publicly. Please let us know if we can improve  [...]
+`,e.jsx(t.p,{children:"We value diversity and strive to support participation by people with all different backgrounds. Rich projects grow from groups with different points of view and different backgrounds. We welcome your suggestions about how we can welcome participation by people at all skill levels and with all aspects of the project."}),`
+`,e.jsxs(t.p,{children:["If you can think of something we are doing that we shouldn't, or something that we should do but aren't, please let us know. If you feel comfortable doing so, use the public mailing lists. Otherwise, reach out to a PMC member or send an email to ",e.jsx(t.a,{href:"mailto:private@hbase.apache.org",children:"the private PMC mailing list"}),"."]})]})}function s(n={}){const{wrapper:t}=n.components||{};return t?e.jsx(t,{...n,children:e.jsx(i,{...n})}):i(n)}function r( [...]
diff --git a/assets/collapsible-DA3DUpZf.js b/assets/collapsible-DA3DUpZf.js
new file mode 100644
index 00000000000..cda7f609bdb
--- /dev/null
+++ b/assets/collapsible-DA3DUpZf.js
@@ -0,0 +1 @@
+import{c as mt}from"./createLucideIcon-BidaCVke.js";import{r as m,j as M,y as he}from"./chunk-EPOLDU6W-B5LwAila.js";import{a as Xt}from"./index-FCA4GwU0.js";import{c as Yt}from"./link-CDX6ZyVQ.js";const Hn=mt("ChevronDown",[["path",{d:"m6 9 6 6 6-6",key:"qrunsl"}]]);const zn=mt("ChevronRight",[["path",{d:"m9 18 6-6-6-6",key:"mthhwq"}]]);const Un=mt("Moon",[["path",{d:"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z",key:"a7tn18"}]]);const qn=mt("Sun",[["circle",{cx:"12",cy:"12",r:"4",key:"4exip2"}],[ [...]
diff --git a/assets/commands-CnrbbtKl.js b/assets/commands-CnrbbtKl.js
new file mode 100644
index 00000000000..b506d1b7ed1
--- /dev/null
+++ b/assets/commands-CnrbbtKl.js
@@ -0,0 +1,446 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let r=`This covers the command-line utilities that administrators would run to create, restore, and merge backups. Tools to
+inspect details on specific backup sessions is covered in the next section, [Administration of Backup Images](/docs/backup-restore/administration).
+
+Run the command \`hbase backup help <command>\` to access the online help that provides basic information about a command
+and its options. The below information is captured in this help message for each command.
+
+### Creating a Backup Image
+
+<Callout type="info">
+  For HBase clusters also using Apache Phoenix: include the SQL system catalog tables in the backup.
+  In the event that you need to restore the HBase backup, access to the system catalog tables enable
+  you to resume Phoenix interoperability with the restored data.
+</Callout>
+
+The first step in running the backup and restore utilities is to perform a full backup and to store the data in a separate image
+from the source. At a minimum, you must do this to get a baseline before you can rely on incremental backups.
+
+Run the following command as HBase superuser:
+
+\`\`\`bash
+hbase backup create <type> <backup_path>
+\`\`\`
+
+After the command finishes running, the console prints a SUCCESS or FAILURE status message. The SUCCESS message includes a *backup* ID.
+The backup ID is the Unix time (also known as Epoch time) that the HBase master received the backup request from the client.
+
+<Callout type="info">
+  Record the backup ID that appears at the end of a successful backup. In case the source cluster
+  fails and you need to recover the dataset with a restore operation, having the backup ID readily
+  available can save time.
+</Callout>
+
+#### Positional Command-Line Arguments
+
+***type***\\
+The type of backup to execute: *full* or *incremental*. As a reminder, an *incremental* backup requires a *full* backup to
+already exist.
+
+***backup\\_path***\\
+The *backup\\_path* argument specifies the full filesystem URI of where to store the backup image. Valid prefixes are
+*hdfs:*, *webhdfs:*, *s3a:* or other compatible Hadoop File System implementations.
+
+#### Named Command-Line Arguments
+
+***-t \\<table\\_name\\[,table\\_name]>***\\
+A comma-separated list of tables to back up. If no tables are specified, all tables are backed up. No regular-expression or
+wildcard support is present; all table names must be explicitly listed. See [Backup Sets](/docs/backup-restore/commands#using-backup-sets) for more
+information about peforming operations on collections of tables. Mutually exclusive with the *-s* option; one of these
+named options are required.
+
+***-s \\<backup\\_set\\_name>***\\
+Identify tables to backup based on a backup set. See [Using Backup Sets](/docs/backup-restore/commands#using-backup-sets) for the purpose and usage
+of backup sets. Mutually exclusive with the *-t* option.
+
+***-w \\<number\\_workers>***\\
+(Optional) Specifies the number of parallel workers to copy data to backup destination. Backups are currently executed by MapReduce jobs
+so this value corresponds to the number of Mappers that will be spawned by the job.
+
+***-b \\<bandwidth\\_per\\_worker>***\\
+(Optional) Specifies the bandwidth of each worker in MB per second.
+
+***-d***\\
+(Optional) Enables "DEBUG" mode which prints additional logging about the backup creation.
+
+***-i***\\
+(Optional) Ignore checksum verify between source snapshot and exported snapshot. Especially when the source and target file system types
+are different, we should use -i option to skip checksum-checks.
+
+***-q \\<name>***\\
+(Optional) Allows specification of the name of a YARN queue which the MapReduce job to create the backup should be executed in. This option
+is useful to prevent backup tasks from stealing resources away from other MapReduce jobs of high importance.
+
+#### Example usage
+
+\`\`\`bash
+$ hbase backup create full hdfs://host5:9000/data/backup -t SALES2,SALES3 -w 3
+\`\`\`
+
+This command creates a full backup image of two tables, SALES2 and SALES3, in the HDFS instance who NameNode is host5:9000
+in the path */data/backup*. The *-w* option specifies that no more than three parallel works complete the operation.
+
+### Restoring a Backup Image
+
+Run the following command as an HBase superuser. You can only restore a backup on a running HBase cluster because the data must be
+redistributed the RegionServers for the operation to complete successfully.
+
+\`\`\`bash
+hbase restore <backup_path> <backup_id>
+\`\`\`
+
+#### Positional Command-Line Arguments
+
+***backup\\_path***\\
+The *backup\\_path* argument specifies the full filesystem URI of where to store the backup image. Valid prefixes are
+*hdfs:*, *webhdfs:*, *s3a:* or other compatible Hadoop File System implementations.
+
+***backup\\_id***\\
+The backup ID that uniquely identifies the backup image to be restored.
+
+#### Named Command-Line Arguments
+
+***-t \\<table\\_name\\[,table\\_name]>***\\
+A comma-separated list of tables to restore. See [Backup Sets](/docs/backup-restore/commands#using-backup-sets) for more
+information about peforming operations on collections of tables. Mutually exclusive with the *-s* option; one of these
+named options are required.
+
+***-s \\<backup\\_set\\_name>***\\
+Identify tables to backup based on a backup set. See [Using Backup Sets](/docs/backup-restore/commands#using-backup-sets) for the purpose and usage
+of backup sets. Mutually exclusive with the *-t* option.
+
+***-q \\<name>***\\
+(Optional) Allows specification of the name of a YARN queue which the MapReduce job to create the backup should be executed in. This option
+is useful to prevent backup tasks from stealing resources away from other MapReduce jobs of high importance.
+
+***-c***\\
+(Optional) Perform a dry-run of the restore. The actions are checked, but not executed.
+
+***-m \\<target\\_tables>***\\
+(Optional) A comma-separated list of tables to restore into. If this option is not provided, the original table name is used. When
+this option is provided, there must be an equal number of entries provided in the \`-t\` option.
+
+***-o***\\
+(Optional) Overwrites the target table for the restore if the table already exists.
+
+#### Example of Usage
+
+\`\`\`bash
+hbase restore /tmp/backup_incremental backupId_1467823988425 -t mytable1,mytable2
+\`\`\`
+
+This command restores two tables of an incremental backup image. In this example:
+โ€ข \`/tmp/backup_incremental\` is the path to the directory containing the backup image.
+โ€ข \`backupId_1467823988425\` is the backup ID.
+โ€ข \`mytable1\` and \`mytable2\` are the names of tables in the backup image to be restored.
+
+<Callout type="info">
+  If the namespace of a table being restored does not exist in the target environment, it will be
+  automatically created during the restore operation.
+  [HBASE-25707](https://issues.apache.org/jira/browse/HBASE-25707)
+</Callout>
+
+### Merging Incremental Backup Images
+
+This command can be used to merge two or more incremental backup images into a single incremental
+backup image. This can be used to consolidate multiple, small incremental backup images into a single
+larger incremental backup image. This command could be used to merge hourly incremental backups
+into a daily incremental backup image, or daily incremental backups into a weekly incremental backup.
+
+\`\`\`bash
+$ hbase backup merge <backup_ids>
+\`\`\`
+
+#### Positional Command-Line Arguments
+
+***backup\\_ids***\\
+A comma-separated list of incremental backup image IDs that are to be combined into a single image.
+
+#### Named Command-Line Arguments
+
+None.
+
+#### Example usage
+
+\`\`\`bash
+$ hbase backup merge backupId_1467823988425,backupId_1467827588425
+\`\`\`
+
+### Using Backup Sets
+
+Backup sets can ease the administration of HBase data backups and restores by reducing the amount of repetitive input
+of table names. You can group tables into a named backup set with the \`hbase backup set add\` command. You can then use
+the \`-set\` option to invoke the name of a backup set in the \`hbase backup create\` or \`hbase restore\` rather than list
+individually every table in the group. You can have multiple backup sets.
+
+<Callout type="info">
+  Note the differentiation between the \`hbase backup set add\` command and the *-set* option. The
+  \`hbase backup set add\` command must be run before using the \`-set\` option in a different command
+  because backup sets must be named and defined before using backup sets as a shortcut.
+</Callout>
+
+If you run the \`hbase backup set add\` command and specify a backup set name that does not yet exist on your system, a new set
+is created. If you run the command with the name of an existing backup set name, then the tables that you specify are added
+to the set.
+
+In this command, the backup set name is case-sensitive.
+
+<Callout type="info">
+  The metadata of backup sets are stored within HBase. If you do not have access to the original
+  HBase cluster with the backup set metadata, then you must specify individual table names to
+  restore the data.
+</Callout>
+
+To create a backup set, run the following command as the HBase superuser:
+
+\`\`\`bash
+$ hbase backup set <subcommand> <backup_set_name> <tables>
+\`\`\`
+
+#### Backup Set Subcommands
+
+The following list details subcommands of the hbase backup set command.
+
+<Callout type="info">
+  You must enter one (and no more than one) of the following subcommands after hbase backup set to
+  complete an operation. Also, the backup set name is case-sensitive in the command-line utility.
+</Callout>
+
+***add***\\
+Adds table\\[s] to a backup set. Specify a *backup\\_set\\_name* value after this argument to create a backup set.
+
+***remove***\\
+Removes tables from the set. Specify the tables to remove in the tables argument.
+
+***list***\\
+Lists all backup sets.
+
+***describe***\\
+Displays a description of a backup set. The information includes whether the set has full
+or incremental backups, start and end times of the backups, and a list of the tables in the set. This subcommand must precede
+a valid value for the *backup\\_set\\_name* value.
+
+***delete***\\
+Deletes a backup set. Enter the value for the *backup\\_set\\_name* option directly after the \`hbase backup set delete\` command.
+
+#### Positional Command-Line Arguments
+
+***backup\\_set\\_name***\\
+Use to assign or invoke a backup set name. The backup set name must contain only printable characters and cannot have any spaces.
+
+***tables***\\
+List of tables (or a single table) to include in the backup set. Enter the table names as a comma-separated list. If no tables
+are specified, all tables are included in the set.
+
+<Callout type="info">
+  Maintain a log or other record of the case-sensitive backup set names and the corresponding tables
+  in each set on a separate or remote cluster, backup strategy. This information can help you in
+  case of failure on the primary cluster.
+</Callout>
+
+#### Example of Usage
+
+\`\`\`bash
+$ hbase backup set add Q1Data TEAM3,TEAM_4
+\`\`\`
+
+Depending on the environment, this command results in *one* of the following actions:
+
+* If the \`Q1Data\` backup set does not exist, a backup set containing tables \`TEAM_3\` and \`TEAM_4\` is created.
+* If the \`Q1Data\` backup set exists already, the tables \`TEAM_3\` and \`TEAM_4\` are added to the \`Q1Data\` backup set.
+`,c={title:"Backup and Restore commands",description:"Command-line utilities for creating, restoring, and merging HBase backups including full and incremental backup operations."},l=[{href:"/docs/backup-restore/administration"},{href:"/docs/backup-restore/commands#using-backup-sets"},{href:"/docs/backup-restore/commands#using-backup-sets"},{href:"/docs/backup-restore/commands#using-backup-sets"},{href:"/docs/backup-restore/commands#using-backup-sets"},{href:"https://issues.apache.org/jir [...]
+inspect details on specific backup sessions is covered in the next section, Administration of Backup Images.`},{heading:void 0,content:`Run the command hbase backup help <command> to access the online help that provides basic information about a command
+and its options. The below information is captured in this help message for each command.`},{heading:"creating-a-backup-image",content:"type: info"},{heading:"creating-a-backup-image",content:`For HBase clusters also using Apache Phoenix: include the SQL system catalog tables in the backup.
+In the event that you need to restore the HBase backup, access to the system catalog tables enable
+you to resume Phoenix interoperability with the restored data.`},{heading:"creating-a-backup-image",content:`The first step in running the backup and restore utilities is to perform a full backup and to store the data in a separate image
+from the source. At a minimum, you must do this to get a baseline before you can rely on incremental backups.`},{heading:"creating-a-backup-image",content:"Run the following command as HBase superuser:"},{heading:"creating-a-backup-image",content:`After the command finishes running, the console prints a SUCCESS or FAILURE status message. The SUCCESS message includes a backup ID.
+The backup ID is the Unix time (also known as Epoch time) that the HBase master received the backup request from the client.`},{heading:"creating-a-backup-image",content:"type: info"},{heading:"creating-a-backup-image",content:`Record the backup ID that appears at the end of a successful backup. In case the source cluster
+fails and you need to recover the dataset with a restore operation, having the backup ID readily
+available can save time.`},{heading:"backup-restore-commands-creating-a-backup-image-positional-command-line-arguments",content:`typeThe type of backup to execute: full or incremental. As a reminder, an incremental backup requires a full backup to
+already exist.`},{heading:"backup-restore-commands-creating-a-backup-image-positional-command-line-arguments",content:`backup_pathThe backup_path argument specifies the full filesystem URI of where to store the backup image. Valid prefixes are
+hdfs:, webhdfs:, s3a: or other compatible Hadoop File System implementations.`},{heading:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",content:`-t <table_name[,table_name]>A comma-separated list of tables to back up. If no tables are specified, all tables are backed up. No regular-expression or
+wildcard support is present; all table names must be explicitly listed. See Backup Sets for more
+information about peforming operations on collections of tables. Mutually exclusive with the -s option; one of these
+named options are required.`},{heading:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",content:`-s <backup_set_name>Identify tables to backup based on a backup set. See Using Backup Sets for the purpose and usage
+of backup sets. Mutually exclusive with the -t option.`},{heading:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",content:`-w <number_workers>(Optional) Specifies the number of parallel workers to copy data to backup destination. Backups are currently executed by MapReduce jobs
+so this value corresponds to the number of Mappers that will be spawned by the job.`},{heading:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",content:"-b <bandwidth_per_worker>(Optional) Specifies the bandwidth of each worker in MB per second."},{heading:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",content:'-d(Optional) Enables "DEBUG" mode which prints additional logging about the backup creation.'},{heading:"backup-resto [...]
+are different, we should use -i option to skip checksum-checks.`},{heading:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",content:`-q <name>(Optional) Allows specification of the name of a YARN queue which the MapReduce job to create the backup should be executed in. This option
+is useful to prevent backup tasks from stealing resources away from other MapReduce jobs of high importance.`},{heading:"backup-restore-commands-creating-a-backup-image-example-usage",content:`This command creates a full backup image of two tables, SALES2 and SALES3, in the HDFS instance who NameNode is host5:9000
+in the path /data/backup. The -w option specifies that no more than three parallel works complete the operation.`},{heading:"restoring-a-backup-image",content:`Run the following command as an HBase superuser. You can only restore a backup on a running HBase cluster because the data must be
+redistributed the RegionServers for the operation to complete successfully.`},{heading:"backup-restore-commands-restoring-a-backup-image-positional-command-line-arguments",content:`backup_pathThe backup_path argument specifies the full filesystem URI of where to store the backup image. Valid prefixes are
+hdfs:, webhdfs:, s3a: or other compatible Hadoop File System implementations.`},{heading:"backup-restore-commands-restoring-a-backup-image-positional-command-line-arguments",content:"backup_idThe backup ID that uniquely identifies the backup image to be restored."},{heading:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",content:`-t <table_name[,table_name]>A comma-separated list of tables to restore. See Backup Sets for more
+information about peforming operations on collections of tables. Mutually exclusive with the -s option; one of these
+named options are required.`},{heading:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",content:`-s <backup_set_name>Identify tables to backup based on a backup set. See Using Backup Sets for the purpose and usage
+of backup sets. Mutually exclusive with the -t option.`},{heading:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",content:`-q <name>(Optional) Allows specification of the name of a YARN queue which the MapReduce job to create the backup should be executed in. This option
+is useful to prevent backup tasks from stealing resources away from other MapReduce jobs of high importance.`},{heading:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",content:"-c(Optional) Perform a dry-run of the restore. The actions are checked, but not executed."},{heading:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",content:`-m <target_tables>(Optional) A comma-separated list of tables to restore into. If this option [...]
+this option is provided, there must be an equal number of entries provided in the -t option.`},{heading:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",content:"-o(Optional) Overwrites the target table for the restore if the table already exists."},{heading:"example-of-usage",content:`This command restores two tables of an incremental backup image. In this example:
+โ€ข /tmp/backup_incremental is the path to the directory containing the backup image.
+โ€ข backupId_1467823988425 is the backup ID.
+โ€ข mytable1 and mytable2 are the names of tables in the backup image to be restored.`},{heading:"example-of-usage",content:"type: info"},{heading:"example-of-usage",content:`If the namespace of a table being restored does not exist in the target environment, it will be
+automatically created during the restore operation.
+HBASE-25707`},{heading:"merging-incremental-backup-images",content:`This command can be used to merge two or more incremental backup images into a single incremental
+backup image. This can be used to consolidate multiple, small incremental backup images into a single
+larger incremental backup image. This command could be used to merge hourly incremental backups
+into a daily incremental backup image, or daily incremental backups into a weekly incremental backup.`},{heading:"backup-restore-commands-merging-incremental-backup-images-positional-command-line-arguments",content:"backup_idsA comma-separated list of incremental backup image IDs that are to be combined into a single image."},{heading:"backup-restore-commands-merging-incremental-backup-images-named-command-line-arguments",content:"None."},{heading:"using-backup-sets",content:`Backup sets [...]
+of table names. You can group tables into a named backup set with the hbase backup set add command. You can then use
+the -set option to invoke the name of a backup set in the hbase backup create or hbase restore rather than list
+individually every table in the group. You can have multiple backup sets.`},{heading:"using-backup-sets",content:"type: info"},{heading:"using-backup-sets",content:`Note the differentiation between the hbase backup set add command and the -set option. The
+hbase backup set add command must be run before using the -set option in a different command
+because backup sets must be named and defined before using backup sets as a shortcut.`},{heading:"using-backup-sets",content:`If you run the hbase backup set add command and specify a backup set name that does not yet exist on your system, a new set
+is created. If you run the command with the name of an existing backup set name, then the tables that you specify are added
+to the set.`},{heading:"using-backup-sets",content:"In this command, the backup set name is case-sensitive."},{heading:"using-backup-sets",content:"type: info"},{heading:"using-backup-sets",content:`The metadata of backup sets are stored within HBase. If you do not have access to the original
+HBase cluster with the backup set metadata, then you must specify individual table names to
+restore the data.`},{heading:"using-backup-sets",content:"To create a backup set, run the following command as the HBase superuser:"},{heading:"backup-set-subcommands",content:"The following list details subcommands of the hbase backup set command."},{heading:"backup-set-subcommands",content:"type: info"},{heading:"backup-set-subcommands",content:`You must enter one (and no more than one) of the following subcommands after hbase backup set to
+complete an operation. Also, the backup set name is case-sensitive in the command-line utility.`},{heading:"backup-set-subcommands",content:"addAdds table[s] to a backup set. Specify a backup_set_name value after this argument to create a backup set."},{heading:"backup-set-subcommands",content:"removeRemoves tables from the set. Specify the tables to remove in the tables argument."},{heading:"backup-set-subcommands",content:"listLists all backup sets."},{heading:"backup-set-subcommands", [...]
+or incremental backups, start and end times of the backups, and a list of the tables in the set. This subcommand must precede
+a valid value for the backup_set_name value.`},{heading:"backup-set-subcommands",content:"deleteDeletes a backup set. Enter the value for the backup_set_name option directly after the hbase backup set delete command."},{heading:"backup-restore-commands-using-backup-sets-positional-command-line-arguments",content:"backup_set_nameUse to assign or invoke a backup set name. The backup set name must contain only printable characters and cannot have any spaces."},{heading:"backup-restore-comma [...]
+are specified, all tables are included in the set.`},{heading:"backup-restore-commands-using-backup-sets-positional-command-line-arguments",content:"type: info"},{heading:"backup-restore-commands-using-backup-sets-positional-command-line-arguments",content:`Maintain a log or other record of the case-sensitive backup set names and the corresponding tables
+in each set on a separate or remote cluster, backup strategy. This information can help you in
+case of failure on the primary cluster.`},{heading:"example-of-usage-1",content:"Depending on the environment, this command results in one of the following actions:"},{heading:"example-of-usage-1",content:"If the Q1Data backup set does not exist, a backup set containing tables TEAM_3 and TEAM_4 is created."},{heading:"example-of-usage-1",content:"If the Q1Data backup set exists already, the tables TEAM_3 and TEAM_4 are added to the Q1Data backup set."}],headings:[{id:"creating-a-backup-i [...]
+inspect details on specific backup sessions is covered in the next section, `,e.jsx(a.a,{href:"/docs/backup-restore/administration",children:"Administration of Backup Images"}),"."]}),`
+`,e.jsxs(a.p,{children:["Run the command ",e.jsx(a.code,{children:"hbase backup help <command>"}),` to access the online help that provides basic information about a command
+and its options. The below information is captured in this help message for each command.`]}),`
+`,e.jsx(a.h3,{id:"creating-a-backup-image",children:"Creating a Backup Image"}),`
+`,e.jsx(t,{type:"info",children:e.jsx(a.p,{children:`For HBase clusters also using Apache Phoenix: include the SQL system catalog tables in the backup.
+In the event that you need to restore the HBase backup, access to the system catalog tables enable
+you to resume Phoenix interoperability with the restored data.`})}),`
+`,e.jsx(a.p,{children:`The first step in running the backup and restore utilities is to perform a full backup and to store the data in a separate image
+from the source. At a minimum, you must do this to get a baseline before you can rely on incremental backups.`}),`
+`,e.jsx(a.p,{children:"Run the following command as HBase superuser:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(a.p,{children:["After the command finishes running, the console prints a SUCCESS or FAILURE status message. The SUCCESS message includes a ",e.jsx(a.em,{children:"backup"}),` ID.
+The backup ID is the Unix time (also known as Epoch time) that the HBase master received the backup request from the client.`]}),`
+`,e.jsx(t,{type:"info",children:e.jsx(a.p,{children:`Record the backup ID that appears at the end of a successful backup. In case the source cluster
+fails and you need to recover the dataset with a restore operation, having the backup ID readily
+available can save time.`})}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-creating-a-backup-image-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"type"})}),e.jsx(a.br,{}),`
+`,"The type of backup to execute: ",e.jsx(a.em,{children:"full"})," or ",e.jsx(a.em,{children:"incremental"}),". As a reminder, an ",e.jsx(a.em,{children:"incremental"})," backup requires a ",e.jsx(a.em,{children:"full"}),` backup to
+already exist.`]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"backup_path"})}),e.jsx(a.br,{}),`
+`,"The ",e.jsx(a.em,{children:"backup_path"}),` argument specifies the full filesystem URI of where to store the backup image. Valid prefixes are
+`,e.jsx(a.em,{children:"hdfs:"}),", ",e.jsx(a.em,{children:"webhdfs:"}),", ",e.jsx(a.em,{children:"s3a:"})," or other compatible Hadoop File System implementations."]}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-creating-a-backup-image-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-t <table_name[,table_name]>"})}),e.jsx(a.br,{}),`
+`,`A comma-separated list of tables to back up. If no tables are specified, all tables are backed up. No regular-expression or
+wildcard support is present; all table names must be explicitly listed. See `,e.jsx(a.a,{href:"/docs/backup-restore/commands#using-backup-sets",children:"Backup Sets"}),` for more
+information about peforming operations on collections of tables. Mutually exclusive with the `,e.jsx(a.em,{children:"-s"}),` option; one of these
+named options are required.`]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-s <backup_set_name>"})}),e.jsx(a.br,{}),`
+`,"Identify tables to backup based on a backup set. See ",e.jsx(a.a,{href:"/docs/backup-restore/commands#using-backup-sets",children:"Using Backup Sets"}),` for the purpose and usage
+of backup sets. Mutually exclusive with the `,e.jsx(a.em,{children:"-t"})," option."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-w <number_workers>"})}),e.jsx(a.br,{}),`
+`,`(Optional) Specifies the number of parallel workers to copy data to backup destination. Backups are currently executed by MapReduce jobs
+so this value corresponds to the number of Mappers that will be spawned by the job.`]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-b <bandwidth_per_worker>"})}),e.jsx(a.br,{}),`
+`,"(Optional) Specifies the bandwidth of each worker in MB per second."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-d"})}),e.jsx(a.br,{}),`
+`,'(Optional) Enables "DEBUG" mode which prints additional logging about the backup creation.']}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-i"})}),e.jsx(a.br,{}),`
+`,`(Optional) Ignore checksum verify between source snapshot and exported snapshot. Especially when the source and target file system types
+are different, we should use -i option to skip checksum-checks.`]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-q <name>"})}),e.jsx(a.br,{}),`
+`,`(Optional) Allows specification of the name of a YARN queue which the MapReduce job to create the backup should be executed in. This option
+is useful to prevent backup tasks from stealing resources away from other MapReduce jobs of high importance.`]}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-creating-a-backup-image-example-usage",children:"Example usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(a.p,{children:[`This command creates a full backup image of two tables, SALES2 and SALES3, in the HDFS instance who NameNode is host5:9000
+in the path `,e.jsx(a.em,{children:"/data/backup"}),". The ",e.jsx(a.em,{children:"-w"})," option specifies that no more than three parallel works complete the operation."]}),`
+`,e.jsx(a.h3,{id:"restoring-a-backup-image",children:"Restoring a Backup Image"}),`
+`,e.jsx(a.p,{children:`Run the following command as an HBase superuser. You can only restore a backup on a running HBase cluster because the data must be
+redistributed the RegionServers for the operation to complete successfully.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(a.h4,{id:"backup-restore-commands-restoring-a-backup-image-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"backup_path"})}),e.jsx(a.br,{}),`
+`,"The ",e.jsx(a.em,{children:"backup_path"}),` argument specifies the full filesystem URI of where to store the backup image. Valid prefixes are
+`,e.jsx(a.em,{children:"hdfs:"}),", ",e.jsx(a.em,{children:"webhdfs:"}),", ",e.jsx(a.em,{children:"s3a:"})," or other compatible Hadoop File System implementations."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"backup_id"})}),e.jsx(a.br,{}),`
+`,"The backup ID that uniquely identifies the backup image to be restored."]}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-restoring-a-backup-image-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-t <table_name[,table_name]>"})}),e.jsx(a.br,{}),`
+`,"A comma-separated list of tables to restore. See ",e.jsx(a.a,{href:"/docs/backup-restore/commands#using-backup-sets",children:"Backup Sets"}),` for more
+information about peforming operations on collections of tables. Mutually exclusive with the `,e.jsx(a.em,{children:"-s"}),` option; one of these
+named options are required.`]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-s <backup_set_name>"})}),e.jsx(a.br,{}),`
+`,"Identify tables to backup based on a backup set. See ",e.jsx(a.a,{href:"/docs/backup-restore/commands#using-backup-sets",children:"Using Backup Sets"}),` for the purpose and usage
+of backup sets. Mutually exclusive with the `,e.jsx(a.em,{children:"-t"})," option."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-q <name>"})}),e.jsx(a.br,{}),`
+`,`(Optional) Allows specification of the name of a YARN queue which the MapReduce job to create the backup should be executed in. This option
+is useful to prevent backup tasks from stealing resources away from other MapReduce jobs of high importance.`]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-c"})}),e.jsx(a.br,{}),`
+`,"(Optional) Perform a dry-run of the restore. The actions are checked, but not executed."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-m <target_tables>"})}),e.jsx(a.br,{}),`
+`,`(Optional) A comma-separated list of tables to restore into. If this option is not provided, the original table name is used. When
+this option is provided, there must be an equal number of entries provided in the `,e.jsx(a.code,{children:"-t"})," option."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"-o"})}),e.jsx(a.br,{}),`
+`,"(Optional) Overwrites the target table for the restore if the table already exists."]}),`
+`,e.jsx(a.h4,{id:"example-of-usage",children:"Example of Usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(a.p,{children:[`This command restores two tables of an incremental backup image. In this example:
+โ€ข `,e.jsx(a.code,{children:"/tmp/backup_incremental"}),` is the path to the directory containing the backup image.
+โ€ข `,e.jsx(a.code,{children:"backupId_1467823988425"}),` is the backup ID.
+โ€ข `,e.jsx(a.code,{children:"mytable1"})," and ",e.jsx(a.code,{children:"mytable2"})," are the names of tables in the backup image to be restored."]}),`
+`,e.jsx(t,{type:"info",children:e.jsxs(a.p,{children:[`If the namespace of a table being restored does not exist in the target environment, it will be
+automatically created during the restore operation.
+`,e.jsx(a.a,{href:"https://issues.apache.org/jira/browse/HBASE-25707",children:"HBASE-25707"})]})}),`
+`,e.jsx(a.h3,{id:"merging-incremental-backup-images",children:"Merging Incremental Backup Images"}),`
+`,e.jsx(a.p,{children:`This command can be used to merge two or more incremental backup images into a single incremental
+backup image. This can be used to consolidate multiple, small incremental backup images into a single
+larger incremental backup image. This command could be used to merge hourly incremental backups
+into a daily incremental backup image, or daily incremental backups into a weekly incremental backup.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(a.h4,{id:"backup-restore-commands-merging-incremental-backup-images-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"backup_ids"})}),e.jsx(a.br,{}),`
+`,"A comma-separated list of incremental backup image IDs that are to be combined into a single image."]}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-merging-incremental-backup-images-named-command-line-arguments",children:"Named Command-Line Arguments"}),`
+`,e.jsx(a.p,{children:"None."}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-merging-incremental-backup-images-example-usage",children:"Example usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(a.h3,{id:"using-backup-sets",children:"Using Backup Sets"}),`
+`,e.jsxs(a.p,{children:[`Backup sets can ease the administration of HBase data backups and restores by reducing the amount of repetitive input
+of table names. You can group tables into a named backup set with the `,e.jsx(a.code,{children:"hbase backup set add"}),` command. You can then use
+the `,e.jsx(a.code,{children:"-set"})," option to invoke the name of a backup set in the ",e.jsx(a.code,{children:"hbase backup create"})," or ",e.jsx(a.code,{children:"hbase restore"}),` rather than list
+individually every table in the group. You can have multiple backup sets.`]}),`
+`,e.jsx(t,{type:"info",children:e.jsxs(a.p,{children:["Note the differentiation between the ",e.jsx(a.code,{children:"hbase backup set add"})," command and the ",e.jsx(a.em,{children:"-set"}),` option. The
+`,e.jsx(a.code,{children:"hbase backup set add"})," command must be run before using the ",e.jsx(a.code,{children:"-set"}),` option in a different command
+because backup sets must be named and defined before using backup sets as a shortcut.`]})}),`
+`,e.jsxs(a.p,{children:["If you run the ",e.jsx(a.code,{children:"hbase backup set add"}),` command and specify a backup set name that does not yet exist on your system, a new set
+is created. If you run the command with the name of an existing backup set name, then the tables that you specify are added
+to the set.`]}),`
+`,e.jsx(a.p,{children:"In this command, the backup set name is case-sensitive."}),`
+`,e.jsx(t,{type:"info",children:e.jsx(a.p,{children:`The metadata of backup sets are stored within HBase. If you do not have access to the original
+HBase cluster with the backup set metadata, then you must specify individual table names to
+restore the data.`})}),`
+`,e.jsx(a.p,{children:"To create a backup set, run the following command as the HBase superuser:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(a.h4,{id:"backup-set-subcommands",children:"Backup Set Subcommands"}),`
+`,e.jsx(a.p,{children:"The following list details subcommands of the hbase backup set command."}),`
+`,e.jsx(t,{type:"info",children:e.jsx(a.p,{children:`You must enter one (and no more than one) of the following subcommands after hbase backup set to
+complete an operation. Also, the backup set name is case-sensitive in the command-line utility.`})}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"add"})}),e.jsx(a.br,{}),`
+`,"Adds table[s] to a backup set. Specify a ",e.jsx(a.em,{children:"backup_set_name"})," value after this argument to create a backup set."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"remove"})}),e.jsx(a.br,{}),`
+`,"Removes tables from the set. Specify the tables to remove in the tables argument."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"list"})}),e.jsx(a.br,{}),`
+`,"Lists all backup sets."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"describe"})}),e.jsx(a.br,{}),`
+`,`Displays a description of a backup set. The information includes whether the set has full
+or incremental backups, start and end times of the backups, and a list of the tables in the set. This subcommand must precede
+a valid value for the `,e.jsx(a.em,{children:"backup_set_name"})," value."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"delete"})}),e.jsx(a.br,{}),`
+`,"Deletes a backup set. Enter the value for the ",e.jsx(a.em,{children:"backup_set_name"})," option directly after the ",e.jsx(a.code,{children:"hbase backup set delete"})," command."]}),`
+`,e.jsx(a.h4,{id:"backup-restore-commands-using-backup-sets-positional-command-line-arguments",children:"Positional Command-Line Arguments"}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"backup_set_name"})}),e.jsx(a.br,{}),`
+`,"Use to assign or invoke a backup set name. The backup set name must contain only printable characters and cannot have any spaces."]}),`
+`,e.jsxs(a.p,{children:[e.jsx(a.strong,{children:e.jsx(a.em,{children:"tables"})}),e.jsx(a.br,{}),`
+`,`List of tables (or a single table) to include in the backup set. Enter the table names as a comma-separated list. If no tables
+are specified, all tables are included in the set.`]}),`
+`,e.jsx(t,{type:"info",children:e.jsx(a.p,{children:`Maintain a log or other record of the case-sensitive backup set names and the corresponding tables
+in each set on a separate or remote cluster, backup strategy. This information can help you in
+case of failure on the primary cluster.`})}),`
+`,e.jsx(a.h4,{id:"example-of-usage-1",children:"Example of Usage"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(a.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(a.p,{children:["Depending on the environment, this command results in ",e.jsx(a.em,{children:"one"})," of the following actions:"]}),`
+`,e.jsxs(a.ul,{children:[`
+`,e.jsxs(a.li,{children:["If the ",e.jsx(a.code,{children:"Q1Data"})," backup set does not exist, a backup set containing tables ",e.jsx(a.code,{children:"TEAM_3"})," and ",e.jsx(a.code,{children:"TEAM_4"})," is created."]}),`
+`,e.jsxs(a.li,{children:["If the ",e.jsx(a.code,{children:"Q1Data"})," backup set exists already, the tables ",e.jsx(a.code,{children:"TEAM_3"})," and ",e.jsx(a.code,{children:"TEAM_4"})," are added to the ",e.jsx(a.code,{children:"Q1Data"})," backup set."]}),`
+`]})]})}function m(n={}){const{wrapper:a}=n.components||{};return a?e.jsx(a,{...n,children:e.jsx(s,{...n})}):s(n)}function i(n,a){throw new Error("Expected component `"+n+"` to be defined: you likely forgot to import, pass, or provide it.")}export{r as _markdown,m as default,l as extractedReferences,c as frontmatter,h as structuredData,d as toc};
diff --git a/assets/community-C_kYyqbI.js b/assets/community-C_kYyqbI.js
new file mode 100644
index 00000000000..be572d61ead
--- /dev/null
+++ b/assets/community-C_kYyqbI.js
@@ -0,0 +1,87 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let s=`## Decisions
+
+### Feature Branches
+
+Feature Branches are easy to make. You do not have to be a committer to make one. Just request the name of your branch be added to JIRA up on the developer's mailing list and a committer will add it for you. Thereafter you can file issues against your feature branch in Apache HBase JIRA. Your code you 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 featu [...]
+
+### 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 master is going to be 3.0.0, branch-2 will be 2.4.0, and branch-1 will be 1.7.0 then:
+
+* Commit only to master (i.e., backward-incompatible new feature): Mark with 3.0.0
+* Commit only to master and branch-2 (i.e., backward-compatible new feature, applicable only to 2.x+): Mark with 3.0.0 and 2.4.0
+* Commit to master, branch-2, and branch-1 (i.e., backward-compatible new feature, applicable everywhere): Mark with 3.0.0, 2.4.0, and 1.7.0
+* Commit to master, branch-2, and branch-2.3, branch-1, branch-1.4 (i.e., bug fix applicable to all active release lines): Mark with 3.0.0, 2.4.0, 2.3.x, 1.7.0, and 1.4.x
+* Commit a fix to the website: no version
+
+### Policy on when to set a RESOLVED JIRA as CLOSED
+
+We agreed that for issues that list multiple releases in their *Fix Version/s* field, CLOSE the issue on the release of any of the versions listed; subsequent change to the issue must happen in a new JIRA.
+
+### Only transient state in ZooKeeper!
+
+You should be able to kill the data in zookeeper and hbase should ride over it recreating the zk content as it goes. This is an old adage around these parts. We just made note of it now. We also are currently in violation of this basic tenet โ€” replication at least keeps permanent state in zk โ€” but we are working to undo this breaking of a golden rule.
+
+## Community Roles
+
+### Release Managers
+
+Each maintained release branch has a release manager, who volunteers to coordinate new features and bug fixes are backported to that release. The release managers are [committers](/team). If you would like your feature or bug fix to be included in a given release, communicate with that release manager. If this list goes out of date or you can't reach the listed person, reach out to someone else on the list.
+
+**Release Managers:**
+
+| Release | Release Manager   | Latest Release                        | EOL            |
+| ------- | ----------------- | ------------------------------------- | -------------- |
+| 0.94    | Lars Hofhansl     | 0.94.27                               | April 2017     |
+| 0.96    | Michael Stack     | 0.96.2                                | September 2014 |
+| 0.98    | Andrew Purtell    | 0.98.24                               | April 2017     |
+| 1.0     | Enis Soztutar     | 1.0.3                                 | January 2016   |
+| 1.1     | Nick Dimiduk      | 1.1.13                                | December 2017  |
+| 1.2     | Sean Busbey       | 1.2.12                                | June 2019      |
+| 1.3     | Mikhail Antonov   | 1.3.6                                 | August 2020    |
+| 1.4     | Andrew Purtell    | 1.4.14                                | October 2021   |
+| 1.5     | Andrew Purtell    | 1.5.0                                 | October 2019   |
+| 1.6     | Andrew Purtell    | 1.6.0                                 | February 2020  |
+| 1.7     | Reid Chan         | 1.7.2                                 | August 2022    |
+| 2.0     | Michael Stack     | 2.0.6                                 | September 2019 |
+| 2.1     | Duo Zhang         | 2.1.10                                | May 2020       |
+| 2.2     | Guanghao Zhang    | 2.2.7                                 | April 2021     |
+| 2.3     | Nick Dimiduk      | 2.3.7                                 | October 2021   |
+| 2.4     | Andrew Purtell    | 2.4.18                                | June 2024      |
+| 2.5     | Andrew Purtell    | Check the [download](/downloads) page | **NOT YET**    |
+| 2.6     | Bryan Beaudreault | Check the [download](/downloads) page | **NOT YET**    |
+
+## Commit Message format
+
+We agreed to the following Git commit message format:
+
+\`\`\`text
+HBASE-xxxxx <title>. (<contributor>)
+\`\`\`
+
+If the person making the commit is the contributor, leave off the '(\\<contributor>)' element.
+`,i={title:"Community",description:"HBase community decisions, release managers, JIRA policies, commit message format, and guidelines for feature branches."},o=[{href:"https://lists.apache.org/thread.html/200513c7e7e4df23c8b9134eeee009d61205c79314e77f222d396006%401346870308%40%3Cdev.hbase.apache.org%3E"},{href:"/team"},{href:"/downloads"},{href:"/downloads"}],l={contents:[{heading:"feature-branches",content:"Feature Branches are easy to make. You do not have to be a committer to make one [...]
+`,e.jsx(n.h3,{id:"feature-branches",children:"Feature Branches"}),`
+`,e.jsxs(n.p,{children:["Feature Branches are easy to make. You do not have to be a committer to make one. Just request the name of your branch be added to JIRA up on the developer's mailing list and a committer will add it for you. Thereafter you can file issues against your feature branch in Apache HBase JIRA. Your code you 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 commi [...]
+`,e.jsx(n.h3,{id:"how-to-set-fix-version-in-jira-on-issue-resolve",children:"How to set fix version in JIRA on issue resolve"}),`
+`,e.jsx(n.p,{children:"Here is how we agreed to set versions in JIRA when we resolve an issue. If master is going to be 3.0.0, branch-2 will be 2.4.0, and branch-1 will be 1.7.0 then:"}),`
+`,e.jsxs(n.ul,{children:[`
+`,e.jsx(n.li,{children:"Commit only to master (i.e., backward-incompatible new feature): Mark with 3.0.0"}),`
+`,e.jsx(n.li,{children:"Commit only to master and branch-2 (i.e., backward-compatible new feature, applicable only to 2.x+): Mark with 3.0.0 and 2.4.0"}),`
+`,e.jsx(n.li,{children:"Commit to master, branch-2, and branch-1 (i.e., backward-compatible new feature, applicable everywhere): Mark with 3.0.0, 2.4.0, and 1.7.0"}),`
+`,e.jsx(n.li,{children:"Commit to master, branch-2, and branch-2.3, branch-1, branch-1.4 (i.e., bug fix applicable to all active release lines): Mark with 3.0.0, 2.4.0, 2.3.x, 1.7.0, and 1.4.x"}),`
+`,e.jsx(n.li,{children:"Commit a fix to the website: no version"}),`
+`]}),`
+`,e.jsx(n.h3,{id:"policy-on-when-to-set-a-resolved-jira-as-closed",children:"Policy on when to set a RESOLVED JIRA as CLOSED"}),`
+`,e.jsxs(n.p,{children:["We agreed that for issues that list multiple releases in their ",e.jsx(n.em,{children:"Fix Version/s"})," field, CLOSE the issue on the release of any of the versions listed; subsequent change to the issue must happen in a new JIRA."]}),`
+`,e.jsx(n.h3,{id:"only-transient-state-in-zookeeper",children:"Only transient state in ZooKeeper!"}),`
+`,e.jsx(n.p,{children:"You should be able to kill the data in zookeeper and hbase should ride over it recreating the zk content as it goes. This is an old adage around these parts. We just made note of it now. We also are currently in violation of this basic tenet โ€” replication at least keeps permanent state in zk โ€” but we are working to undo this breaking of a golden rule."}),`
+`,e.jsx(n.h2,{id:"community-roles",children:"Community Roles"}),`
+`,e.jsx(n.h3,{id:"release-managers",children:"Release Managers"}),`
+`,e.jsxs(n.p,{children:["Each maintained release branch has a release manager, who volunteers to coordinate new features and bug fixes are backported to that release. The release managers are ",e.jsx(n.a,{href:"/team",children:"committers"}),". If you would like your feature or bug fix to be included in a given release, communicate with that release manager. If this list goes out of date or you can't reach the listed person, reach out to someone else on the list."]}),`
+`,e.jsx(n.p,{children:e.jsx(n.strong,{children:"Release Managers:"})}),`
+`,e.jsxs(n.table,{children:[e.jsx(n.thead,{children:e.jsxs(n.tr,{children:[e.jsx(n.th,{children:"Release"}),e.jsx(n.th,{children:"Release Manager"}),e.jsx(n.th,{children:"Latest Release"}),e.jsx(n.th,{children:"EOL"})]})}),e.jsxs(n.tbody,{children:[e.jsxs(n.tr,{children:[e.jsx(n.td,{children:"0.94"}),e.jsx(n.td,{children:"Lars Hofhansl"}),e.jsx(n.td,{children:"0.94.27"}),e.jsx(n.td,{children:"April 2017"})]}),e.jsxs(n.tr,{children:[e.jsx(n.td,{children:"0.96"}),e.jsx(n.td,{children:"Mich [...]
+`,e.jsx(n.h2,{id:"commit-message-format",children:"Commit Message format"}),`
+`,e.jsx(n.p,{children:"We agreed to the following Git commit message format:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(n.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(n.p,{children:"If the person making the commit is the contributor, leave off the '(<contributor>)' element."})]})}function h(a={}){const{wrapper:n}=a.components||{};return n?e.jsx(n,{...a,children:e.jsx(t,{...a})}):t(a)}export{s as _markdown,h as default,o as extractedReferences,i as frontmatter,l as structuredData,d as toc};
diff --git a/assets/compression-BLaOmo6n.js b/assets/compression-BLaOmo6n.js
new file mode 100644
index 00000000000..fec4efd4d30
--- /dev/null
+++ b/assets/compression-BLaOmo6n.js
@@ -0,0 +1,1102 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";import{_ as o,a as t,b as r}from"./data_block_diff_encoding-DaVDpSR3.js";let d=`
+
+
+
+
+
+<Callout type="info">
+  Codecs mentioned in this section are for encoding and decoding data blocks or row keys. For
+  information about replication codecs, see
+  [cluster.replication.preserving.tags](/docs/operational-management/cluster-replication#life-of-a-wal-edit).
+</Callout>
+
+HBase supports several different compression algorithms which can be enabled on a ColumnFamily.
+Data block encoding attempts to limit duplication of information in keys, taking advantage of some of the fundamental designs and patterns of HBase, such as sorted row keys and the schema of a given table.
+Compressors reduce the size of large, opaque byte arrays in cells, and can significantly reduce the storage space needed to store uncompressed data.
+
+Compressors and data block encoding can be used together on the same ColumnFamily.
+
+## Changes Take Effect Upon Compaction
+
+If you change compression or encoding for a ColumnFamily, the changes take effect during compaction.
+
+Some codecs take advantage of capabilities built into Java, such as GZip compression.
+Others rely on native libraries. Native libraries may be available via codec dependencies installed into
+HBase's library directory, or, if you are utilizing Hadoop codecs, as part of Hadoop. Hadoop codecs
+typically have a native code component so follow instructions for installing Hadoop native binary
+support at [Making use of Hadoop Native Libraries in HBase](/docs/compression#making-use-of-hadoop-native-libraries-in-hbase).
+
+This section discusses common codecs that are used and tested with HBase.
+
+No matter what codec you use, be sure to test that it is installed correctly and is available on all nodes in your cluster.
+Extra operational steps may be necessary to be sure that codecs are available on newly-deployed nodes.
+You can use the [compression.test](/docs/compression#compressiontest) utility to check that a given codec is correctly installed.
+
+To configure HBase to use a compressor, see [compressor.install](/docs/compression#compressor-configuration-installation-and-use).
+To enable a compressor for a ColumnFamily, see [changing.compression](/docs/compression#enable-compression-on-a-columnfamily).
+To enable data block encoding for a ColumnFamily, see [data.block.encoding.enable](/docs/compression#enable-data-block-encoding).
+
+## Block Compressors
+
+* **NONE**\\
+  This compression type constant selects no compression, and is the default.
+* **BROTLI**\\
+  [Brotli](https://en.wikipedia.org/wiki/Brotli) is a generic-purpose lossless compression algorithm
+  that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman
+  coding, and 2nd order context modeling, with a compression ratio comparable to the best currently
+  available general-purpose compression methods. It is similar in speed with GZ but offers more
+  dense compression.
+* **BZIP2**\\
+  [Bzip2](https://en.wikipedia.org/wiki/Bzip2) compresses files using the Burrows-Wheeler block
+  sorting text compression algorithm and Huffman coding. Compression is generally considerably
+  better than that achieved by the dictionary- (LZ-) based compressors, but both compression and
+  decompression can be slow in comparison to other options.
+* **GZ**\\
+  gzip is based on the [DEFLATE](https://en.wikipedia.org/wiki/Deflate) algorithm, which is a
+  combination of LZ77 and Huffman coding. It is universally available in the Java Runtime
+  Environment so is a good lowest common denominator option. However in comparison to more modern
+  algorithms like Zstandard it is quite slow.
+* **LZ4**\\
+  [LZ4](https://en.wikipedia.org/wiki/LZ4_\\(compression_algorithm\\)) is a lossless data compression
+  algorithm that is focused on compression and decompression speed. It belongs to the LZ77 family
+  of compression algorithms, like Brotli, DEFLATE, Zstandard, and others. In our microbenchmarks
+  LZ4 is the fastest option for both compression and decompression in that family, and is our
+  universally recommended option.
+* **LZMA**\\
+  [LZMA](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm) is a
+  dictionary compression scheme somewhat similar to the LZ77 algorithm that achieves very high
+  compression ratios with a computationally expensive predictive model and variable size
+  compression dictionary, while still maintaining decompression speed similar to other commonly used
+  compression algorithms. LZMA is superior to all other options in general compression ratio but as
+  a compressor it can be extremely slow, especially when configured to operate at higher levels of
+  compression.
+* **LZO**\\
+  [LZO](https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Oberhumer) is another LZ-variant
+  data compression algorithm, with an implementation focused on decompression speed. It is almost
+  but not quite as fast as LZ4.
+* **SNAPPY**\\
+  [Snappy](https://en.wikipedia.org/wiki/Snappy_\\(compression\\)) is based on ideas from LZ77 but is
+  optimized for very high compression speed, achieving only a "reasonable" compression in trade.
+  It is as fast as LZ4 but does not compress quite as well. We offer a pure Java Snappy codec
+  that can be used instead of GZ as the universally available option for any Java runtime on any
+  hardware architecture.
+* **ZSTD**\\
+  [Zstandard](https://en.wikipedia.org/wiki/Zstd) combines a dictionary-matching stage (LZ77) with
+  a large search window and a fast entropy coding stage, using both Finite State Entropy and
+  Huffman coding. Compression speed can vary by a factor of 20 or more between the fastest and
+  slowest levels, while decompression is uniformly fast, varying by less than 20% between the
+  fastest and slowest levels.\\
+  ZStandard is the most flexible of the available compression codec options, offering a compression
+  ratio similar to LZ4 at level 1 (but with slightly less performance), compression ratios
+  comparable to DEFLATE at mid levels (but with better performance), and LZMA-alike dense
+  compression (and LZMA-alike compression speeds) at high levels; while providing universally fast
+  decompression.
+
+## Data Block Encoding Types
+
+### Prefix
+
+Often, keys are very similar. Specifically, keys often share a common prefix and only differ near the end. For instance, one key might be \`RowKey:Family:Qualifier0\` and the next key might be \`RowKey:Family:Qualifier1\`.
+In Prefix encoding, an extra column is added which holds the length of the prefix shared between the current key and the previous key. Assuming the first key here is totally different from the key before, its prefix length is 0.
+
+The second key's prefix length is \`23\`, since they have the first 23 characters in common.
+
+Obviously if the keys tend to have nothing in common, Prefix will not provide much benefit.
+
+The following image shows a hypothetical ColumnFamily with no data block encoding.
+
+<img alt="ColumnFamily with No Encoding" src={__img0} placeholder="blur" />
+
+Here is the same data with prefix data encoding.
+
+<img alt="ColumnFamily with Prefix Encoding" src={__img1} placeholder="blur" />
+
+### Diff
+
+Diff encoding expands upon Prefix encoding.
+Instead of considering the key sequentially as a monolithic series of bytes, each key field is split so that each part of the key can be compressed more efficiently.
+
+Two new fields are added: timestamp and type.
+
+If the ColumnFamily is the same as the previous row, it is omitted from the current row.
+
+If the key length, value length or type are the same as the previous row, the field is omitted.
+
+In addition, for increased compression, the timestamp is stored as a Diff from the previous row's timestamp, rather than being stored in full.
+Given the two row keys in the Prefix example, and given an exact match on timestamp and the same type, neither the value length, or type needs to be stored for the second row, and the timestamp value for the second row is just 0, rather than a full timestamp.
+
+Diff encoding is disabled by default because writing and scanning are slower but more data is cached.
+
+This image shows the same ColumnFamily from the previous images, with Diff encoding.
+
+<img alt="ColumnFamily with Diff Encoding" src={__img2} placeholder="blur" />
+
+### Fast Diff
+
+Fast Diff works similar to Diff, but uses a faster implementation. It also adds another field which stores a single bit to track whether the data itself is the same as the previous row. If it is, the data is not stored again.
+
+Fast Diff is the recommended codec to use if you have long keys or many columns.
+
+The data format is nearly identical to Diff encoding, so there is not an image to illustrate it.
+
+### Prefix Tree
+
+Prefix tree encoding was introduced as an experimental feature in HBase 0.96.
+It provides similar memory savings to the Prefix, Diff, and Fast Diff encoder, but provides faster random access at a cost of slower encoding speed.
+It was removed in hbase-2.0.0. It was a good idea but little uptake. If interested in reviving this effort, write the hbase dev list.
+
+## Which Compressor or Data Block Encoder To Use
+
+The compression or codec type to use depends on the characteristics of your data. Choosing the wrong type could cause your data to take more space rather than less, and can have performance implications.
+
+In general, you need to weigh your options between smaller size and faster compression/decompression. Following are some general guidelines, expanded from a discussion at [Documenting Guidance on compression and codecs](https://lists.apache.org/thread.html/481e67a61163efaaf4345510447a9244871a8d428244868345a155ff%401378926618%40%3Cdev.hbase.apache.org%3E).
+
+* In most cases, enabling LZ4 or Snappy by default is a good choice, because they have a low
+  performance overhead and provide reasonable space savings. A fast compression algorithm almost
+  always improves overall system performance by trading some increased CPU usage for better I/O
+  efficiency.
+* If the values are large (and not pre-compressed, such as images), use a data block compressor.
+* For *cold data*, which is accessed infrequently, depending on your use case, it might
+  make sense to opt for Zstandard at its higher compression levels, or LZMA, especially for high
+  entropy binary data, or Brotli for data similar in characteristics to web data. Bzip2 might also
+  be a reasonable option but Zstandard is very likely to offer superior decompression speed.
+* For *hot data*, which is accessed frequently, you almost certainly want only LZ4,
+  Snappy, LZO, or Zstandard at a low compression level. These options will not provide as high of
+  a compression ratio but will in trade not unduly impact system performance.
+* If you have long keys (compared to the values) or many columns, use a prefix encoder.
+  FAST\\_DIFF is recommended.
+* If enabling WAL value compression, consider LZ4 or SNAPPY compression, or Zstandard at
+  level 1. Reading and writing the WAL is performance critical. That said, the I/O
+  savings of these compression options can improve overall system performance.
+
+## Making use of Hadoop Native Libraries in HBase
+
+The Hadoop shared library has a bunch of facility including compression libraries and fast crc'ing โ€” hardware crc'ing if your chipset supports it.
+To make this facility available to HBase, do the following. HBase/Hadoop will fall back to use alternatives if it cannot find the native library
+versions โ€” or fail outright if you asking for an explicit compressor and there is no alternative available.
+
+First make sure of your Hadoop. Fix this message if you are seeing it starting Hadoop processes:
+
+\`\`\`
+16/02/09 22:40:24 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
+\`\`\`
+
+It means is not properly pointing at its native libraries or the native libs were compiled for another platform.
+Fix this first.
+
+Then if you see the following in your HBase logs, you know that HBase was unable to locate the Hadoop native libraries:
+
+\`\`\`
+2014-08-07 09:26:20,139 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
+\`\`\`
+
+If the libraries loaded successfully, the WARN message does not show. Usually this means you are good to go but read on.
+
+Let's presume your Hadoop shipped with a native library that suits the platform you are running HBase on.
+To check if the Hadoop native library is available to HBase, run the following tool (available in Hadoop 2.1 and greater):
+
+\`\`\`bash
+$ ./bin/hbase --config ~/conf_hbase org.apache.hadoop.util.NativeLibraryChecker
+2014-08-26 13:15:38,717 WARN  [main] util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
+Native library checking:
+hadoop: false
+zlib:   false
+snappy: false
+lz4:    false
+bzip2:  false
+2014-08-26 13:15:38,863 INFO  [main] util.ExitUtil: Exiting with status 1
+\`\`\`
+
+Above shows that the native hadoop library is not available in HBase context.
+
+The above NativeLibraryChecker tool may come back saying all is hunky-dory
+โ€” i.e. all libs show 'true', that they are available โ€” but follow the below
+presecription anyways to ensure the native libs are available in HBase context,
+when it goes to use them.
+
+To fix the above, either copy the Hadoop native libraries local or symlink to them if the Hadoop and HBase stalls are adjacent in the filesystem.
+You could also point at their location by setting the \`LD_LIBRARY_PATH\` environment variable in your hbase-env.sh.
+
+Where the JVM looks to find native libraries is "system dependent" (See \`java.lang.System#loadLibrary(name)\`). On linux, by default, is going to look in *lib/native/PLATFORM* where \`PLATFORM\` is the label for the platform your HBase is installed on.
+On a local linux machine, it seems to be the concatenation of the java properties \`os.name\` and \`os.arch\` followed by whether 32 or 64 bit.
+HBase on startup prints out all of the java system properties so find the os.name and os.arch in the log.
+For example:
+
+\`\`\`
+...
+2014-08-06 15:27:22,853 INFO  [main] zookeeper.ZooKeeper: Client environment:os.name=Linux
+2014-08-06 15:27:22,853 INFO  [main] zookeeper.ZooKeeper: Client environment:os.arch=amd64
+...
+\`\`\`
+
+So in this case, the PLATFORM string is \`Linux-amd64-64\`.
+Copying the Hadoop native libraries or symlinking at *lib/native/Linux-amd64-64* will ensure they are found.
+Rolling restart after you have made this change.
+
+Here is an example of how you would set up the symlinks.
+Let the hadoop and hbase installs be in your home directory. Assume your hadoop native libs
+are at \\~/hadoop/lib/native. Assume you are on a Linux-amd64-64 platform. In this case,
+you would do the following to link the hadoop native lib so hbase could find them.
+
+\`\`\`bash
+...
+$ mkdir -p ~/hbaseLinux-amd64-64 -> /home/stack/hadoop/lib/native/lib/native/
+$ cd ~/hbase/lib/native/
+$ ln -s ~/hadoop/lib/native Linux-amd64-64
+$ ls -la
+# Linux-amd64-64 -> /home/USER/hadoop/lib/native
+...
+\`\`\`
+
+If you see PureJavaCrc32C in a stack track or if you see something like the below in a perf trace, then native is not working; you are using the java CRC functions rather than native:
+
+\`\`\`
+  5.02%  perf-53601.map      [.] Lorg/apache/hadoop/util/PureJavaCrc32C;.update
+\`\`\`
+
+See [HBASE-11927 Use Native Hadoop Library for HFile checksum (And flip default from CRC32 to CRC32C)](https://issues.apache.org/jira/browse/HBASE-11927),
+for more on native checksumming support. See in particular the release note for how to check if your hardware to see if your processor has support for hardware CRCs.
+Or checkout the Apache [Checksums in HBase](https://blogs.apache.org/hbase/entry/saving_cpu_using_native_hadoop) blog post.
+
+Here is example of how to point at the Hadoop libs with \`LD_LIBRARY_PATH\` environment variable:
+
+\`\`\`bash
+$ LD_LIBRARY_PATH=~/hadoop-2.5.0-SNAPSHOT/lib/native ./bin/hbase --config ~/conf_hbase org.apache.hadoop.util.NativeLibraryChecker
+2014-08-26 13:42:49,332 INFO  [main] bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native
+2014-08-26 13:42:49,337 INFO  [main] zlib.ZlibFactory: Successfully loaded & initialized native-zlib library
+Native library checking:
+hadoop: true /home/stack/hadoop-2.5.0-SNAPSHOT/lib/native/libhadoop.so.1.0.0
+zlib:   true /lib64/libz.so.1
+snappy: true /usr/lib64/libsnappy.so.1
+lz4:    true revision:99
+bzip2:  true /lib64/libbz2.so.1
+\`\`\`
+
+Set in *hbase-env.sh* the LD\\_LIBRARY\\_PATH environment variable when starting your HBase.
+
+## Compressor Configuration, Installation, and Use
+
+### Configure HBase For Compressors
+
+Compression codecs are provided either by HBase compressor modules or by Hadoop's native compression
+support. As described above you choose a compression type in table or column family schema or in
+site configuration using its short label, e.g. *snappy* for Snappy, or *zstd* for ZStandard. Which
+codec implementation is dynamically loaded to support what label is configurable by way of site
+configuration.
+
+| Algorithm label | Codec implementation configuration key | Default value                                               |
+| --------------- | -------------------------------------- | ----------------------------------------------------------- |
+| BROTLI          | hbase.io.compress.brotli.codec         | org.apache.hadoop.hbase.io.compress.brotli.BrotliCodec      |
+| BZIP2           | hbase.io.compress.bzip2.codec          | org.apache.hadoop.io.compress.BZip2Codec                    |
+| GZ              | hbase.io.compress.gz.codec             | org.apache.hadoop.hbase.io.compress.ReusableStreamGzipCodec |
+| LZ4             | hbase.io.compress.lz4.codec            | org.apache.hadoop.io.compress.Lz4Codec                      |
+| LZMA            | hbase.io.compress.lzma.codec           | org.apache.hadoop.hbase.io.compress.xz.LzmaCodec            |
+| LZO             | hbase.io.compress.lzo.codec            | com.hadoop.compression.lzo.LzoCodec                         |
+| SNAPPY          | hbase.io.compress.snappy.codec         | org.apache.hadoop.io.compress.SnappyCodec                   |
+| ZSTD            | hbase.io.compress.zstd.codec           | org.apache.hadoop.io.compress.ZStandardCodec                |
+
+The available codec implementation options are:
+
+| Label  | Codec implementation class                                    | Notes                                                                                                                         |
+| ------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| BROTLI | org.apache.hadoop.hbase.io.compress.brotli.BrotliCodec        | Implemented with [Brotli4j](https://github.com/hyperxpro/Brotli4j)                                                            |
+| BZIP2  | org.apache.hadoop.io.compress.BZip2Codec                      | Hadoop native codec                                                                                                           |
+| GZ     | org.apache.hadoop.hbase.io.compress.ReusableStreamGzipCodec   | Requires the Hadoop native GZ codec                                                                                           |
+| LZ4    | org.apache.hadoop.io.compress.Lz4Codec                        | Hadoop native codec                                                                                                           |
+| LZ4    | org.apache.hadoop.hbase.io.compress.aircompressor.Lz4Codec    | Pure Java implementation                                                                                                      |
+| LZ4    | org.apache.hadoop.hbase.io.compress.lz4.Lz4Codec              | Implemented with [lz4-java](https://github.com/lz4/lz4-java)                                                                  |
+| LZMA   | org.apache.hadoop.hbase.io.compress.xz.LzmaCodec              | Implemented with [XZ For Java](https://tukaani.org/xz/java.html)                                                              |
+| LZO    | com.hadoop.compression.lzo.LzoCodec                           | Hadoop native codec, requires GPL licensed native dependencies                                                                |
+| LZO    | org.apache.hadoop.io.compress.LzoCodec                        | Hadoop native codec, requires GPL licensed native dependencies                                                                |
+| LZO    | org.apache.hadoop.hbase.io.compress.aircompressor.LzoCodec    | Pure Java implementation                                                                                                      |
+| SNAPPY | org.apache.hadoop.io.compress.SnappyCodec                     | Hadoop native codec                                                                                                           |
+| SNAPPY | org.apache.hadoop.hbase.io.compress.aircompressor.SnappyCodec | Pure Java implementation                                                                                                      |
+| SNAPPY | org.apache.hadoop.hbase.io.compress.xerial.SnappyCodec        | Implemented with [snappy-java](https://github.com/xerial/snappy-java)                                                         |
+| ZSTD   | org.apache.hadoop.io.compress.ZStandardCodec                  | Hadoop native codec                                                                                                           |
+| ZSTD   | org.apache.hadoop.hbase.io.compress.aircompressor.ZstdCodec   | Pure Java implementation, limited to a fixed compression level, not data compatible with the Hadoop zstd codec                |
+| ZSTD   | org.apache.hadoop.hbase.io.compress.zstd.ZstdCodec            | Implemented with [zstd-jni](https://github.com/luben/zstd-jni), supports all compression levels, supports custom dictionaries |
+
+Specify which codec implementation option you prefer for a given compression algorithm
+in site configuration, like so:
+
+\`\`\`xml
+...
+<property>
+  <name>hbase.io.compress.lz4.codec</name>
+  <value>org.apache.hadoop.hbase.io.compress.lz4.Lz4Codec</value>
+</property>
+...
+\`\`\`
+
+#### Compressor Microbenchmarks
+
+See [https://github.com/apurtell/jmh-compression-tests](https://github.com/apurtell/jmh-compression-tests)
+
+256MB (258,126,022 bytes exactly) of block data was extracted from two HFiles containing Common
+Crawl data ingested using IntegrationLoadTestCommonCrawl, 2,680 blocks in total. This data was
+processed by each new codec implementation as if the block data were being compressed again for
+write into an HFile, but without writing any data, comparing only the CPU time and resource demand
+of the codec itself. Absolute performance numbers will vary depending on hardware and software
+particulars of your deployment. The relative differences are what are interesting. Measured time
+is the average time in milliseconds required to compress all blocks of the 256MB file. This is
+how long it would take to write the HFile containing these contents, minus the I/O overhead of
+block encoding and actual persistence.
+
+These are the results:
+
+| Codec                   | Level         | Time (milliseconds)  | Result (bytes) | Improvement |
+| ----------------------- | ------------- | -------------------- | -------------- | ----------- |
+| AirCompressor LZ4       | -             | 349.989 ยฑ 2.835      | 76,999,408     | 70.17%      |
+| AirCompressor LZO       | -             | 334.554 ยฑ 3.243      | 79,369,805     | 69.25%      |
+| AirCompressor Snappy    | -             | 364.153 ยฑ 19.718     | 80,201,763     | 68.93%      |
+| AirCompressor Zstandard | 3 (effective) | 1108.267 ยฑ 8.969     | 55,129,189     | 78.64%      |
+| Brotli                  | 1             | 593.107 ยฑ 2.376      | 58,672,319     | 77.27%      |
+| Brotli                  | 3             | 1345.195 ยฑ 27.327    | 53,917,438     | 79.11%      |
+| Brotli                  | 6             | 2812.411 ยฑ 25.372    | 48,696,441     | 81.13%      |
+| Brotli                  | 10            | 74615.936 ยฑ 224.854  | 44,970,710     | 82.58%      |
+| LZ4 (lz4-java)          | -             | 303.045 ยฑ 0.783      | 76,974,364     | 70.18%      |
+| LZMA                    | 1             | 6410.428 ยฑ 115.065   | 49,948,535     | 80.65%      |
+| LZMA                    | 3             | 8144.620 ยฑ 152.119   | 49,109,363     | 80.97%      |
+| LZMA                    | 6             | 43802.576 ยฑ 382.025  | 46,951,810     | 81.81%      |
+| LZMA                    | 9             | 49821.979 ยฑ 580.110  | 46,951,810     | 81.81%      |
+| Snappy (xerial)         | -             | 360.225 ยฑ 2.324      | 80,749,937     | 68.72%      |
+| Zstd (zstd-jni)         | 1             | 654.699 ยฑ 16.839     | 56,719,994     | 78.03%      |
+| Zstd (zstd-jni)         | 3             | 839.160 ยฑ 24.906     | 54,573,095     | 78.86%      |
+| Zstd (zstd-jni)         | 5             | 1594.373 ยฑ 22.384    | 52,025,485     | 79.84%      |
+| Zstd (zstd-jni)         | 7             | 2308.705 ยฑ 24.744    | 50,651,554     | 80.38%      |
+| Zstd (zstd-jni)         | 9             | 3659.677 ยฑ 58.018    | 50,208,425     | 80.55%      |
+| Zstd (zstd-jni)         | 12            | 8705.294 ยฑ 58.080    | 49,841,446     | 80.69%      |
+| Zstd (zstd-jni)         | 15            | 19785.646 ยฑ 278.080  | 48,499,508     | 81.21%      |
+| Zstd (zstd-jni)         | 18            | 47702.097 ยฑ 442.670  | 48,319,879     | 81.28%      |
+| Zstd (zstd-jni)         | 22            | 97799.695 ยฑ 1106.571 | 48,212,220     | 81.32%      |
+
+#### Compressor Support On the Master
+
+A new configuration setting was introduced in HBase 0.95, to check the Master to determine which data block encoders are installed and configured on it, and assume that the entire cluster is configured the same.
+This option, \`hbase.master.check.compression\`, defaults to \`true\`.
+This prevents the situation described in [HBASE-6370](https://issues.apache.org/jira/browse/HBASE-6370), where a table is created or modified to support a codec that a region server does not support, leading to failures that take a long time to occur and are difficult to debug.
+
+If \`hbase.master.check.compression\` is enabled, libraries for all desired compressors need to be installed and configured on the Master, even if the Master does not run a region server.
+
+#### Install GZ Support Via Native Libraries
+
+HBase uses Java's built-in GZip support unless the native Hadoop libraries are available on the CLASSPATH.
+The recommended way to add libraries to the CLASSPATH is to set the environment variable \`HBASE_LIBRARY_PATH\` for the user running HBase.
+If native libraries are not available and Java's GZIP is used, \`Got brand-new compressor\` reports will be present in the logs.
+See [brand.new.compressor](/docs/troubleshooting#logs-flooded-with-2011-01-10-124048407-info-orgapachehadoopiocompresscodecpool-gotbrand-new-compressor-messages)).
+
+#### Install Hadoop Native LZO Support
+
+HBase cannot ship with the Hadoop native LZO codc because of incompatibility between HBase, which uses an Apache Software License (ASL) and LZO, which uses a GPL license.
+See the [Hadoop-LZO at Twitter](https://github.com/twitter/hadoop-lzo/blob/master/README.md) for information on configuring LZO support for HBase.
+
+If you depend upon LZO compression, consider using the pure Java and ASL licensed
+AirCompressor LZO codec option instead of the Hadoop native default, or configure your
+RegionServers to fail to start if native LZO support is not available.
+See [hbase.regionserver.codecs](/docs/compression#enforce-compression-settings-on-a-regionserver).
+
+#### Configure Hadoop Native LZ4 Support
+
+LZ4 support is bundled with Hadoop and is the default LZ4 codec implementation.
+It is not required that you make use of the Hadoop LZ4 codec. Our LZ4 codec implemented
+with lz4-java offers superior performance, and the AirCompressor LZ4 codec offers a
+pure Java option for use where native support is not available.
+
+That said, if you prefer the Hadoop option, make sure the hadoop shared library
+(libhadoop.so) is accessible when you start HBase.
+After configuring your platform (see [hadoop.native.lib](/docs/compression#making-use-of-hadoop-native-libraries-in-hbase)), you can
+make a symbolic link from HBase to the native Hadoop libraries. This assumes the two
+software installs are colocated. For example, if my 'platform' is Linux-amd64-64:
+
+\`\`\`bash
+$ cd $HBASE_HOME
+$ mkdir lib/native
+$ ln -s $HADOOP_HOME/lib/native lib/native/Linux-amd64-64
+\`\`\`
+
+Use the compression tool to check that LZ4 is installed on all nodes.
+Start up (or restart) HBase.
+Afterward, you can create and alter tables to enable LZ4 as a compression codec.:
+
+\`\`\`ruby
+hbase(main):003:0> alter 'TestTable', {NAME => 'info', COMPRESSION => 'LZ4'}
+\`\`\`
+
+#### Install Hadoop native Snappy Support
+
+Snappy support is bundled with Hadoop and is the default Snappy codec implementation.
+It is not required that you make use of the Hadoop Snappy codec. Our Snappy codec
+implemented with Xerial Snappy offers superior performance, and the AirCompressor
+Snappy codec offers a pure Java option for use where native support is not available.
+
+That said, if you prefer the Hadoop codec option, you can install Snappy binaries (for
+instance, by using +yum install snappy+ on CentOS) or build Snappy from source.
+After installing Snappy, search for the shared library, which will be called *libsnappy.so.X* where X is a number.
+If you built from source, copy the shared library to a known location on your system, such as */opt/snappy/lib/*.
+
+In addition to the Snappy library, HBase also needs access to the Hadoop shared library, which will be called something like *libhadoop.so.X.Y*, where X and Y are both numbers.
+Make note of the location of the Hadoop library, or copy it to the same location as the Snappy library.
+
+<Callout type="info">
+  The Snappy and Hadoop libraries need to be available on each node of your cluster.
+  See [compression.test](/docs/compression#compressiontest) to find out how to test that this is the case.
+
+  See [hbase.regionserver.codecs](/docs/compression#enforce-compression-settings-on-a-regionserver) to configure your RegionServers to fail to start if a given compressor is not available.
+</Callout>
+
+Each of these library locations need to be added to the environment variable \`HBASE_LIBRARY_PATH\` for the operating system user that runs HBase.
+You need to restart the RegionServer for the changes to take effect.
+
+#### CompressionTest
+
+You can use the CompressionTest tool to verify that your compressor is available to HBase:
+
+\`\`\`bash
+ $ hbase org.apache.hadoop.hbase.util.CompressionTest hdfs://host/path/to/hbase snappy
+\`\`\`
+
+#### Enforce Compression Settings On a RegionServer
+
+You can configure a RegionServer so that it will fail to restart if compression is configured incorrectly, by adding the option hbase.regionserver.codecs to the *hbase-site.xml*, and setting its value to a comma-separated list of codecs that need to be available.
+For example, if you set this property to \`lzo,gz\`, the RegionServer would fail to start if both compressors were not available.
+This would prevent a new server from being added to the cluster without having codecs configured properly.
+
+### Enable Compression On a ColumnFamily
+
+To enable compression for a ColumnFamily, use an \`alter\` command.
+You do not need to re-create the table or copy data.
+If you are changing codecs, be sure the old codec is still available until all the old StoreFiles have been compacted.
+
+#### Enabling Compression on a ColumnFamily of an Existing Table using HBaseShell
+
+\`\`\`ruby
+hbase> alter 'test', {NAME => 'cf', COMPRESSION => 'GZ'}
+\`\`\`
+
+#### Creating a New Table with Compression On a ColumnFamily
+
+\`\`\`ruby
+hbase> create 'test2', { NAME => 'cf2', COMPRESSION => 'SNAPPY' }
+\`\`\`
+
+#### Verifying a ColumnFamily's Compression Settings
+
+\`\`\`ruby
+hbase> describe 'test'
+DESCRIPTION                                          ENABLED
+ 'test', {NAME => 'cf', DATA_BLOCK_ENCODING => 'NONE false
+ ', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0',
+ VERSIONS => '1', COMPRESSION => 'GZ', MIN_VERSIONS
+ => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS => 'fa
+ lse', BLOCKSIZE => '65536', IN_MEMORY => 'false', B
+ LOCKCACHE => 'true'}
+1 row(s) in 0.1070 seconds
+\`\`\`
+
+### Testing Compression Performance
+
+HBase includes a tool called LoadTestTool which provides mechanisms to test your compression performance.
+You must specify either \`-write\` or \`-update-read\` as your first parameter, and if you do not specify another parameter, usage advice is printed for each option.
+
+**\`LoadTestTool\` Usage**
+
+\`\`\`bash
+$ bin/hbase org.apache.hadoop.hbase.util.LoadTestTool -h
+usage: bin/hbase org.apache.hadoop.hbase.util.LoadTestTool <options>
+Options:
+ -batchupdate                 Whether to use batch as opposed to separate
+                              updates for every column in a row
+ -bloom <arg>                 Bloom filter type, one of [NONE, ROW, ROWCOL]
+ -compression <arg>           Compression type, one of [LZO, GZ, NONE, SNAPPY,
+                              LZ4]
+ -data_block_encoding <arg>   Encoding algorithm (e.g. prefix compression) to
+                              use for data blocks in the test column family, one
+                              of [NONE, PREFIX, DIFF, FAST_DIFF, ROW_INDEX_V1].
+ -encryption <arg>            Enables transparent encryption on the test table,
+                              one of [AES]
+ -generator <arg>             The class which generates load for the tool. Any
+                              args for this class can be passed as colon
+                              separated after class name
+ -h,--help                    Show usage
+ -in_memory                   Tries to keep the HFiles of the CF inmemory as far
+                              as possible.  Not guaranteed that reads are always
+                              served from inmemory
+ -init_only                   Initialize the test table only, don't do any
+                              loading
+ -key_window <arg>            The 'key window' to maintain between reads and
+                              writes for concurrent write/read workload. The
+                              default is 0.
+ -max_read_errors <arg>       The maximum number of read errors to tolerate
+                              before terminating all reader threads. The default
+                              is 10.
+ -multiput                    Whether to use multi-puts as opposed to separate
+                              puts for every column in a row
+ -num_keys <arg>              The number of keys to read/write
+ -num_tables <arg>            A positive integer number. When a number n is
+                              speicfied, load test tool  will load n table
+                              parallely. -tn parameter value becomes table name
+                              prefix. Each table name is in format
+                              <tn>_1...<tn>_n
+ -read <arg>                  <verify_percent>[:#threads=20]
+ -regions_per_server <arg>    A positive integer number. When a number n is
+                              specified, load test tool will create the test
+                              table with n regions per server
+ -skip_init                   Skip the initialization; assume test table already
+                              exists
+ -start_key <arg>             The first key to read/write (a 0-based index). The
+                              default value is 0.
+ -tn <arg>                    The name of the table to read or write
+ -update <arg>                <update_percent>[:#threads=20][:#whether to
+                              ignore nonce collisions=0]
+ -write <arg>                 <avg_cols_per_key>:<avg_data_size>[:#threads=20]
+ -zk <arg>                    ZK quorum as comma-separated host names without
+                              port numbers
+ -zk_root <arg>               name of parent znode in zookeeper
+\`\`\`
+
+#### Example Usage of LoadTestTool
+
+\`\`\`bash
+$ hbase org.apache.hadoop.hbase.util.LoadTestTool -write 1:10:100 -num_keys 1000000 \\
+      -read 100:30 -num_tables 1 -data_block_encoding NONE -tn load_test_tool_NONE
+\`\`\`
+
+## Enable Data Block Encoding
+
+Codecs are built into HBase so no extra configuration is needed.
+Codecs are enabled on a table by setting the \`DATA_BLOCK_ENCODING\` property.
+Disable the table before altering its DATA\\_BLOCK\\_ENCODING setting.
+Following is an example using HBase Shell:
+
+#### Enable Data Block Encoding On a Table
+
+\`\`\`ruby
+hbase> alter 'test', { NAME => 'cf', DATA_BLOCK_ENCODING => 'FAST_DIFF' }
+Updating all regions with the new schema...
+0/1 regions updated.
+1/1 regions updated.
+Done.
+0 row(s) in 2.2820 seconds
+\`\`\`
+
+#### Verifying a ColumnFamily's Data Block Encoding
+
+\`\`\`ruby
+hbase> describe 'test'
+DESCRIPTION                                          ENABLED
+ 'test', {NAME => 'cf', DATA_BLOCK_ENCODING => 'FAST true
+ _DIFF', BLOOMFILTER => 'ROW', REPLICATION_SCOPE =>
+ '0', VERSIONS => '1', COMPRESSION => 'GZ', MIN_VERS
+ IONS => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS =
+ > 'false', BLOCKSIZE => '65536', IN_MEMORY => 'fals
+ e', BLOCKCACHE => 'true'}
+1 row(s) in 0.0650 seconds
+\`\`\`
+`,p={title:"Compression and Data Block Encoding In HBase",description:"Comprehensive guide to compression algorithms and data block encoding options in HBase for optimizing storage and performance."},m=[{href:"/docs/operational-management/cluster-replication#life-of-a-wal-edit"},{href:"/docs/compression#making-use-of-hadoop-native-libraries-in-hbase"},{href:"/docs/compression#compressiontest"},{href:"/docs/compression#compressor-configuration-installation-and-use"},{href:"/docs/compressi [...]
+information about replication codecs, see
+cluster.replication.preserving.tags.`},{heading:void 0,content:`HBase supports several different compression algorithms which can be enabled on a ColumnFamily.
+Data block encoding attempts to limit duplication of information in keys, taking advantage of some of the fundamental designs and patterns of HBase, such as sorted row keys and the schema of a given table.
+Compressors reduce the size of large, opaque byte arrays in cells, and can significantly reduce the storage space needed to store uncompressed data.`},{heading:void 0,content:"Compressors and data block encoding can be used together on the same ColumnFamily."},{heading:"changes-take-effect-upon-compaction",content:"If you change compression or encoding for a ColumnFamily, the changes take effect during compaction."},{heading:"changes-take-effect-upon-compaction",content:`Some codecs take [...]
+Others rely on native libraries. Native libraries may be available via codec dependencies installed into
+HBase's library directory, or, if you are utilizing Hadoop codecs, as part of Hadoop. Hadoop codecs
+typically have a native code component so follow instructions for installing Hadoop native binary
+support at Making use of Hadoop Native Libraries in HBase.`},{heading:"changes-take-effect-upon-compaction",content:"This section discusses common codecs that are used and tested with HBase."},{heading:"changes-take-effect-upon-compaction",content:`No matter what codec you use, be sure to test that it is installed correctly and is available on all nodes in your cluster.
+Extra operational steps may be necessary to be sure that codecs are available on newly-deployed nodes.
+You can use the compression.test utility to check that a given codec is correctly installed.`},{heading:"changes-take-effect-upon-compaction",content:`To configure HBase to use a compressor, see compressor.install.
+To enable a compressor for a ColumnFamily, see changing.compression.
+To enable data block encoding for a ColumnFamily, see data.block.encoding.enable.`},{heading:"block-compressors",content:"NONEThis compression type constant selects no compression, and is the default."},{heading:"block-compressors",content:`BROTLIBrotli is a generic-purpose lossless compression algorithm
+that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman
+coding, and 2nd order context modeling, with a compression ratio comparable to the best currently
+available general-purpose compression methods. It is similar in speed with GZ but offers more
+dense compression.`},{heading:"block-compressors",content:`BZIP2Bzip2 compresses files using the Burrows-Wheeler block
+sorting text compression algorithm and Huffman coding. Compression is generally considerably
+better than that achieved by the dictionary- (LZ-) based compressors, but both compression and
+decompression can be slow in comparison to other options.`},{heading:"block-compressors",content:`GZgzip is based on the DEFLATE algorithm, which is a
+combination of LZ77 and Huffman coding. It is universally available in the Java Runtime
+Environment so is a good lowest common denominator option. However in comparison to more modern
+algorithms like Zstandard it is quite slow.`},{heading:"block-compressors",content:`LZ4LZ4 is a lossless data compression
+algorithm that is focused on compression and decompression speed. It belongs to the LZ77 family
+of compression algorithms, like Brotli, DEFLATE, Zstandard, and others. In our microbenchmarks
+LZ4 is the fastest option for both compression and decompression in that family, and is our
+universally recommended option.`},{heading:"block-compressors",content:`LZMALZMA is a
+dictionary compression scheme somewhat similar to the LZ77 algorithm that achieves very high
+compression ratios with a computationally expensive predictive model and variable size
+compression dictionary, while still maintaining decompression speed similar to other commonly used
+compression algorithms. LZMA is superior to all other options in general compression ratio but as
+a compressor it can be extremely slow, especially when configured to operate at higher levels of
+compression.`},{heading:"block-compressors",content:`LZOLZO is another LZ-variant
+data compression algorithm, with an implementation focused on decompression speed. It is almost
+but not quite as fast as LZ4.`},{heading:"block-compressors",content:`SNAPPYSnappy is based on ideas from LZ77 but is
+optimized for very high compression speed, achieving only a "reasonable" compression in trade.
+It is as fast as LZ4 but does not compress quite as well. We offer a pure Java Snappy codec
+that can be used instead of GZ as the universally available option for any Java runtime on any
+hardware architecture.`},{heading:"block-compressors",content:`ZSTDZstandard combines a dictionary-matching stage (LZ77) with
+a large search window and a fast entropy coding stage, using both Finite State Entropy and
+Huffman coding. Compression speed can vary by a factor of 20 or more between the fastest and
+slowest levels, while decompression is uniformly fast, varying by less than 20% between the
+fastest and slowest levels.ZStandard is the most flexible of the available compression codec options, offering a compression
+ratio similar to LZ4 at level 1 (but with slightly less performance), compression ratios
+comparable to DEFLATE at mid levels (but with better performance), and LZMA-alike dense
+compression (and LZMA-alike compression speeds) at high levels; while providing universally fast
+decompression.`},{heading:"prefix",content:`Often, keys are very similar. Specifically, keys often share a common prefix and only differ near the end. For instance, one key might be RowKey:Family:Qualifier0 and the next key might be RowKey:Family:Qualifier1.
+In Prefix encoding, an extra column is added which holds the length of the prefix shared between the current key and the previous key. Assuming the first key here is totally different from the key before, its prefix length is 0.`},{heading:"prefix",content:"The second key's prefix length is 23, since they have the first 23 characters in common."},{heading:"prefix",content:"Obviously if the keys tend to have nothing in common, Prefix will not provide much benefit."},{heading:"prefix",cont [...]
+Instead of considering the key sequentially as a monolithic series of bytes, each key field is split so that each part of the key can be compressed more efficiently.`},{heading:"diff",content:"Two new fields are added: timestamp and type."},{heading:"diff",content:"If the ColumnFamily is the same as the previous row, it is omitted from the current row."},{heading:"diff",content:"If the key length, value length or type are the same as the previous row, the field is omitted."},{heading:"di [...]
+Given the two row keys in the Prefix example, and given an exact match on timestamp and the same type, neither the value length, or type needs to be stored for the second row, and the timestamp value for the second row is just 0, rather than a full timestamp.`},{heading:"diff",content:"Diff encoding is disabled by default because writing and scanning are slower but more data is cached."},{heading:"diff",content:"This image shows the same ColumnFamily from the previous images, with Diff e [...]
+It provides similar memory savings to the Prefix, Diff, and Fast Diff encoder, but provides faster random access at a cost of slower encoding speed.
+It was removed in hbase-2.0.0. It was a good idea but little uptake. If interested in reviving this effort, write the hbase dev list.`},{heading:"which-compressor-or-data-block-encoder-to-use",content:"The compression or codec type to use depends on the characteristics of your data. Choosing the wrong type could cause your data to take more space rather than less, and can have performance implications."},{heading:"which-compressor-or-data-block-encoder-to-use",content:"In general, you ne [...]
+performance overhead and provide reasonable space savings. A fast compression algorithm almost
+always improves overall system performance by trading some increased CPU usage for better I/O
+efficiency.`},{heading:"which-compressor-or-data-block-encoder-to-use",content:"If the values are large (and not pre-compressed, such as images), use a data block compressor."},{heading:"which-compressor-or-data-block-encoder-to-use",content:`For cold data, which is accessed infrequently, depending on your use case, it might
+make sense to opt for Zstandard at its higher compression levels, or LZMA, especially for high
+entropy binary data, or Brotli for data similar in characteristics to web data. Bzip2 might also
+be a reasonable option but Zstandard is very likely to offer superior decompression speed.`},{heading:"which-compressor-or-data-block-encoder-to-use",content:`For hot data, which is accessed frequently, you almost certainly want only LZ4,
+Snappy, LZO, or Zstandard at a low compression level. These options will not provide as high of
+a compression ratio but will in trade not unduly impact system performance.`},{heading:"which-compressor-or-data-block-encoder-to-use",content:`If you have long keys (compared to the values) or many columns, use a prefix encoder.
+FAST_DIFF is recommended.`},{heading:"which-compressor-or-data-block-encoder-to-use",content:`If enabling WAL value compression, consider LZ4 or SNAPPY compression, or Zstandard at
+level 1. Reading and writing the WAL is performance critical. That said, the I/O
+savings of these compression options can improve overall system performance.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`The Hadoop shared library has a bunch of facility including compression libraries and fast crc'ing โ€” hardware crc'ing if your chipset supports it.
+To make this facility available to HBase, do the following. HBase/Hadoop will fall back to use alternatives if it cannot find the native library
+versions โ€” or fail outright if you asking for an explicit compressor and there is no alternative available.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"First make sure of your Hadoop. Fix this message if you are seeing it starting Hadoop processes:"},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`It means is not properly pointing at its native libraries or the native libs were compiled for another platform.
+Fix this first.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"Then if you see the following in your HBase logs, you know that HBase was unable to locate the Hadoop native libraries:"},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"If the libraries loaded successfully, the WARN message does not show. Usually this means you are good to go but read on."},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`Let's presume your Hadoop sh [...]
+To check if the Hadoop native library is available to HBase, run the following tool (available in Hadoop 2.1 and greater):`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"Above shows that the native hadoop library is not available in HBase context."},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`The above NativeLibraryChecker tool may come back saying all is hunky-dory
+โ€” i.e. all libs show 'true', that they are available โ€” but follow the below
+presecription anyways to ensure the native libs are available in HBase context,
+when it goes to use them.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`To fix the above, either copy the Hadoop native libraries local or symlink to them if the Hadoop and HBase stalls are adjacent in the filesystem.
+You could also point at their location by setting the LD_LIBRARY_PATH environment variable in your hbase-env.sh.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`Where the JVM looks to find native libraries is "system dependent" (See java.lang.System#loadLibrary(name)). On linux, by default, is going to look in lib/native/PLATFORM where PLATFORM is the label for the platform your HBase is installed on.
+On a local linux machine, it seems to be the concatenation of the java properties os.name and os.arch followed by whether 32 or 64 bit.
+HBase on startup prints out all of the java system properties so find the os.name and os.arch in the log.
+For example:`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`So in this case, the PLATFORM string is Linux-amd64-64.
+Copying the Hadoop native libraries or symlinking at lib/native/Linux-amd64-64 will ensure they are found.
+Rolling restart after you have made this change.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`Here is an example of how you would set up the symlinks.
+Let the hadoop and hbase installs be in your home directory. Assume your hadoop native libs
+are at ~/hadoop/lib/native. Assume you are on a Linux-amd64-64 platform. In this case,
+you would do the following to link the hadoop native lib so hbase could find them.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"If you see PureJavaCrc32C in a stack track or if you see something like the below in a perf trace, then native is not working; you are using the java CRC functions rather than native:"},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:`See HBASE-11927 Use Native Hadoop Library for HFile checksum (And flip default from CRC [...]
+for more on native checksumming support. See in particular the release note for how to check if your hardware to see if your processor has support for hardware CRCs.
+Or checkout the Apache Checksums in HBase blog post.`},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"Here is example of how to point at the Hadoop libs with LD_LIBRARY_PATH environment variable:"},{heading:"making-use-of-hadoop-native-libraries-in-hbase",content:"Set in hbase-env.sh the LD_LIBRARY_PATH environment variable when starting your HBase."},{heading:"configure-hbase-for-compressors",content:`Compression codecs are provided either by HBase compressor modules [...]
+support. As described above you choose a compression type in table or column family schema or in
+site configuration using its short label, e.g. snappy for Snappy, or zstd for ZStandard. Which
+codec implementation is dynamically loaded to support what label is configurable by way of site
+configuration.`},{heading:"configure-hbase-for-compressors",content:"Algorithm label"},{heading:"configure-hbase-for-compressors",content:"Codec implementation configuration key"},{heading:"configure-hbase-for-compressors",content:"Default value"},{heading:"configure-hbase-for-compressors",content:"BROTLI"},{heading:"configure-hbase-for-compressors",content:"hbase.io.compress.brotli.codec"},{heading:"configure-hbase-for-compressors",content:"org.apache.hadoop.hbase.io.compress.brotli.Bro [...]
+in site configuration, like so:`},{heading:"compressor-microbenchmarks",content:"See https://github.com/apurtell/jmh-compression-tests"},{heading:"compressor-microbenchmarks",content:`256MB (258,126,022 bytes exactly) of block data was extracted from two HFiles containing Common
+Crawl data ingested using IntegrationLoadTestCommonCrawl, 2,680 blocks in total. This data was
+processed by each new codec implementation as if the block data were being compressed again for
+write into an HFile, but without writing any data, comparing only the CPU time and resource demand
+of the codec itself. Absolute performance numbers will vary depending on hardware and software
+particulars of your deployment. The relative differences are what are interesting. Measured time
+is the average time in milliseconds required to compress all blocks of the 256MB file. This is
+how long it would take to write the HFile containing these contents, minus the I/O overhead of
+block encoding and actual persistence.`},{heading:"compressor-microbenchmarks",content:"These are the results:"},{heading:"compressor-microbenchmarks",content:"Codec"},{heading:"compressor-microbenchmarks",content:"Level"},{heading:"compressor-microbenchmarks",content:"Time (milliseconds)"},{heading:"compressor-microbenchmarks",content:"Result (bytes)"},{heading:"compressor-microbenchmarks",content:"Improvement"},{heading:"compressor-microbenchmarks",content:"AirCompressor LZ4"},{heading [...]
+This option, hbase.master.check.compression, defaults to true.
+This prevents the situation described in HBASE-6370, where a table is created or modified to support a codec that a region server does not support, leading to failures that take a long time to occur and are difficult to debug.`},{heading:"compressor-support-on-the-master",content:"If hbase.master.check.compression is enabled, libraries for all desired compressors need to be installed and configured on the Master, even if the Master does not run a region server."},{heading:"install-gz-sup [...]
+The recommended way to add libraries to the CLASSPATH is to set the environment variable HBASE_LIBRARY_PATH for the user running HBase.
+If native libraries are not available and Java's GZIP is used, Got brand-new compressor reports will be present in the logs.
+See brand.new.compressor).`},{heading:"install-hadoop-native-lzo-support",content:`HBase cannot ship with the Hadoop native LZO codc because of incompatibility between HBase, which uses an Apache Software License (ASL) and LZO, which uses a GPL license.
+See the Hadoop-LZO at Twitter for information on configuring LZO support for HBase.`},{heading:"install-hadoop-native-lzo-support",content:`If you depend upon LZO compression, consider using the pure Java and ASL licensed
+AirCompressor LZO codec option instead of the Hadoop native default, or configure your
+RegionServers to fail to start if native LZO support is not available.
+See hbase.regionserver.codecs.`},{heading:"configure-hadoop-native-lz4-support",content:`LZ4 support is bundled with Hadoop and is the default LZ4 codec implementation.
+It is not required that you make use of the Hadoop LZ4 codec. Our LZ4 codec implemented
+with lz4-java offers superior performance, and the AirCompressor LZ4 codec offers a
+pure Java option for use where native support is not available.`},{heading:"configure-hadoop-native-lz4-support",content:`That said, if you prefer the Hadoop option, make sure the hadoop shared library
+(libhadoop.so) is accessible when you start HBase.
+After configuring your platform (see hadoop.native.lib), you can
+make a symbolic link from HBase to the native Hadoop libraries. This assumes the two
+software installs are colocated. For example, if my 'platform' is Linux-amd64-64:`},{heading:"configure-hadoop-native-lz4-support",content:`Use the compression tool to check that LZ4 is installed on all nodes.
+Start up (or restart) HBase.
+Afterward, you can create and alter tables to enable LZ4 as a compression codec.:`},{heading:"install-hadoop-native-snappy-support",content:`Snappy support is bundled with Hadoop and is the default Snappy codec implementation.
+It is not required that you make use of the Hadoop Snappy codec. Our Snappy codec
+implemented with Xerial Snappy offers superior performance, and the AirCompressor
+Snappy codec offers a pure Java option for use where native support is not available.`},{heading:"install-hadoop-native-snappy-support",content:`That said, if you prefer the Hadoop codec option, you can install Snappy binaries (for
+instance, by using +yum install snappy+ on CentOS) or build Snappy from source.
+After installing Snappy, search for the shared library, which will be called libsnappy.so.X where X is a number.
+If you built from source, copy the shared library to a known location on your system, such as /opt/snappy/lib/.`},{heading:"install-hadoop-native-snappy-support",content:`In addition to the Snappy library, HBase also needs access to the Hadoop shared library, which will be called something like libhadoop.so.X.Y, where X and Y are both numbers.
+Make note of the location of the Hadoop library, or copy it to the same location as the Snappy library.`},{heading:"install-hadoop-native-snappy-support",content:"type: info"},{heading:"install-hadoop-native-snappy-support",content:`The Snappy and Hadoop libraries need to be available on each node of your cluster.
+See compression.test to find out how to test that this is the case.`},{heading:"install-hadoop-native-snappy-support",content:"See hbase.regionserver.codecs to configure your RegionServers to fail to start if a given compressor is not available."},{heading:"install-hadoop-native-snappy-support",content:`Each of these library locations need to be added to the environment variable HBASE_LIBRARY_PATH for the operating system user that runs HBase.
+You need to restart the RegionServer for the changes to take effect.`},{heading:"compressiontest",content:"You can use the CompressionTest tool to verify that your compressor is available to HBase:"},{heading:"enforce-compression-settings-on-a-regionserver",content:`You can configure a RegionServer so that it will fail to restart if compression is configured incorrectly, by adding the option hbase.regionserver.codecs to the hbase-site.xml, and setting its value to a comma-separated list  [...]
+For example, if you set this property to lzo,gz, the RegionServer would fail to start if both compressors were not available.
+This would prevent a new server from being added to the cluster without having codecs configured properly.`},{heading:"enable-compression-on-a-columnfamily",content:`To enable compression for a ColumnFamily, use an alter command.
+You do not need to re-create the table or copy data.
+If you are changing codecs, be sure the old codec is still available until all the old StoreFiles have been compacted.`},{heading:"testing-compression-performance",content:`HBase includes a tool called LoadTestTool which provides mechanisms to test your compression performance.
+You must specify either -write or -update-read as your first parameter, and if you do not specify another parameter, usage advice is printed for each option.`},{heading:"testing-compression-performance",content:"LoadTestTool Usage"},{heading:"enable-data-block-encoding",content:`Codecs are built into HBase so no extra configuration is needed.
+Codecs are enabled on a table by setting the DATA_BLOCK_ENCODING property.
+Disable the table before altering its DATA_BLOCK_ENCODING setting.
+Following is an example using HBase Shell:`}],headings:[{id:"changes-take-effect-upon-compaction",content:"Changes Take Effect Upon Compaction"},{id:"block-compressors",content:"Block Compressors"},{id:"data-block-encoding-types",content:"Data Block Encoding Types"},{id:"prefix",content:"Prefix"},{id:"diff",content:"Diff"},{id:"fast-diff",content:"Fast Diff"},{id:"prefix-tree",content:"Prefix Tree"},{id:"which-compressor-or-data-block-encoder-to-use",content:"Which Compressor or Data Blo [...]
+information about replication codecs, see
+`,e.jsx(i.a,{href:"/docs/operational-management/cluster-replication#life-of-a-wal-edit",children:"cluster.replication.preserving.tags"}),"."]})}),`
+`,e.jsx(i.p,{children:`HBase supports several different compression algorithms which can be enabled on a ColumnFamily.
+Data block encoding attempts to limit duplication of information in keys, taking advantage of some of the fundamental designs and patterns of HBase, such as sorted row keys and the schema of a given table.
+Compressors reduce the size of large, opaque byte arrays in cells, and can significantly reduce the storage space needed to store uncompressed data.`}),`
+`,e.jsx(i.p,{children:"Compressors and data block encoding can be used together on the same ColumnFamily."}),`
+`,e.jsx(i.h2,{id:"changes-take-effect-upon-compaction",children:"Changes Take Effect Upon Compaction"}),`
+`,e.jsx(i.p,{children:"If you change compression or encoding for a ColumnFamily, the changes take effect during compaction."}),`
+`,e.jsxs(i.p,{children:[`Some codecs take advantage of capabilities built into Java, such as GZip compression.
+Others rely on native libraries. Native libraries may be available via codec dependencies installed into
+HBase's library directory, or, if you are utilizing Hadoop codecs, as part of Hadoop. Hadoop codecs
+typically have a native code component so follow instructions for installing Hadoop native binary
+support at `,e.jsx(i.a,{href:"/docs/compression#making-use-of-hadoop-native-libraries-in-hbase",children:"Making use of Hadoop Native Libraries in HBase"}),"."]}),`
+`,e.jsx(i.p,{children:"This section discusses common codecs that are used and tested with HBase."}),`
+`,e.jsxs(i.p,{children:[`No matter what codec you use, be sure to test that it is installed correctly and is available on all nodes in your cluster.
+Extra operational steps may be necessary to be sure that codecs are available on newly-deployed nodes.
+You can use the `,e.jsx(i.a,{href:"/docs/compression#compressiontest",children:"compression.test"})," utility to check that a given codec is correctly installed."]}),`
+`,e.jsxs(i.p,{children:["To configure HBase to use a compressor, see ",e.jsx(i.a,{href:"/docs/compression#compressor-configuration-installation-and-use",children:"compressor.install"}),`.
+To enable a compressor for a ColumnFamily, see `,e.jsx(i.a,{href:"/docs/compression#enable-compression-on-a-columnfamily",children:"changing.compression"}),`.
+To enable data block encoding for a ColumnFamily, see `,e.jsx(i.a,{href:"/docs/compression#enable-data-block-encoding",children:"data.block.encoding.enable"}),"."]}),`
+`,e.jsx(i.h2,{id:"block-compressors",children:"Block Compressors"}),`
+`,e.jsxs(i.ul,{children:[`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"NONE"}),e.jsx(i.br,{}),`
+`,"This compression type constant selects no compression, and is the default."]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"BROTLI"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Brotli",children:"Brotli"}),` is a generic-purpose lossless compression algorithm
+that compresses data using a combination of a modern variant of the LZ77 algorithm, Huffman
+coding, and 2nd order context modeling, with a compression ratio comparable to the best currently
+available general-purpose compression methods. It is similar in speed with GZ but offers more
+dense compression.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"BZIP2"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Bzip2",children:"Bzip2"}),` compresses files using the Burrows-Wheeler block
+sorting text compression algorithm and Huffman coding. Compression is generally considerably
+better than that achieved by the dictionary- (LZ-) based compressors, but both compression and
+decompression can be slow in comparison to other options.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"GZ"}),e.jsx(i.br,{}),`
+`,"gzip is based on the ",e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Deflate",children:"DEFLATE"}),` algorithm, which is a
+combination of LZ77 and Huffman coding. It is universally available in the Java Runtime
+Environment so is a good lowest common denominator option. However in comparison to more modern
+algorithms like Zstandard it is quite slow.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"LZ4"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/LZ4_(compression_algorithm)",children:"LZ4"}),` is a lossless data compression
+algorithm that is focused on compression and decompression speed. It belongs to the LZ77 family
+of compression algorithms, like Brotli, DEFLATE, Zstandard, and others. In our microbenchmarks
+LZ4 is the fastest option for both compression and decompression in that family, and is our
+universally recommended option.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"LZMA"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Markov_chain_algorithm",children:"LZMA"}),` is a
+dictionary compression scheme somewhat similar to the LZ77 algorithm that achieves very high
+compression ratios with a computationally expensive predictive model and variable size
+compression dictionary, while still maintaining decompression speed similar to other commonly used
+compression algorithms. LZMA is superior to all other options in general compression ratio but as
+a compressor it can be extremely slow, especially when configured to operate at higher levels of
+compression.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"LZO"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Lempel%E2%80%93Ziv%E2%80%93Oberhumer",children:"LZO"}),` is another LZ-variant
+data compression algorithm, with an implementation focused on decompression speed. It is almost
+but not quite as fast as LZ4.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"SNAPPY"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Snappy_(compression)",children:"Snappy"}),` is based on ideas from LZ77 but is
+optimized for very high compression speed, achieving only a "reasonable" compression in trade.
+It is as fast as LZ4 but does not compress quite as well. We offer a pure Java Snappy codec
+that can be used instead of GZ as the universally available option for any Java runtime on any
+hardware architecture.`]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"ZSTD"}),e.jsx(i.br,{}),`
+`,e.jsx(i.a,{href:"https://en.wikipedia.org/wiki/Zstd",children:"Zstandard"}),` combines a dictionary-matching stage (LZ77) with
+a large search window and a fast entropy coding stage, using both Finite State Entropy and
+Huffman coding. Compression speed can vary by a factor of 20 or more between the fastest and
+slowest levels, while decompression is uniformly fast, varying by less than 20% between the
+fastest and slowest levels.`,e.jsx(i.br,{}),`
+`,`ZStandard is the most flexible of the available compression codec options, offering a compression
+ratio similar to LZ4 at level 1 (but with slightly less performance), compression ratios
+comparable to DEFLATE at mid levels (but with better performance), and LZMA-alike dense
+compression (and LZMA-alike compression speeds) at high levels; while providing universally fast
+decompression.`]}),`
+`]}),`
+`,e.jsx(i.h2,{id:"data-block-encoding-types",children:"Data Block Encoding Types"}),`
+`,e.jsx(i.h3,{id:"prefix",children:"Prefix"}),`
+`,e.jsxs(i.p,{children:["Often, keys are very similar. Specifically, keys often share a common prefix and only differ near the end. For instance, one key might be ",e.jsx(i.code,{children:"RowKey:Family:Qualifier0"})," and the next key might be ",e.jsx(i.code,{children:"RowKey:Family:Qualifier1"}),`.
+In Prefix encoding, an extra column is added which holds the length of the prefix shared between the current key and the previous key. Assuming the first key here is totally different from the key before, its prefix length is 0.`]}),`
+`,e.jsxs(i.p,{children:["The second key's prefix length is ",e.jsx(i.code,{children:"23"}),", since they have the first 23 characters in common."]}),`
+`,e.jsx(i.p,{children:"Obviously if the keys tend to have nothing in common, Prefix will not provide much benefit."}),`
+`,e.jsx(i.p,{children:"The following image shows a hypothetical ColumnFamily with no data block encoding."}),`
+`,e.jsx(i.p,{children:e.jsx(i.img,{alt:"ColumnFamily with No Encoding",src:o,placeholder:"blur"})}),`
+`,e.jsx(i.p,{children:"Here is the same data with prefix data encoding."}),`
+`,e.jsx(i.p,{children:e.jsx(i.img,{alt:"ColumnFamily with Prefix Encoding",src:t,placeholder:"blur"})}),`
+`,e.jsx(i.h3,{id:"diff",children:"Diff"}),`
+`,e.jsx(i.p,{children:`Diff encoding expands upon Prefix encoding.
+Instead of considering the key sequentially as a monolithic series of bytes, each key field is split so that each part of the key can be compressed more efficiently.`}),`
+`,e.jsx(i.p,{children:"Two new fields are added: timestamp and type."}),`
+`,e.jsx(i.p,{children:"If the ColumnFamily is the same as the previous row, it is omitted from the current row."}),`
+`,e.jsx(i.p,{children:"If the key length, value length or type are the same as the previous row, the field is omitted."}),`
+`,e.jsx(i.p,{children:`In addition, for increased compression, the timestamp is stored as a Diff from the previous row's timestamp, rather than being stored in full.
+Given the two row keys in the Prefix example, and given an exact match on timestamp and the same type, neither the value length, or type needs to be stored for the second row, and the timestamp value for the second row is just 0, rather than a full timestamp.`}),`
+`,e.jsx(i.p,{children:"Diff encoding is disabled by default because writing and scanning are slower but more data is cached."}),`
+`,e.jsx(i.p,{children:"This image shows the same ColumnFamily from the previous images, with Diff encoding."}),`
+`,e.jsx(i.p,{children:e.jsx(i.img,{alt:"ColumnFamily with Diff Encoding",src:r,placeholder:"blur"})}),`
+`,e.jsx(i.h3,{id:"fast-diff",children:"Fast Diff"}),`
+`,e.jsx(i.p,{children:"Fast Diff works similar to Diff, but uses a faster implementation. It also adds another field which stores a single bit to track whether the data itself is the same as the previous row. If it is, the data is not stored again."}),`
+`,e.jsx(i.p,{children:"Fast Diff is the recommended codec to use if you have long keys or many columns."}),`
+`,e.jsx(i.p,{children:"The data format is nearly identical to Diff encoding, so there is not an image to illustrate it."}),`
+`,e.jsx(i.h3,{id:"prefix-tree",children:"Prefix Tree"}),`
+`,e.jsx(i.p,{children:`Prefix tree encoding was introduced as an experimental feature in HBase 0.96.
+It provides similar memory savings to the Prefix, Diff, and Fast Diff encoder, but provides faster random access at a cost of slower encoding speed.
+It was removed in hbase-2.0.0. It was a good idea but little uptake. If interested in reviving this effort, write the hbase dev list.`}),`
+`,e.jsx(i.h2,{id:"which-compressor-or-data-block-encoder-to-use",children:"Which Compressor or Data Block Encoder To Use"}),`
+`,e.jsx(i.p,{children:"The compression or codec type to use depends on the characteristics of your data. Choosing the wrong type could cause your data to take more space rather than less, and can have performance implications."}),`
+`,e.jsxs(i.p,{children:["In general, you need to weigh your options between smaller size and faster compression/decompression. Following are some general guidelines, expanded from a discussion at ",e.jsx(i.a,{href:"https://lists.apache.org/thread.html/481e67a61163efaaf4345510447a9244871a8d428244868345a155ff%401378926618%40%3Cdev.hbase.apache.org%3E",children:"Documenting Guidance on compression and codecs"}),"."]}),`
+`,e.jsxs(i.ul,{children:[`
+`,e.jsx(i.li,{children:`In most cases, enabling LZ4 or Snappy by default is a good choice, because they have a low
+performance overhead and provide reasonable space savings. A fast compression algorithm almost
+always improves overall system performance by trading some increased CPU usage for better I/O
+efficiency.`}),`
+`,e.jsx(i.li,{children:"If the values are large (and not pre-compressed, such as images), use a data block compressor."}),`
+`,e.jsxs(i.li,{children:["For ",e.jsx(i.em,{children:"cold data"}),`, which is accessed infrequently, depending on your use case, it might
+make sense to opt for Zstandard at its higher compression levels, or LZMA, especially for high
+entropy binary data, or Brotli for data similar in characteristics to web data. Bzip2 might also
+be a reasonable option but Zstandard is very likely to offer superior decompression speed.`]}),`
+`,e.jsxs(i.li,{children:["For ",e.jsx(i.em,{children:"hot data"}),`, which is accessed frequently, you almost certainly want only LZ4,
+Snappy, LZO, or Zstandard at a low compression level. These options will not provide as high of
+a compression ratio but will in trade not unduly impact system performance.`]}),`
+`,e.jsx(i.li,{children:`If you have long keys (compared to the values) or many columns, use a prefix encoder.
+FAST_DIFF is recommended.`}),`
+`,e.jsx(i.li,{children:`If enabling WAL value compression, consider LZ4 or SNAPPY compression, or Zstandard at
+level 1. Reading and writing the WAL is performance critical. That said, the I/O
+savings of these compression options can improve overall system performance.`}),`
+`]}),`
+`,e.jsx(i.h2,{id:"making-use-of-hadoop-native-libraries-in-hbase",children:"Making use of Hadoop Native Libraries in HBase"}),`
+`,e.jsx(i.p,{children:`The Hadoop shared library has a bunch of facility including compression libraries and fast crc'ing โ€” hardware crc'ing if your chipset supports it.
+To make this facility available to HBase, do the following. HBase/Hadoop will fall back to use alternatives if it cannot find the native library
+versions โ€” or fail outright if you asking for an explicit compressor and there is no alternative available.`}),`
+`,e.jsx(i.p,{children:"First make sure of your Hadoop. Fix this message if you are seeing it starting Hadoop processes:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.p,{children:`It means is not properly pointing at its native libraries or the native libs were compiled for another platform.
+Fix this first.`}),`
+`,e.jsx(i.p,{children:"Then if you see the following in your HBase logs, you know that HBase was unable to locate the Hadoop native libraries:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.p,{children:"If the libraries loaded successfully, the WARN message does not show. Usually this means you are good to go but read on."}),`
+`,e.jsx(i.p,{children:`Let's presume your Hadoop shipped with a native library that suits the platform you are running HBase on.
+To check if the Hadoop native library is available to HBase, run the following tool (available in Hadoop 2.1 and greater):`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"2014-08-26"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 13:15:38,717"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" WARN"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  [main] util.NativeCodeLoader: Unable to load native-hadoop library "}),e.j [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Native"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" library"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" checking:"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hadoop:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" false"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"zlib:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"   false"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"snappy:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" false"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"lz4:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    false"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"bzip2:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"  false"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"2014-08-26"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 13:15:38,863"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" INFO"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  [main] util.ExitUtil: Exiting with status 1"})]})]})})}),`
+`,e.jsx(i.p,{children:"Above shows that the native hadoop library is not available in HBase context."}),`
+`,e.jsx(i.p,{children:`The above NativeLibraryChecker tool may come back saying all is hunky-dory
+โ€” i.e. all libs show 'true', that they are available โ€” but follow the below
+presecription anyways to ensure the native libs are available in HBase context,
+when it goes to use them.`}),`
+`,e.jsxs(i.p,{children:[`To fix the above, either copy the Hadoop native libraries local or symlink to them if the Hadoop and HBase stalls are adjacent in the filesystem.
+You could also point at their location by setting the `,e.jsx(i.code,{children:"LD_LIBRARY_PATH"})," environment variable in your hbase-env.sh."]}),`
+`,e.jsxs(i.p,{children:['Where the JVM looks to find native libraries is "system dependent" (See ',e.jsx(i.code,{children:"java.lang.System#loadLibrary(name)"}),"). On linux, by default, is going to look in ",e.jsx(i.em,{children:"lib/native/PLATFORM"})," where ",e.jsx(i.code,{children:"PLATFORM"}),` is the label for the platform your HBase is installed on.
+On a local linux machine, it seems to be the concatenation of the java properties `,e.jsx(i.code,{children:"os.name"})," and ",e.jsx(i.code,{children:"os.arch"}),` followed by whether 32 or 64 bit.
+HBase on startup prints out all of the java system properties so find the os.name and os.arch in the log.
+For example:`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{children:"2014-08-06 15:27:22,853 INFO  [main] zookeeper.ZooKeeper: Client environment:os.name=Linux"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{children:"2014-08-06 15:27:22,853 INFO  [main] zookeeper.ZooKeeper: Client environment:os.arch=amd64"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{children:"..."})})]})})}),`
+`,e.jsxs(i.p,{children:["So in this case, the PLATFORM string is ",e.jsx(i.code,{children:"Linux-amd64-64"}),`.
+Copying the Hadoop native libraries or symlinking at `,e.jsx(i.em,{children:"lib/native/Linux-amd64-64"}),` will ensure they are found.
+Rolling restart after you have made this change.`]}),`
+`,e.jsx(i.p,{children:`Here is an example of how you would set up the symlinks.
+Let the hadoop and hbase installs be in your home directory. Assume your hadoop native libs
+are at ~/hadoop/lib/native. Assume you are on a Linux-amd64-64 platform. In this case,
+you would do the following to link the hadoop native lib so hbase could find them.`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" mkdir"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -p"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ~/hbaseLinux-amd64-64"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4 [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" cd"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ~/hbase/lib/native/"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ln"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -s"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ~/hadoop/lib/native"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"}, [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ls"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -la"})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"# Linux-amd64-64 -> /home/USER/hadoop/lib/native"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"..."})})]})})}),`
+`,e.jsx(i.p,{children:"If you see PureJavaCrc32C in a stack track or if you see something like the below in a perf trace, then native is not working; you are using the java CRC functions rather than native:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.p,{children:["See ",e.jsx(i.a,{href:"https://issues.apache.org/jira/browse/HBASE-11927",children:"HBASE-11927 Use Native Hadoop Library for HFile checksum (And flip default from CRC32 to CRC32C)"}),`,
+for more on native checksumming support. See in particular the release note for how to check if your hardware to see if your processor has support for hardware CRCs.
+Or checkout the Apache `,e.jsx(i.a,{href:"https://blogs.apache.org/hbase/entry/saving_cpu_using_native_hadoop",children:"Checksums in HBase"})," blog post."]}),`
+`,e.jsxs(i.p,{children:["Here is example of how to point at the Hadoop libs with ",e.jsx(i.code,{children:"LD_LIBRARY_PATH"})," environment variable:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"2014-08-26"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 13:42:49,332"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" INFO"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  [main] bzip2.Bzip2Factory: Successfully loaded & "}),e.jsx(i.span,{style:{ [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"2014-08-26"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 13:42:49,337"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" INFO"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  [main] zlib.ZlibFactory: Successfully loaded & "}),e.jsx(i.span,{style:{"- [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Native"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" library"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" checking:"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"hadoop:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" true"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" /home/stack/hadoop-2.5.0-SNAPSHOT/lib/native/libhadoop.so.1.0.0"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"zlib:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"   true"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" /lib64/libz.so.1"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"snappy:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" true"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" /usr/lib64/libsnappy.so.1"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"lz4:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"    true"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" revision:99"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"bzip2:"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"  true"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" /lib64/libbz2.so.1"})]})]})})}),`
+`,e.jsxs(i.p,{children:["Set in ",e.jsx(i.em,{children:"hbase-env.sh"})," the LD_LIBRARY_PATH environment variable when starting your HBase."]}),`
+`,e.jsx(i.h2,{id:"compressor-configuration-installation-and-use",children:"Compressor Configuration, Installation, and Use"}),`
+`,e.jsx(i.h3,{id:"configure-hbase-for-compressors",children:"Configure HBase For Compressors"}),`
+`,e.jsxs(i.p,{children:[`Compression codecs are provided either by HBase compressor modules or by Hadoop's native compression
+support. As described above you choose a compression type in table or column family schema or in
+site configuration using its short label, e.g. `,e.jsx(i.em,{children:"snappy"})," for Snappy, or ",e.jsx(i.em,{children:"zstd"}),` for ZStandard. Which
+codec implementation is dynamically loaded to support what label is configurable by way of site
+configuration.`]}),`
+`,e.jsxs(i.table,{children:[e.jsx(i.thead,{children:e.jsxs(i.tr,{children:[e.jsx(i.th,{children:"Algorithm label"}),e.jsx(i.th,{children:"Codec implementation configuration key"}),e.jsx(i.th,{children:"Default value"})]})}),e.jsxs(i.tbody,{children:[e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"BROTLI"}),e.jsx(i.td,{children:"hbase.io.compress.brotli.codec"}),e.jsx(i.td,{children:"org.apache.hadoop.hbase.io.compress.brotli.BrotliCodec"})]}),e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"BZI [...]
+`,e.jsx(i.p,{children:"The available codec implementation options are:"}),`
+`,e.jsxs(i.table,{children:[e.jsx(i.thead,{children:e.jsxs(i.tr,{children:[e.jsx(i.th,{children:"Label"}),e.jsx(i.th,{children:"Codec implementation class"}),e.jsx(i.th,{children:"Notes"})]})}),e.jsxs(i.tbody,{children:[e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"BROTLI"}),e.jsx(i.td,{children:"org.apache.hadoop.hbase.io.compress.brotli.BrotliCodec"}),e.jsxs(i.td,{children:["Implemented with ",e.jsx(i.a,{href:"https://github.com/hyperxpro/Brotli4j",children:"Brotli4j"})]})]}),e.jsxs(i.t [...]
+`,e.jsx(i.p,{children:`Specify which codec implementation option you prefer for a given compression algorithm
+in site configuration, like so:`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),e.jsx(i.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(i.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">hbase.io.compress.lz4.codec</"}),e.jsx(i.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"name"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dar [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  <"}),e.jsx(i.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">org.apache.hadoop.hbase.io.compress.lz4.Lz4Codec</"}),e.jsx(i.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"value"}),e.jsx(i.span,{style:{"--shiki-light" [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(i.span,{style:{"--shiki-light":"#22863A","--shiki-dark":"#85E89D"},children:"property"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"..."})})]})})}),`
+`,e.jsx(i.h4,{id:"compressor-microbenchmarks",children:"Compressor Microbenchmarks"}),`
+`,e.jsxs(i.p,{children:["See ",e.jsx(i.a,{href:"https://github.com/apurtell/jmh-compression-tests",children:"https://github.com/apurtell/jmh-compression-tests"})]}),`
+`,e.jsx(i.p,{children:`256MB (258,126,022 bytes exactly) of block data was extracted from two HFiles containing Common
+Crawl data ingested using IntegrationLoadTestCommonCrawl, 2,680 blocks in total. This data was
+processed by each new codec implementation as if the block data were being compressed again for
+write into an HFile, but without writing any data, comparing only the CPU time and resource demand
+of the codec itself. Absolute performance numbers will vary depending on hardware and software
+particulars of your deployment. The relative differences are what are interesting. Measured time
+is the average time in milliseconds required to compress all blocks of the 256MB file. This is
+how long it would take to write the HFile containing these contents, minus the I/O overhead of
+block encoding and actual persistence.`}),`
+`,e.jsx(i.p,{children:"These are the results:"}),`
+`,e.jsxs(i.table,{children:[e.jsx(i.thead,{children:e.jsxs(i.tr,{children:[e.jsx(i.th,{children:"Codec"}),e.jsx(i.th,{children:"Level"}),e.jsx(i.th,{children:"Time (milliseconds)"}),e.jsx(i.th,{children:"Result (bytes)"}),e.jsx(i.th,{children:"Improvement"})]})}),e.jsxs(i.tbody,{children:[e.jsxs(i.tr,{children:[e.jsx(i.td,{children:"AirCompressor LZ4"}),e.jsx(i.td,{children:"-"}),e.jsx(i.td,{children:"349.989 ยฑ 2.835"}),e.jsx(i.td,{children:"76,999,408"}),e.jsx(i.td,{children:"70.17%"})] [...]
+`,e.jsx(i.h4,{id:"compressor-support-on-the-master",children:"Compressor Support On the Master"}),`
+`,e.jsxs(i.p,{children:[`A new configuration setting was introduced in HBase 0.95, to check the Master to determine which data block encoders are installed and configured on it, and assume that the entire cluster is configured the same.
+This option, `,e.jsx(i.code,{children:"hbase.master.check.compression"}),", defaults to ",e.jsx(i.code,{children:"true"}),`.
+This prevents the situation described in `,e.jsx(i.a,{href:"https://issues.apache.org/jira/browse/HBASE-6370",children:"HBASE-6370"}),", where a table is created or modified to support a codec that a region server does not support, leading to failures that take a long time to occur and are difficult to debug."]}),`
+`,e.jsxs(i.p,{children:["If ",e.jsx(i.code,{children:"hbase.master.check.compression"})," is enabled, libraries for all desired compressors need to be installed and configured on the Master, even if the Master does not run a region server."]}),`
+`,e.jsx(i.h4,{id:"install-gz-support-via-native-libraries",children:"Install GZ Support Via Native Libraries"}),`
+`,e.jsxs(i.p,{children:[`HBase uses Java's built-in GZip support unless the native Hadoop libraries are available on the CLASSPATH.
+The recommended way to add libraries to the CLASSPATH is to set the environment variable `,e.jsx(i.code,{children:"HBASE_LIBRARY_PATH"}),` for the user running HBase.
+If native libraries are not available and Java's GZIP is used, `,e.jsx(i.code,{children:"Got brand-new compressor"}),` reports will be present in the logs.
+See `,e.jsx(i.a,{href:"/docs/troubleshooting#logs-flooded-with-2011-01-10-124048407-info-orgapachehadoopiocompresscodecpool-gotbrand-new-compressor-messages",children:"brand.new.compressor"}),")."]}),`
+`,e.jsx(i.h4,{id:"install-hadoop-native-lzo-support",children:"Install Hadoop Native LZO Support"}),`
+`,e.jsxs(i.p,{children:[`HBase cannot ship with the Hadoop native LZO codc because of incompatibility between HBase, which uses an Apache Software License (ASL) and LZO, which uses a GPL license.
+See the `,e.jsx(i.a,{href:"https://github.com/twitter/hadoop-lzo/blob/master/README.md",children:"Hadoop-LZO at Twitter"})," for information on configuring LZO support for HBase."]}),`
+`,e.jsxs(i.p,{children:[`If you depend upon LZO compression, consider using the pure Java and ASL licensed
+AirCompressor LZO codec option instead of the Hadoop native default, or configure your
+RegionServers to fail to start if native LZO support is not available.
+See `,e.jsx(i.a,{href:"/docs/compression#enforce-compression-settings-on-a-regionserver",children:"hbase.regionserver.codecs"}),"."]}),`
+`,e.jsx(i.h4,{id:"configure-hadoop-native-lz4-support",children:"Configure Hadoop Native LZ4 Support"}),`
+`,e.jsx(i.p,{children:`LZ4 support is bundled with Hadoop and is the default LZ4 codec implementation.
+It is not required that you make use of the Hadoop LZ4 codec. Our LZ4 codec implemented
+with lz4-java offers superior performance, and the AirCompressor LZ4 codec offers a
+pure Java option for use where native support is not available.`}),`
+`,e.jsxs(i.p,{children:[`That said, if you prefer the Hadoop option, make sure the hadoop shared library
+(libhadoop.so) is accessible when you start HBase.
+After configuring your platform (see `,e.jsx(i.a,{href:"/docs/compression#making-use-of-hadoop-native-libraries-in-hbase",children:"hadoop.native.lib"}),`), you can
+make a symbolic link from HBase to the native Hadoop libraries. This assumes the two
+software installs are colocated. For example, if my 'platform' is Linux-amd64-64:`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" mkdir"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" lib/native"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" ln"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -s"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" $HADOOP_HOME"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},childre [...]
+`,e.jsx(i.p,{children:`Use the compression tool to check that LZ4 is installed on all nodes.
+Start up (or restart) HBase.
+Afterward, you can create and alter tables to enable LZ4 as a compression codec.:`}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(i.h4,{id:"install-hadoop-native-snappy-support",children:"Install Hadoop native Snappy Support"}),`
+`,e.jsx(i.p,{children:`Snappy support is bundled with Hadoop and is the default Snappy codec implementation.
+It is not required that you make use of the Hadoop Snappy codec. Our Snappy codec
+implemented with Xerial Snappy offers superior performance, and the AirCompressor
+Snappy codec offers a pure Java option for use where native support is not available.`}),`
+`,e.jsxs(i.p,{children:[`That said, if you prefer the Hadoop codec option, you can install Snappy binaries (for
+instance, by using +yum install snappy+ on CentOS) or build Snappy from source.
+After installing Snappy, search for the shared library, which will be called `,e.jsx(i.em,{children:"libsnappy.so.X"}),` where X is a number.
+If you built from source, copy the shared library to a known location on your system, such as `,e.jsx(i.em,{children:"/opt/snappy/lib/"}),"."]}),`
+`,e.jsxs(i.p,{children:["In addition to the Snappy library, HBase also needs access to the Hadoop shared library, which will be called something like ",e.jsx(i.em,{children:"libhadoop.so.X.Y"}),`, where X and Y are both numbers.
+Make note of the location of the Hadoop library, or copy it to the same location as the Snappy library.`]}),`
+`,e.jsxs(n,{type:"info",children:[e.jsxs(i.p,{children:[`The Snappy and Hadoop libraries need to be available on each node of your cluster.
+See `,e.jsx(i.a,{href:"/docs/compression#compressiontest",children:"compression.test"})," to find out how to test that this is the case."]}),e.jsxs(i.p,{children:["See ",e.jsx(i.a,{href:"/docs/compression#enforce-compression-settings-on-a-regionserver",children:"hbase.regionserver.codecs"})," to configure your RegionServers to fail to start if a given compressor is not available."]})]}),`
+`,e.jsxs(i.p,{children:["Each of these library locations need to be added to the environment variable ",e.jsx(i.code,{children:"HBASE_LIBRARY_PATH"}),` for the operating system user that runs HBase.
+You need to restart the RegionServer for the changes to take effect.`]}),`
+`,e.jsx(i.h4,{id:"compressiontest",children:"CompressionTest"}),`
+`,e.jsx(i.p,{children:"You can use the CompressionTest tool to verify that your compressor is available to HBase:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsx(i.h4,{id:"enforce-compression-settings-on-a-regionserver",children:"Enforce Compression Settings On a RegionServer"}),`
+`,e.jsxs(i.p,{children:["You can configure a RegionServer so that it will fail to restart if compression is configured incorrectly, by adding the option hbase.regionserver.codecs to the ",e.jsx(i.em,{children:"hbase-site.xml"}),`, and setting its value to a comma-separated list of codecs that need to be available.
+For example, if you set this property to `,e.jsx(i.code,{children:"lzo,gz"}),`, the RegionServer would fail to start if both compressors were not available.
+This would prevent a new server from being added to the cluster without having codecs configured properly.`]}),`
+`,e.jsx(i.h3,{id:"enable-compression-on-a-columnfamily",children:"Enable Compression On a ColumnFamily"}),`
+`,e.jsxs(i.p,{children:["To enable compression for a ColumnFamily, use an ",e.jsx(i.code,{children:"alter"}),` command.
+You do not need to re-create the table or copy data.
+If you are changing codecs, be sure the old codec is still available until all the old StoreFiles have been compacted.`]}),`
+`,e.jsx(i.h4,{id:"enabling-compression-on-a-columnfamily-of-an-existing-table-using-hbaseshell",children:"Enabling Compression on a ColumnFamily of an Existing Table using HBaseShell"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(i.h4,{id:"creating-a-new-table-with-compression-on-a-columnfamily",children:"Creating a New Table with Compression On a ColumnFamily"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsx(i.h4,{id:"verifying-a-columnfamilys-compression-settings",children:"Verifying a ColumnFamily's Compression Settings"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"DESCRIPTION"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"                                          ENABLED"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'test'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", {"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"NAME"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children: [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" '"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"BLOOMFILTER"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" VERSIONS"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"'1'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children: [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"'0'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"TTL"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => " [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" lse'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"BLOCKSIZE"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},childre [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" LOCKCACHE"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"'true'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"1"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" row"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(s) "}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"in"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 0.107 [...]
+`,e.jsx(i.h3,{id:"testing-compression-performance",children:"Testing Compression Performance"}),`
+`,e.jsxs(i.p,{children:[`HBase includes a tool called LoadTestTool which provides mechanisms to test your compression performance.
+You must specify either `,e.jsx(i.code,{children:"-write"})," or ",e.jsx(i.code,{children:"-update-read"})," as your first parameter, and if you do not specify another parameter, usage advice is printed for each option."]}),`
+`,e.jsx(i.p,{children:e.jsxs(i.strong,{children:[e.jsx(i.code,{children:"LoadTestTool"})," Usage"]})}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"usage:"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" bin/hbase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" org.apache.hadoop.hbase.util.LoadTestTool"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#0 [...]
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"Options:"})}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -batchupdate"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                 Whether"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" to"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" use"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki- [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              updates"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" for"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" every"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" column"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62" [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -bloom"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"ar"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"g"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:">"}), [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -compression"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"ar"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"g"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children: [...]
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              LZ4]"})}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -data_block_encoding"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"ar"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"g"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},c [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              use"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" for"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" data"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" blocks"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--s [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              of"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" [NONE, "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"PREFIX,"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" DIFF,"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62", [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -encryption"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"ar"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"g"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              one"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" of"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" [AES]"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -generator"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" <"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"ar"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"g"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"> [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              args"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" for"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" this"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" class"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--s [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              separated"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" after"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" class"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" name"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -h,--help"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                    Show"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" usage"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -in_memory"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                   Tries"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" to"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" keep"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-d [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              as"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" possible."}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"  Not"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" guaranteed"}),e.jsx(i.span,{style:{"--shiki-light":"#032 [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"                              served"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" from"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" inmemory"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" -init_only"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                   Initialize"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" the"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" test"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--s [...]
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              loading"})}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -key_window <arg>            The 'key"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" window' to maintain between reads and"})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              writes for concurrent write/read workload. The"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              default is 0."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -max_read_errors <arg>       The maximum number of read errors to tolerate"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              before terminating all reader threads. The default"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              is 10."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -multiput                    Whether to use multi-puts as opposed to separate"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              puts for every column in a row"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -num_keys <arg>              The number of keys to read/write"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -num_tables <arg>            A positive integer number. When a number n is"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              speicfied, load test tool  will load n table"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              parallely. -tn parameter value becomes table name"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              prefix. Each table name is in format"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              <tn>_1...<tn>_n"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -read <arg>                  <verify_percent>[:#threads=20]"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -regions_per_server <arg>    A positive integer number. When a number n is"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              specified, load test tool will create the test"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              table with n regions per server"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -skip_init                   Skip the initialization; assume test table already"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              exists"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -start_key <arg>             The first key to read/write (a 0-based index). The"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              default value is 0."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -tn <arg>                    The name of the table to read or write"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -update <arg>                <update_percent>[:#threads=20][:#whether to"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              ignore nonce collisions=0]"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -write <arg>                 <avg_cols_per_key>:<avg_data_size>[:#threads=20]"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -zk <arg>                    ZK quorum as comma-separated host names without"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"                              port numbers"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" -zk_root <arg>               name of parent znode in zookeeper"})})]})})}),`
+`,e.jsx(i.h4,{id:"example-usage-of-loadtesttool",children:"Example Usage of LoadTestTool"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"      -read"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 100:30"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" -num_tables"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 1"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8 [...]
+`,e.jsx(i.h2,{id:"enable-data-block-encoding",children:"Enable Data Block Encoding"}),`
+`,e.jsxs(i.p,{children:[`Codecs are built into HBase so no extra configuration is needed.
+Codecs are enabled on a table by setting the `,e.jsx(i.code,{children:"DATA_BLOCK_ENCODING"}),` property.
+Disable the table before altering its DATA_BLOCK_ENCODING setting.
+Following is an example using HBase Shell:`]}),`
+`,e.jsx(i.h4,{id:"enable-data-block-encoding-on-a-table",children:"Enable Data Block Encoding On a Table"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Updating"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" all regions with the "}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"new"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" schema..."})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"0"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"/"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"1"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" regions updated."})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"1"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"/"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"1"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" regions updated."})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Done"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"."})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"0"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" row"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(s) "}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"in"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 2.282 [...]
+`,e.jsx(i.h4,{id:"verifying-a-columnfamilys-data-block-encoding",children:"Verifying a ColumnFamily's Data Block Encoding"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M20.156.083c3.033.525 3.893 2.598 3.829 4.77L24 4.822 22.635 22.71 4.89 23.926h.016C3.433 23.864.15 23.729 0 19.139l1.645-3 2.819 6.586.503 1.172 2.805-9.144-.03.007.016-.03 9.255 2.956-1.396-5.431-.99-3.9 8.82-.569-.615-.51L16. [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"DESCRIPTION"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"                                          ENABLED"})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'test'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", {"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"NAME"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children: [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" _DIFF'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"BLOOMFILTER"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},chi [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" '0'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"VERSIONS"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children: [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" IONS"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:"'0'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"TTL [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" >"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" 'false'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"BLOCKSIZE"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},childr [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" e'"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:", "}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"BLOCKCACHE"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" => "}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"1"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" row"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"(s) "}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"in"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:" 0.065 [...]
diff --git a/assets/confirm-CRvfhxAV.js b/assets/confirm-CRvfhxAV.js
new file mode 100644
index 00000000000..8cceb4e5b24
--- /dev/null
+++ b/assets/confirm-CRvfhxAV.js
@@ -0,0 +1,38 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let o=`Make sure HDFS is running first. Start and stop the Hadoop HDFS daemons by running *bin/start-hdfs.sh* over in the \`HADOOP_HOME\` directory. You can ensure it started properly by testing the \`put\` and \`get\` of files into the Hadoop filesystem. HBase does not normally use the MapReduce or YARN daemons. These do not need to be started.
+
+*If* you are managing your own ZooKeeper, start it and confirm it's running, else HBase will start up ZooKeeper for you as part of its start process.
+
+Start HBase with the following command:
+
+\`\`\`bash
+bin/start-hbase.sh
+\`\`\`
+
+Run the above from the \`HBASE_HOME\` directory.
+
+You should now have a running HBase instance. HBase logs can be found in the *logs* subdirectory. Check them out especially if HBase had trouble starting.
+
+HBase also puts up a UI listing vital attributes. By default it's deployed on the Master host at port 16010 (HBase RegionServers listen on port 16020 by default and put up an informational HTTP server at port 16030). If the Master is running on a host named \`master.example.org\` on the default port, point your browser at [http://master.example.org:16010](http://master.example.org:16010) to see the web interface.
+
+Once HBase has started, see the [shell exercises](/docs/getting-started#procedure-use-hbase-for-the-first-time) documentation for how to create tables, add data, scan your insertions, and finally disable and drop your tables.
+
+To stop HBase after exiting the HBase shell enter
+
+\`\`\`bash
+$ ./bin/stop-hbase.sh
+stopping hbase...............
+\`\`\`
+
+Shutdown can take a moment to complete. It can take longer if your cluster is comprised of many machines. If you are running a distributed operation, be sure to wait until HBase has shut down completely before stopping the Hadoop daemons.
+`,r={title:"Running and Confirming Your Installation",description:"Steps to start HBase services and verify your installation is working correctly."},i=[{href:"http://master.example.org:16010"},{href:"/docs/getting-started#procedure-use-hbase-for-the-first-time"}],d={contents:[{heading:void 0,content:"Make sure HDFS is running first. Start and stop the Hadoop HDFS daemons by running bin/start-hdfs.sh over in the HADOOP_HOME directory. You can ensure it started properly by testing the put [...]
+`,e.jsxs(t.p,{children:[e.jsx(t.em,{children:"If"})," you are managing your own ZooKeeper, start it and confirm it's running, else HBase will start up ZooKeeper for you as part of its start process."]}),`
+`,e.jsx(t.p,{children:"Start HBase with the following command:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.p,{children:["Run the above from the ",e.jsx(t.code,{children:"HBASE_HOME"})," directory."]}),`
+`,e.jsxs(t.p,{children:["You should now have a running HBase instance. HBase logs can be found in the ",e.jsx(t.em,{children:"logs"})," subdirectory. Check them out especially if HBase had trouble starting."]}),`
+`,e.jsxs(t.p,{children:["HBase also puts up a UI listing vital attributes. By default it's deployed on the Master host at port 16010 (HBase RegionServers listen on port 16020 by default and put up an informational HTTP server at port 16030). If the Master is running on a host named ",e.jsx(t.code,{children:"master.example.org"})," on the default port, point your browser at ",e.jsx(t.a,{href:"http://master.example.org:16010",children:"http://master.example.org:16010"})," to see the web in [...]
+`,e.jsxs(t.p,{children:["Once HBase has started, see the ",e.jsx(t.a,{href:"/docs/getting-started#procedure-use-hbase-for-the-first-time",children:"shell exercises"})," documentation for how to create tables, add data, scan your insertions, and finally disable and drop your tables."]}),`
+`,e.jsx(t.p,{children:"To stop HBase after exiting the HBase shell enter"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(t.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(t.span,{className:"line",children:[e.jsx(t.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"stopping"}),e.jsx(t.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" hbase..............."})]})]})})}),`
+`,e.jsx(t.p,{children:"Shutdown can take a moment to complete. It can take longer if your cluster is comprised of many machines. If you are running a distributed operation, be sure to wait until HBase has shut down completely before stopping the Hadoop daemons."})]})}function l(n={}){const{wrapper:t}=n.components||{};return t?e.jsx(t,{...n,children:e.jsx(s,{...n})}):s(n)}export{o as _markdown,l as default,i as extractedReferences,r as frontmatter,d as structuredData,h as toc};
diff --git a/assets/contributing-to-documentation-D7Yxgf9I.js b/assets/contributing-to-documentation-D7Yxgf9I.js
new file mode 100644
index 00000000000..0c021f1ed51
--- /dev/null
+++ b/assets/contributing-to-documentation-D7Yxgf9I.js
@@ -0,0 +1,478 @@
+import{j as e}from"./chunk-EPOLDU6W-B5LwAila.js";let d=`## Contributing to Documentation
+
+The Apache HBase project welcomes contributions to all aspects of the project, including the documentation.
+
+In HBase, documentation includes the following areas, and probably some others:
+
+* The [HBase Reference Guide](/docs) (this book)
+* The [HBase website](/)
+* API documentation
+* Command-line utility output and help text
+* Web UI strings, explicit help text, context-sensitive strings, and others
+* Log messages
+* Comments in source files, configuration files, and others
+* Localization of any of the above into target languages other than English
+
+No matter which area you want to help out with, the first step is almost always to download (typically by cloning the Git repository) and familiarize yourself with the HBase source code. For information on downloading and building the source, see [developer](/docs/building-and-developing).
+
+## Contributing to Other Strings
+
+If you spot an error in a string in a UI, utility, script, log message, or elsewhere, or you think something could be made more clear, or you think text needs to be added where it doesn't currently exist, the first step is to file a JIRA. Be sure to set the component to \`Documentation\` in addition to any other involved components. Most components have one or more default owners, who monitor new issues which come into those queues. Regardless of whether you feel able to fix the bug, you [...]
+
+If you want to try your hand at fixing your newly-filed bug, assign it to yourself. You will need to clone the HBase Git repository to your local system and work on the issue there. When you have developed a potential fix, submit it for review. If it addresses the issue and is seen as an improvement, one of the HBase committers will commit it to one or more branches, as appropriate.
+
+### Procedure: Suggested Work flow for Submitting Patches
+
+This procedure goes into more detail than Git pros will need, but is included in this appendix so that people unfamiliar with Git can feel confident contributing to HBase while they learn.
+
+<Steps>
+  <Step>
+    If you have not already done so, clone the Git repository locally. You only need to do this once.
+  </Step>
+
+  <Step>
+    Fairly often, pull remote changes into your local repository by using the \`git pull\` command,
+    while your tracking branch is checked out.
+  </Step>
+
+  <Step>
+    For each issue you work on, create a new branch. One convention that works well for naming the branches is to name a given branch the same as the JIRA it relates to:
+
+    \`\`\`bash
+    $ git checkout -b HBASE-123456
+    \`\`\`
+  </Step>
+
+  <Step>
+    Make your suggested changes on your branch, committing your changes to your local repository
+    often. If you need to switch to working on a different issue, remember to check out the
+    appropriate branch.
+  </Step>
+
+  <Step>
+    When you are ready to submit your patch, first be sure that HBase builds cleanly and behaves as
+    expected in your modified branch.
+  </Step>
+
+  <Step>
+    If you have made documentation or website changes, verify that the site builds correctly by
+    running the development server from the \`hbase-website/\` directory.
+  </Step>
+
+  <Step>
+    If it takes you several days or weeks to implement your fix, or you know that the area of the code you are working in has had a lot of changes lately, make sure you rebase your branch against the remote master and take care of any conflicts before submitting your patch.
+
+    \`\`\`bash
+    $ git checkout HBASE-123456
+    $ git rebase origin/master
+    \`\`\`
+  </Step>
+
+  <Step>
+    Generate your patch against the remote master. Run the following command from the top level of your git repository (usually called \`hbase\`):
+
+    \`\`\`bash
+    $ git format-patch --stdout origin/master > HBASE-123456.patch
+    \`\`\`
+
+    The name of the patch should contain the JIRA ID.
+  </Step>
+
+  <Step>
+    Look over the patch file to be sure that you did not change any additional files by accident and
+    that there are no other surprises.
+  </Step>
+
+  <Step>
+    When you are satisfied, attach the patch to the JIRA and click the **Patch Available** button. A
+    reviewer will review your patch.
+  </Step>
+
+  <Step>
+    If you need to submit a new version of the patch, leave the old one on the JIRA and add a version
+    number to the name of the new patch.
+  </Step>
+
+  <Step>
+    After a change has been committed, there is no need to keep your local branch around.
+  </Step>
+</Steps>
+
+## Editing the HBase Website and Documentation
+
+The HBase website and documentation are now part of a single application built with Remix and Fumadocs. The source files are located in the \`hbase-website/\` directory:
+
+* **Documentation pages**: \`hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/\` - individual MDX files for each documentation section
+* **Single-page view**: \`hbase-website/app/pages/_docs/docs/_mdx/single-page/index.mdx\` - combines all documentation into one page
+* **Website components**: \`hbase-website/app/components/\` - React components used throughout the site
+* **Images**: \`hbase-website/public/\` - static assets including images
+
+You can edit MDX files in any text editor or IDE. To preview your changes locally, run the development server from the \`hbase-website/\` directory and navigate to the documentation pages in your browser. When you are satisfied with your changes, follow the procedure in [submit doc patch procedure](/docs/contributing-to-documentation#procedure-suggested-work-flow-for-submitting-patches) to submit your patch.
+
+## Publishing the HBase Website and Documentation
+
+The HBase website and documentation are built and deployed as a single Remix application. The deployment process is managed through the project's CI/CD pipeline, which builds the site from the \`hbase-website/\` directory and deploys it automatically when changes are merged to the main branch.
+
+## MDX and Fumadocs Components
+
+The HBase documentation is written in MDX (Markdown with JSX), which allows you to use standard Markdown syntax along with React components. For comprehensive documentation on Markdown formatting and MDX features, refer to:
+
+* [Fumadocs Markdown Documentation](https://www.fumadocs.dev/docs/markdown) - Complete guide to MDX syntax and Fumadocs features
+* [CommonMark specification](https://commonmark.org/) - Standard Markdown syntax reference
+* [GFM (GitHub Flavored Markdown)](https://github.github.com/gfm) - GitHub-style Markdown extensions
+
+### Fumadocs Components
+
+Fumadocs provides several components that enhance the documentation:
+
+#### Steps Component
+
+Use \`<Steps>\` to create numbered step-by-step instructions:
+
+\`\`\`mdx
+<Steps>
+
+<Step>First, do this thing.</Step>
+
+<Step>Then, do this other thing.</Step>
+
+</Steps>
+\`\`\`
+
+**Example output:**
+
+<Steps>
+  <Step>
+    First, do this thing.
+  </Step>
+
+  <Step>
+    Then, do this other thing.
+  </Step>
+</Steps>
+
+#### Callout Component
+
+Use \`<Callout>\` for notes, warnings, and important information:
+
+\`\`\`mdx
+<Callout type="info">This is an informational callout.</Callout>
+
+<Callout type="warning">This is a warning callout.</Callout>
+\`\`\`
+
+**Example output:**
+
+<Callout type="info">
+  This is an informational callout.
+</Callout>
+
+<Callout type="warning">
+  This is a warning callout.
+</Callout>
+
+#### Include Directive
+
+The single-page documentation view uses \`<include>\` tags to combine multiple MDX files:
+
+\`\`\`mdx
+<include>../(multi-page)/getting-started.mdx</include>
+\`\`\`
+
+See \`hbase-website/app/pages/_docs/docs/_mdx/single-page/index.mdx\` for examples of how all documentation sections are included in the single-page view.
+
+## Auto-Generated Content
+
+Some parts of the HBase documentation, such as the [default configuration](/docs/configuration/default), are generated automatically to stay in sync with the code. The configuration documentation is generated from the \`hbase-common/src/main/resources/hbase-default.xml\` file.
+
+To add or modify configuration parameters, update the source XML file. To regenerate the documentation from the updated configuration, run:
+
+\`\`\`bash
+npm run extract-hbase-config
+\`\`\`
+
+This command is also executed automatically when you run \`npm ci\`.
+
+## Images in the Documentation
+
+You can include images in the HBase documentation using standard Markdown syntax. Always include descriptive alt text for accessibility:
+
+\`\`\`markdown
+![Alt text describing the image](/path/to/image.png)
+\`\`\`
+
+Save images to the \`hbase-website/public/\` directory or an appropriate subdirectory. Reference them in your MDX files using absolute paths from the public directory:
+
+\`\`\`markdown
+![Architecture diagram](/images/architecture-diagram.png)
+\`\`\`
+
+When submitting a patch that includes images, attach the images to the JIRA issue.
+
+## Adding a New Section to the Documentation
+
+To add a new section to the HBase documentation:
+
+1. Create a new MDX file in \`hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/\` with a descriptive name (e.g., \`my-new-section.mdx\`)
+2. Add frontmatter at the top of the file with a title and description:
+
+\`\`\`mdx
+---
+title: "My New Section"
+description: "Brief description of what this section covers"
+---
+
+## My New Section
+
+Your content here...
+\`\`\`
+
+3. Add your new file to \`hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/meta.json\` in the appropriate location within the \`pages\` array (without the \`.mdx\` extension):
+
+\`\`\`json
+{
+  "pages": [
+    "---My Category---",
+    "my-new-section",
+    ...
+  ]
+}
+\`\`\`
+
+4. Add an \`<include>\` directive to \`hbase-website/app/pages/_docs/docs/_mdx/single-page/index.mdx\` in the appropriate location:
+
+\`\`\`mdx
+<include>../(multi-page)/my-new-section.mdx</include>
+\`\`\`
+
+5. Add your new file to Git before creating your patch.
+
+## Unique Headings Requirement
+
+Since all documentation files are merged into a single-page view, **all heading IDs must be unique across the entire documentation**. A test will fail during the build if duplicate heading IDs are detected, marking the problematic headings.
+
+Headings don't have to be visually unique, but their link IDs must be unique. You can customize the heading ID using Fumadocs syntax:
+
+\`\`\`markdown
+## Configuration [#server-configuration]
+\`\`\`
+
+This creates a heading that displays as "Configuration" but has the unique ID \`#server-configuration\` for linking purposes.
+
+### Hiding Headings from Table of Contents
+
+You can hide specific headings from the right-side table of contents:
+
+\`\`\`markdown
+## Internal Implementation Details [!toc]
+\`\`\`
+
+This heading will still appear in the document but won't show up in the table of contents navigation.
+
+<Callout type="warning">
+  Note: \`[!toc]\` becomes part of the heading ID. For example, \`## Usage [!toc]\` will have the ID
+  \`#usage-toc\`.
+</Callout>
+
+### Combining Custom IDs and TOC Hiding
+
+You can combine both attributes:
+
+\`\`\`markdown
+## Configuration Details [#server-config] [!toc]
+\`\`\`
+
+## Common Documentation Issues
+
+The following documentation issues come up often:
+
+1. **Isolate Changes for Easy Diff Review**
+
+   Avoid reformatting entire files when making content changes. If you need to reformat a file, do that in a separate JIRA where you do not change any content.
+
+2. **Syntax Highlighting**
+
+   MDX supports syntax highlighting for code blocks. Specify the language after the opening triple backticks:
+
+   \`\`\`\`markdown
+   \`\`\`java
+   public class Example {
+       // your code here
+   }
+   \`\`\`
+   \`\`\`\`
+
+3. **Component Syntax**
+
+   Remember to properly close Fumadocs components. Components like \`<Steps>\` and \`<Callout>\` must be properly closed:
+
+   \`\`\`mdx
+   <Callout>Your content here</Callout>
+   \`\`\`
+
+4. **Unique Heading IDs**
+
+   Ensure all heading IDs are unique across the entire documentation. If you get a test failure about duplicate headings, customize the heading ID using \`[#custom-id]\` syntax as described in the [Unique Headings Requirement](#unique-headings-requirement) section.
+`,l={title:"Appendix: Contributing to Documentation",description:"Guide for contributing to Apache HBase documentation, including patch submission procedures, website editing, style guidelines, and best practices."},c=[{href:"/docs"},{href:"/"},{href:"/docs/building-and-developing"},{href:"/docs/contributing-to-documentation#procedure-suggested-work-flow-for-submitting-patches"},{href:"https://www.fumadocs.dev/docs/markdown"},{href:"https://commonmark.org/"},{href:"https://github.github. [...]
+while your tracking branch is checked out.`},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:"For each issue you work on, create a new branch. One convention that works well for naming the branches is to name a given branch the same as the JIRA it relates to:"},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:`Make your suggested changes on your branch, committing your changes to your local repository
+often. If you need to switch to working on a different issue, remember to check out the
+appropriate branch.`},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:`When you are ready to submit your patch, first be sure that HBase builds cleanly and behaves as
+expected in your modified branch.`},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:`If you have made documentation or website changes, verify that the site builds correctly by
+running the development server from the hbase-website/ directory.`},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:"If it takes you several days or weeks to implement your fix, or you know that the area of the code you are working in has had a lot of changes lately, make sure you rebase your branch against the remote master and take care of any conflicts before submitting your patch."},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:"Gener [...]
+that there are no other surprises.`},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:`When you are satisfied, attach the patch to the JIRA and click the Patch Available button. A
+reviewer will review your patch.`},{heading:"procedure-suggested-work-flow-for-submitting-patches",content:`If you need to submit a new version of the patch, leave the old one on the JIRA and add a version
+number to the name of the new patch.`},{heading:"editing-the-hbase-website-and-documentation",content:"The HBase website and documentation are now part of a single application built with Remix and Fumadocs. The source files are located in the hbase-website/ directory:"},{heading:"editing-the-hbase-website-and-documentation",content:"Documentation pages: hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/ - individual MDX files for each documentation section"},{heading:"editing-the-hbas [...]
+#usage-toc.`},{heading:"combining-custom-ids-and-toc-hiding",content:"You can combine both attributes:"},{heading:"common-documentation-issues",content:"The following documentation issues come up often:"},{heading:"common-documentation-issues",content:"Isolate Changes for Easy Diff Review"},{heading:"common-documentation-issues",content:"Avoid reformatting entire files when making content changes. If you need to reformat a file, do that in a separate JIRA where you do not change any cont [...]
+`,e.jsx(i.p,{children:"The Apache HBase project welcomes contributions to all aspects of the project, including the documentation."}),`
+`,e.jsx(i.p,{children:"In HBase, documentation includes the following areas, and probably some others:"}),`
+`,e.jsxs(i.ul,{children:[`
+`,e.jsxs(i.li,{children:["The ",e.jsx(i.a,{href:"/docs",children:"HBase Reference Guide"})," (this book)"]}),`
+`,e.jsxs(i.li,{children:["The ",e.jsx(i.a,{href:"/",children:"HBase website"})]}),`
+`,e.jsx(i.li,{children:"API documentation"}),`
+`,e.jsx(i.li,{children:"Command-line utility output and help text"}),`
+`,e.jsx(i.li,{children:"Web UI strings, explicit help text, context-sensitive strings, and others"}),`
+`,e.jsx(i.li,{children:"Log messages"}),`
+`,e.jsx(i.li,{children:"Comments in source files, configuration files, and others"}),`
+`,e.jsx(i.li,{children:"Localization of any of the above into target languages other than English"}),`
+`]}),`
+`,e.jsxs(i.p,{children:["No matter which area you want to help out with, the first step is almost always to download (typically by cloning the Git repository) and familiarize yourself with the HBase source code. For information on downloading and building the source, see ",e.jsx(i.a,{href:"/docs/building-and-developing",children:"developer"}),"."]}),`
+`,e.jsx(i.h2,{id:"contributing-to-other-strings",children:"Contributing to Other Strings"}),`
+`,e.jsxs(i.p,{children:["If you spot an error in a string in a UI, utility, script, log message, or elsewhere, or you think something could be made more clear, or you think text needs to be added where it doesn't currently exist, the first step is to file a JIRA. Be sure to set the component to ",e.jsx(i.code,{children:"Documentation"})," in addition to any other involved components. Most components have one or more default owners, who monitor new issues which come into those queues. Reg [...]
+`,e.jsx(i.p,{children:"If you want to try your hand at fixing your newly-filed bug, assign it to yourself. You will need to clone the HBase Git repository to your local system and work on the issue there. When you have developed a potential fix, submit it for review. If it addresses the issue and is seen as an improvement, one of the HBase committers will commit it to one or more branches, as appropriate."}),`
+`,e.jsx(i.h3,{id:"procedure-suggested-work-flow-for-submitting-patches",children:"Procedure: Suggested Work flow for Submitting Patches"}),`
+`,e.jsx(i.p,{children:"This procedure goes into more detail than Git pros will need, but is included in this appendix so that people unfamiliar with Git can feel confident contributing to HBase while they learn."}),`
+`,e.jsxs(o,{children:[e.jsx(n,{children:e.jsx(i.p,{children:"If you have not already done so, clone the Git repository locally. You only need to do this once."})}),e.jsx(n,{children:e.jsxs(i.p,{children:["Fairly often, pull remote changes into your local repository by using the ",e.jsx(i.code,{children:"git pull"}),` command,
+while your tracking branch is checked out.`]})}),e.jsxs(n,{children:[e.jsx(i.p,{children:"For each issue you work on, create a new branch. One convention that works well for naming the branches is to name a given branch the same as the JIRA it relates to:"}),e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg  [...]
+often. If you need to switch to working on a different issue, remember to check out the
+appropriate branch.`})}),e.jsx(n,{children:e.jsx(i.p,{children:`When you are ready to submit your patch, first be sure that HBase builds cleanly and behaves as
+expected in your modified branch.`})}),e.jsx(n,{children:e.jsxs(i.p,{children:[`If you have made documentation or website changes, verify that the site builds correctly by
+running the development server from the `,e.jsx(i.code,{children:"hbase-website/"})," directory."]})}),e.jsxs(n,{children:[e.jsx(i.p,{children:"If it takes you several days or weeks to implement your fix, or you know that the area of the code you are working in has had a lot of changes lately, make sure you rebase your branch against the remote master and take care of any conflicts before submitting your patch."}),e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes gith [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:"$"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" git"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" rebase"}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:" origin/master"})]})]})})})]}),e.jsxs(n,{children:[e.jsxs(i.p,{children:["Generate your patc [...]
+that there are no other surprises.`})}),e.jsx(n,{children:e.jsxs(i.p,{children:["When you are satisfied, attach the patch to the JIRA and click the ",e.jsx(i.strong,{children:"Patch Available"}),` button. A
+reviewer will review your patch.`]})}),e.jsx(n,{children:e.jsx(i.p,{children:`If you need to submit a new version of the patch, leave the old one on the JIRA and add a version
+number to the name of the new patch.`})}),e.jsx(n,{children:"After a change has been committed, there is no need to keep your local branch around."})]}),`
+`,e.jsx(i.h2,{id:"editing-the-hbase-website-and-documentation",children:"Editing the HBase Website and Documentation"}),`
+`,e.jsxs(i.p,{children:["The HBase website and documentation are now part of a single application built with Remix and Fumadocs. The source files are located in the ",e.jsx(i.code,{children:"hbase-website/"})," directory:"]}),`
+`,e.jsxs(i.ul,{children:[`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"Documentation pages"}),": ",e.jsx(i.code,{children:"hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/"})," - individual MDX files for each documentation section"]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"Single-page view"}),": ",e.jsx(i.code,{children:"hbase-website/app/pages/_docs/docs/_mdx/single-page/index.mdx"})," - combines all documentation into one page"]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"Website components"}),": ",e.jsx(i.code,{children:"hbase-website/app/components/"})," - React components used throughout the site"]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.strong,{children:"Images"}),": ",e.jsx(i.code,{children:"hbase-website/public/"})," - static assets including images"]}),`
+`]}),`
+`,e.jsxs(i.p,{children:["You can edit MDX files in any text editor or IDE. To preview your changes locally, run the development server from the ",e.jsx(i.code,{children:"hbase-website/"})," directory and navigate to the documentation pages in your browser. When you are satisfied with your changes, follow the procedure in ",e.jsx(i.a,{href:"/docs/contributing-to-documentation#procedure-suggested-work-flow-for-submitting-patches",children:"submit doc patch procedure"})," to submit your pat [...]
+`,e.jsx(i.h2,{id:"publishing-the-hbase-website-and-documentation",children:"Publishing the HBase Website and Documentation"}),`
+`,e.jsxs(i.p,{children:["The HBase website and documentation are built and deployed as a single Remix application. The deployment process is managed through the project's CI/CD pipeline, which builds the site from the ",e.jsx(i.code,{children:"hbase-website/"})," directory and deploys it automatically when changes are merged to the main branch."]}),`
+`,e.jsx(i.h2,{id:"mdx-and-fumadocs-components",children:"MDX and Fumadocs Components"}),`
+`,e.jsx(i.p,{children:"The HBase documentation is written in MDX (Markdown with JSX), which allows you to use standard Markdown syntax along with React components. For comprehensive documentation on Markdown formatting and MDX features, refer to:"}),`
+`,e.jsxs(i.ul,{children:[`
+`,e.jsxs(i.li,{children:[e.jsx(i.a,{href:"https://www.fumadocs.dev/docs/markdown",children:"Fumadocs Markdown Documentation"})," - Complete guide to MDX syntax and Fumadocs features"]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.a,{href:"https://commonmark.org/",children:"CommonMark specification"})," - Standard Markdown syntax reference"]}),`
+`,e.jsxs(i.li,{children:[e.jsx(i.a,{href:"https://github.github.com/gfm",children:"GFM (GitHub Flavored Markdown)"})," - GitHub-style Markdown extensions"]}),`
+`]}),`
+`,e.jsx(i.h3,{id:"fumadocs-components",children:"Fumadocs Components"}),`
+`,e.jsx(i.p,{children:"Fumadocs provides several components that enhance the documentation:"}),`
+`,e.jsx(i.h4,{id:"steps-component",children:"Steps Component"}),`
+`,e.jsxs(i.p,{children:["Use ",e.jsx(i.code,{children:"<Steps>"})," to create numbered step-by-step instructions:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Step"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">First, do this thing.</"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Step"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E [...]
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Step"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">Then, do this other thing.</"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Step"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark": [...]
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"</"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Steps"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:">"})]})]})})}),`
+`,e.jsx(i.p,{children:e.jsx(i.strong,{children:"Example output:"})}),`
+`,e.jsxs(o,{children:[e.jsx(n,{children:"First, do this thing."}),e.jsx(n,{children:"Then, do this other thing."})]}),`
+`,e.jsx(i.h4,{id:"callout-component",children:"Callout Component"}),`
+`,e.jsxs(i.p,{children:["Use ",e.jsx(i.code,{children:"<Callout>"})," for notes, warnings, and important information:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"<"}),e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:"Callout"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" type"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"="}),e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'"wa [...]
+`,e.jsx(i.p,{children:e.jsx(i.strong,{children:"Example output:"})}),`
+`,e.jsx(s,{type:"info",children:"This is an informational callout."}),`
+`,e.jsx(s,{type:"warning",children:"This is a warning callout."}),`
+`,e.jsx(i.h4,{id:"include-directive",children:"Include Directive"}),`
+`,e.jsxs(i.p,{children:["The single-page documentation view uses ",e.jsx(i.code,{children:"<include>"})," tags to combine multiple MDX files:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.p,{children:["See ",e.jsx(i.code,{children:"hbase-website/app/pages/_docs/docs/_mdx/single-page/index.mdx"})," for examples of how all documentation sections are included in the single-page view."]}),`
+`,e.jsx(i.h2,{id:"auto-generated-content",children:"Auto-Generated Content"}),`
+`,e.jsxs(i.p,{children:["Some parts of the HBase documentation, such as the ",e.jsx(i.a,{href:"/docs/configuration/default",children:"default configuration"}),", are generated automatically to stay in sync with the code. The configuration documentation is generated from the ",e.jsx(i.code,{children:"hbase-common/src/main/resources/hbase-default.xml"})," file."]}),`
+`,e.jsx(i.p,{children:"To add or modify configuration parameters, update the source XML file. To regenerate the documentation from the updated configuration, run:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="m 4,4 a 1,1 0 0 0 -0.7070312,0.2929687 1,1 0 0 0 0,1.4140625 L 8.5859375,11 3.2929688,16.292969 a 1,1 0 0 0 0,1.414062 1,1 0 0 0 1.4140624,0 l 5.9999998,-6 a 1.0001,1.0001 0 0 0 0,-1.414062 L 4.7070312,4.2929687 A 1,1 0 0 0 4,4  [...]
+`,e.jsxs(i.p,{children:["This command is also executed automatically when you run ",e.jsx(i.code,{children:"npm ci"}),"."]}),`
+`,e.jsx(i.h2,{id:"images-in-the-documentation",children:"Images in the Documentation"}),`
+`,e.jsx(i.p,{children:"You can include images in the HBase documentation using standard Markdown syntax. Always include descriptive alt text for accessibility:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.p,{children:["Save images to the ",e.jsx(i.code,{children:"hbase-website/public/"})," directory or an appropriate subdirectory. Reference them in your MDX files using absolute paths from the public directory:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.p,{children:"When submitting a patch that includes images, attach the images to the JIRA issue."}),`
+`,e.jsx(i.h2,{id:"adding-a-new-section-to-the-documentation",children:"Adding a New Section to the Documentation"}),`
+`,e.jsx(i.p,{children:"To add a new section to the HBase documentation:"}),`
+`,e.jsxs(i.ol,{children:[`
+`,e.jsxs(i.li,{children:["Create a new MDX file in ",e.jsx(i.code,{children:"hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/"})," with a descriptive name (e.g., ",e.jsx(i.code,{children:"my-new-section.mdx"}),")"]}),`
+`,e.jsx(i.li,{children:"Add frontmatter at the top of the file with a title and description:"}),`
+`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:'title: "My New Section"'})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:'description: "Brief description of what this section covers"'})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"},children:"---"})}),`
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-light-font-weight":"bold","--shiki-dark":"#79B8FF","--shiki-dark-font-weight":"bold"},children:"## My New Section"})}),`
+`,e.jsx(i.span,{className:"line"}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"Your content here..."})})]})})}),`
+`,e.jsxs(i.ol,{start:"3",children:[`
+`,e.jsxs(i.li,{children:["Add your new file to ",e.jsx(i.code,{children:"hbase-website/app/pages/_docs/docs/_mdx/(multi-page)/meta.json"})," in the appropriate location within the ",e.jsx(i.code,{children:"pages"})," array (without the ",e.jsx(i.code,{children:".mdx"})," extension):"]}),`
+`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#005CC5","--shiki-dark":"#79B8FF"},children:'  "pages"'}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:": ["})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'    "---My Category---"'}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:","})]}),`
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#032F62","--shiki-dark":"#9ECBFF"},children:'    "my-new-section"'}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:","})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#B31D28","--shiki-light-font-style":"italic","--shiki-dark":"#FDAEB7","--shiki-dark-font-style":"italic"},children:"    ..."})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"  ]"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})})]})})}),`
+`,e.jsxs(i.ol,{start:"4",children:[`
+`,e.jsxs(i.li,{children:["Add an ",e.jsx(i.code,{children:"<include>"})," directive to ",e.jsx(i.code,{children:"hbase-website/app/pages/_docs/docs/_mdx/single-page/index.mdx"})," in the appropriate location:"]}),`
+`]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.ol,{start:"5",children:[`
+`,e.jsx(i.li,{children:"Add your new file to Git before creating your patch."}),`
+`]}),`
+`,e.jsx(i.h2,{id:"unique-headings-requirement",children:"Unique Headings Requirement"}),`
+`,e.jsxs(i.p,{children:["Since all documentation files are merged into a single-page view, ",e.jsx(i.strong,{children:"all heading IDs must be unique across the entire documentation"}),". A test will fail during the build if duplicate heading IDs are detected, marking the problematic headings."]}),`
+`,e.jsx(i.p,{children:"Headings don't have to be visually unique, but their link IDs must be unique. You can customize the heading ID using Fumadocs syntax:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.p,{children:['This creates a heading that displays as "Configuration" but has the unique ID ',e.jsx(i.code,{children:"#server-configuration"})," for linking purposes."]}),`
+`,e.jsx(i.h3,{id:"hiding-headings-from-table-of-contents",children:"Hiding Headings from Table of Contents"}),`
+`,e.jsx(i.p,{children:"You can hide specific headings from the right-side table of contents:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.p,{children:"This heading will still appear in the document but won't show up in the table of contents navigation."}),`
+`,e.jsx(s,{type:"warning",children:e.jsxs(i.p,{children:["Note: ",e.jsx(i.code,{children:"[!toc]"})," becomes part of the heading ID. For example, ",e.jsx(i.code,{children:"## Usage [!toc]"}),` will have the ID
+`,e.jsx(i.code,{children:"#usage-toc"}),"."]})}),`
+`,e.jsx(i.h3,{id:"combining-custom-ids-and-toc-hiding",children:"Combining Custom IDs and TOC Hiding"}),`
+`,e.jsx(i.p,{children:"You can combine both attributes:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsx(i.h2,{id:"common-documentation-issues",children:"Common Documentation Issues"}),`
+`,e.jsx(i.p,{children:"The following documentation issues come up often:"}),`
+`,e.jsxs(i.ol,{children:[`
+`,e.jsxs(i.li,{children:[`
+`,e.jsx(i.p,{children:e.jsx(i.strong,{children:"Isolate Changes for Easy Diff Review"})}),`
+`,e.jsx(i.p,{children:"Avoid reformatting entire files when making content changes. If you need to reformat a file, do that in a separate JIRA where you do not change any content."}),`
+`]}),`
+`,e.jsxs(i.li,{children:[`
+`,e.jsx(i.p,{children:e.jsx(i.strong,{children:"Syntax Highlighting"})}),`
+`,e.jsx(i.p,{children:"MDX supports syntax highlighting for code blocks. Specify the language after the opening triple backticks:"}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`,e.jsxs(i.span,{className:"line",children:[e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:"public"}),e.jsx(i.span,{style:{"--shiki-light":"#D73A49","--shiki-dark":"#F97583"},children:" class"}),e.jsx(i.span,{style:{"--shiki-light":"#6F42C1","--shiki-dark":"#B392F0"},children:" Example"}),e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:" {"})]}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#6A737D","--shiki-dark":"#6A737D"},children:"    // your code here"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"}"})}),`
+`,e.jsx(i.span,{className:"line",children:e.jsx(i.span,{style:{"--shiki-light":"#24292E","--shiki-dark":"#E1E4E8"},children:"```"})})]})})}),`
+`]}),`
+`,e.jsxs(i.li,{children:[`
+`,e.jsx(i.p,{children:e.jsx(i.strong,{children:"Component Syntax"})}),`
+`,e.jsxs(i.p,{children:["Remember to properly close Fumadocs components. Components like ",e.jsx(i.code,{children:"<Steps>"})," and ",e.jsx(i.code,{children:"<Callout>"})," must be properly closed:"]}),`
+`,e.jsx(e.Fragment,{children:e.jsx(i.pre,{className:"shiki shiki-themes github-light github-dark",style:{"--shiki-light":"#24292e","--shiki-dark":"#e1e4e8","--shiki-light-bg":"#fff","--shiki-dark-bg":"#24292e"},tabIndex:"0",icon:'<svg viewBox="0 0 24 24"><path d="M 6,1 C 4.354992,1 3,2.354992 3,4 v 16 c 0,1.645008 1.354992,3 3,3 h 12 c 1.645008,0 3,-1.354992 3,-3 V 8 7 A 1.0001,1.0001 0 0 0 20.707031,6.2929687 l -5,-5 A 1.0001,1.0001 0 0 0 15,1 h -1 z m 0,2 h 7 v 3 c 0,1.645008 1.354992, [...]
+`]}),`
+`,e.jsxs(i.li,{children:[`
+`,e.jsx(i.p,{children:e.jsx(i.strong,{children:"Unique Heading IDs"})}),`
+`,e.jsxs(i.p,{children:["Ensure all heading IDs are unique across the entire documentation. If you get a test failure about duplicate headings, customize the heading ID using ",e.jsx(i.code,{children:"[#custom-id]"})," syntax as described in the ",e.jsx(i.a,{href:"#unique-headings-requirement",children:"Unique Headings Requirement"})," section."]}),`
+`]}),`
+`]})]})}function m(t={}){const{wrapper:i}=t.components||{};return i?e.jsx(i,{...t,children:e.jsx(h,{...t})}):h(t)}function a(t,i){throw new Error("Expected component `"+t+"` to be defined: you likely forgot to import, pass, or provide it.")}export{d as _markdown,m as default,c as extractedReferences,l as frontmatter,u as structuredData,g as toc};
diff --git a/assets/cp-Crzqt88_.js b/assets/cp-Crzqt88_.js
new file mode 100644
index 00000000000..54376d2975d
--- /dev/null
+++ b/assets/cp-Crzqt88_.js
@@ -0,0 +1,1555 @@
+import{j as s}from"./chunk-EPOLDU6W-B5LwAila.js";let h=`HBase Coprocessors are modeled after Google BigTable's coprocessor implementation
+([http://research.google.com/people/jeff/SOCC2010-keynote-slides.pdf](http://research.google.com/people/jeff/SOCC2010-keynote-slides.pdf) pages 41-42.).
+Efforts are ongoing to bridge gaps between HBase's
+implementation and BigTable's architecture. For more information see
+[HBASE-4047](https://issues.apache.org/jira/browse/HBASE-4047).
+
+The information in this chapter is primarily sourced and heavily reused from the following
+resources:
+
+1. Mingjie Lai's blog post
+   [Coprocessor Introduction](https://blogs.apache.org/hbase/entry/coprocessor_introduction).
+2. Gaurav Bhardwaj's blog post
+   [The How To Of HBase Coprocessors](http://www.3pillarglobal.com/insights/hbase-coprocessors).
+
+<Callout type="warn" title="Use Coprocessors At Your Own Risk">
+  Coprocessors are an advanced feature of HBase and are intended to be used by system
+  developers only. Because coprocessor code runs directly on the RegionServer and has
+  direct access to your data, they introduce the risk of data corruption, man-in-the-middle
+  attacks, or other malicious data access. Currently, there is no mechanism to prevent
+  data corruption by coprocessors, though work is underway on
+  [HBASE-4047](https://issues.apache.org/jira/browse/HBASE-4047).
+
+  In addition, there is no resource isolation, so a well-intentioned but misbehaving
+  coprocessor can severely degrade cluster performance and stability.
+</Callout>
+
+## Coprocessor Overview
+
+In HBase, you fetch data using a \`Get\` or \`Scan\`, whereas in an RDBMS you use a SQL
+query. In order to fetch only the relevant data, you filter it using a HBase
+[Filter](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/filter/Filter.html)
+, whereas in an RDBMS you use a \`WHERE\` predicate.
+
+After fetching the data, you perform computations on it. This paradigm works well
+for "small data" with a few thousand rows and several columns. However, when you scale
+to billions of rows and millions of columns, moving large amounts of data across your
+network will create bottlenecks at the network layer, and the client needs to be powerful
+enough and have enough memory to handle the large amounts of data and the computations.
+In addition, the client code can grow large and complex.
+
+In this scenario, coprocessors might make sense. You can put the business computation
+code into a coprocessor which runs on the RegionServer, in the same location as the
+data, and returns the result to the client.
+
+This is only one scenario where using coprocessors can provide benefit. Following
+are some analogies which may help to explain some of the benefits of coprocessors.
+
+### Coprocessor Analogies
+
+**Triggers and Stored Procedure**\\
+An Observer coprocessor is similar to a trigger in a RDBMS in that it executes
+your code either before or after a specific event (such as a \`Get\` or \`Put\`)
+occurs. An endpoint coprocessor is similar to a stored procedure in a RDBMS
+because it allows you to perform custom computations on the data on the
+RegionServer itself, rather than on the client.
+
+**MapReduce**\\
+MapReduce operates on the principle of moving the computation to the location of
+the data. Coprocessors operate on the same principal.
+
+**AOP**\\
+If you are familiar with Aspect Oriented Programming (AOP), you can think of a coprocessor
+as applying advice by intercepting a request and then running some custom code,
+before passing the request on to its final destination (or even changing the destination).
+
+### Coprocessor Implementation Overview
+
+1. Your class should implement one of the Coprocessor interfaces -
+   [Coprocessor](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/Coprocessor.html),
+   [RegionObserver](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionObserver.html),
+   [CoprocessorService](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/CoprocessorService.html) - to name a few.
+2. Load the coprocessor, either statically (from the configuration) or dynamically,
+   using HBase Shell. For more details see [Loading Coprocessors](/docs/cp#loading-coprocessors).
+3. Call the coprocessor from your client-side code. HBase handles the coprocessor
+   transparently.
+
+The framework API is provided in the
+[coprocessor](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/package-summary.html)
+package.
+
+## Types of Coprocessors
+
+### Observer Coprocessors
+
+Observer coprocessors are triggered either before or after a specific event occurs.
+Observers that happen before an event use methods that start with a \`pre\` prefix,
+such as [\`prePut\`](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionObserver.html#prePut\\(org.apache.hadoop.hbase.coprocessor.ObserverContext,org.apache.hadoop.hbase.client.Put,org.apache.hadoop.hbase.wal.WALEdit\\)). Observers that happen just after an event override methods that start
+with a \`post\` prefix, such as [\`postPut\`](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionObserver.html#postPut\\(org.apache.hadoop.hbase.coprocessor.ObserverContext,org.apache.hadoop.hbase.client.Put,org.apache.hadoop.hbase.wal.WALEdit\\)).
+
+#### Use Cases for Observer Coprocessors
+
+**Security**\\
+Before performing a \`Get\` or \`Put\` operation, you can check for permission using
+\`preGet\` or \`prePut\` methods.
+
+**Referential Integrity**\\
+HBase does not directly support the RDBMS concept of refential integrity, also known
+as foreign keys. You can use a coprocessor to enforce such integrity. For instance,
+if you have a business rule that every insert to the \`users\` table must be followed
+by a corresponding entry in the \`user_daily_attendance\` table, you could implement
+a coprocessor to use the \`prePut\` method on \`user\` to insert a record into \`user_daily_attendance\`.
+
+**Secondary Indexes**\\
+You can use a coprocessor to maintain secondary indexes. For more information, see
+[SecondaryIndexing](https://cwiki.apache.org/confluence/display/HADOOP2/Hbase+SecondaryIndexing).
+
+#### Types of Observer Coprocessor
+
+**RegionObserver**\\
+A RegionObserver coprocessor allows you to observe events on a region, such as \`Get\`
+and \`Put\` operations. See
+[RegionObserver](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionObserver.html).
+
+**RegionServerObserver**\\
+A RegionServerObserver allows you to observe events related to the RegionServer's
+operation, such as starting, stopping, or performing merges, commits, or rollbacks.
+See
+[RegionServerObserver](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionServerObserver.html).
+
+**MasterObserver**\\
+A MasterObserver allows you to observe events related to the HBase Master, such
+as table creation, deletion, or schema modification. See
+[MasterObserver](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/MasterObserver.html).
+
+**WalObserver**\\
+A WalObserver allows you to observe events related to writes to the Write-Ahead
+Log (WAL). See
+[WALObserver](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/WALObserver.html).
+
+[Examples](/docs/cp#cp-examples) provides working examples of observer coprocessors.
+
+### Endpoint Coprocessor
+
+Endpoint processors allow you to perform computation at the location of the data.
+See [Coprocessor Analogy](/docs/cp#coprocessor-analogies). An example is the need to calculate a running
+average or summation for an entire table which spans hundreds of regions.
+
+In contrast to observer coprocessors, where your code is run transparently, endpoint
+coprocessors must be explicitly invoked using the
+[CoprocessorService()](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/AsyncTable.html#coprocessorService\\(java.util.function.Function,org.apache.hadoop.hbase.client.ServiceCaller,byte%5B%5D\\))
+method available in
+[AsyncTable](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/AsyncTable.html).
+
+<Callout type="warn" title="On using coprocessorService method with sync client">
+  The coprocessorService method in [Table](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Table.html)
+  has been deprecated.
+
+  In [HBASE-21512](https://issues.apache.org/jira/browse/HBASE-21512)
+  we reimplement the sync client based on the async client. The coprocessorService
+  method defined in \`Table\` interface directly references a method from protobuf's
+  \`BlockingInterface\`, which means we need to use a separate thread pool to execute
+  the method so we avoid blocking the async client(We want to avoid blocking calls in
+  our async implementation).
+
+  Since coprocessor is an advanced feature, we believe it is OK for coprocessor users to
+  instead switch over to use \`AsyncTable\`. There is a lightweight
+  [toAsyncConnection](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/client/Connection.html#toAsyncConnection\\(\\))
+  method to get an \`AsyncConnection\` from \`Connection\` if needed.
+</Callout>
+
+Starting with HBase 0.96, endpoint coprocessors are implemented using Google Protocol
+Buffers (protobuf). For more details on protobuf, see Google's
+[Protocol Buffer Guide](https://developers.google.com/protocol-buffers/docs/proto).
+Endpoints Coprocessor written in version 0.94 are not compatible with version 0.96 or later.
+See
+[HBASE-5448](https://issues.apache.org/jira/browse/HBASE-5448)). To upgrade your
+HBase cluster from 0.94 or earlier to 0.96 or later, you need to reimplement your
+coprocessor.
+
+In HBase 2.x, we made use of a shaded version of protobuf 3.x, but kept the
+protobuf for coprocessors on 2.5.0. In HBase 3.0.0, we removed all dependencies on
+non-shaded protobuf so you need to reimplement your coprocessor to make use of the
+shaded protobuf version provided in hbase-thirdparty. Please see
+the [protobuf](/docs/protobuf) section for more details.
+
+Coprocessor Endpoints should make no use of HBase internals and
+only avail of public APIs; ideally a CPEP should depend on Interfaces
+and data structures only. This is not always possible but beware
+that doing so makes the Endpoint brittle, liable to breakage as HBase
+internals evolve. HBase internal APIs annotated as private or evolving
+do not have to respect semantic versioning rules or general java rules on
+deprecation before removal. While generated protobuf files are
+absent the hbase audience annotations โ€” they are created by the
+protobuf protoc tool which knows nothing of how HBase works โ€”
+they should be consided \`@InterfaceAudience.Private\` so are liable to
+change.
+
+[Examples](/docs/cp#cp-examples) provides working examples of endpoint coprocessors.
+
+## Loading Coprocessors
+
+To make your coprocessor available to HBase, it must be *loaded*, either statically
+(through the HBase configuration) or dynamically (using HBase Shell or the Java API).
+
+### Static Loading
+
+Follow these steps to statically load your coprocessor. Keep in mind that you must
+restart HBase to unload a coprocessor that has been loaded statically.
+
+1. Define the Coprocessor in *hbase-site.xml*, with a \`<property>\` element with a \`<name>\`
+   and a \`<value>\` sub-element. The \`<name>\` should be one of the following:
+
+   * \`hbase.coprocessor.region.classes\` for RegionObservers and Endpoints.
+   * \`hbase.coprocessor.wal.classes\` for WALObservers.
+   * \`hbase.coprocessor.master.classes\` for MasterObservers.
+
+     \`<value>\` must contain the fully-qualified class name of your coprocessor's implementation
+     class.
+
+     For example to load a Coprocessor (implemented in class SumEndPoint.java) you have to create
+     following entry in RegionServer's 'hbase-site.xml' file (generally located under 'conf' directory):
+
+     \`\`\`xml
+     <property>
+         <name>hbase.coprocessor.region.classes</name>
+         <value>org.myname.hbase.coprocessor.endpoint.SumEndPoint</value>
+     </property>
+     \`\`\`
+
+     If multiple classes are specified for loading, the class names must be comma-separated.
+     The framework attempts to load all the configured classes using the default class loader.
+     Therefore, the jar file must reside on the server-side HBase classpath.
+
+     Coprocessors which are loaded in this way will be active on all regions of all tables.
+     These are also called system Coprocessor.
+     The first listed Coprocessors will be assigned the priority \`Coprocessor.Priority.SYSTEM\`.
+     Each subsequent coprocessor in the list will have its priority value incremented by one (which
+     reduces its priority, because priorities have the natural sort order of Integers).
+
+     These priority values can be manually overriden in hbase-site.xml. This can be useful if you
+     want to guarantee that a coprocessor will execute after another. For example, in the following
+     configuration \`SumEndPoint\` would be guaranteed to go last, except in the case of a tie with
+     another coprocessor:
+
+     \`\`\`xml
+     <property>
+         <name>hbase.coprocessor.region.classes</name>
+         <value>org.myname.hbase.coprocessor.endpoint.SumEndPoint|2147483647</value>
+     </property>
+     \`\`\`
+
+   When calling out to registered observers, the framework executes their callbacks methods in the
+   sorted order of their priority.
+   Ties are broken arbitrarily.
+
+2. Put your code on HBase's classpath. One easy way to do this is to drop the jar
+   (containing you code and all the dependencies) into the \`lib/\` directory in the
+   HBase installation.
+
+3. Restart HBase.
+
+### Static Unloading
+
+1. Delete the coprocessor's \`<property>\` element, including sub-elements, from \`hbase-site.xml\`.
+2. Restart HBase.
+3. Optionally, remove the coprocessor's JAR file from the classpath or HBase's \`lib/\`
+   directory.
+
+### Dynamic Loading
+
+You can also load a coprocessor dynamically, without restarting HBase. This may seem
+preferable to static loading, but dynamically loaded coprocessors are loaded on a
+per-table basis, and are only available to the table for which they were loaded. For
+this reason, dynamically loaded tables are sometimes called **Table Coprocessor**.
+
+In addition, dynamically loading a coprocessor acts as a schema change on the table,
+and the table must be taken offline to load the coprocessor.
+
+There are three ways to dynamically load Coprocessor.
+
+<Callout type="info" title="Assumptions">
+  The below mentioned instructions makes the following assumptions:
+
+  * A JAR called \`coprocessor.jar\` contains the Coprocessor implementation along with all of its
+    dependencies.
+  * The JAR is available in HDFS in some location like
+    \`hdfs://NAMENODE:PORT/user/HADOOP_USER/coprocessor.jar\`.
+</Callout>
+
+#### Using HBase Shell
+
+1. Load the Coprocessor, using a command like the following:
+
+   \`\`\`ruby
+   hbase alter 'users', METHOD => 'table_att', 'Coprocessor'=>'hdfs://NAMENODE:PORT/user/HADOOP_USER/coprocessor.jar|org.myname.hbase.Coprocessor.RegionObserverExample|1073741823|arg1=1,arg2=2'
+   \`\`\`
+
+   The Coprocessor framework will try to read the class information from the coprocessor table
+   attribute value.
+   The value contains four pieces of information which are separated by the pipe (\`|\`) character.
+
+   * File path: The jar file containing the Coprocessor implementation must be in a location where
+     all region servers can read it.
+     You could copy the file onto the local disk on each region server, but it is recommended to store
+     it in HDFS.
+     [HBASE-14548](https://issues.apache.org/jira/browse/HBASE-14548) allows a directory containing the jars
+     or some wildcards to be specified, such as: \`hdfs://NAMENODE:PORT/user/HADOOP_USER/\` or
+     \`hdfs://NAMENODE:PORT/user/HADOOP_USER/*.jar\`. Please note that if a directory is specified,
+     all jar files(.jar) in the directory are added. It does not search for files in sub-directories.
+     Do not use a wildcard if you would like to specify a directory. This enhancement applies to the
+     usage via the JAVA API as well.
+   * Class name: The full class name of the Coprocessor.
+   * Priority: An integer. The framework will determine the execution sequence of all configured
+     observers registered at the same hook using priorities. This field can be left blank. In that
+     case the framework will assign a default priority value.
+   * Arguments (Optional): This field is passed to the Coprocessor implementation. This is optional.
+
+2. Verify that the coprocessor loaded:
+
+   \`\`\`ruby
+   hbase(main):04:0> describe 'users'
+   \`\`\`
+
+   The coprocessor should be listed in the \`TABLE_ATTRIBUTES\`.
+
+#### Using the Java API (all HBase versions)
+
+The following Java code shows how to use the \`setValue()\` method of \`HTableDescriptor\`
+to load a coprocessor on the \`users\` table.
+
+\`\`\`java
+TableName tableName = TableName.valueOf("users");
+String path = "hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar";
+Configuration conf = HBaseConfiguration.create();
+Connection connection = ConnectionFactory.createConnection(conf);
+Admin admin = connection.getAdmin();
+HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
+HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
+columnFamily1.setMaxVersions(3);
+hTableDescriptor.addFamily(columnFamily1);
+HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
+columnFamily2.setMaxVersions(3);
+hTableDescriptor.addFamily(columnFamily2);
+hTableDescriptor.setValue("COPROCESSOR$1", path + "|"
++ RegionObserverExample.class.getCanonicalName() + "|"
++ Coprocessor.PRIORITY_USER);
+admin.modifyTable(tableName, hTableDescriptor);
+\`\`\`
+
+#### Using the Java API (HBase 0.96+ only)
+
+In HBase 0.96 and newer, the \`addCoprocessor()\` method of \`HTableDescriptor\` provides
+an easier way to load a coprocessor dynamically.
+
+\`\`\`java
+TableName tableName = TableName.valueOf("users");
+Path path = new Path("hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar");
+Configuration conf = HBaseConfiguration.create();
+Connection connection = ConnectionFactory.createConnection(conf);
+Admin admin = connection.getAdmin();
+HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
+HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
+columnFamily1.setMaxVersions(3);
+hTableDescriptor.addFamily(columnFamily1);
+HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
+columnFamily2.setMaxVersions(3);
+hTableDescriptor.addFamily(columnFamily2);
+hTableDescriptor.addCoprocessor(RegionObserverExample.class.getCanonicalName(), path,
+Coprocessor.PRIORITY_USER, null);
+admin.modifyTable(tableName, hTableDescriptor);
+\`\`\`
+
+<Callout type="warn">
+  There is no guarantee that the framework will load a given Coprocessor successfully. For example,
+  the shell command neither guarantees a jar file exists at a particular location nor verifies
+  whether the given class is actually contained in the jar file.
+</Callout>
+
+### Dynamic Unloading
+
+#### Using HBase Shell
+
+1. Alter the table to remove the coprocessor with \`table_att_unset\`.
+
+   \`\`\`ruby
+   hbase> alter 'users', METHOD => 'table_att_unset', NAME => 'coprocessor$1'
+   \`\`\`
+
+2. Alter the table to remove the coprocessor with \`table_remove_coprocessor\` introduced in
+   [HBASE-26524](https://issues.apache.org/jira/browse/HBASE-26524) by specifying an explicit
+   classname
+
+   \`\`\`ruby
+   hbase> alter 'users', METHOD => 'table_remove_coprocessor', CLASSNAME => \\
+       'org.myname.hbase.Coprocessor.RegionObserverExample'
+   \`\`\`
+
+#### Using the Java API
+
+Reload the table definition without setting the value of the coprocessor either by
+using \`setValue()\` or \`addCoprocessor()\` methods. This will remove any coprocessor
+attached to the table.
+
+\`\`\`java
+TableName tableName = TableName.valueOf("users");
+String path = "hdfs://<namenode>:<port>/user/<hadoop-user>/coprocessor.jar";
+Configuration conf = HBaseConfiguration.create();
+Connection connection = ConnectionFactory.createConnection(conf);
+Admin admin = connection.getAdmin();
+HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
+HColumnDescriptor columnFamily1 = new HColumnDescriptor("personalDet");
+columnFamily1.setMaxVersions(3);
+hTableDescriptor.addFamily(columnFamily1);
+HColumnDescriptor columnFamily2 = new HColumnDescriptor("salaryDet");
+columnFamily2.setMaxVersions(3);
+hTableDescriptor.addFamily(columnFamily2);
+admin.modifyTable(tableName, hTableDescriptor);
+\`\`\`
+
+In HBase 0.96 and newer, you can instead use the \`removeCoprocessor()\` method of the
+\`HTableDescriptor\` class.
+
+## Examples
+
+HBase ships examples for Observer Coprocessor.
+
+A more detailed example is given below.
+
+These examples assume a table called \`users\`, which has two column families \`personalDet\`
+and \`salaryDet\`, containing personal and salary details. Below is the graphical representation
+of the \`users\` table.
+
+**Users Table**
+
+|            | **personalDet** |              |            | **salaryDet** |         |                |
+| ---------- | --------------- | ------------ | ---------- | ------------- | ------- | -------------- |
+| **rowkey** | **name**        | **lastname** | **dob**    | **gross**     | **net** | **allowances** |
+| admin      | Admin           | Admin        |            |               |         |                |
+| cdickens   | Charles         | Dickens      | 02/07/1812 | 10000         | 8000    | 2000           |
+| jverne     | Jules           | Verne        | 02/08/1828 | 12000         | 9000    | 3000           |
+
+### Observer Example
+
+The following Observer coprocessor prevents the details of the user \`admin\` from being
+returned in a \`Get\` or \`Scan\` of the \`users\` table.
+
+1. Write a class that implements the
+   [RegionCoprocessor](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionCoprocessor.html),
+   [RegionObserver](https://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/coprocessor/RegionObserver.html)
+   class.
+2. Override the \`preGetOp()\` method (the \`preGet()\` method is deprecated) to check
+   whether the client has queried for the rowkey with value \`admin\`. If so, return an
+   empty result. Otherwise, process the request as normal.
+3. Put your code and dependencies in a JAR file.
+4. Place the JAR in HDFS where HBase can locate it.
+5. Load the Coprocessor.
+6. Write a simple program to test it.
+
+Following are the implementation of the above steps:
+
+\`\`\`java
+public class RegionObserverExample implements RegionCoprocessor, RegionObserver {
+
+    private static final byte[] ADMIN = Bytes.toBytes("admin");
+    private static final byte[] COLUMN_FAMILY = Bytes.toBytes("details");
+    private static final byte[] COLUMN = Bytes.toBytes("Admin_det");
+    private static final byte[] VALUE = Bytes.toBytes("You can't see Admin details");
+
+    @Override
+    public Optional<RegionObserver> getRegionObserver() {
+      return Optional.of(this);
+    }
+
+    @Override
+    public void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> e, final Get get, final List<Cell> results)
+    throws IOException {
+
+        if (Bytes.equals(get.getRow(),ADMIN)) {
+            Cell c = CellUtil.createCell(get.getRow(),COLUMN_FAMILY, COLUMN,
+            System.currentTimeMillis(), (byte)4, VALUE);
+            results.add(c);
+            e.bypass();
+        }
+    }
+}
+\`\`\`
+
+Overriding the \`preGetOp()\` will only work for \`Get\` operations. You also need to override
+the \`preScannerOpen()\` method to filter the \`admin\` row from scan results.
+
+\`\`\`java
+@Override
+public RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> e, final Scan scan,
+final RegionScanner s) throws IOException {
+
+    Filter filter = new RowFilter(CompareOp.NOT_EQUAL, new BinaryComparator(ADMIN));
+    scan.setFilter(filter);
+    return s;
+}
+\`\`\`
+
+This method works but there is a *side effect*. If the client has used a filter in
+its scan, that filter will be replaced by this filter. Instead, you can explicitly
+remove any \`admin\` results from the scan:
+
+\`\`\`java
+@Override
+public boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> e, final InternalScanner s,
+final List<Result> results, final int limit, final boolean hasMore) throws IOException {
+        Result result = null;
+    Iterator<Result> iterator = results.iterator();
+    while (iterator.hasNext()) {
+    result = iterator.next();
+        if (Bytes.equals(result.getRow(), ROWKEY)) {
+            iterator.remove();
+            break;
+        }
+    }
+    return hasMore;
+}
+\`\`\`
+
+### Endpoint Example
+
+Still using the \`users\` table, this example implements a coprocessor to calculate
+the sum of all employee salaries, using an endpoint coprocessor.
+
+1. Create a '.proto' file defining your service.
+
+   \`\`\`protobuf
+   option java_package = "org.myname.hbase.coprocessor.autogenerated";
+   option java_outer_classname = "Sum";
+   option java_generic_services = true;
+   option java_generate_equals_and_hash = true;
+   option optimize_for = SPEED;
+   message SumRequest {
+       required string family = 1;
+       required string column = 2;
+   }
+
+   message SumResponse {
+   required int64 sum = 1 [default = 0];
+   }
+
+   service SumService {
+   rpc getSum(SumRequest)
+       returns (SumResponse);
+   }
+   \`\`\`
+
+2. Execute the \`protoc\` command to generate the Java code from the above .proto' file.
+
+   \`\`\`bash
+   $ mkdir src
+   $ protoc --java_out=src ./sum.proto
+   \`\`\`
+
+   This will generate a class call \`Sum.java\`.
+
+3. Write a class that extends the generated service class, implement the \`Coprocessor\`
+   and \`CoprocessorService\` classes, and override the service method.
+
+   <Callout type="warn">
+     If you load a coprocessor from \`hbase-site.xml\` and then load the same coprocessor
+     again using HBase Shell, it will be loaded a second time. The same class will
+     exist twice, and the second instance will have a higher ID (and thus a lower priority).
+     The effect is that the duplicate coprocessor is effectively ignored.
+   </Callout>
+
+   \`\`\`java
+   public class SumEndPoint extends Sum.SumService implements Coprocessor, CoprocessorService {
+
+       private RegionCoprocessorEnvironment env;
+
+       @Override
+       public Service getService() {
+           return this;
+       }
+
+       @Override
+       public void start(CoprocessorEnvironment env) throws IOException {
+           if (env instanceof RegionCoprocessorEnvironment) {
+               this.env = (RegionCoprocessorEnvironment)env;
+           } else {
+               throw new CoprocessorException("Must be loaded on a table region!");
+           }
+       }
+
+       @Override
+       public void stop(CoprocessorEnvironment env) throws IOException {
+           // do nothing
+       }
+
+       @Override
+       public void getSum(RpcController controller, Sum.SumRequest request, RpcCallback<Sum.SumResponse> done) {
+           Scan scan = new Scan();
+           scan.addFamily(Bytes.toBytes(request.getFamily()));
+           scan.addColumn(Bytes.toBytes(request.getFamily()), Bytes.toBytes(request.getColumn()));
+
+           Sum.SumResponse response = null;
+           InternalScanner scanner = null;
+
+           try {
+               scanner = env.getRegion().getScanner(scan);
+               List<Cell> results = new ArrayList<>();
+               boolean hasMore = false;
+               long sum = 0L;
+
+               do {
+                   hasMore = scanner.next(results);
+                   for (Cell cell : results) {
+                       sum = sum + Bytes.toLong(CellUtil.cloneValue(cell));
+                   }
+                   results.clear();
+               } while (hasMore);
+
+               response = Sum.SumResponse.newBuilder().setSum(sum).build();
+           } catch (IOException ioe) {
+               ResponseConverter.setControllerException(controller, ioe);
+           } finally {
+               if (scanner != null) {
+                   try {
+                       scanner.close();
+                   } catch (IOException ignored) {}
+               }
+           }
+
+           done.run(response);
+       }
+   }
+   \`\`\`
+
+   \`\`\`java
+   Configuration conf = HBaseConfiguration.create();
+   Connection connection = ConnectionFactory.createConnection(conf);
+   TableName tableName = TableName.valueOf("users");
+   Table table = connection.getTable(tableName);
+
+   final Sum.SumRequest request = Sum.SumRequest.newBuilder().setFamily("salaryDet").setColumn("gross").build();
+   try {
+       Map<byte[], Long> results = table.coprocessorService(
+           Sum.SumService.class,
+           null,  /* start key */
+           null,  /* end   key */
+           new Batch.Call<Sum.SumService, Long>() {
+               @Override
+               public Long call(Sum.SumService aggregate) throws IOException {
+                   BlockingRpcCallback<Sum.SumResponse> rpcCallback = new BlockingRpcCallback<>();
+                   aggregate.getSum(null, request, rpcCallback);
+                   Sum.SumResponse response = rpcCallback.get();
+
+                   return response.hasSum() ? response.getSum() : 0L;
+               }
+           }
+       );
+
+       for (Long sum : results.values()) {
+           System.out.println("Sum = " + sum);
+       }
+   } catch (ServiceException e) {
+       e.printStackTrace();
+   } catch (Throwable e) {
+       e.printStackTrace();
+   }
+   \`\`\`
+
+4. Load the Coprocessor.
+
+5. Write a client code to call the Coprocessor.
+
+## Guidelines For Deploying A Coprocessor
+
+**Bundling Coprocessors**\\
+You can bundle all classes for a coprocessor into a
+single JAR on the RegionServer's classpath, for easy deployment. Otherwise,
+place all dependencies on the RegionServer's classpath so that they can be
+loaded during RegionServer start-up. The classpath for a RegionServer is set
+in the RegionServer's \`hbase-env.sh\` file.
+
+**Automating Deployment**\\
+You can use a tool such as Puppet, Chef, or
+Ansible to ship the JAR for the coprocessor to the required location on your
+RegionServers' filesystems and restart each RegionServer, to automate
+coprocessor deployment. Details for such set-ups are out of scope of this
+document.
+
+**Updating a Coprocessor**\\
+Deploying a new version of a given coprocessor is not as simple as disabling it,
+replacing the JAR, and re-enabling the coprocessor. This is because you cannot
+reload a class in a JVM unless you delete all the current references to it.
+Since the current JVM has reference to the existing coprocessor, you must restart
+the JVM, by restarting the RegionServer, in order to replace it. This behavior
+is not expected to change.
+
+**Coprocessor Logging**\\
+The Coprocessor framework does not provide an API for logging beyond standard Java
+logging.
+
+**Coprocessor Configuration**\\
+If you do not want to load coprocessors from the HBase Shell, you can add their configuration
+properties to \`hbase-site.xml\`. In [Using HBase Shell](/docs/cp#using-hbase-shell), two arguments are
+set: \`arg1=1,arg2=2\`. These could have been added to \`hbase-site.xml\` as follows:
+
+\`\`\`xml
+<property>
+  <name>arg1</name>
+  <value>1</value>
+</property>
+<property>
+  <name>arg2</name>
+  <value>2</value>
+</property>
+\`\`\`
+
+Then you can read the configuration using code like the following:
+
+\`\`\`java
+Configuration conf = HBaseConfiguration.create();
+Connection connection = ConnectionFactory.createConnection(conf);
+TableName tableName = TableName.valueOf("users");
+Table table = connection.getTable(tableName);
+
+Get get = new Get(Bytes.toBytes("admin"));
+Result result = table.get(get);
+for (Cell c : result.rawCells()) {
+    System.out.println(Bytes.toString(CellUtil.cloneRow(c))
+        + "==> " + Bytes.toString(CellUtil.cloneFamily(c))
+        + "{" + Bytes.toString(CellUtil.cloneQualifier(c))
+        + ":" + Bytes.toLong(CellUtil.cloneValue(c)) + "}");
+}
+Scan scan = new Scan();
+ResultScanner scanner = table.getScanner(scan);
+for (Result res : scanner) {
+    for (Cell c : res.rawCells()) {
+        System.out.println(Bytes.toString(CellUtil.cloneRow(c))
+        + " ==> " + Bytes.toString(CellUtil.cloneFamily(c))
+        + " {" + Bytes.toString(CellUtil.cloneQualifier(c))
+        + ":" + Bytes.toLong(CellUtil.cloneValue(c))
+        + "}");
+    }
+}
+\`\`\`
+
+## Restricting Coprocessor Usage
+
+Restricting arbitrary user coprocessors can be a big concern in multitenant environments. HBase provides a continuum of options for ensuring only expected coprocessors are running:
+
+* \`hbase.coprocessor.enabled\`: Enables or disables all coprocessors. This will limit the functionality of HBase, as disabling all coprocessors will disable some security providers. An example coproccessor so affected is \`org.apache.hadoop.hbase.security.access.AccessController\`.
+  * \`hbase.coprocessor.user.enabled\`: Enables or disables loading coprocessors on tables (i.e. user coprocessors).
+  * One can statically load coprocessors, and optionally tune their priorities, via the following tunables in \`hbase-site.xml\`:
+    * \`hbase.coprocessor.regionserver.classes\`: A comma-separated list of coprocessors that are loaded by region servers
+    * \`hbase.coprocessor.region.classes\`: A comma-separated list of RegionObserver and Endpoint coprocessors
+    * \`hbase.coprocessor.user.region.classes\`: A comma-separated list of coprocessors that are loaded by all regions
+    * \`hbase.coprocessor.master.classes\`: A comma-separated list of coprocessors that are loaded by the master (MasterObserver coprocessors)
+    * \`hbase.coprocessor.wal.classes\`: A comma-separated list of WALObserver coprocessors to load
+  * \`hbase.coprocessor.abortonerror\`: Whether to abort the daemon which has loaded the coprocessor if the coprocessor should error other than \`IOError\`. If this is set to false and an access controller coprocessor should have a fatal error the coprocessor will be circumvented, as such in secure installations this is advised to be \`true\`; however, one may override this on a per-table basis for user coprocessors, to ensure they do not abort their running region server and are instead [...]
+  * \`hbase.coprocessor.region.whitelist.paths\`: A comma separated list available for those loading \`org.apache.hadoop.hbase.security.access.CoprocessorWhitelistMasterObserver\` whereby one can use the following options to white-list paths from which coprocessors may be loaded.
+    * Coprocessors on the classpath are implicitly white-listed
+    * \`*\` to wildcard all coprocessor paths
+    * An entire filesystem (e.g. \`hdfs://my-cluster/\`)
+    * A wildcard path to be evaluated by [FilenameUtils.wildcardMatch](https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/FilenameUtils.html)
+    * Note: Path can specify scheme or not (e.g. \`file:///usr/hbase/lib/coprocessors\` or for all filesystems \`/usr/hbase/lib/coprocessors\`)
+`,t={title:"Apache HBase Coprocessors",description:"The coprocessor framework provides mechanisms for running your custom code directly on the RegionServers managing your data."},o=[{href:"http://research.google.com/people/jeff/SOCC2010-keynote-slides.pdf"},{href:"https://issues.apache.org/jira/browse/HBASE-4047"},{href:"https://blogs.apache.org/hbase/entry/coprocessor_introduction"},{href:"http://www.3pillarglobal.com/insights/hbase-coprocessors"},{href:"https://issues.apache.org/jira/b [...]
+(http://research.google.com/people/jeff/SOCC2010-keynote-slides.pdf pages 41-42.).
+Efforts are ongoing to bridge gaps between HBase's
+implementation and BigTable's architecture. For more information see
+HBASE-4047.`},{heading:void 0,content:`The information in this chapter is primarily sourced and heavily reused from the following
+resources:`},{heading:void 0,content:`Mingjie Lai's blog post
+Coprocessor Introduction.`},{heading:void 0,content:`Gaurav Bhardwaj's blog post
+The How To Of HBase Coprocessors.`},{heading:void 0,content:"type: warn"},{heading:void 0,content:"title: Use Coprocessors At Your Own Risk"},{heading:void 0,content:`Coprocessors are an advanced feature of HBase and are intended to be used by system
+developers only. Because coprocessor code runs directly on the RegionServer and has
+direct access to your data, they introduce the risk of data corruption, man-in-the-middle
+attacks, or other malicious data access. Currently, there is no mechanism to prevent
+data corruption by coprocessors, though work is underway on
+HBASE-4047.`},{heading:void 0,content:`In addition, there is no resource isolation, so a well-intentioned but misbehaving
+coprocessor can severely degrade cluster performance and stability.`},{heading:"coprocessor-overview",content:`In HBase, you fetch data using a Get or Scan, whereas in an RDBMS you use a SQL
+query. In order to fetch only the relevant data, you filter it using a HBase
+Filter
+, whereas in an RDBMS you use a WHERE predicate.`},{heading:"coprocessor-overview",content:`After fetching the data, you perform computations on it. This paradigm works well
+for "small data" with a few thousand rows and several columns. However, when you scale
+to billions of rows and millions of columns, moving large amounts of data across your
+network will create bottlenecks at the network layer, and the client needs to be powerful
+enough and have enough memory to handle the large amounts of data and the computations.
+In addition, the client code can grow large and complex.`},{heading:"coprocessor-overview",content:`In this scenario, coprocessors might make sense. You can put the business computation
+code into a coprocessor which runs on the RegionServer, in the same location as the
+data, and returns the result to the client.`},{heading:"coprocessor-overview",content:`This is only one scenario where using coprocessors can provide benefit. Following
+are some analogies which may help to explain some of the benefits of coprocessors.`},{heading:"coprocessor-analogies",content:`Triggers and Stored ProcedureAn Observer coprocessor is similar to a trigger in a RDBMS in that it executes
+your code either before or after a specific event (such as a Get or Put)
+occurs. An endpoint coprocessor is similar to a stored procedure in a RDBMS
+because it allows you to perform custom computations on the data on the
+RegionServer itself, rather than on the client.`},{heading:"coprocessor-analogies",content:`MapReduceMapReduce operates on the principle of moving the computation to the location of
+the data. Coprocessors operate on the same principal.`},{heading:"coprocessor-analogies",content:`AOPIf you are familiar with Aspect Oriented Programming (AOP), you can think of a coprocessor
+as applying advice by intercepting a request and then running some custom code,
+before passing the request on to its final destination (or even changing the destination).`},{heading:"coprocessor-implementation-overview",content:`Your class should implement one of the Coprocessor interfaces -
+Coprocessor,
+RegionObserver,
+CoprocessorService - to name a few.`},{heading:"coprocessor-implementation-overview",content:`Load the coprocessor, either statically (from the configuration) or dynamically,
+using HBase Shell. For more details see Loading Coprocessors.`},{heading:"coprocessor-implementation-overview",content:`Call the coprocessor from your client-side code. HBase handles the coprocessor
+transparently.`},{heading:"coprocessor-implementation-overview",content:`The framework API is provided in the
+coprocessor
+package.`},{heading:"observer-coprocessors",content:`Observer coprocessors are triggered either before or after a specific event occurs.
+Observers that happen before an event use methods that start with a pre prefix,
+such as prePut. Observers that happen just after an event override methods that start
+with a post prefix, such as postPut.`},{heading:"use-cases-for-observer-coprocessors",content:`SecurityBefore performing a Get or Put operation, you can check for permission using
+preGet or prePut methods.`},{heading:"use-cases-for-observer-coprocessors",content:`Referential IntegrityHBase does not directly support the RDBMS concept of refential integrity, also known
+as foreign keys. You can use a coprocessor to enforce such integrity. For instance,
+if you have a business rule that every insert to the users table must be followed
+by a corresponding entry in the user_daily_attendance table, you could implement
+a coprocessor to use the prePut method on user to insert a record into user_daily_attendance.`},{heading:"use-cases-for-observer-coprocessors",content:`Secondary IndexesYou can use a coprocessor to maintain secondary indexes. For more information, see
+SecondaryIndexing.`},{heading:"types-of-observer-coprocessor",content:`RegionObserverA RegionObserver coprocessor allows you to observe events on a region, such as Get
+and Put operations. See
+RegionObserver.`},{heading:"types-of-observer-coprocessor",content:`RegionServerObserverA RegionServerObserver allows you to observe events related to the RegionServer's
+operation, such as starting, stopping, or performing merges, commits, or rollbacks.
+See
+RegionServerObserver.`},{heading:"types-of-observer-coprocessor",content:`MasterObserverA MasterObserver allows you to observe events related to the HBase Master, such
+as table creation, deletion, or schema modification. See
+MasterObserver.`},{heading:"types-of-observer-coprocessor",content:`WalObserverA WalObserver allows you to observe events related to writes to the Write-Ahead
+Log (WAL). See
+WALObserver.`},{heading:"types-of-observer-coprocessor",content:"Examples provides working examples of observer coprocessors."},{heading:"endpoint-coprocessor",content:`Endpoint processors allow you to perform computation at the location of the data.
+See Coprocessor Analogy. An example is the need to calculate a running
+average or summation for an entire table which spans hundreds of regions.`},{heading:"endpoint-coprocessor",content:`In contrast to observer coprocessors, where your code is run transparently, endpoint
+coprocessors must be explicitly invoked using the
+CoprocessorService()
+method available in
+AsyncTable.`},{heading:"endpoint-coprocessor",content:"type: warn"},{heading:"endpoint-coprocessor",content:"title: On using coprocessorService method with sync client"},{heading:"endpoint-coprocessor",content:`The coprocessorService method in Table
+has been deprecated.`},{heading:"endpoint-coprocessor",content:`In HBASE-21512
+we reimplement the sync client based on the async client. The coprocessorService
+method defined in Table interface directly references a method from protobuf's
+BlockingInterface, which means we need to use a separate thread pool to execute
+the method so we avoid blocking the async client(We want to avoid blocking calls in
+our async implementation).`},{heading:"endpoint-coprocessor",content:`Since coprocessor is an advanced feature, we believe it is OK for coprocessor users to
+instead switch over to use AsyncTable. There is a lightweight
+toAsyncConnection
+method to get an AsyncConnection from Connection if needed.`},{heading:"endpoint-coprocessor",content:`Starting with HBase 0.96, endpoint coprocessors are implemented using Google Protocol
+Buffers (protobuf). For more details on protobuf, see Google's
+Protocol Buffer Guide.
+Endpoints Coprocessor written in version 0.94 are not compatible with version 0.96 or later.
+See
+HBASE-5448). To upgrade your
+HBase cluster from 0.94 or earlier to 0.96 or later, you need to reimplement your
+coprocessor.`},{heading:"endpoint-coprocessor",content:`In HBase 2.x, we made use of a shaded version of protobuf 3.x, but kept the
+protobuf for coprocessors on 2.5.0. In HBase 3.0.0, we removed all dependencies on
+non-shaded protobuf so you need to reimplement your coprocessor to make use of the
+shaded protobuf version provided in hbase-thirdparty. Please see
+the protobuf section for more details.`},{heading:"endpoint-coprocessor",content:`Coprocessor Endpoints should make no use of HBase internals and
+only avail of public APIs; ideally a CPEP should depend on Interfaces
+and data structures only. This is not always possible but beware
+that doing so makes the Endpoint brittle, liable to breakage as HBase
+internals evolve. HBase internal APIs annotated as private or evolving
+do not have to respect semantic versioning rules or general java rules on
+deprecation before removal. While generated protobuf files are
+absent the hbase audience annotations โ€” they are created by the
+protobuf protoc tool which knows nothing of how HBase works โ€”
+they should be consided @InterfaceAudience.Private so are liable to
+change.`},{heading:"endpoint-coprocessor",content:"Examples provides working examples of endpoint coprocessors."},{heading:"loading-coprocessors",content:`To make your coprocessor available to HBase, it must be loaded, either statically
+(through the HBase configuration) or dynamically (using HBase Shell or the Java API).`},{heading:"static-loading",content:`Follow these steps to statically load your coprocessor. Keep in mind that you must
+restart HBase to unload a coprocessor that has been loaded statically.`},{heading:"static-loading",content:`Define the Coprocessor in hbase-site.xml, with a <property> element with a <name>
+and a <value> sub-element. The <name> should be one of the following:`},{heading:"static-loading",content:"hbase.coprocessor.region.classes for RegionObservers and Endpoints."},{heading:"static-loading",content:"hbase.coprocessor.wal.classes for WALObservers."},{heading:"static-loading",content:"hbase.coprocessor.master.classes for MasterObservers."},{heading:"static-loading",content:`<value> must contain the fully-qualified class name of your coprocessor's implementation
+class.`},{heading:"static-loading",content:`For example to load a Coprocessor (implemented in class SumEndPoint.java) you have to create
+following entry in RegionServer's 'hbase-site.xml' file (generally located under 'conf' directory):`},{heading:"static-loading",content:`If multiple classes are specified for loading, the class names must be comma-separated.
+The framework attempts to load all the configured classes using the default class loader.
+Therefore, the jar file must reside on the server-side HBase classpath.`},{heading:"static-loading",content:`Coprocessors which are loaded in this way will be active on all regions of all tables.
+These are also called system Coprocessor.
+The first listed Coprocessors will be assigned the priority Coprocessor.Priority.SYSTEM.
+Each subsequent coprocessor in the list will have its priority value incremented by one (which
+reduces its priority, because priorities have the natural sort order of Integers).`},{heading:"static-loading",content:`These priority values can be manually overriden in hbase-site.xml. This can be useful if you
+want to guarantee that a coprocessor will execute after another. For example, in the following
+configuration SumEndPoint would be guaranteed to go last, except in the case of a tie with
+another coprocessor:`},{heading:"static-loading",content:`When calling out to registered observers, the framework executes their callbacks methods in the
+sorted order of their priority.
+Ties are broken arbitrarily.`},{heading:"static-loading",content:`Put your code on HBase's classpath. One easy way to do this is to drop the jar
+(containing you code and all the dependencies) into the lib/ directory in the
+HBase installation.`},{heading:"static-loading",content:"Restart HBase."},{heading:"static-unloading",content:"Delete the coprocessor's <property> element, including sub-elements, from hbase-site.xml."},{heading:"static-unloading",content:"Restart HBase."},{heading:"static-unloading",content:`Optionally, remove the coprocessor's JAR file from the classpath or HBase's lib/
+directory.`},{heading:"dynamic-loading",content:`You can also load a coprocessor dynamically, without restarting HBase. This may seem
+preferable to static loading, but dynamically loaded coprocessors are loaded on a
+per-table basis, and are only available to the table for which they were loaded. For
+this reason, dynamically loaded tables are sometimes called Table Coprocessor.`},{heading:"dynamic-loading",content:`In addition, dynamically loading a coprocessor acts as a schema change on the table,
+and the table must be taken offline to load the coprocessor.`},{heading:"dynamic-loading",content:"There are three ways to dynamically load Coprocessor."},{heading:"dynamic-loading",content:"type: info"},{heading:"dynamic-loading",content:"title: Assumptions"},{heading:"dynamic-loading",content:"The below mentioned instructions makes the following assumptions:"},{heading:"dynamic-loading",content:`A JAR called coprocessor.jar contains the Coprocessor implementation along with all of its
+dependencies.`},{heading:"dynamic-loading",content:`The JAR is available in HDFS in some location like
+hdfs://NAMENODE:PORT/user/HADOOP_USER/coprocessor.jar.`},{heading:"using-hbase-shell",content:"Load the Coprocessor, using a command like the following:"},{heading:"using-hbase-shell",content:`The Coprocessor framework will try to read the class information from the coprocessor table
+attribute value.
+The value contains four pieces of information which are separated by the pipe (|) character.`},{heading:"using-hbase-shell",content:`File path: The jar file containing the Coprocessor implementation must be in a location where
+all region servers can read it.
+You could copy the file onto the local disk on each region server, but it is recommended to store
+it in HDFS.
+HBASE-14548 allows a directory containing the jars
+or some wildcards to be specified, such as: hdfs://NAMENODE:PORT/user/HADOOP_USER/ or
+hdfs://NAMENODE:PORT/user/HADOOP_USER/*.jar. Please note that if a directory is specified,
+all jar files(.jar) in the directory are added. It does not search for files in sub-directories.
+Do not use a wildcard if you would like to specify a directory. This enhancement applies to the
+usage via the JAVA API as well.`},{heading:"using-hbase-shell",content:"Class name: The full class name of the Coprocessor."},{heading:"using-hbase-shell",content:`Priority: An integer. The framework will determine the execution sequence of all configured
... 204309 lines suppressed ...