未验证 提交 d9e112ac 编写于 作者: C chaow 提交者: GitHub

Merge pull request #1 from apachecn/master

update
......@@ -49,16 +49,20 @@
然后回复 ISSUE,注明“章节 + QQ 号”(一定要留 QQ)。
### 二、翻译
### 二、校对
可以合理利用翻译引擎(例如[谷歌](https://translate.google.cn/)),但一定要把它变得可读!
需要校对:
如果遇到格式问题,请随手把它改正。
1. 语法
2. 术语使用
3. 文档格式
原文在`docs/en/`中,文件名相同。如果觉得现有翻译不好,重新翻译也是可以的。
### 三、提交
+ `fork` Github 项目
+ 将译文放在`docs`文件夹下
+ 修改`docs`中的文档。
+ `push`
+ `pull request`
......
# 前言
> 者:[xixici](https://github.com/xixici)
> 贡献者:[xixici](https://github.com/xixici)
此处为[HBase](https://hbase.apache.org/)版本的官方参考指南。
从这里,你不仅能找到发布的HBase版本的最终文档,而且包括相关[Javadoc](https://hbase.apache.org/apidocs/index.html)[JIRA](https://issues.apache.org/jira/browse/HBASE)信息。
从这里,你不仅能找到发布的 HBase 版本的最终文档,而且包括相关[Javadoc](https://hbase.apache.org/apidocs/index.html)[JIRA](https://issues.apache.org/jira/browse/HBASE)信息。
## 关于指南
本指南仍在编辑当中。本指南的源码可以在文件夹_src/main/asciidoc当中找到。本指南最终使用 [AsciiDoc](http://asciidoc.org/) 构建,成为'站点'的一部分.
本指南仍在编辑当中。本指南的源码可以在文件夹 _src/main/asciidoc 当中找到。本指南最终使用 [AsciiDoc](http://asciidoc.org/) 构建,成为'站点'的一部分.
运行
......@@ -17,50 +17,50 @@
mvn site
```
来生成此文档。并且欢迎对此进行修改和改进。点击[此链接](https://issues.apache.org/jira/secure/CreateIssueDetails!init.jspa?pid=12310753&issuetype=1&components=12312132&summary=SHORT+DESCRIPTION) 提供bug反馈.
来生成此文档。并且欢迎对此进行修改和改进。点击[此链接](https://issues.apache.org/jira/secure/CreateIssueDetails!init.jspa?pid=12310753&issuetype=1&components=12312132&summary=SHORT+DESCRIPTION) 提供 bug 反馈.
## 文档贡献
有关AsciiDoc的概述以及文档参与的建议,请参阅本文档后面的[相关部分](#appendix_contributing_to_documentation)
有关 AsciiDoc 的概述以及文档参与的建议,请参阅本文档后面的[相关部分](#appendix_contributing_to_documentation)
如果这是你第一次涉足分布式计算领域......
若这是你第一次踏入分布式计算的精彩世界,你会感到这是一个有趣的年代。分布式计算是很难的,做一个分布式系统需要很多软硬件和网络的技能。
你的集群可以会因为各式各样的错误发生故障。比如HBase本身的Bug,错误的配置(包括操作系统),硬件的故障(网卡和磁盘甚至内存)(Issue里有两个最近的硬件问题示例,表现为“HBase很慢”) 如果你一直在写单机程序的话,你需要重新开始学习。这是一个很好的起点[分布式计算的谬论](http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing).
你的集群可以会因为各式各样的错误发生故障。比如 HBase 本身的 Bug,错误的配置(包括操作系统),硬件的故障(网卡和磁盘甚至内存)(Issue 里有两个最近的硬件问题示例,表现为“HBase 很慢”) 如果你一直在写单机程序的话,你需要重新开始学习。这是一个很好的起点[分布式计算的谬论](http://en.wikipedia.org/wiki/Fallacies_of_Distributed_Computing).
所以,欢迎你。
这是一个有趣的地方。
HBase社区。
HBase 社区。
# 报告bugs
# 报告 bugs
请使用 [JIRA](https://issues.apache.org/jira/browse/hbase) 报告与安全无关的错误。
为了保护现有HBase安装免受新漏洞的影响,**请勿**使用JIRA报告与安全相关的错误。 相反,请将您的报告发送到邮件列表[private@hbase.apache.org](mailto:private@hbase.apache.org),该列表允许任何人发送邮件,但限制谁可以阅读邮件。 该列表中的某个人将与您联系以跟进您的报告。
为了保护现有 HBase 安装免受新漏洞的影响,**请勿**使用 JIRA 报告与安全相关的错误。 相反,请将您的报告发送到邮件列表[private@hbase.apache.org](mailto:private@hbase.apache.org),该列表允许任何人发送邮件,但限制谁可以阅读邮件。 该列表中的某个人将与您联系以跟进您的报告。
## 支持和测试
以下短语/支持/,/不支持/,/测试/,和/未测试/经常出现在本指南中。 为方便起见,这里先简要解释了这些短语在HBase背景下的含义
以下短语/支持/,/不支持/,/测试/,和/未测试/经常出现在本指南中。 为方便起见,这里先简要解释了这些短语在 HBase 背景下的含义
>许多Hadoop供应商都提供Apache HBase的商业版本的技术支持。 但这不是在Apache HBase项目中/ 支持 /的意义。 Apache HBase团队对您的HBase集群,配置或数据不承担任何责任。
>许多 Hadoop 供应商都提供 Apache HBase 的商业版本的技术支持。 但这不是在 Apache HBase 项目中/ 支持 /的意义。 Apache HBase 团队对您的 HBase 集群,配置或数据不承担任何责任。
### 支持
Apache HBase中,/ 支持 /意味着HBase被设计为以所描述的方式工作,并且应该将与定义的行为或功能的偏差报告为错误。
Apache HBase 中,/ 支持 /意味着 HBase 被设计为以所描述的方式工作,并且应该将与定义的行为或功能的偏差报告为错误。
### 不支持
Apache HBase中,/不支持/意味着用例或使用模式不会重视,应该被视为反模式。如果您认为应该针对给定功能或使用模式重新考虑,请提交JIRA或通过邮件讨论。
Apache HBase 中,/不支持/意味着用例或使用模式不会重视,应该被视为反模式。如果您认为应该针对给定功能或使用模式重新考虑,请提交 JIRA 或通过邮件讨论。
### 已测试
Apache HBase中,/ 已测试 /意味着单元或集成测试涵盖了一个功能,并且已经证明可以按预期工作。
Apache HBase 中,/ 已测试 /意味着单元或集成测试涵盖了一个功能,并且已经证明可以按预期工作。
### 未测试
在Apache HBase中,/未测试/表示功能或使用模式可能或可能不以给定方式工作,并且可能会也可能不会损坏您的数据或导致操作问题。这是未知的,没有任何保证。如果您可以提供指定为/未经测试/的功能以特定方式工作的证据,请提交测试和指标,以便其他用户可以确定使用有关功能或使用模式。
\ No newline at end of file
在 Apache HBase 中,/未测试/表示功能或使用模式可能或可能不以给定方式工作,并且可能会也可能不会损坏您的数据或导致操作问题。这是未知的,没有任何保证。如果您可以提供指定为/未经测试/的功能以特定方式工作的证据,请提交测试和指标,以便其他用户可以确定使用有关功能或使用模式。
\ No newline at end of file
此差异已折叠。
因为 它太大了无法显示 source diff 。你可以改为 查看blob
# 内存压缩
## 77.概述
# In-memory Compaction
内存压缩(A.K.A Accordion)是 hbase-2.0.0 中的一项新功能。它首先在 [Accordion 的 Apache HBase 博客上推出:HBase 通过内存压缩进行呼吸](https://blogs.apache.org/hbase/entry/accordion-hbase-breathes-with-in)。引用博客:
## 77\. Overview
> Accordion 将 LSM 主体[ _Log-Structured-Merge Tree_ ,HBase 所基于的设计模式]重新应用于 MemStore,以便在数据仍在 RAM 中时消除冗余和其他开销。这样做可以降低冲洗到 HDFS 的频率,从而减少写入放大和整个磁盘占用空间。由于刷新次数较少,因此 MemStore 溢出时写入操作停止的频率降低,因此写入性能得到改善。磁盘上的数据越少,对块缓存的压力越小,命中率越高,最终读取响应时间越长。最后,具有较少的磁盘写入也意味着在后台发生较少的压缩,即,从生产(读取和写入)工作中窃取的循环较少。总而言之,内存压缩的效果可以被设想为催化剂,使系统整体上移动得更快。
In-memory Compaction (A.K.A Accordion) is a new feature in hbase-2.0.0. It was first introduced on the Apache HBase Blog at [Accordion: HBase Breathes with In-Memory Compaction](https://blogs.apache.org/hbase/entry/accordion-hbase-breathes-with-in). Quoting the blog:
开发人员视图可在 [Accordion:内存压缩的开发人员视图](https://blogs.apache.org/hbase/entry/accordion-developer-view-of-in)中找到。
> Accordion reapplies the LSM principal [_Log-Structured-Merge Tree_, the design pattern upon which HBase is based] to MemStore, in order to eliminate redundancies and other overhead while the data is still in RAM. Doing so decreases the frequency of flushes to HDFS, thereby reducing the write amplification and the overall disk footprint. With less flushes, the write operations are stalled less frequently as the MemStore overflows, therefore the write performance is improved. Less data on disk also implies less pressure on the block cache, higher hit rates, and eventually better read response times. Finally, having less disk writes also means having less compaction happening in the background, i.e., less cycles are stolen from productive (read and write) work. All in all, the effect of in-memory compaction can be envisioned as a catalyst that enables the system move faster as a whole.
内存压缩在高数据流失时效果最佳;当数据仍在内存中时,可以消除覆盖或过度版本。如果写入都是唯一的,则可能会拖动写入吞吐量(内存中压缩成本 CPU)。我们建议您在部署到生产之前进行测试和比较。
A developer view is available at [Accordion: Developer View of In-Memory Compaction](https://blogs.apache.org/hbase/entry/accordion-developer-view-of-in).
在本节中,我们将介绍如何启用 Accordion 和可用的配置。
In-memory compaction works best when high data churn; overwrites or over-versions can be eliminated while the data is still in memory. If the writes are all uniques, it may drag write throughput (In-memory compaction costs CPU). We suggest you test and compare before deploying to production.
## 78.启用
In this section we describe how to enable Accordion and the available configurations.
要启用内存中压缩,请在您希望行为的每个列族上设置 _IN_MEMORY _COMPACTION_ 属性。 _IN_MEMORY _COMPACTION_ 属性可以具有四个值之一。
## 78\. Enabling
* _ 无 _:无内存压缩。
To enable in-memory compactions, set the _IN_MEMORY_COMPACTION_ attribute on per column family where you want the behavior. The _IN_MEMORY_COMPACTION_ attribute can have one of four values.
* _BASIC_ :基本策略启用刷新并保持刷新管道,直到我们跳过管道最大阈值,然后我们刷新到磁盘。没有内存中的压缩,但可以帮助提高吞吐量,因为数据从挥霍的原生 ConcurrentSkipListMap 数据类型转移到更紧凑(和高效)的数据类型。
* _NONE_: No in-memory compaction.
* _EAGER_ :这是 _BASIC_ 政策加上内存压缩的冲洗(很像是对 hfiles 进行的盘上压缩);在压缩方面,我们应用磁盘规则来消除版本,重复,ttl'd 单元格等。
* _BASIC_: Basic policy enables flushing and keeps a pipeline of flushes until we trip the pipeline maximum threshold and then we flush to disk. No in-memory compaction but can help throughput as data is moved from the profligate, native ConcurrentSkipListMap data-type to more compact (and efficient) data types.
* _ADAPTIVE_ :自适应压缩适应工作负载。它根据数据中重复单元格的比例应用索引压缩或数据压缩。实验。
* _EAGER_: This is _BASIC_ policy plus in-memory compaction of flushes (much like the on-disk compactions done to hfiles); on compaction we apply on-disk rules eliminating versions, duplicates, ttl’d cells, etc.
* _ADAPTIVE_: Adaptive compaction adapts to the workload. It applies either index compaction or data compaction based on the ratio of duplicate cells in the data. Experimental.
To enable _BASIC_ on the _info_ column family in the table _radish_, disable the table and add the attribute to the _info_ column family, and then reenable:
要在表 _ 萝卜 _ 中的 _info_ 列系列上启用 _BASIC_ ,请禁用该表并将该属性添加到 _info_ 列族,然后重新启用:
```
hbase(main):002:0> disable 'radish'
......@@ -45,25 +43,24 @@ COLUMN FAMILIES DESCRIPTION
1 row(s)
Took 0.0239 seconds
hbase(main):005:0> enable 'radish'
Took 0.7537 seconds
Took 0.7537 seconds
```
Note how the IN_MEMORY_COMPACTION attribute shows as part of the _METADATA_ map.
请注意 IN_MEMORY_COMPACTION 属性如何显示为 _METADATA_ 映射的一部分。
There is also a global configuration, _hbase.hregion.compacting.memstore.type_ which you can set in your _hbase-site.xml_ file. Use it to set the default on creation of a new table (On creation of a column family Store, we look first to the column family configuration looking for the _IN_MEMORY_COMPACTION_ setting, and if none, we then consult the _hbase.hregion.compacting.memstore.type_ value using its content; default is _BASIC_).
还有一个全局配置, _hbase.hregion.compacting.memstore.type_ ,您可以在 _hbase-site.xml_ 文件中设置。使用它来设置创建新表时的默认值(在创建列族存储时,我们首先查看列族配置,查找 _IN_MEMORY _COMPACTION_ 设置,如果没有,我们再咨询 _hbase.hregion.compacting.memstore.type_ 值使用其内容;默认为 _BASIC_ )。
By default, new hbase system tables will have _BASIC_ in-memory compaction set. To specify otherwise, on new table-creation, set _hbase.hregion.compacting.memstore.type_ to _NONE_ (Note, setting this value post-creation of system tables will not have a retroactive effect; you will have to alter your tables to set the in-memory attribute to _NONE_).
默认情况下,新的 hbase 系统表将具有 _BASIC_ 内存中压缩集。为了另外指定,在新的表创建时,将 _hbase.hregion.compacting.memstore.type_ 设置为 _NONE_ (注意,设置此值后创建系统表将不具有追溯效果;您必须更改表格以将内存中属性设置为 _NONE_ )。
When an in-memory flush happens is calculated by dividing the configured region flush size (Set in the table descriptor or read from _hbase.hregion.memstore.flush.size_) by the number of column families and then multiplying by _hbase.memstore.inmemoryflush.threshold.factor_. Default is 0.014.
当内存中的刷新发生时,通过将配置的区域刷新大小(在表描述符中设置或从 _hbase.hregion.memstore.flush.size_ 中读取)除以列族的数量然后相乘来计算 _hbase.memstore.inmemoryflush.threshold.factor_ 。默认值为 0.014。
The number of flushes carried by the pipeline is monitored so as to fit within the bounds of memstore sizing but you can also set a maximum on the number of flushes total by setting _hbase.hregion.compacting.pipeline.segments.limit_. Default is 2.
监视管道所承载的刷新次数,以便符合 memstore 大小调整的范围,但您也可以通过设置 _hbase.hregion.compacting.pipeline.segments.limit 来设置总刷新次数的最大值 _。默认值为 2。
When a column family Store is created, it says what memstore type is in effect. As of this writing there is the old-school _DefaultMemStore_ which fills a _ConcurrentSkipListMap_ and then flushes to disk or the new _CompactingMemStore_ that is the implementation that provides this new in-memory compactions facility. Here is a log-line from a RegionServer that shows a column family Store named _family_ configured to use a _CompactingMemStore_:
创建列族 Store 时,它会说明哪些 memstore 类型有效。在撰写本文时,有一个老派 _DefaultMemStore_ 填充 _ConcurrentSkipListMap_ ,然后刷新到磁盘或新的 _CompactingMemStore_ ,它是提供这个新功能的实现内存中压缩设施。以下是来自 RegionServer 的日志行,该日志行显示了一个名为 _ 系列 _ 的列族存储配置为使用 _CompactingMemStore_ :
```
Note how the IN_MEMORY_COMPACTION attribute shows as part of the _METADATA_ map.
2018-03-30 11:02:24,466 INFO [Time-limited test] regionserver.HStore(325): Store=family, memstore type=CompactingMemStore, storagePolicy=HOT, verifyBulkLoads=false, parallelPutCountPrintThreshold=10
2018-03-30 11:02:24,466 INFO [Time-limited test] regionserver.HStore(325): Store=family, memstore type=CompactingMemStore, storagePolicy=HOT, verifyBulkLoads=false, parallelPutCountPrintThreshold=10
```
Enable TRACE-level logging on the CompactingMemStore class (_org.apache.hadoop.hbase.regionserver.CompactingMemStore_) to see detail on its operation.
在 CompactingMemStore 类( _org.apache.hadoop.hbase.regionserver.CompactingMemStore_ )上启用 TRACE 级别日志记录,以查看其操作的详细信息。
\ No newline at end of file
此差异已折叠。
# 同步复制
## 93.背景
# Synchronous Replication
HBase 中的当前[复制](#_cluster_replication)异步。因此,如果主集群崩溃,则从集群可能没有最新数据。如果用户想要强一致性,那么他们就无法切换到从属群集。
## 93\. Background
## 94.设计
The current [replication](#_cluster_replication) in HBase in asynchronous. So if the master cluster crashes, the slave cluster may not have the newest data. If users want strong consistency then they can not switch to the slave cluster.
请参阅 [HBASE-19064](https://issues.apache.org/jira/browse/HBASE-19064) 上的设计文档
## 94\. Design
## 95.运行和维护
Please see the design doc on [HBASE-19064](https://issues.apache.org/jira/browse/HBASE-19064)
Case.1 设置两个同步复制集群
## 95\. Operation and maintenance
* 在源集群和对等集群中添加同步对等体。
Case.1 Setup two synchronous replication clusters
* Add a synchronous peer in both source cluster and peer cluster.
For source cluster:
对于源群集:
```
hbase> add_peer '1', CLUSTER_KEY => 'lg-hadoop-tst-st01.bj:10010,lg-hadoop-tst-st02.bj:10010,lg-hadoop-tst-st03.bj:10010:/hbase/test-hbase-slave', REMOTE_WAL_DIR=>'hdfs://lg-hadoop-tst-st01.bj:20100/hbase/test-hbase-slave/remoteWALs', TABLE_CFS => {"ycsb-test"=>[]}
hbase> add_peer '1', CLUSTER_KEY => 'lg-hadoop-tst-st01.bj:10010,lg-hadoop-tst-st02.bj:10010,lg-hadoop-tst-st03.bj:10010:/hbase/test-hbase-slave', REMOTE_WAL_DIR=>'hdfs://lg-hadoop-tst-st01.bj:20100/hbase/test-hbase-slave/remoteWALs', TABLE_CFS => {"ycsb-test"=>[]}
```
For peer cluster:
对于对等集群:
```
hbase> add_peer '1', CLUSTER_KEY => 'lg-hadoop-tst-st01.bj:10010,lg-hadoop-tst-st02.bj:10010,lg-hadoop-tst-st03.bj:10010:/hbase/test-hbase', REMOTE_WAL_DIR=>'hdfs://lg-hadoop-tst-st01.bj:20100/hbase/test-hbase/remoteWALs', TABLE_CFS => {"ycsb-test"=>[]}
hbase> add_peer '1', CLUSTER_KEY => 'lg-hadoop-tst-st01.bj:10010,lg-hadoop-tst-st02.bj:10010,lg-hadoop-tst-st03.bj:10010:/hbase/test-hbase', REMOTE_WAL_DIR=>'hdfs://lg-hadoop-tst-st01.bj:20100/hbase/test-hbase/remoteWALs', TABLE_CFS => {"ycsb-test"=>[]}
```
> For synchronous replication, the current implementation require that we have the same peer id for both source and peer cluster. Another thing that need attention is: the peer does not support cluster-level, namespace-level, or cf-level replication, only support table-level replication now.
> 对于同步复制,当前实现要求源和对等集群具有相同的对等 ID。另一件需要注意的事情是:peer 不支持集群级,命名空间级或 cf-level 复制,现在只支持表级复制。
* Transit the peer cluster to be STANDBY state
* 将对等集群转换为 STANDBY 状态
```
hbase> transit_peer_sync_replication_state '1', 'STANDBY'
hbase> transit_peer_sync_replication_state '1', 'STANDBY'
```
* Transit the source cluster to be ACTIVE state
* 将源群集转换为 ACTIVE 状态
```
hbase> transit_peer_sync_replication_state '1', 'ACTIVE'
hbase> transit_peer_sync_replication_state '1', 'ACTIVE'
```
Now, the synchronous replication has been set up successfully. the HBase client can only request to source cluster, if request to peer cluster, the peer cluster which is STANDBY state now will reject the read/write requests.
现在,已成功设置同步复制。 HBase 客户端只能请求源集群,如果请求到对等集群,现在处于 STANDBY 状态的对等集群将拒绝读/写请求。
Case.2 How to operate when standby cluster crashed
Case.2 备用集群崩溃时的操作方法
If the standby cluster has been crashed, it will fail to write remote WAL for the active cluster. So we need to transit the source cluster to DOWNGRANDE_ACTIVE state, which means source cluster won’t write any remote WAL any more, but the normal replication (asynchronous Replication) can still work fine, it queue the newly written WALs, but the replication block until the peer cluster come back.
如果备用群集已崩溃,则无法为活动群集写入远程 WAL。因此我们需要将源集群转移到 DOWNGRANDE_ACTIVE 状态,这意味着源集群将不再编写任何远程 WAL,但正常复制(异步复制)仍然可以正常工作,它会对新写入的 WAL 进行排队,但复制块直到对等集群回来。
```
hbase> transit_peer_sync_replication_state '1', 'DOWNGRADE_ACTIVE'
hbase> transit_peer_sync_replication_state '1', 'DOWNGRADE_ACTIVE'
```
Once the peer cluster come back, we can just transit the source cluster to ACTIVE, to ensure that the replication will be synchronous.
一旦对等集群返回,我们就可以将源集群转移到 ACTIVE,以确保复制是同步的。
```
hbase> transit_peer_sync_replication_state '1', 'ACTIVE'
hbase> transit_peer_sync_replication_state '1', 'ACTIVE'
```
Case.3 How to operate when active cluster crashed
Case.3 当活动集群崩溃时如何操作
If the active cluster has been crashed (it may be not reachable now), so let’s just transit the standby cluster to DOWNGRANDE_ACTIVE state, and after that, we should redirect all the requests from client to the DOWNGRADE_ACTIVE cluster.
如果活动集群已崩溃(现在可能无法访问),那么让我们将备用集群转移到 DOWNGRANDE_ACTIVE 状态,之后,我们应该将所有请求从客户端重定向到 DOWNGRADE_ACTIVE 集群。
```
hbase> transit_peer_sync_replication_state '1', 'DOWNGRADE_ACTIVE'
hbase> transit_peer_sync_replication_state '1', 'DOWNGRADE_ACTIVE'
```
If the crashed cluster come back again, we just need to transit it to STANDBY directly. Otherwise if you transit the cluster to DOWNGRADE_ACTIVE, the original ACTIVE cluster may have redundant data compared to the current ACTIVE cluster. Because we designed to write source cluster WALs and remote cluster WALs concurrently, so it’s possible that the source cluster WALs has more data than the remote cluster, which result in data inconsistency. The procedure of transiting ACTIVE to STANDBY has no problem, because we’ll skip to replay the original WALs.
如果崩溃的集群再次返回,我们只需要将其直接转移到 STANDBY。否则,如果将群集传输到 DOWNGRADE_ACTIVE,则原始 ACTIVE 群集可能具有与当前 ACTIVE 群集相比的冗余数据。因为我们设计同时编写源群集 WAL 和远程群集 WAL,所以源群集 WALs 可能比远程群集具有更多数据,这导致数据不一致。将 ACTIVE 转换为 STANDBY 的过程没有问题,因为我们将跳过重放原始的 WAL。
```
hbase> transit_peer_sync_replication_state '1', 'STANDBY'
hbase> transit_peer_sync_replication_state '1', 'STANDBY'
```
After that, we can promote the DOWNGRADE_ACTIVE cluster to ACTIVE now, to ensure that the replication will be synchronous.
之后,我们现在可以将 DOWNGRADE_ACTIVE 集群提升为 ACTIVE,以确保复制是同步的。
```
hbase> transit_peer_sync_replication_state '1', 'ACTIVE'
```
hbase> transit_peer_sync_replication_state '1', 'ACTIVE'
```
\ No newline at end of file
# Apache HBase APIs
> 者:[xixici](https://github.com/xixici)
> 贡献者:[xixici](https://github.com/xixici)
本章节提供有关使用基础HBase API执行操作的方法。 此方法并非详尽无遗,快速参考 [User API Reference](https://hbase.apache.org/apidocs/index.html)。 此处的示例不全面,仅用于说明目的。
本章节提供有关使用基础 HBase API 执行操作的方法。 此方法并非详尽无遗,快速参考 [User API Reference](https://hbase.apache.org/apidocs/index.html)。 此处的示例不全面,仅用于说明目的。
Apache HBase 也拥有多种外部 APIs. 详见:[Apache HBase External APIs](#external_apis)
## 96\. 例子
Example 25\. 使用Java创建.修改和删除表
Example 25\. 使用 Java 创建.修改和删除表
```
package com.example.hbase.admin;
......
# Apache HBase 外部 APIs
> 者:[xixici](https://github.com/xixici)
> 贡献者:[xixici](https://github.com/xixici)
本章将介绍通过非Java语言和自定义协议访问Apache HBase。 有关使用本机HBase API的信息,请参阅[User API Reference](https://hbase.apache.org/apidocs/index.html) [HBase APIs](#hbase_apis)
本章将介绍通过非 Java 语言和自定义协议访问 Apache HBase。 有关使用本机 HBase API 的信息,请参阅[User API Reference](https://hbase.apache.org/apidocs/index.html) [HBase APIs](#hbase_apis)
## 97\. REST
表述性状态转移Representational State Transfer (REST)于2000年在HTTP规范的主要作者之一Roy Fielding的博士论文中引入。
表述性状态转移 Representational State Transfer (REST)于 2000 年在 HTTP 规范的主要作者之一 Roy Fielding 的博士论文中引入。
REST本身超出了本文档的范围,但通常,REST允许通过与URL本身绑定的API进行客户端 - 服务器交互。 本节讨论如何配置和运行HBase附带的REST服务器,该服务器将HBase表,行,单元和元数据公开为URL指定的资源。 还有一系列关于如何使用Jesse Anderson的Apache HBase REST接口的博客 [How-to: Use the Apache HBase REST Interface](http://blog.cloudera.com/blog/2013/03/how-to-use-the-apache-hbase-rest-interface-part-1/)
REST 本身超出了本文档的范围,但通常,REST 允许通过与 URL 本身绑定的 API 进行客户端 - 服务器交互。 本节讨论如何配置和运行 HBase 附带的 REST 服务器,该服务器将 HBase 表,行,单元和元数据公开为 URL 指定的资源。 还有一系列关于如何使用 Jesse Anderson 的 Apache HBase REST 接口的博客 [How-to: Use the Apache HBase REST Interface](http://blog.cloudera.com/blog/2013/03/how-to-use-the-apache-hbase-rest-interface-part-1/)
### 97.1\. 启动和停止REST服务
### 97.1\. 启动和停止 REST 服务
包含的REST服务器可以作为守护程序运行,该守护程序启动嵌入式Jetty servlet容器并将servlet部署到其中。 使用以下命令之一在前台或后台启动REST服务器。 端口是可选的,默认为8080。
包含的 REST 服务器可以作为守护程序运行,该守护程序启动嵌入式 Jetty servlet 容器并将 servlet 部署到其中。 使用以下命令之一在前台或后台启动 REST 服务器。 端口是可选的,默认为 8080。
```
# Foreground
......@@ -22,28 +22,28 @@ $ bin/hbase rest start -p <port>
$ bin/hbase-daemon.sh start rest -p <port>
```
要停止REST服务器,请在前台运行时使用Ctrl-C,如果在后台运行则使用以下命令。
要停止 REST 服务器,请在前台运行时使用 Ctrl-C,如果在后台运行则使用以下命令。
```
$ bin/hbase-daemon.sh stop rest
```
### 97.2\. 配置REST服务器和客户端
### 97.2\. 配置 REST 服务器和客户端
有关为SSL配置REST服务器和客户端以及为REST服务器配置`doAs` 模拟的信息,请参阅[配置Thrift网关以代表客户端进行身份验证](#security.gateway.thrift)以及 [Securing Apache HBase](#security)
有关为 SSL 配置 REST 服务器和客户端以及为 REST 服务器配置`doAs` 模拟的信息,请参阅[配置 Thrift 网关以代表客户端进行身份验证](#security.gateway.thrift)以及 [Securing Apache HBase](#security)
### 97.3\. 使用REST
### 97.3\. 使用 REST
以下示例使用占位符服务器http://example.com:8000,并且可以使用`curl``wget`命令运行以下命令。您可以通过不为纯文本添加头信息来请求纯文本(默认),XML或JSON输出,或者为XML添加头信息“Accept:text / xml”,为JSON添加“Accept:application / json”或为协议缓冲区添加“Accept: application/x-protobuf”。
以下示例使用占位符服务器 http://example.com:8000,并且可以使用`curl``wget`命令运行以下命令。您可以通过不为纯文本添加头信息来请求纯文本(默认),XML 或 JSON 输出,或者为 XML 添加头信息“Accept:text / xml”,为 JSON 添加“Accept:application / json”或为协议缓冲区添加“Accept: application/x-protobuf”。
>
> 除非指定,否则使用`GET`请求进行查询,`PUT`或`POST`请求进行创建或修改,`DELETE`用于删除。
| 端口 | HTTP 名词 | 描述 | 示例 |
| :----------------- | :-------- | :------------------ | :----------------------------------------------------------- |
| `/version/cluster` | `GET` | 集群上运行HBase版本 | ``` curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/version/cluster"``` |
| `/version/cluster` | `GET` | 集群上运行 HBase 版本 | ``` curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/version/cluster"``` |
| `/status/cluster` | `GET` | 集群状态 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/status/cluster"``` |
| `/` | `GET` | 列出所有非系统表格 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/"``` |
......@@ -66,21 +66,21 @@ $ bin/hbase-daemon.sh stop rest
| 端口 | HTTP 名词 | 描述 | 示例 |
| ----------------------------------------------------------- | --------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `/_table_/_row_` | `GET` | 获取单行的所有列。值为Base-64编码。这需要“Accept”请求标头,其类型可以包含多个列 (like xml, json or protobuf). | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1"``` |
| `/_table_/_row_/_column:qualifier_/_timestamp_` | `GET` | 获取单个列的值。值为Base-64编码。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a/1458586888395"``` |
| `/_table_/_row_/_column:qualifier_` | `GET` | 获取单个列的值。值为Base-64编码。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a" 或者 curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a/"``` |
| `/_table_/_row_/_column:qualifier_/?v=_number_of_versions_` | `GET` | 获取指定单元格的指定版本数. 获取单个列的值。值为Base-64编码。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a?v=2"``` |
| `/_table_/_row_` | `GET` | 获取单行的所有列。值为 Base-64 编码。这需要“Accept”请求标头,其类型可以包含多个列 (like xml, json or protobuf). | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1"``` |
| `/_table_/_row_/_column:qualifier_/_timestamp_` | `GET` | 获取单个列的值。值为 Base-64 编码。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a/1458586888395"``` |
| `/_table_/_row_/_column:qualifier_` | `GET` | 获取单个列的值。值为 Base-64 编码。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a" 或者 curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a/"``` |
| `/_table_/_row_/_column:qualifier_/?v=_number_of_versions_` | `GET` | 获取指定单元格的指定版本数. 获取单个列的值。值为 Base-64 编码。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/row1/cf:a?v=2"``` |
| 端口 | HTTP 名词 | 描述 | 示例 |
| ------------------------------- | --------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `/_table_/scanner/` | `PUT` | 获取Scanner对象。 所有其他扫描操作都需要。 将批处理参数调整为扫描应在批处理中返回的行数。 请参阅下一个向扫描仪添加过滤器的示例。 扫描程序端点URL作为HTTP响应中的 `Location`返回。 此表中的其他示例假定扫描仪端点为`http://example.com:8000/users/scanner/145869072824375522207`。 | ```curl -vi -X PUT \ -H "Accept: text/xml" \ -H "Content-Type: text/xml" \ -d '<Scanner batch="1"/>' \ "http://example.com:8000/users/scanner/"``` |
| `/_table_/scanner/` | `PUT` | 要向扫描程序对象提供过滤器或以任何其他方式配置扫描程序,您可以创建文本文件并将过滤器添加到文件中。 例如,要仅返回以<codeph>u123</codeph>开头的行并使用批量大小为100的行,过滤器文件将如下所示:[source,xml] ---- <Scanner batch="100"> <filter> { "type": "PrefixFilter", "value": "u123" } </filter> </Scanner>----将文件传递给`curl``-d`参数 请求。 | ```curl -vi -X PUT \ -H "Accept: text/xml" \ -H "Content-Type:text/xml" \ -d @filter.txt \ "http://example.com:8000/users/scanner/"``` |
| `/_table_/scanner/_scanner-id_` | `GET` | 从扫描仪获取下一批。 单元格值是字节编码的。 如果扫描仪已耗尽,则返回HTTP状态`204`。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/scanner/145869072824375522207"``` |
| `/_table_/scanner/` | `PUT` | 获取 Scanner 对象。 所有其他扫描操作都需要。 将批处理参数调整为扫描应在批处理中返回的行数。 请参阅下一个向扫描仪添加过滤器的示例。 扫描程序端点 URL 作为 HTTP 响应中的 `Location`返回。 此表中的其他示例假定扫描仪端点为`http://example.com:8000/users/scanner/145869072824375522207`。 | ```curl -vi -X PUT \ -H "Accept: text/xml" \ -H "Content-Type: text/xml" \ -d '<Scanner batch="1"/>' \ "http://example.com:8000/users/scanner/"``` |
| `/_table_/scanner/` | `PUT` | 要向扫描程序对象提供过滤器或以任何其他方式配置扫描程序,您可以创建文本文件并将过滤器添加到文件中。 例如,要仅返回以<codeph>u123</codeph>开头的行并使用批量大小为 100 的行,过滤器文件将如下所示:[source,xml] ---- <Scanner batch="100"> <filter> { "type": "PrefixFilter", "value": "u123" } </filter> </Scanner>----将文件传递给`curl``-d`参数 请求。 | ```curl -vi -X PUT \ -H "Accept: text/xml" \ -H "Content-Type:text/xml" \ -d @filter.txt \ "http://example.com:8000/users/scanner/"``` |
| `/_table_/scanner/_scanner-id_` | `GET` | 从扫描仪获取下一批。 单元格值是字节编码的。 如果扫描仪已耗尽,则返回 HTTP 状态`204`。 | ```curl -vi -X GET \ -H "Accept: text/xml" \ "http://example.com:8000/users/scanner/145869072824375522207"``` |
| `_table_/scanner/_scanner-id_` | `DELETE` | 删除所有扫描并释放资源 | ```curl -vi -X DELETE \ -H "Accept: text/xml" \ "http://example.com:8000/users/scanner/145869072824375522207"``` |
| 端口 | HTTP 名词 | 描述 | 示例 |
| -------------------- | --------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `/_table_/_row_key_` | `PUT` | 在表中写一行。 行,列限定符和值必须均为Base-64编码。 要编码字符串,请使用`base64`命令行实用程序。 要解码字符串,请使用`base64 -d`。 有效负载位于`--data`参数中,`/ users / fakerow`值是占位符。 通过将多行添加到`<CellSet>`元素来插入多行。 您还可以将要插入的数据保存到文件中,并使用`-d @ filename.txt`等语法将其传递给`-d`参数。 | ```curl -vi -X PUT \ -H "Accept: text/xml" \ -H "Content-Type: text/xml" \ -d '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><Row key="cm93NQo="><Cell column="Y2Y6ZQo=">dmFsdWU1Cg==</Cell></Row></CellSet>' \ "http://example.com:8000/users/fakerow" 或者 curl -vi -X PUT \ -H "Accept: text/json" \ -H "Content-Type: text/json" \ -d '{"Row":[{"key":"cm93NQo=", "Cell": [{"column":"Y2Y6ZQo=", "$":"dmFsdWU1Cg=="}]}]}'' \ "example.com:8000/users/fakerow"``` |
| `/_table_/_row_key_` | `PUT` | 在表中写一行。 行,列限定符和值必须均为 Base-64 编码。 要编码字符串,请使用`base64`命令行实用程序。 要解码字符串,请使用`base64 -d`。 有效负载位于`--data`参数中,`/ users / fakerow`值是占位符。 通过将多行添加到`<CellSet>`元素来插入多行。 您还可以将要插入的数据保存到文件中,并使用`-d @ filename.txt`等语法将其传递给`-d`参数。 | ```curl -vi -X PUT \ -H "Accept: text/xml" \ -H "Content-Type: text/xml" \ -d '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><Row key="cm93NQo="><Cell column="Y2Y6ZQo=">dmFsdWU1Cg==</Cell></Row></CellSet>' \ "http://example.com:8000/users/fakerow" 或者 curl -vi -X PUT \ -H "Accept: text/json" \ -H "Content-Type: text/json" \ -d '{"Row":[{"key":"cm93NQo=", "Cell": [{"column":"Y2Y6ZQo=", "$":"dmFsdWU1Cg=="}]}]}'' \ "example.com:8000/users/fakerow"``` |
### 97.4\. REST XML 结构
......@@ -348,13 +348,13 @@ message Scanner {
## 99\. C/C++ Apache HBase 客户端
FB’s Chip Turner编写了纯正 C/C++ 客户端. [Check it out](https://github.com/hinaria/native-cpp-hbase-client).
FB’s Chip Turner 编写了纯正 C/C++ 客户端. [Check it out](https://github.com/hinaria/native-cpp-hbase-client).
C++ client 实现. 详见: [HBASE-14850](https://issues.apache.org/jira/browse/HBASE-14850).
## 100\. 将 Java Data Objects (JDO) 和 HBase一起使用
## 100\. 将 Java Data Objects (JDO) 和 HBase 一起使用
[Java数据对象Java Data Objects (JDO)](https://db.apache.org/jdo/) 是一种访问数据库中持久数据的标准方法,使用普通的旧Java对象(POJO)来表示持久数据。
[Java 数据对象 Java Data Objects (JDO)](https://db.apache.org/jdo/) 是一种访问数据库中持久数据的标准方法,使用普通的旧 Java 对象(POJO)来表示持久数据。
依赖
......@@ -375,7 +375,7 @@ C++ client 实现. 详见: [HBASE-14850](https://issues.apache.org/jira/browse/H
Example 26\. JDO 示例
此示例使用JDO创建一个表和一个索引,在表中插入行,获取行,获取列值,执行查询以及执行一些其他HBase操作。
此示例使用 JDO 创建一个表和一个索引,在表中插入行,获取行,获取列值,执行查询以及执行一些其他 HBase 操作。
```
......@@ -495,7 +495,7 @@ public class HBaseExample {
### 101.1\. 设置类路径
要将Scala与HBase一起使用,您的CLASSPATH必须包含HBase的类路径以及代码所需的Scala JAR。首先,在运行HBase RegionServer进程的服务器上使用以下命令,以获取HBase的类路径。
要将 Scala 与 HBase 一起使用,您的 CLASSPATH 必须包含 HBase 的类路径以及代码所需的 Scala JAR。首先,在运行 HBase RegionServer 进程的服务器上使用以下命令,以获取 HBase 的类路径。
```
......@@ -503,7 +503,7 @@ $ ps aux |grep regionserver| awk -F 'java.library.path=' {'print $2'} | awk {'pr
/usr/lib/hadoop/lib/native:/usr/lib/hbase/lib/native/Linux-amd64-64
```
设置`$CLASSPATH`环境变量以包括您在上一步中找到的路径,以及项目所需的`scala-library.jar`路径和每个与Scala相关的其他JAR。
设置`$CLASSPATH`环境变量以包括您在上一步中找到的路径,以及项目所需的`scala-library.jar`路径和每个与 Scala 相关的其他 JAR。
```
......@@ -527,7 +527,7 @@ libraryDependencies ++= Seq(
### 101.3\. Scala 示例
此示例列出HBase表,创建新表并向其添加行:
此示例列出 HBase 表,创建新表并向其添加行:
```
......@@ -562,22 +562,22 @@ println(Bytes.toString(value))
### 102.1\. 设置类路径
要将Jython与HBase一起使用,您的CLASSPATH必须包含HBase的类路径以及代码所需的Jython JAR。
要将 Jython 与 HBase 一起使用,您的 CLASSPATH 必须包含 HBase 的类路径以及代码所需的 Jython JAR。
将路径设置为包含`Jython.jar`的目录,以及每个项目需要的附加的Jython相关JAR。然后将的HBASE_CLASSPATH指向$JYTHON_HOME 。
将路径设置为包含`Jython.jar`的目录,以及每个项目需要的附加的 Jython 相关 JAR。然后将的 HBASE_CLASSPATH 指向$JYTHON_HOME 。
```
$ export HBASE_CLASSPATH=/directory/jython.jar
```
在类路径中使用HBase和Hadoop JAR启动Jython shell: $ bin/hbase org.python.util.jython
在类路径中使用 HBase 和 Hadoop JAR 启动 Jython shell: $ bin/hbase org.python.util.jython
### 102.2\. Jython 示例
Example 27\. 使用Jython创建表,填充,获取和删除表
Example 27\. 使用 Jython 创建表,填充,获取和删除表
以下Jython代码示例检查表,如果存在,则删除它然后创建它。然后,它使用数据填充表并获取数据。
以下 Jython 代码示例检查表,如果存在,则删除它然后创建它。然后,它使用数据填充表并获取数据。
```
......@@ -623,7 +623,7 @@ data = java.lang.String(result.getValue("content", "qual"), "UTF8")
print "The fetched row contains the value '%s'" % data
```
Example 28\. 使用Jython进行表扫描
Example 28\. 使用 Jython 进行表扫描
此示例扫描表并返回与给定族限定符匹配的结果。
......
# Thrift API 和过滤器语言
> 者:[xixici](https://github.com/xixici)
> 贡献者:[xixici](https://github.com/xixici)
Apache [Thrift](https://thrift.apache.org/) 是跨平台跨语言的开发框架。HBase包含了 Thrift API和过滤语言。Thrift API 依赖于客户端和服务器进程。
Apache [Thrift](https://thrift.apache.org/) 是跨平台跨语言的开发框架。HBase 包含了 Thrift API 和过滤语言。Thrift API 依赖于客户端和服务器进程。
你可以在服务端和客户端维Thrift设置安全身份验证,参照 [Client-side Configuration for Secure Operation - Thrift Gateway](#security.client.thrift)[Configure the Thrift Gateway to Authenticate on Behalf of the Client](#security.gateway.thrift).
你可以在服务端和客户端维 Thrift 设置安全身份验证,参照 [Client-side Configuration for Secure Operation - Thrift Gateway](#security.client.thrift)[Configure the Thrift Gateway to Authenticate on Behalf of the Client](#security.gateway.thrift).
接下来,讨论Thrift API所提供的过滤器语言。
接下来,讨论 Thrift API 所提供的过滤器语言。
## 103\. 过滤器语言
Thrift 过滤语言在 HBase 0.92版本引入. 提供了通过在HBase上使用Thrift 或使用HBase Shell 来进行服务端过滤. 你可以在Shell中,使用`scan help`查看详细信息.
Thrift 过滤语言在 HBase 0.92 版本引入. 提供了通过在 HBase 上使用 Thrift 或使用 HBase Shell 来进行服务端过滤. 你可以在 Shell 中,使用`scan help`查看详细信息.
将过滤器写成字符串,在服务端解析成过滤器。
......@@ -31,9 +31,9 @@ Thrift 过滤语言在 HBase 0.92版本引入. 提供了通过在HBase上使用T
* 布尔值, 整形, 比较符 ( <, >, !=)不需要用引号包括。
* 过滤器名称必须是单个单词。除空格,单引号和括号外,允许使用所有ASCII字符。
* 过滤器名称必须是单个单词。除空格,单引号和括号外,允许使用所有 ASCII 字符。
* 过滤器的参数可以包含任何ASCII字符。如果参数中存在单引号,则必须通过附加的前一个单引号对其进行转义。
* 过滤器的参数可以包含任何 ASCII 字符。如果参数中存在单引号,则必须通过附加的前一个单引号对其进行转义。
### 103.2\. 复合过滤器和运算符
......@@ -114,13 +114,13 @@ is evaluated as
比较器可以如下任一种:
1. _BinaryComparator_ - 按字典顺序比较特定字节数组,使用Bytes.compareTo(byte[], byte[])
1. _BinaryComparator_ - 按字典顺序比较特定字节数组,使用 Bytes.compareTo(byte[], byte[])
2. _BinaryPrefixComparator_ - 按字典顺序比较特定字节数组,只比较字节数组长度.
3. _RegexStringComparator_ - 使用给定正则表达式,比较特定字节组。在这种比较器中,只有EQUAL 和 NOT_EQUAL有效
3. _RegexStringComparator_ - 使用给定正则表达式,比较特定字节组。在这种比较器中,只有 EQUAL 和 NOT_EQUAL 有效
4. _SubStringComparator_ - 给定字符子串是否出现在特定字节组中。不区分大小写。在这种比较器中,只有EQUAL 和 NOT_EQUAL有效
4. _SubStringComparator_ - 给定字符子串是否出现在特定字节组中。不区分大小写。在这种比较器中,只有 EQUAL 和 NOT_EQUAL 有效
比较器一般语法规则: `ComparatorType:ComparatorValue`
......@@ -140,13 +140,13 @@ is evaluated as
1. `binary:abc` 匹配字典顺序大于"abc"
2. `binaryprefix:abc` 匹配字典书序前3字符等于 "abc"
2. `binaryprefix:abc` 匹配字典书序前 3 字符等于 "abc"
3. `regexstring:ab*yz` 匹配以ab开头,已yz结尾的内容
3. `regexstring:ab*yz` 匹配以 ab 开头,已 yz 结尾的内容
4. `substring:abc123` 匹配所有以"abc123"开头的内容
### 103.6\. PHP客户端使用示例
### 103.6\. PHP 客户端使用示例
```
<?
......@@ -185,9 +185,9 @@ is evaluated as
* 或者满足一下条件:
* 键值对必须位于字典序 >= abc 和 < xyz之间
* 键值对必须位于字典序 >= abc 和 < xyz 之间
* `"SKIP ValueFilter (0)"` 如果行中任何值部位0, 则跳过
* `"SKIP ValueFilter (0)"` 如果行中任何值部位 0, 则跳过
### 103.8\. 单个过滤器语法
......@@ -241,22 +241,22 @@ TimeStampsFilter
RowFilter
该过滤器采用比较运算符和比较器。它使用compare运算符将每个行键与比较器进行比较,如果比较返回true,则返回该行中的所有键值。
该过滤器采用比较运算符和比较器。它使用 compare 运算符将每个行键与比较器进行比较,如果比较返回 true,则返回该行中的所有键值。
Family Filter
该过滤器采用比较运算符和比较器。它使用比较运算符将每个列族名称与比较器进行比较,如果比较返回true,则返回该列族中的所有单元格。
该过滤器采用比较运算符和比较器。它使用比较运算符将每个列族名称与比较器进行比较,如果比较返回 true,则返回该列族中的所有单元格。
QualifierFilter
该过滤器采用比较运算符和比较器。它使用compare运算符将每个限定符名称与比较器进行比较,如果比较返回true,则返回该列中的所有键值。
该过滤器采用比较运算符和比较器。它使用 compare 运算符将每个限定符名称与比较器进行比较,如果比较返回 true,则返回该列中的所有键值。
ValueFilter
该过滤器采用比较运算符和比较器。它使用比较运算符将每个值与比较器进行比较,如果比较返回true,则返回该键值。
该过滤器采用比较运算符和比较器。它使用比较运算符将每个值与比较器进行比较,如果比较返回 true,则返回该键值。
DependentColumnFilter
......@@ -266,14 +266,14 @@ DependentColumnFilter
SingleColumnValueFilter
该过滤器采用列族,限定符,比较运算符和比较器。如果未找到指定的列 - 将发出该行的所有列。如果找到该列并且与比较器的比较返回true,则将发出该行的所有列。如果条件失败,则不会发出该行。
该过滤器采用列族,限定符,比较运算符和比较器。如果未找到指定的列 - 将发出该行的所有列。如果找到该列并且与比较器的比较返回 true,则将发出该行的所有列。如果条件失败,则不会发出该行。
SingleColumnValueExcludeFilter
此过滤器采用相同的参数,其行为与SingleColumnValueFilter相同 - 但是,如果找到该列并且条件通过,则除了测试的列值之外,将发出该行的所有列。
此过滤器采用相同的参数,其行为与 SingleColumnValueFilter 相同 - 但是,如果找到该列并且条件通过,则除了测试的列值之外,将发出该行的所有列。
ColumnRangeFilter
此过滤器仅用于选择列在minColumn和maxColumn之间的键。它还需要两个布尔变量来指示是否包含minColumn和maxColumn。
\ No newline at end of file
此过滤器仅用于选择列在 minColumn 和 maxColumn 之间的键。它还需要两个布尔变量来指示是否包含 minColumn 和 maxColumn。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
# Apache HBase 案例研究
## 147.概述
# Apache HBase Case Studies
本章将介绍各种性能和故障排除案例研究,这些案例研究可以为诊断 Apache HBase 集群问题提供有用的蓝图。
## 147\. Overview
有关性能和故障排除的更多信息,请参阅 [Apache HBase 性能调优](#performance)[故障排除和调试 Apache HBase](#trouble)
This chapter will describe a variety of performance and troubleshooting case studies that can provide a useful blueprint on diagnosing Apache HBase cluster issues.
## 148.架构设计
For more information on Performance and Troubleshooting, see [Apache HBase Performance Tuning](#performance) and [Troubleshooting and Debugging Apache HBase](#trouble).
请参阅此处的架构设计案例研究:[架构设计案例研究](#schema.casestudies)
## 148\. Schema Design
## 149.性能/故障排除
See the schema design case studies here: [Schema Design Case Studies](#schema.casestudies)
### 149.1。案例研究#1(单节点上的性能问题)
## 149\. Performance/Troubleshooting
#### 149.1.1。脚本
### 149.1\. Case Study #1 (Performance Issue On A Single Node)
在计划的重新启动之后,一个数据节点开始表现出异常行为。常规 MapReduce 作业针对 HBase 表运行,这些表在 5 到 6 分钟内定期完成,开始需要 30 或 40 分钟才能完成。一直发现这些作业在地图上等待并减少分配给故障数据节点的任务(例如,慢地图任务都具有相同的输入分割)。在分布式副本期间,当滞后节点严重延长副本时,情况就出现了问题。
#### 149.1.1\. Scenario
#### 149.1.2。硬件
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.
数据节点:
#### 149.1.2\. Hardware
* 两个 12 核处理器
Datanodes:
* 六个企业级 SATA 磁盘
* Two 12-core processors
* 24GB 的 RAM
* Six Enterprise SATA disks
* 两个绑定的千兆网卡
* 24GB of RAM
网络:
* Two bonded gigabit NICs
* 10 千兆位架顶式交换机
Network:
* 机架之间的 20 千兆位绑定互连。
* 10 Gigabit top-of-rack switches
#### 149.1.3。假设
* 20 Gigabit bonded interconnects between racks.
##### HBase“热点”地区
#### 149.1.3\. Hypotheses
我们假设我们遇到了一个熟悉的痛点:HBase 表中的“热点”区域,其中不均匀的密钥空间分布可能会将大量请求汇集到单个 HBase 区域,轰炸 RegionServer 进程并导致响应缓慢时间。检查 HBase 主状态页面显示对故障节点的 HBase 请求数几乎为零。此外,对 HBase 日志的检查表明,没有区域分裂,压缩或其他区域转变正在进行中。这有效地排除了“热点”作为观察到的缓慢的根本原因。
##### HBase "Hot Spot" Region
##### 具有非本地数据的 HBase 区域
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.
我们的下一个假设是,其中一个 MapReduce 任务是从 HBase 请求数据,这些数据不是 DataNode 的本地数据,因此迫使 HDFS 通过网络从其他服务器请求数据块。对 DataNode 日志的检查表明,通过网络请求的块非常少,表明 HBase 区域已正确分配,并且大多数必要数据位于节点上。这排除了非本地数据导致经济放缓的可能性。
##### HBase Region With Non-Local Data
##### 由于交换或过度工作或故障硬盘而导致 I / O 等待过多
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.
在得出 Hadoop 和 HBase 不太可能成为罪魁祸首之后,我们继续对 DataNode 的硬件进行故障排除。根据设计,Java 将定期扫描其整个内存空间以进行垃圾收集。如果系统内存过度使用,Linux 内核可能会进入恶性循环,耗尽其所有资源,当 Java 尝试运行垃圾回收时,将 Java 堆从磁盘来回交换到 RAM。此外,发生故障的硬盘通常会在放弃并返回错误之前多次重试读取和/或写入。这可以表现为高 iowait,因为正在运行的进程等待读取和写入完成。最后,接近其性能范围上限的磁盘将开始引起 iowait,因为它通知内核它不能再接受任何数据,并且内核将传入数据排入内存中的脏写池。但是,使用`vmstat(1)``free(1)`,我们可以看到没有使用交换,磁盘 IO 的数量仅为每秒几千字节。
##### 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.
接下来,我们检查系统是否由于非常高的计算负荷而缓慢执行。 `top(1)`表明系统负载高于正常值,但`vmstat(1)``mpstat(1)`表明用于实际计算的处理器数量很少。
##### 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:
由于磁盘和处理器都没有被大量使用,我们转向了网络接口的性能。 DataNode 有两个千兆以太网适配器,绑定形成一个活动 - 备用接口。 `ifconfig(8)`显示出一些不寻常的异常,即接口错误,溢出,帧错误。虽然并非闻所未闻,但这些错误在现代硬件上非常罕见,而现代硬件的运行应该是:
```
$ /sbin/ifconfig bond0
......@@ -68,10 +66,10 @@ 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)
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.
这些错误立即导致我们怀疑一个或多个以太网接口可能已经协商错误的线路速度。通过从外部主机运行 ICMP ping 并观察超过 700 毫秒的往返时间,并通过在绑定接口的成员上运行`ethtool(8)`并发现活动接口以 100Mbs /运行,全双工。
```
$ sudo ethtool eth0
......@@ -99,28 +97,27 @@ MDI-X: Unknown
Supports Wake-on: umbg
Wake-on: g
Current message level: 0x00000003 (3)
Link detected: yes
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.
#### 149.1.4\. Resolution
在正常操作中,ICMP ping 往返时间应为 20ms 左右,接口速度和双工应分别为“1000MB / s”和“Full”。
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:
#### 149.1.4。解析度
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.
在确定活动的以太网适配器速度不正确之后,我们使用`ifenslave(8)`命令使备用接口成为活动接口,从而立即提高了 MapReduce 的性能,并使网络吞吐量提高了 10 倍:
### 149.2\. 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)
### 149.2。案例研究#2(2012 年绩效研究)
### 149.3\. Case Study #3 (Performance Research 2010))
调查结果自我描述“我们不确定什么是错的,但似乎很慢”的问题。 [http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html](http://gbif.blogspot.com/2012/03/hbase-performance-evaluation-continued.html)
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. [http://hstack.org/hbase-performance-testing/](http://hstack.org/hbase-performance-testing/)
### 149.3。案例研究#3(2010 年绩效研究))
### 149.4\. Case Study #4 (max.transfer.threads Config)
从 2010 年开始对一般集群性能的调查结果。虽然这项研究是在较旧版本的代码库上进行的,但这种写法在方法方面仍然非常有用。 [http://hstack.org/hbase-performance-testing/](http://hstack.org/hbase-performance-testing/)
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)
### 149.4。案例研究#4(max.transfer.threads 配置)
See also [`dfs.datanode.max.transfer.threads`](#dfs.datanode.max.transfer.threads) .
配置`max.transfer.threads`(以前称为`xcievers`)并诊断错误配置错误的案例研究。 [http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html](http://www.larsgeorge.com/2012/03/hadoop-hbase-and-xceivers.html)
另请参见 [`dfs.datanode.max.transfer.threads`](#dfs.datanode.max.transfer.threads)
\ No newline at end of file
此差异已折叠。
此差异已折叠。
# 单元测试 HBase 应用程序
# Unit Testing HBase Applications
This chapter discusses unit testing your HBase application using JUnit, Mockito, MRUnit, and HBaseTestingUtility. Much of the information comes from [a community blog post about testing HBase applications](http://blog.cloudera.com/blog/2013/09/how-to-test-hbase-applications-using-popular-tools/). For information on unit tests for HBase itself, see [hbase.tests](#hbase.tests).
本章讨论使用 JUnit,Mockito,MRUnit 和 HBaseTestingUtility 对 HBase 应用程序进行单元测试。大部分信息来自[关于测试 HBase 应用程序的社区博客文章](http://blog.cloudera.com/blog/2013/09/how-to-test-hbase-applications-using-popular-tools/)。有关 HBase 本身的单元测试的信息,请参阅 [hbase.tests](#hbase.tests)
## 175\. JUnit
HBase uses [JUnit](http://junit.org) for unit tests
HBase 使用 [JUnit](http://junit.org) 进行单元测试
This example will add unit tests to the following example class:
此示例将单元测试添加到以下示例类:
```
public class MyHBaseDAO {
......@@ -27,10 +25,10 @@ public class MyHBaseDAO {
Bytes.toBytes(obj.getData2()));
return put;
}
}
}
```
The first step is to add JUnit dependencies to your Maven POM file:
第一步是将 JUnit 依赖项添加到 Maven POM 文件中:
```
<dependency>
......@@ -38,10 +36,10 @@ The first step is to add JUnit dependencies to your Maven POM file:
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependency>
```
Next, add some unit tests to your code. Tests are annotated with `@Test`. Here, the unit tests are in bold.
接下来,在代码中添加一些单元测试。测试用`@Test`注释。这里,单元测试以粗体显示。
```
public class TestMyHbaseDAOData {
......@@ -56,20 +54,20 @@ public class TestMyHbaseDAOData {
assertEquals(obj.getData1(), Bytes.toString(put.get(Bytes.toBytes("CF"), Bytes.toBytes("CQ-1")).get(0).getValue()));
assertEquals(obj.getData2(), Bytes.toString(put.get(Bytes.toBytes("CF"), Bytes.toBytes("CQ-2")).get(0).getValue()));
}
}
}
```
These tests ensure that your `createPut` method creates, populates, and returns a `Put` object with expected values. Of course, JUnit can do much more than this. For an introduction to JUnit, see [https://github.com/junit-team/junit/wiki/Getting-started](https://github.com/junit-team/junit/wiki/Getting-started).
这些测试确保您的`createPut`方法创建,填充和返回具有预期值的`Put`对象。当然,JUnit 可以做的远不止这些。有关 JUnit 的介绍,请参阅 [https://github.com/junit-team/junit/wiki/Getting-started](https://github.com/junit-team/junit/wiki/Getting-started)
## 176\. Mockito
Mockito is a mocking framework. It goes further than JUnit by allowing you to test the interactions between objects without having to replicate the entire environment. You can read more about Mockito at its project site, [https://code.google.com/p/mockito/](https://code.google.com/p/mockito/).
Mockito 是一个嘲弄的框架。它比 JUnit 更进一步,允许您测试对象之间的交互,而不必复制整个环境。您可以在其项目网站上阅读有关 Mockito 的更多信息, [https://code.google.com/p/mockito/](https://code.google.com/p/mockito/)
You can use Mockito to do unit testing on smaller units. For instance, you can mock a `org.apache.hadoop.hbase.Server` instance or a `org.apache.hadoop.hbase.master.MasterServices` interface reference rather than a full-blown `org.apache.hadoop.hbase.master.HMaster`.
您可以使用 Mockito 在较小的单元上进行单元测试。例如,您可以模拟`org.apache.hadoop.hbase.Server`实例或`org.apache.hadoop.hbase.master.MasterServices`接口参考而不是完整的`org.apache.hadoop.hbase.master.HMaster`
This example builds upon the example code in [unit.tests](#unit.tests), to test the `insertRecord` method.
此示例基于 [unit.tests](#unit.tests) 中的示例代码,以测试`insertRecord`方法。
First, add a dependency for Mockito to your Maven POM file.
首先,将 Mockito 的依赖项添加到 Maven POM 文件中。
```
<dependency>
......@@ -77,10 +75,10 @@ First, add a dependency for Mockito to your Maven POM file.
<artifactId>mockito-core</artifactId>
<version>2.1.0</version>
<scope>test</scope>
</dependency>
</dependency>
```
Next, add a `@RunWith` annotation to your test class, to direct it to use Mockito.
接下来,将`@RunWith`注释添加到测试类,以指示它使用 Mockito。
```
@RunWith(MockitoJUnitRunner.class)
......@@ -113,18 +111,18 @@ public class TestMyHBaseDAO{
assertEquals(Bytes.toString(put.get(Bytes.toBytes("CF"),Bytes.toBytes("CQ-1")).get(0).getValue()), "DATA-1");
assertEquals(Bytes.toString(put.get(Bytes.toBytes("CF"),Bytes.toBytes("CQ-2")).get(0).getValue()), "DATA-2");
}
}
}
```
This code populates `HBaseTestObj` with `ROWKEY-1'',` DATA-1'', ``DATA-2'' as values. It then inserts the record into the mocked table. The Put that the DAO would have inserted is captured, and values are tested to verify that they are what you expected them to be.
该代码用`ROWKEY-1'',` DATA-1'',``DATA-2''填充`HBaseTestObj`作为值。然后它将记录插入到模拟表中。捕获 DAO 将插入的 Put,并测试值以验证它们是否符合您的预期。
The key here is to manage Connection and Table instance creation outside the DAO. This allows you to mock them cleanly and test Puts as shown above. Similarly, you can now expand into other operations such as Get, Scan, or Delete.
这里的关键是在 DAO 之外管理 Connection 和 Table 实例创建。这允许您干净地模拟它们并测试 Puts,如上所示。同样,您现在可以扩展到其他操作,例如“获取”,“扫描”或“删除”。
## 177\. MRUnit
[Apache MRUnit](https://mrunit.apache.org/) is a library that allows you to unit-test MapReduce jobs. You can use it to test HBase jobs in the same way as other MapReduce jobs.
[Apache MRUnit](https://mrunit.apache.org/) 是一个允许您对 MapReduce 作业进行单元测试的库。您可以使用它以与其他 MapReduce 作业相同的方式测试 HBase 作业。
Given a MapReduce job that writes to an HBase table called `MyTest`, which has one column family called `CF`, the reducer of such a job could look like the following:
给定一个写入名为`MyTest`的 HBase 表的 MapReduce 作业,该表有一个名为`CF`的列族,这样的作业的缩减器可能如下所示:
```
public class MyReducer extends TableReducer<Text, Text, ImmutableBytesWritable> {
......@@ -143,10 +141,10 @@ public class MyReducer extends TableReducer<Text, Text, ImmutableBytesWritable>
//write to HBase
context.write(new ImmutableBytesWritable(Bytes.toBytes(key.toString())), put);
}
}
}
```
To test this code, the first step is to add a dependency to MRUnit to your Maven POM file.
要测试此代码,第一步是将 MRUnit 的依赖项添加到 Maven POM 文件中。
```
<dependency>
......@@ -154,10 +152,10 @@ To test this code, the first step is to add a dependency to MRUnit to your Maven
<artifactId>mrunit</artifactId>
<version>1.0.0 </version>
<scope>test</scope>
</dependency>
</dependency>
```
Next, use the ReducerDriver provided by MRUnit, in your Reducer job.
接下来,在 Reducer 作业中使用 MRUnit 提供的 ReducerDriver。
```
public class MyReducerTest {
......@@ -197,16 +195,16 @@ strValue2 = "DATA2";
assertEquals(expectedOutput,c );
}
}
}
```
Your MRUnit test verifies that the output is as expected, the Put that is inserted into HBase has the correct value, and the ColumnFamily and ColumnQualifier have the correct values.
您的 MRUnit 测试验证输出是否符合预期,插入 HBase 的 Put 具有正确的值,ColumnFamily 和 ColumnQualifier 具有正确的值。
MRUnit includes a MapperDriver to test mapping jobs, and you can use MRUnit to test other operations, including reading from HBase, processing data, or writing to HDFS,
MRUnit 包含一个 MapperDriver 来测试映射作业,您可以使用 MRUnit 测试其他操作,包括从 HBase 读取,处理数据或写入 HDFS,
## 178\. Integration Testing with an HBase Mini-Cluster
## 178.使用 HBase Mini-Cluster 进行集成测试
HBase ships with HBaseTestingUtility, which makes it easy to write integration tests using a _mini-cluster_. The first step is to add some dependencies to your Maven POM file. Check the versions to be sure they are appropriate.
HBase 附带 HBaseTestingUtility,这使得使用 _ 迷你集群 _ 编写集成测试变得容易。第一步是向 Maven POM 文件添加一些依赖项。检查版本以确保它们合适。
```
<properties>
......@@ -220,10 +218,10 @@ HBase ships with HBaseTestingUtility, which makes it easy to write integration t
<version>${hbase.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencies>
```
This code represents an integration test for the MyDAO insert shown in [unit.tests](#unit.tests).
此代码表示 [unit.tests](#unit.tests) 中显示的 MyDAO 插入的集成测试。
```
public class MyHBaseIntegrationTest {
......@@ -257,12 +255,11 @@ public class MyHBaseIntegrationTest {
assertEquals(Bytes.toString(result2.getRow()), obj.getRowKey());
assertEquals(Bytes.toString(result2.value()), obj.getData2());
}
}
}
```
This code creates an HBase mini-cluster and starts it. Next, it creates a table called `MyTest` with one column family, `CF`. A record is inserted, a Get is performed from the same table, and the insertion is verified.
> Starting the mini-cluster takes about 20-30 seconds, but that should be appropriate for integration testing.
此代码创建一个 HBase 迷你集群并启动它。接下来,它创建一个名为`MyTest`的表,其中包含一个列族`CF`。插入记录,从同一个表执行 Get,并验证插入。
See the paper at [HBase Case-Study: Using HBaseTestingUtility for Local Testing and Development](http://blog.sematext.com/2010/08/30/hbase-case-study-using-hbasetestingutility-for-local-testing-development/) (2010) for more information about HBaseTestingUtility.
> 启动迷你集群大约需要 20-30 秒,但这应该适合集成测试。
有关 HBaseTestingUtility 的更多信息,请参阅 [HBase 案例研究中的论文:使用 HBaseTestingUtility 进行本地测试和开发](http://blog.sematext.com/2010/08/30/hbase-case-study-using-hbasetestingutility-for-local-testing-development/)(2010)。
\ No newline at end of file
# Protobuf in HBase
# HBase 中的 Protobuf
## 179\. Protobuf
HBase uses Google’s [protobufs](https://developers.google.com/protocol-buffers/) wherever it persists metadata — in the tail of hfiles or Cells written by HBase into the system hbase:meta table or when HBase writes znodes to zookeeper, etc. — and when it passes objects over the wire making [RPCs](#hbase.rpc). HBase uses protobufs to describe the RPC Interfaces (Services) we expose to clients, for example the `Admin` and `Client` Interfaces that the RegionServer fields, or specifying the arbitrary extensions added by developers via our [Coprocessor Endpoint](#cp) mechanism.
HBase 使用 Google 的 [protobufs](https://developers.google.com/protocol-buffers/) ,无论它在哪里持久存储元数据 - 在 hfiles 或 HBase 写入系统 hbase:meta 表格中,或者当 HBase 将 znodes 写入 zookeeper 等时 - 以及当它将对象传递给制丝 [RPCs](#hbase.rpc) 。 HBase 使用 protobufs 来描述我们向客户端公开的 RPC 接口(服务),例如 RegionServer 字段的`Admin``Client`接口,或指定开发人员通过我们的[协处理器端点](#cp)添加的任意扩展机制。
In this chapter we go into detail for developers who are looking to understand better how it all works. This chapter is of particular use to those who would amend or extend HBase functionality.
在本章中,我们将详细介绍那些希望更好地了解它的工作原理的开发人员。本章特别适用于那些修改或扩展 HBase 功能的人。
With protobuf, you describe serializations and services in a `.protos` file. You then feed these descriptors to a protobuf tool, the `protoc` binary, to generate classes that can marshall and unmarshall the described serializations and field the specified Services.
使用 protobuf,您可以在`.protos`文件中描述序列化和服务。然后,您将这些描述符提供给 protobuf 工具(`protoc`二进制文件),以生成可以编组和解组所描述的序列化并对指定的服务进行字段处理的类。
See the `README.txt` in the HBase sub-modules for details on how to run the class generation on a per-module basis; e.g. see `hbase-protocol/README.txt` for how to generate protobuf classes in the hbase-protocol module.
有关如何基于每个模块运行类生成的详细信息,请参阅 HBase 子模块中的`README.txt`;例如请参阅`hbase-protocol/README.txt`了解如何在 hbase 协议模块中生成 protobuf 类。
In HBase, `.proto` files are either in the `hbase-protocol` module; a module dedicated to hosting the common proto files and the protoc generated classes that HBase uses internally serializing metadata. For extensions to hbase such as REST or Coprocessor Endpoints that need their own descriptors; their protos are located inside the function’s hosting module: e.g. `hbase-rest` is home to the REST proto files and the `hbase-rsgroup` table grouping Coprocessor Endpoint has all protos that have to do with table grouping.
在 HBase 中,`.proto`文件位于`hbase-protocol`模块中;一个专用于托管公共 proto 文件的模块和 HBase 使用内部序列化元数据的 protoc 生成的类。对于 hbase 的扩展,例如需要自己的描述符的 REST 或协处理器端点;他们的 protos 位于函数的托管模块内:例如`hbase-rest`是 REST 原型文件的主页,`hbase-rsgroup`表分组协处理器端点具有与表分组有关的所有原型。
Protos are hosted by the module that makes use of them. While this makes it so generation of protobuf classes is distributed, done per module, we do it this way so modules encapsulate all to do with the functionality they bring to hbase.
Protos 由使用它们的模块托管。虽然这使得 protobuf 类的生成分布式,按模块完成,我们这样做,因此模块封装了它们带给 hbase 的功能。
Extensions whether REST or Coprocessor Endpoints will make use of core HBase protos found back in the hbase-protocol module. They’ll use these core protos when they want to serialize a Cell or a Put or refer to a particular node via ServerName, etc., as part of providing the CPEP Service. Going forward, after the release of hbase-2.0.0, this practice needs to whither. We’ll explain why in the later [hbase-2.0.0](#shaded.protobuf) section.
扩展是否 REST 或协处理器端点将使用在 hbase 协议模块中找到的核心 HBase 原型。当他们想要序列化 Cell 或 Put 时,或者通过 ServerName 等引用特定节点时,他们将使用这些核心 protos,作为提供 CPEP 服务的一部分。展望未来,在 hbase-2.0.0 发布之后,这种做法需要向前推进。我们将在后面的 [hbase-2.0.0](#shaded.protobuf) 部分解释原因。
### 179.1\. hbase-2.0.0 and the shading of protobufs (HBASE-15638)
### 179.1。 hbase-2.0.0 和 protobufs 的阴影(HBASE-15638)
As of hbase-2.0.0, our protobuf usage gets a little more involved. HBase core protobuf references are offset so as to refer to a private, bundled protobuf. Core stops referring to protobuf classes at com.google.protobuf.* and instead references protobuf at the HBase-specific offset org.apache.hadoop.hbase.shaded.com.google.protobuf.*. We do this indirection so hbase core can evolve its protobuf version independent of whatever our dependencies rely on. For instance, HDFS serializes using protobuf. HDFS is on our CLASSPATH. Without the above described indirection, our protobuf versions would have to align. HBase would be stuck on the HDFS protobuf version until HDFS decided to upgrade. HBase and HDFS versions would be tied.
从 hbase-2.0.0 开始,我们的 protobuf 使用情况变得更加复杂。 HBase 核心 protobuf 引用被抵消,以便引用私有的捆绑 protobuf。核心在 com.google.protobuf 中停止引用 protobuf 类。 _ 而是在 HBase 特定的偏移量 org.apache.hadoop.hbase.shaded.com.google.protobuf 上引用 protobuf。_ 。我们这样做是间接的,因此 hbase 核心可以独立于我们的依赖关系所依赖的方式发展其 protobuf 版本。例如,HDFS 使用 protobuf 序列化。 HDFS 在我们的 CLASSPATH 上。如果没有上述间接,我们的 protobuf 版本必须对齐。在 HDFS 决定升级之前,HBase 将停留在 HDFS protobuf 版本上。 HBase 和 HDFS 版本将捆绑在一起。
We had to move on from protobuf-2.5.0 because we need facilities added in protobuf-3.1.0; in particular being able to save on copies and avoiding bringing protobufs onheap for serialization/deserialization.
我们不得不继续使用 protobuf-2.5.0,因为我们需要在 protobuf-3.1.0 中添加设施;特别是能够保存副本并避免在序列化/反序列化时使用 protobufs。
In hbase-2.0.0, we introduced a new module, `hbase-protocol-shaded` inside which we contained all to do with protobuf and its subsequent relocation/shading. This module is in essence a copy of much of the old `hbase-protocol` but with an extra shading/relocation step. Core was moved to depend on this new module.
在 hbase-2.0.0 中,我们引入了一个新模块`hbase-protocol-shaded`,其中包含了与 protobuf 及其后续重定位/着色相关的所有内容。这个模块本质上是许多旧`hbase-protocol`的副本,但有一个额外的着色/重定位步骤。核心被转移到依赖这个新模块。
That said, a complication arises around Coprocessor Endpoints (CPEPs). CPEPs depend on public HBase APIs that reference protobuf classes at `com.google.protobuf.*` explicitly. For example, in our Table Interface we have the below as the means by which you obtain a CPEP Service to make invocations against:
也就是说,协处理器端点(CPEP)出现了复杂问题。 CPEP 依赖于明确引用`com.google.protobuf.*`的 protobuf 类的公共 HBase API。例如,在我们的表格接口中,我们使用以下内容作为获取 CPEP 服务以对其进行调用的方式:
```
...
<T extends com.google.protobuf.Service,R> Map<byte[],R> coprocessorService(
Class<T> service, byte[] startKey, byte[] endKey,
org.apache.hadoop.hbase.client.coprocessor.Batch.Call<T,R> callable)
throws com.google.protobuf.ServiceException, Throwable
throws com.google.protobuf.ServiceException, Throwable
```
Existing CPEPs will have made reference to core HBase protobufs specifying ServerNames or carrying Mutations. So as to continue being able to service CPEPs and their references to `com.google.protobuf.` **across the upgrade to hbase-2.0.0 and beyond, HBase needs to be able to deal with both `com.google.protobuf.`** references and its internal offset `org.apache.hadoop.hbase.shaded.com.google.protobuf.*` protobufs.
The `hbase-protocol-shaded` module hosts all protobufs used by HBase core.
现有的 CPEP 将参考指定 ServerNames 或携带 Mutations 的核心 HBase protobufs。为了能够在升级到 hbase-2.0.0 及更高版本的过程中继续为 CPEP 及其对`com.google.protobuf.` **的引用提供服务,HBase 需要能够处理`com.google.protobuf.`** 引用及其内部偏移`org.apache.hadoop.hbase.shaded.com.google.protobuf.*` protobufs。
But for the vestigial CPEP references to the (non-shaded) content of `hbase-protocol`, we keep around most of this module going forward just so it is available to CPEPs. Retaining the most of `hbase-protocol` makes for overlapping, 'duplicated' proto instances where some exist as non-shaded/non-relocated here in their old module location but also in the new location, shaded under `hbase-protocol-shaded`. In other words, there is an instance of the generated protobuf class `org.apache.hadoop.hbase.protobuf.generated.ServerName` in hbase-protocol and another generated instance that is the same in all regards except its protobuf references are to the internal shaded version at `org.apache.hadoop.hbase.shaded.protobuf.generated.ServerName` (note the 'shaded' addition in the middle of the package name).
`hbase-protocol-shaded`模块托管 HBase 核心使用的所有 protobufs。
If you extend a proto in `hbase-protocol-shaded` for internal use, consider extending it also in `hbase-protocol` (and regenerating).
但是对于退化的 CPEP 参考`hbase-protocol`的(非阴影)内容,我们保留了这个模块的大部分内容,因此它可供 CPEP 使用。保留`hbase-protocol`的大部分会产生重叠的“重复”原型实例,其中一些存在于其旧模块位置中的非阴影/非重定位,但也存在于新位置,在`hbase-protocol-shaded`下阴影。换句话说,在 hbase 协议中有一个生成的 protobuf 类`org.apache.hadoop.hbase.protobuf.generated.ServerName`的实例,并且在所有方面都有相同的生成实例,除了它的 protobuf 引用是`org.apache.hadoop.hbase.shaded.protobuf.generated.ServerName`的内部着色版本(注意'阴影' '在包名称中间添加)。
Going forward, we will provide a new module of common types for use by CPEPs that will have the same guarantees against change as does our public API. TODO.
如果在`hbase-protocol-shaded`中扩展原型供内部使用,请考虑在`hbase-protocol`中扩展它(并重新生成)。
展望未来,我们将提供 CPEP 使用的常见类型的新模块,它们将像我们的公共 API 一样具有相同的变更保证。去做。
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
# 社区
## 198.决定
# Community
功能分支
## 198\. Decisions
功能分支很容易制作。你不必成为一个提交者。只需要在开发人员的邮件列表中将您的分支名称添加到 JIRA,并且提交者将为您添加它。此后,您可以针对 Apache HBase JIRA 中的功能分支提出问题。您保存在其他地方的代码 - 它应该是公共的,以便可以观察到 - 并且您可以根据进度更新开发邮件列表。当该功能准备好提交时,来自提交者的 3 + 1 将使您的功能合并。参见 [HBase,邮件#dev - 关于大型功能开发分支的想法](http://search-hadoop.com/m/asM982C5FkS1)
Feature Branches
如何在问题解决时在 JIRA 中设置修复版本
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 feature merged. See [HBase, mail # dev - Thoughts about large feature dev branches](http://search-hadoop.com/m/asM982C5FkS1)
以下是[我们在解决问题时同意](http://search-hadoop.com/m/azemIi5RCJ1)在 JIRA 中设置版本的方式。如果 master 将是 2.0.0,而 branch-1 1.4.0 则是:
How to set fix version in JIRA on issue resolve
* 仅提交给 master:标记为 2.0.0
Here is how [we agreed](http://search-hadoop.com/m/azemIi5RCJ1) to set versions in JIRA when we resolve an issue. If master is going to be 2.0.0, and branch-1 1.4.0 then:
* 提交 branch-1 和 master:标记为 2.0.0 和 1.4.0
* Commit only to master: Mark with 2.0.0
* 提交 branch-1.3,branch-1 和 master:标记为 2.0.0,1.4.0 和 1.3.x.
* Commit to branch-1 and master: Mark with 2.0.0, and 1.4.0
* 提交站点修复:没有版本
* Commit to branch-1.3, branch-1, and master: Mark with 2.0.0, 1.4.0, and 1.3.x
何时将 RESOLVED JIRA 设置为 CLOSED 的政策
* Commit site fixes: no version
我们[同意](http://search-hadoop.com/m/4cIKs1iwXMS1)对于在 _ 修正版/_ 字段中列出多个版本的问题,请关闭所列出的任何版本的发布问题;随后的问题变更必须在新的 JIRA 中进行。
Policy on when to set a RESOLVED JIRA as CLOSED
只有 ZooKeeper 中的瞬态!
We [agreed](http://search-hadoop.com/m/4cIKs1iwXMS1) 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.
你应该能够杀死 zookeeper 中的数据,而 hbase 应该在它上面重新创建 zk 内容。这是围绕这些部分的古老谚语。我们现在才注意到它。我们目前也违反了这个基本原则 - 复制至少在 zk 中保持永久状态 - 但我们正在努力撤销这个打破黄金法则。
Only transient state in ZooKeeper!
## 199.社区角色
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.
### 199.1。发布经理
## 199\. Community Roles
每个维护的发布分支都有一个发布管理器,他自愿协调新功能,并将错误修复程序反向移植到该发行版。发布经理是[提交者](https://hbase.apache.org/team-list.html)。如果您希望将特性或错误修复包含在给定版本中,请与该版本管理器进行通信。如果此列表已过期或您无法联系到列出的人员,请与列表中的其他人联系。
### 199.1\. 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](https://hbase.apache.org/team-list.html). 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.
> End-of-life releases are not included in this list.
| Release | Release Manager |
| 发布 | 发布经理 |
| --- | --- |
| 1.2 | Sean Busbey |
| 1.3 | Mikhail Antonov |
| 1.4 | Andrew Purtell |
| 1.2 | 肖恩布斯贝 |
| 1.3 | 米哈伊尔安东诺夫 |
| 1.4 | 安德鲁普特尔 |
| 2.0 | Michael Stack |
| 2.1 | Duo Zhang |
| 2.1 | 张多 |
## 200\. Commit Message format
## 200.提交消息格式
We [agreed](http://search-hadoop.com/m/Gwxwl10cFHa1) to the following Git commit message format:
我们[同意](http://search-hadoop.com/m/Gwxwl10cFHa1)以下 Git 提交消息格式:
```
HBASE-xxxxx <title>. (<contributor>)
HBASE-xxxxx <title>. (<contributor>)
```
If the person making the commit is the contributor, leave off the '(<contributor>)' element.
如果提交者是贡献者,则不要使用'(&lt;contributor&gt;)'元素。&lt;/contributor&gt;
\ No newline at end of file
此差异已折叠。
此差异已折叠。
# Apache HBase Shell
> 者:[xixici](https://github.com/xixici)
> 贡献者:[xixici](https://github.com/xixici)
Apache HBase Shell 是 [(J)Ruby](http://jruby.org)'s IRB 的基础上增加了一些 HBase 特定的命令。你可以在 IRB 中做的任何事情,都可以在 HBase Shell 中完成。
......@@ -15,31 +15,31 @@ $ ./bin/hbase shell
请参阅 [shell exercises](#shell_exercises)
这是Rajeshbabu Chintaguntla的[所有shell命令](http://learnhbase.wordpress.com/2013/03/02/hbase-shell-commands/)
这是 Rajeshbabu Chintaguntla 的[所有 shell 命令](http://learnhbase.wordpress.com/2013/03/02/hbase-shell-commands/)
## 14\. 用Ruby编写脚本
## 14\. 用 Ruby 编写脚本
有关Apache HBase脚本示例, 请查看 HBase _bin_ 文件夹. 查看以 _*.rb_结尾的文件. 执行下面操作,运行:
有关 Apache HBase 脚本示例, 请查看 HBase _bin_ 文件夹. 查看以 _*.rb_ 结尾的文件. 执行下面操作,运行:
```
$ ./bin/hbase org.jruby.Main PATH_TO_SCRIPT
```
## 15\. 非交互方式运行Shell
## 15\. 非交互方式运行 Shell
HBase Shell 先增了一种非交互方式([HBASE-11658)](https://issues.apache.org/jira/browse/HBASE-11658).非交互模式捕获 HBase Shell 命令的退出状态(成功或失败),并将该状态返回给命令解释器。如果您使用正常的交互模式,HBase Shell 将只会返回自己的退出状态,这几乎总是会`0`成功的。
要调用非交互模式,请将 `-n``--non-interactive` 选项传递给 HBase Shell。
## 16\. 系统脚本中的HBase Shell
## 16\. 系统脚本中的 HBase Shell
您可以在操作系统脚本解释器中使用 HBase shell,例如 Bash shell,它是大多数 Linux 和 UNIX 发行版的默认命令解释程序。以下准则使用 Bash 语法,但可以调整为使用 C 样式的 shell(例如 csh 或 tcsh),并且可能会修改为使用 Microsoft Windows 脚本解释器一起使用。
> 这种方式生成 HBase Shell 命令的速度很慢,所以在决定何时将 HBase 操作与操作系统命令行相结合时,请记住这一点。
Example 4\. 传递命令到HBase Shell
Example 4\. 传递命令到 HBase Shell
您可以使用 `echo` 命令和 `|`(管道)操作,以非交互模式将命令传递到 HBase Shell。 (详见: [hbase.shell.noninteractive](#hbase.shell.noninteractive)) .一定要转义 HBase 命令中的字符,否则 shell 将会解释这些字符。一些调试级别的输出已从下面的示例中截断。
......@@ -93,10 +93,10 @@ return $status
获取退出代码`0`意味着您脚本编写的命令确实成功了。但是,获取非零退出代码并不一定意味着命令失败。该命令可能已成功,但客户端失去连接,或者其他事件阻碍了其成功。这是因为 RPC 命令是无状态的。确保操作状态的唯一方法是检查。例如,如果你的脚本创建一个表,但返回一个非零的退出值,你应该检查表是否实际创建,然后再试图创建它。
## 17\. 从命令文件读取HBase Shell命令
## 17\. 从命令文件读取 HBase Shell 命令
您可以将 HBase Shell 命令输入到文本文件中,每行一个命令,并将该文件传递给HBase Shell。
您可以将 HBase Shell 命令输入到文本文件中,每行一个命令,并将该文件传递给 HBase Shell。
命令文件示例
......@@ -114,7 +114,7 @@ disable 'test'
enable 'test'
```
Example 6\. 指示HBase Shell执行命令
Example 6\. 指示 HBase Shell 执行命令
将命令文件的路径作为 `hbase shell` 命令的唯一参数传递。每个命令都会执行并显示其输出。如果您未在脚本中包含该 `exit` 命令,则会返回到 HBase shell 提示符。没有办法以编程方式检查每个单独的命令是否成功或失败。此外,尽管您看到每个命令的输出,但命令本身并未回显到屏幕,因此可能难以将命令与其输出对齐。
......@@ -151,9 +151,9 @@ COLUMN CELL
0 row(s) in 0.4360 seconds
```
## 18\. 将VM选项传递给Shell
## 18\. 将 VM 选项传递给 Shell
您可以使用 `HBASE_SHELL_OPTS` 环境变量将 VM 选项传递到 HBase Shell 。您可以在您的环境中进行设置,例如通过编辑 _〜/.bashrc_,或将其设置为启动HBase Shell 的命令的一部分。以下的示例设置了几个与垃圾回收相关的变量,仅用于运行 HBase Shell 的 VM 的生命周期。为了可读性,该命令应该在单行中全部运行,但是会被 `\` 字符打断。
您可以使用 `HBASE_SHELL_OPTS` 环境变量将 VM 选项传递到 HBase Shell 。您可以在您的环境中进行设置,例如通过编辑 _〜/.bashrc_,或将其设置为启动 HBase Shell 的命令的一部分。以下的示例设置了几个与垃圾回收相关的变量,仅用于运行 HBase Shell 的 VM 的生命周期。为了可读性,该命令应该在单行中全部运行,但是会被 `\` 字符打断。
```
......@@ -161,9 +161,9 @@ $ HBASE_SHELL_OPTS="-verbose:gc -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCD
-XX:+PrintGCDetails -Xloggc:$HBASE_HOME/logs/gc-hbase.log" ./bin/hbase shell
```
## 19\. 覆盖启动HBase Shell的配置
## 19\. 覆盖启动 HBase Shell 的配置
hbase-2.0.5/hbase-2.1.3/hbase-2.2.0/hbase-1.4.10/hbase-1.5.0, 您可以传递或覆盖`hbase-*.xml`中指定的hbase配置。在命令行上传递前缀为`-D`的键/值,如下所示:
hbase-2.0.5/hbase-2.1.3/hbase-2.2.0/hbase-1.4.10/hbase-1.5.0, 您可以传递或覆盖`hbase-*.xml`中指定的 hbase 配置。在命令行上传递前缀为`-D`的键/值,如下所示:
```
$ ./bin/hbase shell -Dhbase.zookeeper.quorum=ZK0.remote.cluster.example.org,ZK1.remote.cluster.example.org,ZK2.remote.cluster.example.org -Draining=false
......@@ -175,7 +175,7 @@ hbase(main):002:0> @shell.hbase.configuration.get("raining")
```
## 20\. Shell技巧
## 20\. Shell 技巧
### 20.1\. Table 变量
......@@ -294,7 +294,7 @@ IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"
```
如果您想避免将每个表达式的计算结果打印到stderr,例如从“list”命令返回的表数组:
如果您想避免将每个表达式的计算结果打印到 stderr,例如从“list”命令返回的表数组:
```
......@@ -302,12 +302,12 @@ $ echo "IRB.conf[:ECHO] = false" >>~/.irbrc
```
请参阅_.irbrc_的`ruby`文档以了解其他可能的配置。
请参阅 _.irbrc_ 的`ruby`文档以了解其他可能的配置。
### 20.3\. LOG data to timestamp
要将日期'08/08/16 20:56:29'从hbase日志转换为时间戳,请执行以下操作:
要将日期'08/08/16 20:56:29'从 hbase 日志转换为时间戳,请执行以下操作:
```
hbase(main):021:0> import java.text.SimpleDateFormat
......
此差异已折叠。
# HBase 和 Schema 设计
> 者:[Raymondcode](https://github.com/raymondcode)
> 贡献者:[Raymondcode](https://github.com/raymondcode)
关于各种非 RDBMS 数据存储建模的优缺点,可以在 Ian Varley 的硕士论文 [No Relation: The Mixed Blessings of Non-Relational Databases](http://ianvarley.com/UT/MR/Varley_MastersReport_Full_2009-08-07.pdf) 中找到。虽然有点过时,但是如果你想了解 HBase schema 的建模方式和 RDBMS 的实现方式有什么区别的话,可以当做背景知识阅读一下。另外,阅读 [keyvalue](#keyvalue) 来了解 HBase 内部是如何存储数据的,以及 [schema.casestudies](#schema.casestudies) 章节。
Cloud Bigtable 网站上的 [Designing Your Schema](https://cloud.google.com/bigtable/docs/schema-design) 是很好的相关文档,从里面学到的内容同样适用于 HBase 领域;只要把文档里任何引用的值除10左右即可得到对 HBase 适用的值。比如:文档中提到单个值的大小可以到约10MBs,HBase 也类似,或者最好尽可能的小一些;同时文档中提到,Cloud Bigtable 最多有 100 个列族,在 HBase 建模时考虑改为 约10个列族。
Cloud Bigtable 网站上的 [Designing Your Schema](https://cloud.google.com/bigtable/docs/schema-design) 是很好的相关文档,从里面学到的内容同样适用于 HBase 领域;只要把文档里任何引用的值除 10 左右即可得到对 HBase 适用的值。比如:文档中提到单个值的大小可以到约 10MBs,HBase 也类似,或者最好尽可能的小一些;同时文档中提到,Cloud Bigtable 最多有 100 个列族,在 HBase 建模时考虑改为 约 10 个列族。
另请参阅 Robert Yokota 的 [HBase Application Archetypes](https://blogs.apache.org/hbase/entry/hbase-application-archetypes-redux) (其他 HBaser 所完成工作的最新信息),以便对 HBase 模型上的使用案例进行有用的分类。
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -62,9 +62,15 @@
themeColor: '#ba160c',
repo: 'apachecn/hbase-doc-zh',
plugins: [window.docsPlugin],
search: {
paths: 'auto',
placeholder: '搜索',
noData: '没有结果',
},
}
</script>
<script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
<script src="//unpkg.com/docsify/lib/plugins/search.min.js"></script>
</body>
</html>
\ No newline at end of file
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册