Copyright © 2010 Apache Software Foundation, 盛大游戏-数据仓库团队-颜开(译)
Revision History |
|
Revision 0.90.4 |
|
配置,数据模型使用入门 |
Abstract
这是 ].现在官方的发行版都没有这个功能,所以你要自己打这个补丁。推荐看 Michael Noll写的详细的说明, ] [3].
需要澄清的,这两个设置是针对操作系统的,不是Hbase本身的。有一个常见的错误是Hbase运行的用户,和设置最大值的用户不是一个用户。在Hbase启动的时候,第一行日志会现在ulimit信息,所以你最好检查一下。 [4]
1.3.1.6.1. 在Ubuntu上设置ulimit
如果你使用的是Ubuntu,你可以这样设置:
在文件 /etc/security/limits.conf 添加一行,如:
hadoop - nofile 32768
可以把 hadoop 替换成你运行Hbase和Hadoop的用户。如果你用两个用户,你就需要配两个。还有配nproc hard 和 soft limits.如:
hadoop soft/hard nproc 32000
.
在 /etc/pam.d/common-session 加上这一行:
session required pam_limits.so
否则在 /etc/security/limits.conf上的配置不会生效.
还有注销再登录,这些配置才能生效!
1.3.1.7. dfs.datanode.max.xcievers
一个 Hadoop HDFS Datanode有一个同时处理文件的上限. 这个参数叫 xcievers (Hadoop的作者把这个单词拼错了).在你加载之前,先确认下你有没有配置这个文件conf/hdfs-site.xml里面的xceivers参数,至少要有4096:
<property>
<name>dfs.datanode.max.xcievers</name>
<value>4096</value>
</property>
对于HDFS修改配置要记得重启.
如果没有这一项配置,你可能会遇到奇怪的失败。你会在Datanode的日志中看到xcievers exceeded,但是运行起来会报 missing blocks错误。例如: 10/12/08 20:10:31 INFO hdfs.DFSClient: Couldnot obtain block blk_XXXXXXXXXXXXXXXXXXXXXX_YYYYYYYY from any node:java.io.IOException: No live nodes contain current block. Will get new blocklocations from namenode and retry... [5]
1.3.1.8. Windows
HBase没有怎么在Windows下测试过。所以不推荐在Windows下运行.
如果你实在是想运行,需要安装].
分布式模式需要使用 Hadoop Distributed File System (HDFS).可以参见 ]
1.3.2.2.2. 完全分布式模式
要想运行完全分布式模式,你要进行如下配置,先在 hbase-site.xml,加一个属性 hbase.cluster.distributed 设置为 true 然后把 hbase.rootdir 设置为HDFS的NameNode的位置。例如,你的namenode运行在namenode.example.org,端口是9000你期望的目录是 /hbase,使用如下的配置
<configuration>
...
<property>
<name>hbase.rootdir</name>
<value>hdfs://namenode.example.org:9000/hbase</value>
<description>The directory shared by RegionServers.
</description>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
<description>The mode the cluster will be in. Possible values are
false:standalone and pseudo-distributed setups with managed Zookeeper
true:fully-distributed with unmanaged Zookeeper Quorum (see hbase-env.sh)
</description>
</property>
...
</configuration>
1.3.2.2.2.1. regionservers
完全分布式模式的还需要修改conf/regionservers.在 ]
对于zookeepr的配置,你至少要在 hbase-site.xml中列出zookeepr的ensemble servers,具体的字段是 hbase.zookeeper.quorum.该这个字段的默认值是 localhost,这个值对于分布式应用显然是不可以的. (远程连接无法使用).
我需要运行几个zookeeper?
你运行一个zookeeper也是可以的,但是在生产环境中,你最好部署3,5,7个节点。部署的越多,可靠性就越高,当然只能部署奇数个,偶数个是不可以的。你需要给每个zookeeper 1G左右的内存,如果可能的话,最好有独立的磁盘。 (独立磁盘可以确保zookeeper是高性能的。).如果你的集群负载很重,不要把Zookeeper和RegionServer运行在同一台机器上面。就像DataNodes和 TaskTrackers一样
打个比方,Hbase管理着的ZooKeeper集群在节点 rs{1,2,3,4,5}.example.com,监听2222端口(默认是2181),并确保conf/hbase-env.sh文件中 HBASE_MANAGE_ZK的值是 true ,再编辑 conf/hbase-site.xml 设置hbase.zookeeper.property.clientPort 和 hbase.zookeeper.quorum。你还可以设置 hbase.zookeeper.property.dataDir属性来把ZooKeeper保存数据的目录地址改掉。默认值是 /tmp ,这里在重启的时候会被操作系统删掉,可以把它修改到 /user/local/zookeeper.
<configuration>
...
<property>
<name>hbase.zookeeper.property.clientPort</name>
<value>2222</value>
<description>Property from ZooKeeper's config zoo.cfg.
The port atwhich the clients will connect.
</description>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>rs1.example.com,rs2.example.com,rs3.example.com,rs4.example.com,rs5.example.com</value>
<description>Comma separated list of servers in the ZooKeeperQuorum.
For example,"host1.mydomain.com,host2.mydomain.com,host3.mydomain.com".
By defaultthis is set to localhost for local and pseudo-distributed modes
of operation.For a fully-distributed setup, this should be set to a full
list ofZooKeeper quorum servers. If HBASE_MANAGES_ZK is set in hbase-env.sh
this is thelist of servers which we will start/stop ZooKeeper on.
</description>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/usr/local/zookeeper</value>
<description>Property from ZooKeeper's config zoo.cfg.
The directorywhere the snapshot is stored.
</description>
</property>
...
</configuration>
1.3.2.2.2.2.1. 使用现有的ZooKeeper例子
让Hbase使用一个现有的不被Hbase托管的Zookeep集群,需要设置 conf/hbase-env.sh文件中的HBASE_MANAGES_ZK 属性为 false
...
# Tell HBasewhether it should manage it's own instance of Zookeeper or not.
exportHBASE_MANAGES_ZK=false
接下来,指明Zookeeper的host和端口。可以在 hbase-site.xml中设置,也可以在Hbase的CLASSPATH下面加一个zoo.cfg配置文件。 HBase 会优先加载 zoo.cfg 里面的配置,把hbase-site.xml里面的覆盖掉.
当Hbase托管ZooKeeper的时候,Zookeeper集群的启动是Hbase启动脚本的一部分。但现在,你需要自己去运行。你可以这样做
${HBASE_HOME}/bin/hbase-daemons.sh {start,stop} zookeeper
你可以用这条命令启动ZooKeeper而不启动Hbase. HBASE_MANAGES_ZK 的值是 false,如果你想在Hbase重启的时候不重启ZooKeeper,你可以这样做
对于独立Zoopkeeper的问题,你可以在 ] See CHANGES.txt in branch-0.20-append to see list of patchesinvolved adding append on the Hadoop 0.20 branch.
[2] See Jack Levin's majorhdfs issues note up on the user list.
[3] 这样的需求对于数据库应用来说是很常见的,例如Oracle。 SettingShell Limits for the Oracle User in ] A useful readsetting config on you hadoop cluster is Aaron Kimballs' ConfigurationParameters: What can you just ignore?
[5] 参见 ] 这两个命名法来自于Hadoop.
[7] See Pseudo-distributedmode extras for notes on how to start extra Masters and RegionServerswhen running pseudo-distributed.
[8] For the full listof ZooKeeper configurations, see ZooKeeper's zoo.cfg. HBase does not ship with a zoo.cfg so you willneed to browse the conf directory inan appropriate ZooKeeper download.
Chapter 2. 升级
Table of Contents
2.1.从HBase 0.20.x or 0.89.x 升级到 HBase 0.90.x
参见 ] .
[9] 参见 ] .
当你使用分布式模式的时间,当你编辑完一个文件之后,记得要把这个文件复制到整个集群的conf 目录下。Hbase不会帮你做这些,你得用 rsync.
3.1. hbase-site.xml 和 hbase-default.xml
正如Hadoop放置HDFS的配置文件hdfs-site.xml,Hbase的配置文件是 conf/hbase-site.xml.你可以在 ].
还要在本书的尾部参见 ] 随着数据量的增大,splite会被持续执行。如果你需要知道你现在有几个region,比如长时间的debug或者做调优,你需要手动切割。通过跟踪日志来了解region级的问题是很难的,因为他在不停的切割和重命名。data offlineingbug和未知量的region会让你没有办法。如果一个 HLog 或者 StoreFile由于一个奇怪的bug,Hbase没有执行它。等到一天之后,你才发现这个问题,你可以确保现在的regions和那个时候的一样,这样你就可以restore或者replay这些数据。你还可以调优你的合并算法。如果数据是均匀的,随着数据增长,很容易导致split / compaction疯狂的运行。因为所有的region都是差不多大的。用手的切割,你就可以交错执行定时的合并和切割操作,降低IO负载。
为什么我关闭自动split呢?因为自动的splite是配置文件中的 hbase.hregion.max.filesize决定的.你把它设置成ILong.MAX_VALUE是不推荐的做法,要是你忘记了手工切割怎么办.推荐的做法是设置成100GB,一旦到达这样的值,至少需要一个小时执行 major compactions。
那什么是最佳的在pre-splite regions的数量呢。这个决定于你的应用程序了。你可以先从低的开始,比如每个server10个pre-spliteregions.然后花时间观察数据增长。有太少的region至少比出错好,你可以之后再rolling split.一个更复杂的答案是这个值是取决于你的region中的最大的storefile。随着数据的增大,这个也会跟着增大。你可以当这个文件足够大的时候,用一个定时的操作使用Store的合并选择算法(compact selectionalgorithm)来仅合并这一个HStore。如果你不这样做,这个算法会启动一个 major compactions,很多region会受到影响,你的集群会疯狂的运行。需要注意的是,这样的疯狂合并操作是数据增长造成的,而不是手动分割操作决定的。
如果你 pre-split导致 regions 很小,你可以通过配置HConstants.MAJOR_COMPACTION_PERIOD把你的major compaction参数调大
如果你的数据变得太大,可以使用org.apache.hadoop.hbase.util.RegionSplitter 脚本来执行针对全部集群的一个网络IO安全的rolling split操作。
因为Hbase的Master有可能转移,所有客户端需要访问ZooKeeper来获得现在的位置。ZooKeeper会保存这些值。因此客户端必须知道Zookeeper集群的地址,否则做不了任何事情。通常这个地址存在 hbase-site.xml 里面,客户端可以从CLASSPATH取出这个文件.
如果你是使用一个IDE来运行Hbase客户端,你需要将conf/放入你的 classpath,这样 hbase-site.xml就可以找到了,(或者把hbase-site.xml放到 src/test/resources,这样测试的时候可以使用).
Hbase客户端最小化的依赖是 hbase, hadoop, log4j, commons-logging,commons-lang,和 ZooKeeper ,这些jars 需要能在 CLASSPATH 中找到。
下面是一个基本的客户端 hbase-site.xml 例子:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl"href="configuration.xsl"?>
<configuration>
<property>
<name>hbase.zookeeper.quorum</name>
<value>example1,example2,example3</value>
<description>The directory shared by region servers.
</description>
</property>
</configuration>
3.7.1. Java客户端配置
Java是如何读到hbase-site.xml 的内容的
Java客户端使用的配置信息是被映射在一个] Be careful editingXML. Make sure you close all elements. Run your file through xmllint orsimilar to ensure well-formedness of your document after an edit session.
[11] 参见 ] What follows istaken from the javadoc at the head of the org.apache.hadoop.hbase.util.RegionSplitter tool addedto HBase post-0.90.0 release.
Chapter 4. The HBase Shell
Table of Contents
]
· 可以发起包含版本的写操作,但是他们的版本顺序和操作顺序相反吗?[14]
下面我们介绍下在Hbase中版本是如何工作的。[15].
11.7.1. Hbase的操作(包含版本操作)
在这一章我们来仔细看看在Hbase的各个主要操作中版本起到了什么作用。
11.7.1.1. Get/Scan
Gets实在Scan的基础上实现的。可以详细参见下面的讨论 ]若你知道的版本比数据中的版本晚,就意味着这一行中的所有数据都会被删除。
11.7.2. 现有的限制
关于版本还有一些bug(或者称之为未实现的功能),计划在下个版本实现。
11.7.2.1. 删除标记误删Puts
删除标记操作可能会标记之后put的数据。[17].需要值得注意的是,当写下一个删除标记后,只有下一个major compaction操作发起之后,这个删除标记才会消失。设想一下,当你写下一个删除标记-“删除所有<=时间T的数据”。但之后,你又执行了一个Put操作,版本<= T。这样就算这个Put发生在删除之后,他的数据也算是打上了删除标记。这个Put并不会失败,但是你需要注意的是这个操作没有任何作用。只有一个major compaction执行只有,一切才会恢复正常。如果你的Put操作一直使用升序的版本,这个错误就不会发生。但是也有可能出现这样的情况,你删除之后,
11.7.2.2. Major compactions改变查询的结果
“设想一下,你一个cell有三个版本t1,t2和t3。你的maximun-version设置是2.当你请求获取全部版本的时候,只会返回两个,t2和t3。如果你将t2和t3删除,就会返回t1。但是如果在删除之前,发生了major compaction操作,那么什么值都不好返回了。[18]”
[13] 目前,只有最新的那个是可以获取到的。.
[14] 可以
[15] See HBASE-2406 fordiscussion of HBase versions. Bending time inHBase makes for a good read on the version, or time, dimension inHBase. It has more detail on versioning than is provided here. As of thiswriting, the limiitation Overwriting values at existing timestamps mentionedin the article no longer holds in HBase. This section is basically a synopsisof this article by Bruno Dumon.
[16] 当Hbase执行一次major compaction,标记删除的数据会被实际的删除,删除标记也会被删除。
[17] HBASE-2256
[18] See GarbageCollection in Bending time in HBase
Chapter 12. 架构
Table of Contents
12.1. 客户端
Hbase客户端的 ]
12.4.3.3. 如果处理一个发生在当RegionServers'WALs分割时候的EOFExceptions异常
如果我们在分割日志的时候发生EOF,就是hbase.hlog.split.skip.errors设置为 false,我们也会进行处理。一个EOF会发生在一行一行读取Log,但是Log中最后一行似乎只写了一半就停止了。如果在处理过程中发生了EOF,我们还会继续处理,除非这个文件是要处理的最后一个文件。[20]
[19] See HBASE-2958When hbase.hlog.split.skip.errors is set to false, we fail the split but thatsit. We need to do more than just fail split if this flag is set.
[20] 要想知道背景知识,参见 ][22] (译者注:Bloom Filter是一个算法,可以用来快速确认一个Row Key或者值是否在一个Hfile里面。)
14.1. 配置
可以在column family的选项的配置Blooms.可以通过Hbase Shell,也可以用Java代码操作 org.apache.hadoop.hbase.HColumnDescriptor.
14.1.1. HColumnDescriptor 配置
使用 HColumnDescriptor.setBloomFilterType(NONE | ROW | ROWCOL)来控制每个column family的Blooms这种。默认值是 NONE ,如果值是ROW,就会在插入的时候去Hash这个row,加入到Bloom中去。如果值是ROWCOL,就Hash这个row,column family和column familyqualifer。(译者注,ROW是哈希row key)
14.1.2. io.hfile.bloom.enabled 全局关闭开关
当有些东西出错的时候,Configuration中的io.hfile.bloom.enabled是一个关闭的开关。默认是 true.
14.1.3. io.hfile.bloom.error.rate
io.hfile.bloom.error.rate =平均错误率。默认是 1%.减少一半(如 .5%),就意味着每个bloom entry加一个bit.
14.1.4. io.hfile.bloom.max.fold
io.hfile.bloom.max.fold =保证最低的fold率。大多数人不该修改这个值,默认是7,就是说可以折叠到原本大小的1/128。参见 DevelopmentProcess中的文档 ] For description ofthe development process -- why static blooms rather than dynamic -- and for anoverview of the unique properties that pertain to blooms in HBase, as well aspossible future directions, see the Development Process sectionof the document BloomFilters in HBase attached to HBase-1200.
[22] The bloom filtersdescribed here are actually version two of blooms in HBase. In versions up to0.19.x, HBase had a dynamic bloom option based on work done by the European Commission One-LabProject 034819. The core of the HBase bloom work was later pulled up intoHadoop to implement org.apache.hadoop.io.BloomMapFile. Version 1 of HBaseblooms never worked that well. Version 2 is a rewrite from scratch though againit starts with the one-lab work.
Chapter 15. Hbase的故障排除和Debug
Table of Contents
15.4.1.ScannerTimeoutException
15.1. 一般准则
首先可以看看master的log。通常情况下,他总是一行一行的重复信息。如果不是这样,说明有问题,可以Google或是用search-hadoop.com来搜索遇到的exception。
一个错误通常不是单独出现在Hbase中的,通常是某一个地方发生了异常,然后对其他的地方发生影响。到处都是exception和stack straces。遇到这样的错误,最好的办法是查日志,找到最初的异常。例如Region会在abort的时候打印一下信息。Grep这个Dump就有可能找到最初的异常信息。
RegionServer的自杀是很“正常”的。当一些事情发生错误的,他们就会自杀。如果ulimit和xcievers(最重要的两个设定,详见Section 1.3.1.6, “ ulimit 和 nproc ”)没有修改,HDFS将无法运转正常,在HBase看来,HDFS死掉了。假想一下,你的MySQL突然无法访问它的文件系统,他会怎么做。同样的事情会发生在Hbase和HDFS上。还有一个造成RegionServer切腹(译者注:竟然用日文词)自杀的常见的原因是,他们执行了一个长时间的GC操作,这个时间超过了ZooKeeper的session timeout。关于GC停顿的详细信息,参见Todd Lipcon的 3 part blog post by Todd Lipcon 和上面的 Section 13.1.1.1, “长时间GC停顿”.
15.2. Logs
重要日志的位置( <user>是启动服务的用户,<hostname>是机器的名字)
NameNode: $HADOOP_HOME/logs/hadoop-<user>-namenode-<hostname>.log
DataNode: $HADOOP_HOME/logs/hadoop-<user>-datanode-<hostname>.log
JobTracker: $HADOOP_HOME/logs/hadoop-<user>-jobtracker-<hostname>.log
TaskTracker: $HADOOP_HOME/logs/hadoop-<user>-jobtracker-<hostname>.log
HMaster: $HBASE_HOME/logs/hbase-<user>-master-<hostname>.log
RegionServer: $HBASE_HOME/logs/hbase-<user>-regionserver-<hostname>.log
ZooKeeper: TODO
15.2.1. Log位置
对于单节点模式,Log都会在一台机器上,但是对于生产环境,都会运行在一个集群上。
15.2.1.1. NameNode
NameNode的日志在NameNode server上。HBase Master 通常也运行在NameNode server上,ZooKeeper通常也是这样。
对于小一点的机器,JobTracker也通常运行在NameNode server上面。
15.2.1.2. DataNode
每一台DataNode server有一个HDFS的日志,Region有一个Hbase日志。
每个DataNode server还有一份TaskTracker的日志,来记录MapReduce的Task信息。
15.3. 工具
15.3.1. search-hadoop.com
search-hadoop.com将所有的 mailing lists 和 JIRA建立了索引。用它来找Hadoop/HBase的问题很方便。
15.3.2. tail
tail是一个命令行工具,可以用来看日志的尾巴。加入的"-f"参数后,就会在数据更新的时候自己刷新。用它来看日志很方便。例如,一个机器需要花很多时间来启动或关闭,你可以tail他的master log(也可以是region server的log)。
15.3.3. top
top是一个很重要的工具来看你的机器各个进程的资源占用情况。下面是一个生产环境的例子:
top - 14:46:59 up 39 days, 11:55, 1 user, load average: 3.75, 3.57, 3.84
Tasks: 309 total, 1 running, 308 sleeping, 0stopped, 0 zombie
Cpu(s): 4.5%us, 1.6%sy, 0.0%ni, 91.7%id, 1.4%wa, 0.1%hi, 0.6%si, 0.0%st
Mem: 24414432ktotal, 24296956k used, 117476kfree, 7196k buffers
Swap: 16008732k total, 14348kused, 15994384k free, 11106908k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
15558 hadoop18 -2 3292m 2.4g 3556 S 79 10.4 6523:52 java
13268 hadoop18 -2 8967m 8.2g 4104 S 21 35.1 5170:30 java
8895 hadoop 18 -21581m 497m 3420 S 11 2.1 4002:32 java
…
这里你可以看到系统的load average在最近5分钟是3.75,意思就是说这5分钟里面平均有3.75个线程在CPU时间的等待队列里面。通常来说,最完美的情况是这个值和CPU和核数相等,比这个值低意味着资源闲置,比这个值高就是过载了。这是一个重要的概念,要想理解的更多,可以看这篇文章 http://www.linuxjournal.com/article/9001.
处理负载,我们可以看到系统已经几乎使用了他的全部RAM,其中大部分都是用于OS cache(这是一件好事).Swap只使用了一点点KB,这正是我们期望的,如果数值很高的话,就意味着在进行交换,这对Java程序的性能是致命的。另一种检测交换的方法是看Load average是否过高(load average过高还可能是磁盘损坏或者其它什么原因导致的)。
默认情况下进程列表不是很有用,我们可以看到3个Java进程使用了111%的CPU。要想知道哪个进程是什么,可以输入"c",每一行就会扩展信息。输入“1”可以显示CPU的每个核的具体状况。
15.3.4. jps
jps是JDK集成的一个工具,可以用来看当前用户的Java进程id。(如果是root,可以看到所有用户的id),例如:
hadoop@sv4borg12:~$ jps
1322 TaskTracker
17789 HRegionServer
27862 Child
1158 DataNode
25115 HQuorumPeer
2950 Jps
19750 ThriftServer
18776 jmx
按顺序看
· Hadoop TaskTracker,管理本地的Task
· HBase RegionServer,提供region的服务
· Child,一个 MapReduce task,无法看出详细类型
· Hadoop DataNode,管理blocks
· HQuorumPeer, ZooKeeper集群的成员
· Jps,就是这个进程
· ThriftServer,当thrif启动后,就会有这个进程
· jmx,这个是本地监控平台的进程。你可以不用这个。
你可以看到这个进程启动是全部命令行信息。
hadoop@sv4borg12:~$ ps aux | grep HRegionServer
hadoop 17789 155 35.2 9067824 8604364 ? S<l Mar04 9855:48 /usr/java/jdk1.6.0_14/bin/java -Xmx8000m-XX:+DoEscapeAnalysis -XX:+AggressiveOpts -XX:+UseConcMarkSweepGC-XX:NewSize=64m -XX:MaxNewSize=64m -XX:CMSInitiatingOccupancyFraction=88-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps-Xloggc:/export1/hadoop/logs/gc-hbase.log-Dcom.sun.management.jmxremote.port=10102-Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.password.file=/home/hadoop/hbase/conf/jmxremote.password-Dcom.sun.management.jmxremote -Dhbase.log.dir=/export1/hadoop/logs-Dhbase.log.file=hbase-hadoop-regionserver-sv4borg12.log -Dhbase.home.dir=/home/hadoop/hbase-Dhbase.id.str=hadoop -Dhbase.root.logger=INFO,DRFA-Djava.library.path=/home/hadoop/hbase/lib/native/Linux-amd64-64 -classpath/home/hadoop/hbase/bin/../conf:[many jars]:/home/hadoop/hadoop/conforg.apache.hadoop.hbase.regionserver.HRegionServer start
15.3.5. jstack
jstack 是一个最重要(除了看Log)的java工具,可以看到具体的Java进程的在做什么。可以先用Jps看到进程的Id,然后就可以用jstack。他会按线程的创建顺序显示线程的列表,还有这个线程在做什么。下面是例子:
这个主线程是一个RegionServer正在等master返回什么信息。
"regionserver60020" prio=10 tid=0x0000000040ab4000 nid=0x45cfwaiting on condition [0x00007f16b6a96000..0x00007f16b6a96a70]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00007f16cd5c2f30> (ajava.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
atjava.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198)
atjava.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1963)
atjava.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:395)
atorg.apache.hadoop.hbase.regionserver.HRegionServer.run(HRegionServer.java:647)
at java.lang.Thread.run(Thread.java:619)
The MemStore flusher thread that iscurrently flushing to a file:
"regionserver60020.cacheFlusher" daemon prio=10tid=0x0000000040f4e000 nid=0x45eb in Object.wait()[0x00007f16b5b86000..0x00007f16b5b87af0]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
atorg.apache.hadoop.ipc.Client.call(Client.java:803)
- locked <0x00007f16cb14b3a8> (aorg.apache.hadoop.ipc.Client$Call)
atorg.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:221)
at $Proxy1.complete(Unknown Source)
atsun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
atjava.lang.reflect.Method.invoke(Method.java:597)
atorg.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:82)
atorg.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:59)
at $Proxy1.complete(Unknown Source)
atorg.apache.hadoop.hdfs.DFSClient$DFSOutputStream.closeInternal(DFSClient.java:3390)
- locked <0x00007f16cb14b470> (aorg.apache.hadoop.hdfs.DFSClient$DFSOutputStream)
atorg.apache.hadoop.hdfs.DFSClient$DFSOutputStream.close(DFSClient.java:3304)
atorg.apache.hadoop.fs.FSDataOutputStream$PositionCache.close(FSDataOutputStream.java:61)
atorg.apache.hadoop.fs.FSDataOutputStream.close(FSDataOutputStream.java:86)
atorg.apache.hadoop.hbase.io.hfile.HFile$Writer.close(HFile.java:650)
atorg.apache.hadoop.hbase.regionserver.StoreFile$Writer.close(StoreFile.java:853)
atorg.apache.hadoop.hbase.regionserver.Store.internalFlushCache(Store.java:467)
- locked <0x00007f16d00e6f08> (ajava.lang.Object)
atorg.apache.hadoop.hbase.regionserver.Store.flushCache(Store.java:427)
at org.apache.hadoop.hbase.regionserver.Store.access$100(Store.java:80)
atorg.apache.hadoop.hbase.regionserver.Store$StoreFlusherImpl.flushCache(Store.java:1359)
atorg.apache.hadoop.hbase.regionserver.HRegion.internalFlushcache(HRegion.java:907)
at org.apache.hadoop.hbase.regionserver.HRegion.internalFlushcache(HRegion.java:834)
atorg.apache.hadoop.hbase.regionserver.HRegion.flushcache(HRegion.java:786)
atorg.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.java:250)
atorg.apache.hadoop.hbase.regionserver.MemStoreFlusher.flushRegion(MemStoreFlusher.java:224)
atorg.apache.hadoop.hbase.regionserver.MemStoreFlusher.run(MemStoreFlusher.java:146)
一个处理线程是在等一些东西(例如put, delete,scan...):
"IPC Server handler 16 on 60020" daemon prio=10tid=0x00007f16b011d800 nid=0x4a5e waiting on condition[0x00007f16afefd000..0x00007f16afefd9f0]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00007f16cd3f8dd8> (ajava.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
atjava.util.concurrent.locks.LockSupport.park(LockSupport.java:158)
atjava.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1925)
atjava.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:358)
atorg.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1013)
有一个线程正在忙,在递增一个counter(这个阶段是正在创建一个scanner来读最新的值):
"IPC Server handler 66 on 60020" daemon prio=10tid=0x00007f16b006e800 nid=0x4a90 runnable[0x00007f16acb77000..0x00007f16acb77cf0]
java.lang.Thread.State: RUNNABLE
at org.apache.hadoop.hbase.regionserver.KeyValueHeap.<init>(KeyValueHeap.java:56)
atorg.apache.hadoop.hbase.regionserver.StoreScanner.<init>(StoreScanner.java:79)
atorg.apache.hadoop.hbase.regionserver.Store.getScanner(Store.java:1202)
at org.apache.hadoop.hbase.regionserver.HRegion$RegionScanner.<init>(HRegion.java:2209)
atorg.apache.hadoop.hbase.regionserver.HRegion.instantiateInternalScanner(HRegion.java:1063)
atorg.apache.hadoop.hbase.regionserver.HRegion.getScanner(HRegion.java:1055)
atorg.apache.hadoop.hbase.regionserver.HRegion.getScanner(HRegion.java:1039)
atorg.apache.hadoop.hbase.regionserver.HRegion.getLastIncrement(HRegion.java:2875)
atorg.apache.hadoop.hbase.regionserver.HRegion.incrementColumnValue(HRegion.java:2978)
atorg.apache.hadoop.hbase.regionserver.HRegionServer.incrementColumnValue(HRegionServer.java:2433)
atsun.reflect.GeneratedMethodAccessor20.invoke(Unknown Source)
atsun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
atjava.lang.reflect.Method.invoke(Method.java:597)
atorg.apache.hadoop.hbase.ipc.HBaseRPC$Server.call(HBaseRPC.java:560)
atorg.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1027)
还有一个线程在从HDFS获取数据。
"IPC Client (47) connection tosv4borg9/10.4.24.40:9000 from hadoop" daemon prio=10tid=0x00007f16a02d0000 nid=0x4fa3 runnable[0x00007f16b517d000..0x00007f16b517dbf0]
java.lang.Thread.State:RUNNABLE
atsun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
atsun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215)
atsun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)
atsun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)
- locked <0x00007f17d5b68c00> (asun.nio.ch.Util$1)
- locked <0x00007f17d5b68be8> (ajava.util.Collections$UnmodifiableSet)
- locked <0x00007f1877959b50> (asun.nio.ch.EPollSelectorImpl)
atsun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)
atorg.apache.hadoop.NET.SocketIOWithTimeout$SelectorPool.select(SocketIOWithTimeout.java:332)
atorg.apache.hadoop.Net.SocketIOWithTimeout.doIO(SocketIOWithTimeout.java:157)
atorg.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:155)
atorg.apache.hadoop.net.SocketInputStream.read(SocketInputStream.java:128)
atjava.io.FilterInputStream.read(FilterInputStream.java:116)
atorg.apache.hadoop.ipc.Client$Connection$PingInputStream.read(Client.java:304)
atjava.io.BufferedInputStream.fill(BufferedInputStream.java:218)
atjava.io.BufferedInputStream.read(BufferedInputStream.java:237)
-locked <0x00007f1808539178> (a java.io.BufferedInputStream)
atjava.io.DataInputStream.readInt(DataInputStream.java:370)
atorg.apache.hadoop.ipc.Client$Connection.receiveResponse(Client.java:569)
at org.apache.hadoop.ipc.Client$Connection.run(Client.java:477)
这里是一个RegionServer死了,master正在试着恢复。
"LeaseChecker" daemon prio=10tid=0x00000000407ef800 nid=0x76cd waiting on condition[0x00007f6d0eae2000..0x00007f6d0eae2a70]
--
java.lang.Thread.State:WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
atorg.apache.hadoop.ipc.Client.call(Client.java:726)
- locked <0x00007f6d1cd28f80> (aorg.apache.hadoop.ipc.Client$Call)
atorg.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:220)
at $Proxy1.recoverBlock(Unknown Source)
atorg.apache.hadoop.hdfs.DFSClient$DFSOutputStream.processDatanodeError(DFSClient.java:2636)
atorg.apache.hadoop.hdfs.DFSClient$DFSOutputStream.<init>(DFSClient.java:2832)
atorg.apache.hadoop.hdfs.DFSClient.append(DFSClient.java:529)
atorg.apache.hadoop.hdfs.DistributedFileSystem.append(DistributedFileSystem.java:186)
atorg.apache.hadoop.fs.FileSystem.append(FileSystem.java:530)
atorg.apache.hadoop.hbase.util.FSUtils.recoverFileLease(FSUtils.java:619)
atorg.apache.hadoop.hbase.regionserver.wal.HLog.splitLog(HLog.java:1322)
at org.apache.hadoop.hbase.regionserver.wal.HLog.splitLog(HLog.java:1210)
atorg.apache.hadoop.hbase.master.HMaster.splitLogAfterStartup(HMaster.java:648)
atorg.apache.hadoop.hbase.master.HMaster.joinCluster(HMaster.java:572)
at org.apache.hadoop.hbase.master.HMaster.run(HMaster.java:503)
15.3.6. OpenTSDB
OpenTSDB是一个Ganglia的很好的替代品,因为他使用Hbase来存储所有的时序而不需要采样。使用OpenTSDB来监控你的Hbase是一个很好的实践
这里有一个例子,集群正在同时进行上百个compaction,严重影响了IO性能。(TODO:在这里插入compactionQueueSize的图片)(译者注:囧)
给集群构建一个图表监控是一个很好的实践。包括集群和每台机器。这样就可以快速定位到问题。例如,在StumbleUpon,每个机器有一个图表监控,包括OS和Hbase,涵盖所有的重要的信息。你也可以登录到机器上,获取更多的信息。
15.3.7. clusterssh+top
clusterssh+top,感觉是一个穷人用的监控系统,但是他确实很有效,当你只有几台机器的是,很好设置。启动clusterssh后,你就会每台机器有个终端,还有一个终端,你在这个终端的操作都会反应到其他的每一个终端上。这就意味着,你在一天机器执行“top”,集群中的所有机器都会给你全部的top信息。你还可以这样tail全部的log,等等。
15.4. 客户端
15.4.1. ScannerTimeoutException
当从客户端到RegionServer的RPC请求超时。例如如果Scan.setCacheing的值设置为500,RPC请求就要去获取500行的数据,每500次.next()操作获取一次。因为数据是以大块的形式传到客户端的,就可能造成超时。将这个 serCacheing的值调小是一个解决办法,但是这个值要是设的太小就会影响性能。
15.5. RegionServer
15.5.1. 启动错误
15.5.1.1. 压缩链接错误
因为LZO压缩算法需要在集群中的每台机器都要安装,这是一个启动失败的常见错误。如果你获得了如下信息
11/02/20 01:32:15 ERROR lzo.GPLNativeCodeLoader: Couldnot load native gpl library
java.lang.UnsatisfiedLinkError: no gplcompression injava.library.path
atjava.lang.ClassLoader.loadLibrary(ClassLoader.java:1734)
atjava.lang.Runtime.loadLibrary0(Runtime.java:823)
atjava.lang.System.loadLibrary(System.java:1028)
就意味着你的压缩库出现了问题。参见配置章节的 LZO compression configuration.
15.5.2. 运行时错误
15.5.2.1. java.io.IOException...(Toomany open files)
参见快速入门的章节ulimit and nproc configuration.
15.5.2.2. xceiverCount 258 exceedsthe limit of concurrent xcievers 256
这个时常会出现在DataNode的日志中。
参见快速入门章节的 xceivers configuration.
15.5.2.3. 系统不稳定,DataNode或者其他系统进程有"java.lang.OutOfMemoryError: unable to create new native thread inexceptions"的错误
参见快速入门章节的 ulimit and nproc configuration.
15.5.2.4. DFS不稳定或者RegionServer租期超时
如果你收到了如下的消息
2009-02-24 10:01:33,516 WARNorg.apache.hadoop.hbase.util.Sleeper: We slept xxx ms, ten times longer thanscheduled: 10000
2009-02-24 10:01:33,516 WARNorg.apache.hadoop.hbase.util.Sleeper: We slept xxx ms, ten times longer thanscheduled: 15000
2009-02-24 10:01:36,472 WARNorg.apache.hadoop.hbase.regionserver.HRegionServer: unable to report to masterfor xxx milliseconds - retrying
或者看到了全GC压缩操作,你可能正在执行一个全GC。
15.5.2.5. "No live nodescontain current block" and/or YouAreDeadException
这个错误有可能是OS的文件句柄溢出,也可能是网络故障导致节点无法访问。
参见快速入门章节 ulimit and nproc configuration,检查你的网络。
15.5.3. 终止错误
15.6. Master
15.6.1. 启动错误
15.6.2. 终止错误
Appendix A. 工具
Table of Contents
A.3.1. HLog 工具
这里我们列举一些Hbase管理,分析,修理和Debug的工具。
A.1. HBase hbck
用于Hbase安装的 fsck
在Hbase集群上运行 hbck
$ ./bin/hbase hbck
这个命令的输出是 OK 或者 INCONSISTENCY.如果你的集群汇报inconsistencies,加上-details 看更多的详细信息。如果inconsistencies,多运行hbck 几次,因为inconsistencies可能是暂时的。 (集群正在启动或者region正在split)。加上-fix可以修复inconsistency(这是一个实验性的功能)
A.2. HFile工具
参见 Section 12.3.4.2.2, “HFile工具”.
A.3. WAL Tools
A.3.1. HLog 工具
HLog的main方法提供了手动切割和dump的方法。会把WALs或者splite的结果的内容保存在recovered.edits目录下
你可以使用
$ ./bin/hbaseorg.apache.hadoop.hbase.regionserver.wal.HLog --dumphdfs://example.org:9000/hbase/.logs/example.org,60020,1283516293161/10.10.21.10%3A60020.1283973724012
来获得一个WAL文件内容的文本化的Dump。如果返回码部位0,说明文件有错误,所有你可以用这个命令来看文件是否健康,将命令重定向到/dev/null,检查返回码就可以了。
相似的,你可以将一个log切割,运行如下命令:
$ ./bin/hbaseorg.apache.hadoop.hbase.regionserver.wal.HLog --splithdfs://example.org:9000/hbase/.logs/example.org,60020,1283516293161/
A.4. 压缩工具
参见 Section A.4, “压缩工具”.
A.5. Node下线
你可以在Hbase的特定的节点上运行下面的脚本来停止RegionServer:
$ ./bin/hbase-daemon.sh stop regionserver
RegionServer会首先关闭所有的region然后把它自己关闭,在停止的过程中,RegionServer的会向Zookeeper报告说他已经过期了。master会发现RegionServer已经死了,会把它当作崩溃的server来处理。他会将region分配到其他的节点上去。
在下线节点之前要停止Load Balancer
如果在运行load balancer的时候,一个节点要关闭,则Load Balancer和Master的recovery可能会争夺这个要下线的Regionserver。为了避免这个问题,先将load balancer停止,参见下面的 LoadBalancer.
RegionServer下线有一个缺点就是其中的Region会有好一会离线。Regions是被按顺序关闭的。如果一个server上有很多region,从第一个region会被下线,到最后一个region被关闭,并且Master确认他已经死了,该region才可以上线,整个过程要花很长时间。在Hbase 0.90.2中,我们加入了一个功能,可以让节点逐渐的摆脱他的负载,最后关闭。HBase 0.90.2加入了 graceful_stop.sh脚本,可以这样用,
$ ./bin/graceful_stop.sh
Usage: graceful_stop.sh [--config &conf-dir>][--restart] [--reload] [--thrift] [--rest] &hostname>
thrift If we should stop/start thriftbefore/after the hbase stop/start
rest If we should stop/start rest before/afterthe hbase stop/start
restart If we should restart after graceful stop
reload Move offloaded regions back on to thestopped server
debug Move offloaded regions back on to thestopped server
hostname Hostname of server we are to stop
要下线一台RegionServer可以这样做
$ ./bin/graceful_stop.sh HOSTNAME
这里的HOSTNAME是RegionServer的host you woulddecommission.
On HOSTNAME
传递到graceful_stop.sh的HOSTNAME必须和hbase使用的hostname一致,hbase用它来区分RegionServers。可以用master的UI来检查RegionServers的id。通常是hostname,也可能是FQDN。不管Hbase使用的哪一个,你可以将它传到 graceful_stop.sh脚本中去,目前他还不支持使用IP地址来推断hostname。所以使用IP就会发现server不在运行,也没有办法下线了。
graceful_stop.sh 脚本会一个一个将region从RegionServer中移除出去,以减少改RegionServer的负载。他会先移除一个region,然后再将这个region安置到一个新的地方,再移除下一个,直到全部移除。最后graceful_stop.sh脚本会让RegionServer stop.,Master会注意到RegionServer已经下线了,这个时候所有的region已经重新部署好。RegionServer就可以干干净净的结束,没有WAL日志需要分割。
Load Balancer
当执行graceful_stop脚本的时候,要将Region LoadBalancer关掉(否则balancer和下线脚本会在region部署的问题上存在冲突):
hbase(main):001:0> balance_switch false
true
0 row(s) in 0.3590 seconds
上面是将balancer关掉,要想开启:
hbase(main):001:0> balance_switch true
false
0 row(s) in 0.3590 seconds
A.5.1. 依次重启
你还可以让这个脚本重启一个RegionServer,不改变上面的Region的位置。要想保留数据的位置,你可以依次重启(Rolling Restart),就像这样:
$ for i in `cat conf/regionservers|sort`; do./bin/graceful_stop.sh --restart --reload --debug $i; done &>/tmp/log.txt &
Tail /tmp/log.txt来看脚本的运行过程.上面的脚本只对RegionServer进行操作。要确认load balancer已经关掉。还需要在之前更新master。下面是一段依次重启的伪脚本,你可以借鉴它:
1. 确认你的版本,保证配置已经rsync到整个集群中。如果版本是0.90.2,需要打上HBASE-3744和 HBASE-3756两个补丁。
2. 运行hbck确保你的集群是一致的
$ ./bin/hbase hbck
当发现不一致的时候,可以修复他。
3. 重启Master:
$ ./bin/hbase-daemon.sh stop master;./bin/hbase-daemon.sh start master
4. 关闭region balancer:
$ echo "balance_switch false" | ./bin/hbase
5. 在每个RegionServer上运行graceful_stop.sh:
6.$ for i in `cat conf/regionservers|sort`;do ./bin/graceful_stop.sh --restart --reload --debug $i; done &>/tmp/log.txt &
如果你在RegionServer还开起来thrift和rest server。还需要加上--thrift or --rest选项 (参见 graceful_stop.sh 脚本的用法).
7. 再次重启Master.这会把已经死亡的server列表清空,重新开启balancer.
8. 运行 hbck保证集群是一直的
Appendix B. HBase中的压缩
Table of Contents
B.2. hbase.regionserver.codecs
B.1. 测试压缩工具
HBase有一个用来测试压缩新的工具。要想运行它,输入/bin/hbase org.apache.hadoop.hbase.util.CompressionTest.就会有提示这个工具的具体用法
B.2. hbase.regionserver.codecs
如果你的安装错误,就会测试不成功,或者无法启动。可以在你的hbase-site.xml加上配置 hbase.regionserver.codecs 值你需要的codecs。例如,如果 hbase.regionserver.codecs 的值是 lzo,gz 同时lzo不存在或者没有正确安装, RegionServer在启动的时候会提示配置错误。
当一台新机器加入到集群中的时候,管理员一定要注意,这台新机器有可能要安装特定的压缩解码器。
B.3. LZO
参见上面的 Section 3.6.4, “LZO 压缩”
B.4. GZIP
相对于LZO,GZIP的压缩率更高但是速度更慢。在某些特定情况下,压缩率是优先考量的。Java会使用Java自带的GZIP,除非Hadoop的本地库在CLASSPATH中。在这种情况下,最好使用本地压缩器。(如果本地库不存在,可以在Log看到很多Got brand-newcompressor。参见Q:)
Appendix C. FAQ
C.1. 一般问题
Hbase还有其他的FAQs吗?
HBase 支持 SQL吗?
HBase是如何工作在HDFS上的?
为什么日志的最后一行是'2011-01-10 12:40:48,407 INFOorg.apache.hadoop.io.compress.CodecPool: Got brand-new compressor'?
C.2. EC2
为什么我的连接EC2上的集群的远程Java连接不能工作?
C.3. 构建 HBase
当我build的时候,为什么遇到 Unable to find resource'VM_global_library.vm'?
C.4. Runtime
为什么我在Hbase loading的是看到了停顿
为什么我的RegionServer会突然挂住?
为什么我看到RegionServer的数量是实际的两倍。一半使用域名,一半使用IP。
C.5. 我如何在Hbase中建立
二级索引?
C.1.一般问题 |
|
Hbase还有其他的FAQs吗? |
|
可以在Hbase的wiki HBase Wiki FAQ 和 Troubleshooting 看到更多的FAQ. |
|
HBase支持 SQL吗? |
|
不支持。可以通过Hive的SQL-ish来支持,该功能还在开发中。但是Hive是基于MapReduce的,对于低延迟的应用并不适合。参见Chapter 11, 数据模型,可以看到Hbase客户端的例子。 |
|
HBase是如何工作在HDFS上的? |
|
HDFS是一个为大文件设计的分布式文件系统。他的文档明确说了,它不是一个通用的文件系统,文件不支持快速的记录查找。另一方面,HBase是建立在HDFS之上,并且支持大表快速记录查找(更新)。这有时候会混淆概念。参见Chapter 11, 数据模型 和 Chapter 12, 架构,来了解更多Hbase的目标。 |
|
为什么日志的最后一行是'2011-01-10 12:40:48,407 INFO org.apache.hadoop.io.compress.CodecPool: Got brand-new compressor'? |
|
因为我们没有使用本地的压缩类库。参见 HBASE-1900 Put back native support when hadoop 0.21 is released.将Hadoop的本地类库拷贝到Hbase下面(或者做软链接)就可以了 |
|
C.2. EC2 |
|
为什么我的连接EC2上的集群的远程Java连接不能工作? |
|
根据用户列表,参见: Remote Java client connection into EC2 instance. |
|
C.3.构建 HBase |
|
当我build的时候,为什么遇到 Unable to find resource 'VM_global_library.vm'? |
|
当我build的时候,为什么遇到 Unable to find resource 'VM_global_library.vm'? |
|
忽略他。这不是一个错误。这是officially ugly . |
|
C.4. Runtime |
|
为什么我在Hbase loading的是看到了停顿 |
|
如果启用了压缩,参见用户列表 Long client pauses with compression. |
|
为什么我的RegionServer会突然挂住? |
|
如果你使用了一个老式的JVM (< 1.6.0_u21?)?你可以看看thread dump,是不是线程都BLOCKED但是没有一个hold着锁。参见 HBASE 3622 Deadlock in HBaseServer (JVM bug?). 在Hbase的conf/hbase-env.sh中的HBASE_OPTS加上 -XX:+UseMembar 来修复它。 |
|
为什么我看到RegionServer的数量是实际的两倍。一半使用域名,一半使用IP。 |
|
修正你的DNS。在Hbase 0.92.x之前的版本,反向DNS和正向DNS需要返回一致。参见 HBASE 3431 Regionserver is not using the name given it by the master; double entry in master listing of servers 获得详细信息. |
|
C.5.我如何在Hbase中建立 |
|
二级索引? |
|
对于在Hbase中维护一个二级索引的问题,有一个用户的指导。参见David Butler在 HBase, mail # user - Stargate+hbase的信息。 |
Appendix D. YCSB: 雅虎云服务 测试 和Hbase
TODO: YCSB不能很多的增加集群负载.
TODO:如果给Hbase安装
Ted Dunning重做了YCSV,这个是用maven管理了,加入了核实工作量的功能。参见 Ted Dunning's YCSB.
Index
C
Cells, Cells
Column Family, ColumnFamily
H
Hadoop, hadoop
L
LZO, LZO压缩
N
nproc, ulimit 和 nproc
U
ulimit, ulimit 和 nproc
V
Versions, 版本
X
xcievers, dfs.datanode.max.xcievers
Z
ZooKeeper, ZooKeeper