HBase-管理秘籍-二-

85 阅读48分钟

HBase 管理秘籍(二)

原文:HBase Administration Cookbook

协议:CC BY-NC-SA 4.0

四、备份和恢复 HBase 数据

在本章中,我们将介绍:

  • 使用 distcp进行完全关闭备份
  • 使用 CopyTable将数据从一个表复制到另一个表
  • 导出 HBase 表以转储 HDFS 上的文件
  • 通过从 HDFS 导入转储文件恢复 HBase 数据
  • 备份 NameNode 元数据
  • 正在备份区域起始键
  • 群集复制

简介

如果您正在考虑在生产中使用 HBase,您可能希望了解 HBase 的备份选项和做法。 挑战在于您需要备份的数据集可能很大,因此备份解决方案必须高效。 预计它将能够扩展到数百 TB 的存储容量,并在合理的时间框架内完成数据恢复。

备份 HBase 有两种策略:

  • 通过完全关闭群集来备份它
  • 在实时群集上备份它

完全关闭备份必须首先停止 HBase(或禁用所有表),然后使用 Hadoop 的 distcp命令将 HBase 目录的内容复制到同一 HDFS 上的另一个目录,或复制到不同的 HDFS。 要从完全关闭的备份恢复,只需使用 distcp将备份的文件复制回 HBase 目录。

实时群集备份有几种方法:

  • 使用 CopyTable实用程序将数据从一个表复制到另一个表
  • 将 HBase 表导出到 HDFS 文件,然后将文件导入回 HBase
  • HBase 群集复制

CopyTable实用程序可用于将数据从一个表复制到同一集群上的另一个表,或复制到不同的集群。 Export实用程序将表的数据转储到同一集群上的 HDFS。 作为一组 ExportImport实用程序用于恢复转储文件的数据。

上述每种方法都有其优缺点。 完全关闭备份的好处是在备份过程中没有机会将数据写入群集,因此可以确保备份状态一致。 不利的一面是显而易见的--集群已经停机。 至于实时群集备份方法,由于群集已启动,因此在备份过程中可能会丢失编辑。 此外,由于 HBase 编辑仅在行级别是原子的,如果您的表相互依赖,则在执行 ExportCopyTable的同时修改表可能会导致备份不一致。 当前 Apache 版本不支持创建 HBase 表的快照。

HBase 支持集群复制。 这是在不同的 HBase 部署之间复制数据的一种方式。 可以将群集复制视为 HBase 级别的灾难恢复解决方案。

除了表之外,您可能还需要备份 HDFS 元数据和 HBase 区域起始键。 HDFS 元数据包含 HDFS 的文件系统映像和提交日志。 元数据损坏可能会损坏整个 HDFS 元数据;建议经常备份元数据。 区域起始键代表 HBase 中的数据分布。 备份区域起始键不仅可以恢复数据,还可以恢复数据分布。 如果我们提前拆分表,使用分布均匀的区域起始键,使用 CopyTable/Import实用程序恢复数据的速度可以显著提高。

在本章中,我们将介绍如何使用上述方法备份 HBase 数据,它们的优缺点,以及根据您的数据集大小、资源和要求选择哪种方法。

使用 Distcp 进行完全关闭备份

distcp(Distributed Copy)是 Hadoop 提供的一个工具,用于在相同或不同的 HDFS 群集上复制大型数据集。 它使用 MapReduce 并行复制文件、处理错误和恢复,并报告作业状态。

由于 HBase 将其所有文件(包括 HDFS 上的系统文件)都存储在 HDFS 上,因此我们可以简单地使用 distcp将 HBase 目录复制到同一 HDFS 上的另一个目录,或者复制到不同的 HDFS,以备份源 HBase 集群。

请注意,这是一个完全关闭的备份解决方案。 distcp工具之所以有效,是因为 HBase 集群已关闭(或所有表都被禁用),并且在此过程中没有对文件进行编辑。 不要在活动的 HBase 群集上使用而不是。 因此,此解决方案适用于能够容忍其 HBase 群集定期完全关闭的环境。 例如,用于后端批处理但不服务于前端请求的集群。

我们将介绍如何使用 distcp将完全关闭的 HBase 集群备份到不同的 HDFS 集群。 在不同群集上进行备份可用作灾难恢复解决方案,并有助于提高数据可用性。 在生产中,建议将完全关闭的 HBase 集群备份到不同的 HDFS 集群。

在本章后面部分,我们还将演示如何从备份中还原数据。

做好准备

如果要使用 distcp将 HBase 数据备份到另一个群集,则需要一个辅助群集。 您还可以将 HBase 数据备份到与源 HBase 群集相同的群集。 对于这种情况,不需要另一个群集。

在本食谱中,我们将使用不同的群集进行备份。 备份群集在不同的 EC2 实例上运行。 我们假设备份集群上运行的 HDFS 为 hdfs://l-master1:8020; l-master1,表示该集群运行在 EC2 大型实例上。 这是因为我们稍后将使用该集群进行性能调优,而小实例规格对于该用途来说太低了。

分别在源群集和备份群集上启动 HDFS。

distcp工具使用 MapReduce 并行复制文件,因此您还需要在源群集上启动 MapReduce。 可以使用以下命令从 JobTracker 节点启动 MapReduce:

hadoop@master1$ $HADOOP_HOME/bin/start-mapred.sh

我们将备份备份集群上 /backup目录下的 HBase 目录。 使用以下命令从备份群集的 Hadoop 客户端(l-client1)提前创建此目录:

hadoop@l-client1$ $HADOOP_HOME/bin/hadoop fs -mkdir /backup

怎么做……

按照以下说明使用 distcp:备份/恢复 HBase 数据

  1. 关闭源和备份 HBase 群集(如果它们正在运行):

    hadoop@master1$ $HBASE_HOME/bin/stop-hbase.sh
    
    
  2. 通过检查 HMaster 守护程序是否已启动,确保已在源群集上关闭 HBase:

    hadoop@master1$ $JAVA_HOME/bin/jps
    1567 JobTracker
    1416 NameNode
    1705 Jps
    1690 QuorumPeerMain
    
    
    • 确保输出中没有列出 HMaster 守护程序。
  3. Also, make sure mapred.map.tasks.speculative.execution is not set to final and true on the client of the source cluster.

    此属性在$HADOOP_HOME/conf目录下的 MapReduce 配置文件(mapred-site.xml)中设置。 如果设置为finaltrue,请删除该设置。 这是一个客户端更改;它只会影响从该客户端提交的 MapReduce 作业。

  4. 使用 distcp将 HBase 根目录从源群集复制到备份群集。 HBase 根目录由 HBase 配置文件(hbase-site.xml)中的 hbase.rootdir属性设置。 我们假设它是 hdfs://master1:8020/hbase,在这个配方中:

    hadoop@client1$ $HADOOP_HOME/bin/hadoop distcp hdfs://master1:8020/hbase hdfs://l-master1:8020/backup
    12/01/03 12:27:53 INFO tools.DistCp: srcPaths=[hdfs://master1:8020/hbase]
    12/01/03 12:27:53 INFO tools.DistCp: destPath=hdfs://l-master1:8020/backup
    12/01/03 12:27:54 INFO tools.DistCp: sourcePathsCount=76
    12/01/03 12:27:54 INFO tools.DistCp: filesToCopyCount=34
    12/01/03 12:27:54 INFO tools.DistCp: bytesToCopyCount=102.0m
    12/01/03 12:27:55 INFO mapred.JobClient: Running job: job_201201031153_0002
    12/01/03 12:27:56 INFO mapred.JobClient: map 0% reduce 0%
    ...
    
    

您将从 JobTracker 的管理页面中找到源群集的正在运行的 MapReduce 作业:

How to do it...

distcp作业完成后,您应该能够在备份群集上的 /backup目录下找到复制的 HBase 目录:

hadoop@l-client1$ $HADOOP_HOME/bin/hadoop fs -lsr /backup/hbase
drwxr-xr-x - hadoop hadoop 0 2012-01-03 12:28 /backup/hbase/-ROOT-
...

从上次备份恢复数据的步骤如下:

  1. 使用以下命令在备份群集上启动 MapReduce:

    hadoop@l-master1$ $HADOOP_HOME/bin/start-mapred.sh
    
    
  2. 确保备份群集客户端上的 mapred.map.tasks.speculative.execution未设置为 finaltrue

  3. 确保 HBase 未在源群集和备份群集上运行。 如果 HBase 正在运行,请先停止它:

    hadoop@l-master1$ $HBASE_HOME/bin/stop-hbase.sh
    
    
  4. 确保源群集上的 hbase.rootdir目录下没有文件。 如果存在文件,请将它们移动到另一个路径:

    hadoop@client1$ $HADOOP_HOME/bin/hadoop fs -mv /hbase /tmp
    
    
    • 如果您确定不需要这些文件,则可以将其删除。
  5. 将 HBase 目录从备份群集复制到源群集:

    hadoop@l-client1$ $HADOOP_HOME/bin/hadoop distcp hdfs: //l-master1:8020/backup/hbase hdfs://master1:8020/
    
    
  6. 在源群集上启动 HBase;您应该能够通过 HBase Shell 访问恢复的数据:

hadoop@master1$ $HBASE_HOME/bin/start-hbase.sh

它是如何工作的.

正如我们提到的, distcp是一个完全关闭的备份选项;因此,我们在步骤 1 中停止 HBase,并在步骤 2 中确认停止。 jps是 Java SDK 附带的一个方便的命令。 它显示被执行用户拥有的所有 Java 进程。 在我们的例子中,因为所有与 HBase 相关的守护进程都是由 hadoop用户启动的,所以我们可以使用 jps命令来查看 HBase 的主守护进程(HMaster)是否正在运行。

distcp使用 MapReduce 并行复制文件。 如果属性 mapred.map.tasks.speculative.execution设置为 true,则可以并行执行某些映射任务的多个实例,以执行相同的任务。 这是每个作业的客户端属性。 distcp会将其 MapReduce 作业的此属性设置为 false,因为 HDFS 不会处理同一文件的多个编写器。 但最终属性不能在单个 MapReduce 作业中更改。 如果将 mapred.map.tasks.speculative.execution设置为 finaltrue,则复制结果未定义。 在步骤 3 中,我们删除最后一个设置,以使 distcp能够在其 MapReduce 作业中配置此属性。

我们只需要复制 hbase.rootdir目录。 在步骤 4 中,我们执行 distcp将其从源群集复制到备份群集。参数包括源目录的完整路径(包括其 HDFS 架构)以及备份群集上目标目录的 HDFS 架构和路径。 正如您从其输出中看到的那样, distcp启动了一个 MapReduce 作业来并行复制数据。

distcp启动的 MapReduce 作业仅在其映射阶段复制数据。 贴图的最大数量由 -m选项指定。 请注意,这只是对 MapReduce 作业的一个提示;更多的映射不一定会增加同步副本的数量或总体吞吐量。

为了从备份恢复,我们将数据从备份群集复制回源群集,然后在源群集上启动 HBase。

有关 distcp选项的完整列表,请键入以下命令:

$HADOOP_HOME/bin/hadoop distcp

使用 CopyTable 将数据从一个表复制到另一个表

CopyTable是一个实用程序,用于将一个表的数据复制到同一集群或不同 HBase 集群上的另一个表。 您可以复制到同一群集中的表;但是,如果您有另一个要作为备份的群集,则可能需要使用 CopyTable作为实时备份选项,将表的数据复制到备份群集。

CopyTable可配置开始和结束时间戳。 如果指定,则只复制特定时间范围内带有时间戳的数据。 此功能使得在某些情况下可以增量备份 HBase 表。

备注

“增量备份”是一种只备份上次备份期间更改的数据的方法。

提示

注意:由于群集持续运行,因此在复制过程中可能会丢失编辑。

在本食谱中,我们将介绍如何使用 CopyTable将一个表的数据复制到不同 HBase 集群上的另一个表中。 我们将演示将数据从 hly_temp表复制到 hly_temp2表;我们将只复制列族 n中的数据。

做好准备

在客户机节点上,您需要将 HBase 配置文件(hbase-site.xml)添加到 Hadoop 的类路径,以便 MapReduce 作业可以访问 HBase 集群。 您可以通过链接 Hadoop 配置目录下的 hbase-site.xml来完成此操作,如下所示:

hadoop@client1$ ln -s $HBASE_HOME/conf/hbase-site.xml $HADOOP_HOME/conf/hbase-site.xml

另外,通过编辑 hadoop-env.sh:,将 HBase 依赖 JAR 添加到 Hadoop 的类路径中

hadoop@client1$ vi $HADOOP_HOME/conf/hadoop-env.sh

export HADOOP_CLASSPATH= /usr/local/zookeeper/current/zookeeper-3.4.3.jar

备注

上述步骤是在 HBase 上运行 MapReduce 的最低要求。 由于这是一个常见的过程,我们将在这本书中跳过它的细节。

在源群集和备份群集上启动 HBase。 如果没有另一个群集,还可以将一个表复制到本地群集上的另一个表。 但是,不建议将其用于生产中的备份目的。 我们假设备份集群的 ZooKeeper 仲裁为 l-master1:2181,HBase 根目录为 /hbase

CopyTable使用 MapReduce 并行复制数据;您需要使用以下命令在源群集上启动 MapReduce:

hadoop@master1$ $HADOOP_HOME/bin/start-mapred.sh

怎么做……

以下是将列族 n中的数据从 hly_temp表复制到备份群集上的 hly_temp2表的说明:

  1. 通过 HBase Shell 连接到备份 HBase 群集,如果目标表不存在,则创建目标表:

    hbase> create 'hly_temp2', {NAME => 'n'}
    
    
  2. Run the following command from your client node of the source cluster to copy data from the hly_temp table to hly_temp2 on the backup cluster:

    hac@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar copytable --families=n --peer.adr=l-master1:2181:/hbase --new.name=hly_temp2 hly_temp
    2/01/09 15:24:34 INFO zookeeper.ZooKeeper: Initiating client connection, connectString=l-master1:2181 sessionTimeout=10000 watcher=hconnection
    12/01/09 15:24:34 INFO zookeeper.ClientCnxn: Opening socket connection to server l-master1/10.170.114.96:2181
    12/01/09 15:24:34 INFO zookeeper.ClientCnxn: Socket connection established to l-master1/10.170.114.96:2181, initiating session
    12/01/09 15:24:34 INFO zookeeper.ClientCnxn: Session establishment complete on server l-master1/10.170.114.96:2181, sessionid = 0x134c11bb47c000a, negotiated timeout = 10000
    12/01/09 15:24:34 INFO mapreduce.TableOutputFormat: Created table instance for hly_temp2
    12/01/09 15:24:34 INFO zookeeper.ZooKeeper: Initiating client connection, connectString=master1:2181 sessionTimeout=10000 watcher=hconnection
    12/01/09 15:24:34 INFO zookeeper.ClientCnxn: Opening socket connection to server master1/10.166.105.212:2181
    12/01/09 15:24:34 INFO zookeeper.ClientCnxn: Socket connection established to master1/10.166.105.212:2181, initiating session
    12/01/09 15:24:34 INFO zookeeper.ClientCnxn: Session establishment complete on server master1/10.166.105.212:2181, sessionid = 0x134c11d62a20019, negotiated timeout = 10000
    12/01/09 15:24:34 INFO mapred.JobClient: Running job: job_201201091517_0001
    12/01/09 15:24:35 INFO mapred.JobClient: map 0% reduce 0%
    12/01/09 15:25:49 INFO mapred.JobClient: map 50% reduce 0%
    ...
    
    
    • 您将从 JobTracker 的管理页面中找到源群集的正在运行的 MapReduce 作业:

    How to do it...

  3. 您应该能够通过 HBase Shell:

    hbase> scan 'hly_temp2', { LIMIT => 1 }
    ROW COLUMN+CELL
    AQW000617050101 column=n:v01, timestamp=1323026325955, value=808C
    AQW000617050101 column=n:v02, timestamp=1323026325955, value=806C
    AQW000617050101 column=n:v03, timestamp=1323026325955, value=803C
    hbase> count 'hly_temp2'
    95630 row(s) in 22.4740 seconds
    
    

    访问备份群集上 hly_temp2中的数据

  4. 键入以下命令以仅复制具有特定时间戳范围的数据:

    hac@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar copytable --families=n --peer.adr=l-master1:2181:/hbase --new.name=hly_temp2 --starttime=1324173586754 --endtime=1324189940000 hly_temp
    
    

它是如何工作的.

在步骤 1 中,我们使用要复制的列 MARY(N)在备份集群上创建目标表(hly_temp2)。

在步骤 2 中,我们将 FAMILY n列中的数据从 hly_temp表复制到备份群集上的 hly_temp2表。 备份集群由 --peer.adr选项指定,方法是指定 ZooKeeper 仲裁地址,格式为 hbase.zookeeper.quorum:hbase.zookeeper.client.port:zookeeper.znode.parent,如 server,server2,server3:2181:/hbase

--families选项用于指定要复制的族的逗号分隔列表。 目标表由 --new.name选项指定;如果两个表具有相同的名称,则跳过此选项。

正如您从输出中看到的,数据是在 MapReduce 作业中复制的。 hadoop jar命令用于在 MapReduce 中运行 JAR 文件。 MapReduce 作业扫描源表,读取属于目标系列的数据条目,然后使用其普通客户端 API 将它们写入备份群集上的目标表。

从步骤 3 的输出中,您将发现列族 n中的 hly_temp表的数据(包括每个条目的时间戳)已被复制到备份集群上的 hly_temp2表中。 HBase 使用时间戳对编辑进行排序;时间戳较大的编辑具有较新的单元格版本。 默认情况下,时间戳由 HBase 使用长值自动设置,该值表示当前时间和午夜(1970 年 1 月 1 日 UTC)之间的毫秒差。

在步骤 4 中,我们将时间戳范围参数添加到 CopyTable命令中。在复制作业的扫描阶段,将跳过特定时间范围之外的数据。 由 --starttime选项指定的最小时间戳值包含在内。 由 --endtime选项指定的最大时间戳值是独占的。

步骤 2 可用于完全备份,而步骤 3 在某些情况下可用于增量备份。 使用具有特定时间戳范围的 CopyTable与增量备份不同。 这是因为,在将数据放入 HBase 时,时间戳可以由客户端显式指定,并且不能保证新插入的数据具有更大的时间戳。 另一个原因是 CopyTable不会处理删除。 没有办法知道数据是否被删除。 我们建议您在应用级别实施自己的增量备份解决方案。

有关 CopyTable用法的完整说明,请键入以下命令:

$HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar copytable

导出 HBase 表以转储 HDFS 上的文件

HBase export实用程序将表的内容转储到同一个 HDFS 集群。 转储文件采用 Hadoop 序列文件格式。 将数据导出到 Hadoop 序列文件对于数据备份有好处,因为 Hadoop 序列文件格式支持多种压缩类型和算法。 有了它,我们可以选择最适合我们环境的压缩选项。

与我们在前面的菜谱中提到的 copytable实用程序一样, export可配置为具有开始和结束时间戳,因此只有特定时间范围内的数据才会被转储。 此功能使 export能够增量地将 HBase 表导出到 HDFS。

HBase export也是一个实时备份选项。 由于群集正在运行,因此在导出过程中可能会丢失编辑。 在本食谱中,我们将介绍如何使用 export实用程序将表导出到同一集群上的 HDFS。 我们将在下一个配方中介绍 import实用程序,该实用程序用于从 export转储恢复数据。

做好准备

首先,启动 HDFS 和 HBase 集群。

我们将把 hly_temp表导出到 HDFS 群集上的 /backup/hly_temp。 您需要预先创建一个 /backup目录。

export实用程序使用 MapReduce 导出数据。 将 HBase 的可配置文件(hbase-site.xml)和依赖项 JAR 文件添加到您的客户端节点上 Hadoop 的类路径中。

怎么做……

按照以下说明使用 export实用程序将 HBase 表导出到 HDFS:

  1. Run the following command from your client node to export all the data in the hly_temp table:

    hadoop@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar export -D mapred.output.compress=true -D mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec -D mapred.output.compression.type=BLOCK hly_temp /backup/hly_temp 2147483647
    12/01/08 07:39:35 INFO mapreduce.Export: verisons=2147483647, starttime=0, endtime=9223372036854775807
    ...
    12/01/08 07:39:37 INFO zookeeper.ClientCnxn: Session establishment complete on server master1/10.160.229.77:2181, sessionid = 0x134ba4a09070013, negotiated timeout = 10000
    12/01/08 07:39:38 INFO mapred.JobClient: Running job: job_201201080737_0001
    12/01/08 07:39:39 INFO mapred.JobClient: map 0% reduce 0%
    12/01/08 07:42:56 INFO mapred.JobClient: map 25% reduce 0%
    
    
    • 您将从 JobTracker 的管理页面中找到导出 MapReduce 作业:

    How to do it...

    • MapReduce 作业完成后,您将在 HDFS 上的/backup/hly_temp目录下找到生成的转储文件(part-m-000x):

    How to do it...

  2. 执行以下命令,仅导出具有特定时间戳范围的数据:

hadoop@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar export -D mapred.output.compress=true -D mapred.output.compression.codec=org.apache.hadoop.io.compress.BZip2Codec -D mapred.output.compression.type=BLOCK hly_temp /backup/hly_temp_2 2147483647 1324601918502 1324693970000

它是如何工作的.

运行带有 export参数的 HBase JAR 文件将执行 export实用程序来转储 HBase 表的内容。 在步骤 1 中,我们将 hly_temp表转储到 HDFS 上的 /backup/hly_temp目录。 最后一个参数指定要导出的数据的最高版本。 HBase 支持在一个单元中存储多个版本的数据。 单元格可以存储的最大版本由其列族的 VERSIONS属性确定,该属性是在创建表时指定的。 要转储具有多版本列族的表,我们必须将要导出的最高版本传递给 export命令,否则将只导出最新版本。 在我们的示例中,我们只指定 Integer.MAX_VALUE (2147483647)来导出所有版本的数据。

许多 -D属性已传递给 export命令。 这些被设置为控制其运行时属性的导出 MapReduce 作业。 将 mapred.output.compress属性设置为 true以使 MapReduce 压缩其输出(序列文件)。 mapred.output.compression.codec属性控制用于导出的压缩算法。 我们将其设置为使用压缩比最高的 BZip2 编解码器。

在撰写本书时,这些是 Hadoop 广泛使用的编解码器。 选择哪种编解码器取决于您的需求;所有这些编解码器都有空间/时间权衡:

|

压缩格式

|

Hadoop 压缩编解码器

|

压缩比 / 压缩率

|

(解)压缩速度

| | --- | --- | --- | --- | | gzip | org.apache.hadoop.io.compress.GzipCodec | 中等的 / 中号的 / 适中的 / 半生熟的 | 中等的 / 中号的 / 适中的 / 半生熟的 | | BZip2 | org.apache.hadoop.io.compress.BZip2Codec | 高的 / 大的 / 高级的 / 高音调的 | 低速的 / 慢的 / 迟钝的 / 不曲折的 | | LZO | com.hadoop.compression.lzo.LzoCodec | 洛 (人名) | 快速的 / 牢实的 / 感光快的 / 紧的 |

由于许可问题,LZO 不包含在 Hadoop 包中;请参阅基本性能调优中的使用压缩配方来安装 LZO。

mapred.output.compression.type属性用于指定 Hadoop 序列文件的压缩类型。可用值为 NONE, RECORDBLOCK。 对于大多数情况,您应该选择 BLOCK,因为它将记录序列压缩在块中,这是最有效的压缩方式。

正如您从输出中看到的,数据是通过 MapReduce 导出的。 这是通过 hadoop jar命令完成的,该命令在 MapReduce 中运行一个 JAR 文件。 MapReduce 作业扫描该表,读取所有数据条目,然后将它们写入同一 HDFS 群集上输出路径下的 Hadoop 序列文件。

我们已在步骤 2 中向 export命令添加了时间戳范围参数。在导出作业的扫描阶段将跳过特定时间范围之外的数据。 最小时间戳值(1324601918502)是包含的,而最大时间戳值(1324693970000)是排除的。

就像我们在前面的食谱中提到的 CopyTable实用程序一样,步骤 1(没有特定的开始/结束时间)可用于完全备份,而步骤 2(具有特定的开始/结束时间)在某些情况下用于增量备份。

还有更多...

在将数据导出到同一群集上的 HDFS 时,如果 HDFS 崩溃,则备份可能不可用。 我们建议您使用 Hadoop distcp工具将导出的文件复制到不同的 HDFS 群集。 如果您的数据量不是很大,一个更好的选择是将转储的文件复制到磁带上,以便进行脱机备份。

另请参阅

  • 在本章中,通过从 HDFS配方导入转储文件来恢复 HBase 数据
  • 使用压缩配方,在第 8 章基本性能调整

通过从 HDFS 导入转储文件恢复 HBase 数据

HBase Import实用程序用于将 Export实用程序导出的数据加载到现有 HBase 表中。 这是从 Export实用程序备份解决方案还原数据的过程。

我们将在本食谱中查看 Import实用程序的用法。

做好准备

首先,启动 HDFS 和 HBase 集群。

我们将把在上一个配方中导出的文件导入到我们的 hly_temp表中。 如果您没有这些转储文件,请参考Exporting HBase 表在 HDFS配方上转储文件,以便提前生成转储文件。 我们假设转储文件保存在 /backup/hly_temp目录中。

Import实用程序使用 MapReduce 导入数据。 将 HBase 可配置文件(hbase-site.xml)和依赖项 JAR 文件添加到客户端节点上的 Hadoop 类路径。

怎么做……

要将转储文件导入 hly_temp表,请执行以下操作:

  1. 通过 HBase Shell 连接到您的 HBase 群集,如果目标表不存在,则创建目标表:

    hbase> create 'hly_temp', {NAME => 'n'} 
    
    
  2. Run the following command from your client node to import data into the hly_temp table:

    hadoop@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar import hly_temp /backup/hly_temp
    12/01/08 08:52:42 INFO mapreduce.TableOutputFormat: Created table instance for hly_temp
    12/01/08 08:52:42 INFO input.FileInputFormat: Total input paths to process : 4
    12/01/08 08:52:42 INFO mapred.JobClient: Running job: job_201201080737_0004
    12/01/08 08:52:43 INFO mapred.JobClient: map 0% reduce 0%
    12/01/08 08:53:09 INFO mapred.JobClient: map 1% reduce 0%
    ...
    
    
    • 您将从 JobTracker 的管理页面找到导入 MapReduce 作业:

    How to do it...

  3. 在 MapReduce 作业完成后,您应该能够通过 HBase Shell 访问 hly_temp表中的数据:

    hbase> scan 'hly_temp', {LIMIT => 1}
    ROW COLUMN+CELL
    AQW000617050101 column=n:v01, timestamp=1323026325955, value=808C
    AQW000617050101 column=n:v02, timestamp=1323026325955, value=806C
    AQW000617050101 column=n:v03, timestamp=1323026325955, value=803C
    ...
    
    

它是如何工作的.

我们在步骤 1 中创建了目标表。该表必须具有转储文件中存在的所有列族;否则,导入作业将失败,并显示 NoSuchColumnFamilyException错误消息。

从步骤 2 的输出中可以看到,数据是通过 MapReduce 导入的。 这是通过 hadoop jar命令完成的,该命令执行打包在 JAR 文件中的 MapReduce 代码。 导入 MapReduce 作业从输入目录(/backup/hly_temp)下的转储文件读取数据条目,然后使用 HBase 的客户端 API 将它们写入目标表(hly_temp)。

转储文件中的数据(包括每个条目的时间戳)将由 Import实用程序恢复。 在此之后,我们建议您对表进行重大压缩并手动执行集群平衡,以使集群以最佳状态运行。 这可以通过 HBase Shell 使用以下命令来完成:

hbase> major_compact 'hly_temp'
hbase> balancer

还有更多...

如果要将数据导入到新创建的表中,您可能会发现导入速度没有预期的那么快。 这是因为表格只从一个区域开始,所有编辑都将转到该区域。 这使得托管区域服务器忙于处理这些请求。 同时,其他地域的服务器都是空载的。 群集保持在这种不平衡状态下运行,直到第一个区域中的数据达到阈值,并且该区域被分成两个区域。 新表格需要很长时间才能通过这种自动区域拆分实现良好的平衡。

解决方案是在创建表时预先创建足够的区域。 需要使用适当的边界创建区域,以便可以将编辑内容很好地分发到所有这些预先创建的区域。 为了确定正确的边界,您可能还需要备份区域起始键,这也可用于恢复 HBase 表的区域分布。

从 HBase 0.94 开始, Import实用程序可以生成用于批量加载的 HBase 内部文件(HFiles)。 使用此功能,我们能够在更短的时间内恢复转储文件。 有关详细信息(https://issues.apache.org/jira/browse/HBASE-5440),请参阅HBase-5440

另请参阅

在本章中:

  • 导出 HBase 表以转储 HDFS上的文件
  • 正在备份区域起始键

第 9 章中,高级配置和调整:

  • 使用您自己的算法预先创建区域

第 3 章中,使用管理工具:

  • 使用 HBase Shell 管理群集

备份 NameNode 元数据

由于 HBase 在 HDFS 中运行,因此除了照顾 HBase 集群之外,保持 HDFS 在健康状态下运行也很重要。 NameNode 是 HDFS 集群中最重要的组件。 NameNode 崩溃会导致整个 HDFS 群集无法访问。 HDFS 集群的元数据(包括文件系统映像和编辑日志)由 NameNode 管理。

我们需要在两种情况下保护 NameNode 元数据:

  • 崩溃时丢失的元数据
  • 元数据因任何原因损坏

对于第一种情况,我们可以设置 NameNode 将其元数据与 NFS 挂载一起写入其本地磁盘。 正如设置多个高可用性(HA)主节点配方中所述,在第 1 章设置 HBase 集群中,我们甚至可以设置多个 NameNode 节点来实现高可用性。

对于第二种情况,我们的解决方案是频繁备份元数据,以便在元数据损坏时恢复 NameNode 状态。

在本指南中,我们将介绍如何备份和恢复 NameNode 元数据。

做好准备

启动 HDFS 并登录到客户端节点。 我们假设 NameNode 正在使用默认的 Web UI 端口 50070master1服务器上运行。 确保为您的客户端节点打开端口。

dfs.name.dir属性指定 NameNode 元数据的保存位置。 Grep HDFS 配置文件(hdfs-site.xml)以找出执行恢复任务所需的此属性的值。 在演示中,我们假设该值为 /usr/local/hadoop/var/dfs/name

我们将备份保存在客户端节点上的 /backup/namenode下,并使用 NameNode 服务器上的 /restore/namenode作为恢复的工作目录。 创建这些目录,并确保运行备份任务的用户对它们具有写入权限。

怎么做……

要备份 NameNode 元数据,请执行以下操作:

  1. 设置环境变量:

    hadoop@client1$ export BACKUP_DIR=/backup/namenode
    
    
  2. 从 NameNode Web 用户界面获取 HDFS 的文件系统映像:

    hadoop@client1$ curl http://master1:50070/getimage?getimage=1 > $BACKUP_DIR/fsimage
    
    
  3. 从 NameNode Web 用户界面获取 HDFS 的编辑日志:

    hadoop@client1$ curl http://master1:50070/getimage?getedit=1 > $BACKUP_DIR/edits
    
    
  4. 使用以下命令为获取的元数据创建 tarball:

    hadoop@client1$ tar cfvj $BACKUP_DIR/metadata.`date +%Y%m%d`.tar.bz2 -C $BACKUP_DIR fsimage edits
    
    

为了从元数据备份恢复 NameNode 状态:

  1. 如果 NameNode 守护程序正在您的 NameNode 服务器上运行,请停止它:

    hadoop@master1$ $HADOOP_HOME/bin/hadoop-daemon.sh stop namenode
    
    
    • 如果前面的命令由于某种原因不起作用,只需终止 NameNode 的 Java 进程即可。
  2. 将元数据从备份复制到 NameNode 服务器上的 dfs.name.dir目录:

    hadoop@master1$ cd /usr/local/hadoop/var/dfs/name/current
    hadoop@master1$ tar cfvj /restore/namenode/metadata-org.tar.bz2 fsimage edits
    hadoop@master1$ scp client1:/backup/namenode/metadata.`date +%Y%m%d`.tar.bz2 ./
    hadoop@master1$ tar xfvj metadata.`date +%Y%m%d`.tar.bz2
    hadoop@master1$ rm metadata.`date +%Y%m%d`.tar.bz2
    
    
  3. 再次启动 NameNode 后台进程:

    hadoop@master1$ $HADOOP_HOME/bin/hadoop-daemon.sh start namenode
    
    
  4. Run hadoop fsck to check inconsistencies after the NameNode server has been restarted:

    hadoop@master1$ $HADOOP_HOME/bin/hadoop fsck / -files | grep CORRUPT
    
    

    How to do it...

    • 如果许多文件已损坏(如您在 Web 用户界面中看到的那样),NameNode 可能会继续处于安全模式,直到您显式将其关闭:

    How to do it...

  5. Turn off safe mode by explicitly using the following command:

    hadoop@master1$ $HADOOP_HOME/bin/hadoop dfsadmin -safemode leave
    Safe mode is OFF
    
    
    • Web 用户界面不会声明安全模式已关闭;相反,它可能会在页面上显示一条警告消息:

    How to do it...

  6. 运行 hadoop fsck -move将损坏的文件(如果有)移动到 /lost+found:

    hadoop@master1$ $HADOOP_HOME/bin/hadoop fsck / -move
    The filesystem under path '/' is CORRUPT
    
    
  7. 删除后再次运行 hadoop fsck以确认不存在不一致:

    hadoop@master1$ $HADOOP_HOME/bin/hadoop fsck /
    The filesystem under path '/' is HEALTHY
    
    

它是如何工作的.

NameNode 支持从其 Web 用户界面获取其文件系统映像和编辑日志。 从第 1 步到第 4 步,我们使用此功能将 NameNode 元数据提取到客户机节点上的本地磁盘,然后将提取的元数据压缩为一个文件作为备份。

为了从备份中恢复元数据,我们首先在步骤 5 中停止 NameNode 守护进程,然后在步骤 6 中,将原始元数据移动到我们的工作目录中,以防您出于任何原因想要取消恢复。 之后,我们将备份复制到存储 NameNode 元数据的 $dfs.name.dir/current目录,然后再次启动 NameNode 守护进程。

如果在我们的最新备份之后进行了编辑,我们恢复的元数据将与 DataNode 上的实际数据不匹配,在这种情况下,我们的 HDFS 将变得不一致。 我们在步骤 8 中运行 hadoop fsck命令来检查 HDFS 不一致。如果提供了路径和 -files选项, fsck将检查指定路径下的不一致,并打印它正在检查的文件。

如果检测到损坏的文件,我们需要删除它们以使 HDFS 保持一致。 如果许多文件已损坏,NameNode 将无法达到其将保持在安全模式下的报告块比率的阈值。 在删除损坏的文件之前,我们需要显式关闭 NameNode 安全模式。 这是通过步骤 9 中的 hadoop dfsadmin命令完成的。 Dfsadmin是用于管理任务的 HDFS 命令。 使用 -safemode leave选项运行它会显式关闭 NameNode 安全模式。

当安全模式关闭时,我们可以使用带有 -move选项的 fsck命令将损坏的文件移动到 /lost+found。 在此之后, fsck应该报告文件系统健康,您应该能够访问 HDFS。

还有更多...

从元数据备份恢复 NameNode 状态可能需要很长时间才能完成。 这是因为重新启动 NameNode 守护进程将首先从磁盘加载文件系统映像,然后重播编辑日志以重建最终的系统状态。 编辑日志可能很大,重放可能需要很长时间。

HDFS 有一个针对此问题的 Second DaryNameNode 组件。 请注意,Second daryNameNode 不是 NameNode 的备份守护进程。 它会定期(默认为 1 小时)将编辑日志压缩到检查点中,以便在重新启动 NameNode 后加载最新的检查点,并加载一个小得多的编辑日志,其中仅包含自检查点以来所做的编辑。 借助这种压缩功能,Second DaryNameNode 使 NameNode 元数据的备份和恢复更加高效。

默认情况下,Second daryNameNode 与 NameNode 在同一节点上运行。 为了提高可伸缩性和持久性,我们建议您在与 NameNode 服务器不同的服务器上运行它。 配置在 Hadoop 配置目录下的 masters文件中:

hadoop@master1$ vi $HADOOP_HOME/conf/masters

secondary_namenode_host

要在此文件中启动 Second daryNameNode,请添加所需的主机名,然后重新启动 HDFS 以应用更改。

备份区域起始键

除了 HBase 中的表之外,我们还应该备份每个表的区域起始键。 区域起始键决定表中的数据分布,因为区域由区域起始键拆分。 地域是 HBase 中负载均衡和指标采集的基本单位。

如果使用 distcp执行完全关机备份,则无需备份区域起始密钥,因为 distcp还会将区域边界复制到备份群集。

但对于实时备份选项,备份区域起始键与表数据一样重要,如果您的数据分布难以提前计算,或者您的区域是手动拆分的,则备份区域起始键尤其重要。 这一点很重要,因为实时备份选项(包括 CopyTableExport实用程序)使用普通的 HBase 客户端 API 来还原 MapReduce 作业中的数据。 如果我们在运行 Restore MapReduce 作业之前预先创建分割良好的区域,则可以显著提高恢复速度。

在本食谱中,我们将介绍如何备份 HBase 表的区域起始键。 我们将创建一个脚本来从 HBase 表中获取区域起始键。

做好准备

启动您的 HBase 集群,创建一个表,并在其中放入一些数据。 表中需要有几个区域,这样我们才能验证我们的脚本是否正常工作。 如果您的表只有一个区域,请从 HBase web UI 的表页手动将其拆分为几个区域。 我们将在此配方中使用 hly_temp表;其 Web 用户界面页面类似于以下屏幕截图中所示的网页:

Getting ready

我们将备份客户端节点上 /backup/hly_temp目录下的 hly_temp表的区域起始键。 创建此目录,并向将运行备份脚本的用户授予写入权限。

怎么做……

按照以下说明备份 hly_temp表的区域起始键:

  1. 为 __T0 创建抯脚本文件:\T1++

  2. 在客户端节点上运行脚本:

    hac@client1 $HBASE_HOME/bin/hbase org.jruby.Main region-starting-keys.rb hly_temp /backup/hly_temp/regions
    
    
  3. 脚本将创建一个包含区域起始键的文件(/backup/hly_temp/regions)。 该文件如下所示:

    hac@client1$ cat /backup/hly_temp/regions
    USW000128350706
    USW000138830523
    USW000149221223
    
    

它是如何工作的.

要获取 HBase 表的区域起始键,我们需要从脚本访问 HBase Java 客户端 API。 有几种基于 JVM 的脚本语言,比如 Jython、Scala 和 JRuby。 我们在步骤 1 中创建的脚本是用 JRuby 编写的。 我们之所以选择 JRuby,是因为 HBase Shell 是用 JRuby 编写的,不需要引入另一种语言及其依赖项。

在脚本中,我们创建了一个 HTable实例来访问我们的 hly_temp表。 HTable类用于与单个 HBase 表通信。 我们只将表名(hly_temp)传递给 HTable类的构造函数。 HBase 集群的 ZooKeeper 法定连接字符串被设置为默认值,这是通过使用 hbase命令从客户端上的 HBase 配置文件(hbase-site.xml)实现的。 如果成功创建了 HTable实例,则将建立与 ZooKeeper 仲裁的连接会话。 之后,我们可以通过 HTable实例与我们的 hly_temp表通信。

接下来,我们调用 HTable实例的 getStartKeys()方法,该方法返回表的区域起始键数组。 区域起始键是 HBase 中由字节数组表示的行键。

在脚本的下一步中,我们使用 Bytes类将键转换为字符串。 Bytes类是将其他对象从字节数组转换为字节数组或将其他对象转换为字节数组的实用程序类。 这个类很有用,因为所有键/值都以字节数组的形式存储在 HBase 中,而不考虑它们的原始数据类型。

在脚本的最后一步,我们将转换后的字符串写入输出文件,最后关闭到集群的连接。

在步骤 2 中,我们通过运行 hbase命令来执行脚本。 hbase命令用于在当前 HBase 上下文中运行 Java 类。 要运行 JRuby 脚本,我们将 JRuby 的 org.jruby.Main—themain 类传递给 hbase命令。 我们的脚本被传递给 org.jruby.Main类并在 HBase 上下文中运行。 表名和输出文件的路径也通过命令行传递给脚本。

正如您从步骤 3 的输出中看到的,我们写入输出文件的区域起始键与我们在表的管理网页上看到的相同。

另请参阅

  • 第 9 章高级配置和调整中,使用您自己的算法配方预先创建区域

群集复制

HBase 支持集群复制,这是在 HBase 集群之间复制数据的一种方式。 例如,它可以用作轻松地将编辑从实时前端集群传送到后端的批处理目的集群的一种方式。

HBase 复制的基本架构非常实用。 主群集捕获预写日志(WAL),并将可复制的键/值(在支持复制的情况下对列族进行编辑)从日志放入复制队列。 然后,复制消息被发送到对等群集,然后使用其正常的 HBase 客户端 API 在该群集上重放。 主集群还会保留 ZooKeeper 中复制的 WAL 的当前位置,以进行故障恢复。

由于 HBase 复制是异步完成的,因此参与复制的群集在地理上可能相距遥远。 如果它们之间的连接离线一段时间,这不是问题,因为主群集会跟踪复制,并在连接再次在线后恢复它。 这意味着 HBase 复制可以作为 HBase 层的灾难恢复解决方案。

在本食谱中,我们将了解如何在两个集群之间启用表的复制。

做好准备

您需要两个 HBase 集群-一个是主集群,另一个是复制对等(从)集群。 这里,假设主机是 master1:2181/hbase,对等方是 l-master1:2181/hbase;这两个集群不需要具有相同的大小。

ZooKeeper 应该独立处理,而不是由 HBase 处理。 检查 hbase-env.sh文件中的 HBASE_MANAGES_ZK设置,并确保将其设置为 false

所有机器,包括 ZooKeeper 集群和 HBase 集群,都需要能够访问其他机器。 确保两个群集具有相同的 HBase 和 Hadoop 主版本。 例如,主服务器上的 0.92.1 和对等机上的 0.92.0 是正确的,但 0.90 是不正确的。

怎么做……

按照以下说明在 HBase 群集之间复制数据:

  1. 将以下代码添加到 HBase 的配置文件(hbase-site.xml)以启用主群集上的复制:

    hadoop@master1$ vi $HBASE_HOME/conf/hbase-site.xml
    <property>
    <name>hbase.replication</name>
    <value>true</value>
    </property>
    
    
  2. 将更改同步到所有服务器,包括集群中的客户端节点,然后重新启动 HBase。

  3. 连接到主群集上的 HBase Shell,并在要复制的表上启用复制:

    hac@client1$ $HBASE_HOME/bin/hbase shell
    hbase> create 'reptable1', { NAME => 'cf1', REPLICATION_SCOPE => 1}
    
    
    hbase> disable 'reptable1'
    hbase> alter 'reptable1', NAME => 'cf1', REPLICATION_SCOPE => '1'
    hbase> enable 'reptable1'
    
    
    • 如果您使用的是现有表,请更改它以支持复制:
  4. 在对等(从)群集上也执行步骤 1 到 3。 这包括启用复制、重新启动 HBase 和创建表的相同副本。

  5. 通过 HBase Shell 从主群集添加对等复制群集:

    hbase> add_peer '1', 'l-master1:2181:/hbase'
    
    
  6. 通过运行以下命令在主群集上启动复制:

    hbase> start_replication
    
    
  7. 向主群集中添加一些数据:

    hbase> put 'reptable1', 'row1', 'cf1:v1', 'foo'
    hbase> put 'reptable1', 'row1', 'cf1:v2', 'bar'
    hbase> put 'reptable1', 'row2', 'cf1:v1', 'foobar'
    
    
    • 您应该能够在短时间内看到数据出现在对等群集表中。
  8. 连接到对等群集上的 HBase Shell 并对表进行扫描,以查看数据是否已复制:

    hac@l-client1$ $HBASE_HOME/bin/hbase shell
    hbase> scan ' reptable1'
    ROW COLUMN+CELL
    row1 column=cf1:v1, timestamp=1326095294209, value=foo
    row1 column=cf1:v2, timestamp=1326095300633, value=bar
    row2 column=cf1:v1, timestamp=1326095307619, value=foobar
    2 row(s) in 0.0280 seconds
    
    
  9. 通过在主群集上调用 verifyrep命令来验证两个群集上的复制数据:

    hac@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar verifyrep 1 reptable1
    12/01/09 16:50:22 INFO replication.ReplicationZookeeper: Replication is now started
    ...
    12/01/09 16:50:24 INFO mapred.JobClient: Running job: job_201201091517_0005
    12/01/09 16:50:25 INFO mapred.JobClient: map 0% reduce 0%
    12/01/09 16:50:46 INFO mapred.JobClient: map 100% reduce 0%
    12/01/09 16:50:51 INFO mapred.JobClient: Job complete: job_201201091517_0005
    12/01/09 16:50:51 INFO mapred.JobClient: Counters: 19
    ...
    12/01/09 16:50:51 INFO mapred.JobClient: File Output Format Counters
    12/01/09 16:50:51 INFO mapred.JobClient: Bytes Written=0
    12/01/09 16:50:51 INFO mapred.JobClient: org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication$Verifier$Counters
    12/01/09 16:50:51 INFO mapred.JobClient: GOODROWS=2
    ...
    
    
    • 我们跳过了 verifyrep 命令的一些输出,以使其更清晰。
  10. 通过运行以下命令停止主群集上的复制:

```scala
hbase> stop_replication

```

11. 使用以下命令从主群集中删除复制对等:

```scala
hbase> remove_peer '1'

```

它是如何工作的.

复制仍被视为试验性功能,默认情况下该功能处于禁用状态。 为了启用它,我们在 HBase 的配置文件(hbase-site.xml)中添加了 hbase.replication属性,并将其设置为 true。 为了应用更改,我们将其同步到所有节点,包括集群中的客户端节点,然后在步骤 2 中重新启动 HBase。数据复制配置在列系列级别。 使用 REPLICATION_SCOPE => '1'属性设置柱族可以使该柱族支持复制。 我们在步骤 3 中实现了这一点,方法是更改现有表,或者创建一个复制范围设置为 1的新表。

对于对等群集,我们在步骤 4 中执行了相同的过程-为那些复制族启用复制支持并创建具有完全相同名称的相同表。

在步骤 1 和步骤 4 之间完成准备之后,我们在步骤 5 中将复制对等群集添加到主群集,以便随后可以向其发送编辑内容。 复制对等点由 ID(在我们的示例中为 1)和集群的 ZooKeeper 仲裁的完整描述(格式为 hbase.zookeeper.quorum:hbase.zookeeper.client.port:zookeeper.znode.parent,如 server,server2,server3:2181:/hbase)标识。 之后,我们开始将编辑记录实际传送到对等集群。

为了测试我们的复制设置,我们将一些数据放入表中,一段时间后,正如您从对等群集上的 scan命令的输出中看到的那样,数据已经正确地传送到对等群集。 虽然在只查看几行时很容易做到这一点,但更好的方法是使用 verifyrep命令在两个表之间进行比较。 以下是 verifyrep命令的帮助说明:

hac@client1$ $HADOOP_HOME/bin/hadoop jar $HBASE_HOME/hbase-0.92.1.jar verifyrep
Usage: verifyrep [--starttime=X] [--stoptime=Y] [--families=A] <peerid> <tablename>
Options:
starttime beginning of the time range
without endtime means from starttime to forever
stoptime end of the time range
families comma-separated list of families to copy
Args:
peerid Id of the peer used for verification, must match the one given for replication
tablename Name of the table to verify
Examples:
To verify the data replicated from TestTable for a 1 hour window with peer #5
$ bin/hbase org.apache.hadoop.hbase.mapreduce.replication.VerifyReplication --starttime=1265875194289 --stoptime=1265878794289 5 TestTable

hadoop jar命令运行 verifyrep,使用对等体 ID(在步骤 5 中用于建立复制流)和表名的参数,将启动 MapReduce 作业,以比较原始表和复制表中的每个单元。 使用 verifyrep命令提供两个计数器-Verifier.Counters.GOODROWSVerifier.Counters.BADROWS。 好行意味着两个表之间的行是完全匹配的,而坏行是不匹配的行。 当我们的数据被成功复制时,我们得到了以下输出:

12/01/09 16:50:51 INFO mapred.JobClient: GOODROWS=2

如果有一些错误的行,请检查 MapReduce 作业的映射日志以了解原因。

最后,我们停止复制并从主群集中删除对等项。 停止复制仍将完成将所有排队的编辑传送到对等方,但不接受进一步处理。

还有更多...

要深入了解用于 HBase 集群复制的体系结构,请参阅以下文档-hbase.apache.org/replication…

五、监控与诊断

在本章中,我们将重点介绍:

  • 显示 HBase 表的磁盘利用率
  • 设置 Ganglia 以监视 HBase 群集
  • OpenTSDB-使用 HBase 监视 HBase 群集
  • 设置 Nagios 以监视 HBase 进程
  • 使用 Nagios 检查 Hadoop/HBase 日志
  • 用于报告群集状态的简单脚本
  • 热区-写入诊断

简介

监视 HBase 群集的状态以确保其按预期运行是至关重要的。 除了单独考虑每台服务器的情况外,监视分布式系统的挑战还在于您还需要查看集群的整体状态。

HBase 继承了 Hadoop 指标框架的监控 API。 它公开了大量的指标,提供了集群的洞察信息。 这些指标随后被配置为公开其他监视系统,如 Ganglia 或 OpenTSDB,以收集它们并使其通过图形可见。 Ganglia/OpenTSDB 图帮助我们理解集群的洞察力,包括单个服务器和整个集群。

图形有助于获得历史状态的概述,但我们还需要一种机制来检查群集的当前状态,并在群集出现问题时向我们发送通知或采取一些自动操作。 Nagios 是这类监控任务的一个很好的解决方案。 Nagios 位于监控系统的中心,用于监视集群资源并提醒用户。

我们将介绍如何使用 Ganglia、OpenTSDB、Nagios 和其他工具监视和诊断 HBase 集群。 我们将从一个简单的任务开始,显示 HBase 表的磁盘利用率。 我们将安装和配置 Ganglia 以监视 HBase 指标,并使用 Ganglia 图显示一个示例。 我们还将设置 OpenTSDB,它类似于 Ganglia,但可伸缩性更好,因为它构建在 HBase 之上。

我们将设置 Nagios 来检查我们想要检查的所有内容,包括与 HBase 相关的守护进程运行状况、Hadoop/HBase 日志、HBase 不一致、HDFS 运行状况和空间利用率。

在最后一个菜谱中,我们将描述一种诊断和修复常见热点区域问题的方法。

显示 HBase 表的磁盘利用率

在本食谱中,我们将显示以下简单问题的答案:

HBase 或单个 HBase 表在 HDFS 上使用了多少空间?

这是一项非常简单的任务,但您可能需要经常回答这个问题。 我们会给您一些小费,让您轻松一点。

做好准备

启动您的 HBase 群集并登录到您的 HBase 客户端节点。 我们假设 HDFS 上的 HBase 根目录为 /hbase

怎么做……

显示 HBase 表磁盘利用率的说明如下:

  1. 通过执行以下命令显示所有 HBase 对象的磁盘利用率:

    $ $HADOOP_HOME/bin/hadoop fs -dus /hbase
    hdfs://master1:8020/hbase 1016842660
    
    
  2. 通过执行以下命令显示特定 HBase 表(hly_temp)的磁盘利用率:

    $ $HADOOP_HOME/bin/hadoop fs -dus /hbase/hly_temp
    hdfs://master1:8020/hbase/hly_temp 54738763
    
    
  3. 通过执行以下命令,显示 HBase 表的区域及其磁盘利用率的列表:

    $ $HADOOP_HOME/bin/hadoop fs -du /hbase/hly_temp
    Found 3 items
    27709729 hdfs://master1:8020/hbase/hly_temp/
    0b593d9dc044f1fe011ec0c902f68fc5
    13545245 hdfs://master1:8020/hbase/hly_temp/
    5740a39d9eaa59c4175487c14e0a272a
    13483789 hdfs://master1:8020/hbase/hly_temp/
    5ef67f6d2a792fb0bd737863dc00b6a7
    
    

它是如何工作的.

所有 HBase 对象都存储在 HDFS 上的 HBase 根目录下。 HBase 根目录由 HBase 配置文件(hbase-site.xml)中的 hbase.rootdir属性配置。 默认情况下,根目录为 /hbase。 因此,所有 HBase 对象的磁盘使用率等于 HBase 根目录下的 HDFS 使用率。

在步骤 1 中,为了显示 HDFS 的使用情况,我们运行 hadoop fs -dus命令,将我们的 HBase 根目录(/HBase)传递给它。 /hbase目录下的空间量以字节为单位显示在输出中。

在步骤 2 中,为了显示 hly_temp表的磁盘利用率,我们只将 /hbase/hly_temp传递给 hadoop fs -dus命令。 这是可能的,因为特定 HBase 表的对象存储在 HDFS 上的 ${hbase.rootdir}/<table_name>目录下。

第三步有点不同。 我们运行 hadoop fs -du命令以显示 hly_temp表的区域及其磁盘利用率的列表。 hadoop fs -du命令类似于 hadoop fs -dus命令,但会显示特定路径下每个目录/文件的空间量。

还有更多...

正如您从输出中看到的,磁盘利用率是以字节为单位显示的,这对用户不友好,特别是当它是一个大数字时。 下面是一个简单的 JRuby 脚本,用于将输出转换为人类可读的格式:

  1. 创建包含以下内容的 dus.rb文件:

    $ vi dus.rb
    include Java
    import org.apache.hadoop.util.StringUtils
    path = ARGV[0]
    dus = %x[$HADOOP_HOME/bin/hadoop fs -dus #{path}]
    splited = dus.split
    byteDesc = StringUtils.byteDesc(splited[1].to_i)
    puts splited[0] + "\t" + byteDesc
    
    
  2. Run dus.rb to show HBase's disk utilization with a humanly readable output:

    $ $HBASE_HOME/bin/hbase org.jruby.Main dus.rb /hbase
    hdfs://master1:8020/hbase 969.74 MB
    
    

    dus.rb中,我们只需执行相同的 hadoop fs -dus命令来确定 HBase 正在使用的空间量。 之后,我们使用 org.apache.hadoop.util.StringUtils类将值转换为友好的格式,然后将转换后的值显示为输出。

设置 Ganglia 以监视 HBase 群集

HBase 操作任务中最重要的部分之一是监视集群并确保其按预期运行。 HBase 从 Hadoop 继承其监控 API。 它公开了许多指标,这些指标提供了集群当前状态的洞察信息,包括基于区域的统计信息、RPC 详细信息以及**Java Virtual Machine(JVM)**内存和垃圾收集数据。

然后将这些指标配置为向 JMX 和 Ganglia 公开,从而使指标通过图形可见。 Ganglia 是监控大规模集群的推荐工具。 Ganglia 本身是一个可伸缩的分布式系统;据说它能够处理具有 2000 个节点的集群。

在本食谱中,我们将描述如何使用 Ganglia 监视 HBase 集群。 我们将在集群中的每个节点上安装Ganglia Monitoring Daemon(Gmond),它将收集该节点的服务器和 HBase 指标。 这些指标随后被轮询到**Ganglia Meta Daemon(Gmetad)服务器,在那里使用轮询数据库工具(RRDtool)**计算指标并将其保存在轮询的时间序列数据库中。 我们在这里只设置一个 Gmetad 节点,但也可以向外扩展到多个 Gmetad 节点,在每个 Gmetad 节点上聚合其分配的 Gmond 节点的结果。

我们还将在同一个 Gmetad 服务器上安装 PHP Web 前端,这样我们就可以从 Web 浏览器访问 Ganglia。 最后,我们将描述如何配置 HBase 以将其指标公开给 Ganglia。

做好准备

除了集群中的服务器之外,您还需要一个 Gmetad 服务器来在其上运行 Gmetad 守护进程。 在我们的演示中,我们将使用 master2作为 Gmetad 服务器。

添加 ganglia用户作为 Ganglia 守护进程的所有者:

# adduser --disabled-login --no-create-home ganglia

在您想要监视的所有节点上,从downloads.sourceforge.net/project/gan…下载 Ganglia-3.0.7。

解压下载的 tarball。 您需要所有服务器上的 root 权限才能安装 Ganglia。

怎么做……

设置 Gmond 的说明如下;需要在要监视的所有节点上执行:

  1. 安装依赖项:

    # apt-get install build-essential libapr1-dev libconfuse-dev libexpat1-dev python-dev
    
    
  2. 构建并安装 Ganglia:

    # cd ganglia-3.0.7
    # ./configure
    # make
    # make install
    
    
  3. 生成默认配置文件:__T0++

  4. 对生成的配置文件进行以下更改:

    # vi /etc/gmond.conf
    globals {
    user = ganglia
    }
    cluster {
    name = "hbase-cookbook"
    }
    udp_send_channel {
    # mcast_join = 239.2.11.71
    host = master2
    port = 8649
    # ttl = 1
    }
    udp_recv_channel {
    # mcast_join = 239.2.11.71
    port = 8649
    # bind = 239.2.11.71
    }
    
    
  5. 启动 Gmond:

    # gmond
    
    
    • 按照以下说明设置 Gmetad。 仅在 Gmetad 节点上执行它们。
  6. 安装依赖项:

    # apt-get install build-essential libapr1-dev libconfuse-dev libexpat1-dev python-dev librrd2-dev
    
    
  7. 构建并安装 Gmetad:

    # cd ganglia-3.0.7
    # ./configure --with-gmetad
    # make
    # make install
    
    
  8. 将示例配置文件(gmetad.conf)复制到其默认位置:

    # cp ganglia-3.0.7/gmetad/gmetad.conf /etc/gmetad.conf
    
    
  9. 找到并更改以下设置,如下面的代码片断所示:

    # vi /etc/gmetad.conf
    data_source "hbase-cookbook" master2
    gridname "hbase-cookbook"
    setuid_username "ganglia"
    
    
  10. 为循环数据库创建目录,以存储收集的数据:

```scala
# mkdir -p /var/lib/ganglia/rrds

# chown -R ganglia:ganglia /var/lib/ganglia

```

11. 启动 Gmetad:

```scala
# gmetad

```

*   以下是设置 Ganglia Web 前端的说明。 仅在 Web 前端节点上执行这些步骤。 它通常与 Gmetad 节点相同。

12. 安装依赖项:

```scala
# apt-get install rrdtool apache2 php5-mysql libapache2-mod-php5 php5-gd

```

13. 将 Ganglia Web 前端的 PHP 文件复制到存储 Apache Web 文件的位置:

```scala

# cp -r ganglia-3.0.7/web /var/www/ganglia

```

14. Restart the Apache web server:

```scala
# /etc/init.d/apache2 restart

```

*   You should be able to access your Ganglia web frontend page at: `http://master2/ganglia/.`

    Ganglia 前端页面包含 Ganglia 收集的所有指标图,如以下屏幕截图所示:

![How to do it...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/2a86982073414731a8c0f7e7032c4634~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1773139932&x-signature=q7oMYmwrEHeBnmZnVwsKwb5UBsg%3D)

*   最后,以下是 HBase 将其指标导出到 Ganglia 的说明:

15. 编辑 HBase 指标配置文件(hadoop-metrics.properties),如下所示:

```scala
hadoop@master1$ vi $HBASE_HOME/conf/hadoop-metrics.properties
hbase.extendedperiod = 3600
hbase.class=org.apache.hadoop.metrics.ganglia.GangliaContext
hbase.period=10
hbase.servers=master2:8649
jvm.class=org.apache.hadoop.metrics.ganglia.GangliaContext
jvm.period=10
jvm.servers=master2:8649
rpc.class=org.apache.hadoop.metrics.ganglia.GangliaContext
rpc.period=10
rpc.servers=master2:8649

```

16. Sync hadoop-metrics.properties to the slave nodes and restart HBase. You will find that HBase metrics are now collected by Ganglia automatically, as shown in the following screenshot:

![How to do it...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/6258afc45c934dc5bd7a5ac0cbb351b6~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1773139932&x-signature=CiKiLwkclPaD3fk1pBedrrvrKrA%3D)

它是如何工作的.

在撰写本书时,HBase 只支持 Ganglia 3.0.x 版本。 这是因为在较新的 3.1.x 版本中更改了网络协议。 这就是为什么我们必须从源代码安装 Ganglia,而不是使用包管理系统。

我们通过在步骤 3 中执行 gmond --default_config命令生成了一个默认配置文件。该文件在 /etc/gmond.conf处创建,这是 gmond 守护进程将读取的默认配置文件。

在步骤 4 中,我们将 gmond 守护进程的所有者设置为 ganglia用户,并将群集名称设置为 hbase-cookbook。 我们将 Gmond 之间使用的默认 UDP 多播通信方法配置为使用单播消息,而不是使用默认的 UDP 多播通信方法。 这是通过注释掉多播地址和**生存时间(TTL)**设置,并在 gmond.conf文件中添加专用主 Gmond 节点(master2)来实现的。 我们选择单播是因为 Amazon EC2 环境不支持多播。 另一个原因是,使用单播对于大型集群是有好处的,比如拥有 100 个以上节点的集群。

需要在要监视的所有节点上安装并启动 Gmond。 默认情况下,Gmond 监视该节点上的一些基本服务器指标,例如平均负载和 CPU/内存/磁盘使用率。

要安装 Gmetad,我们添加了 --with-gmetad选项,以便从源代码编译 Gmetad。 在步骤 8 和 9 中,我们将示例配置文件(gmetad.conf)复制到默认位置 /etc/gmetad.conf,并添加了一些更改,包括设置 Gmetad 守护进程的数据源、网格名称和所有者用户。 请注意,当使用单播时,您需要将 data_source设置为在 Gmond 设置中配置的专用 Gmond 服务器。

在步骤 10 中,我们创建了默认目录(/var/lib/ganglia/rrds),Gmetad 将收集的数据存储在循环数据库中。 之后,我们在 Gmetad 服务器(master2)上启动了 gmetad 守护进程。

Ganglia 设置的最后一部分是 PHP Web 前端。 它通常设置在相同的 Gmetad 节点上,以便它可以访问由 Gmetad 守护进程创建的循环数据库。 这一点在前面说明的步骤 12 到 14 中进行了说明。 您现在应该能够访问位于 http://master2/ganglia/的 Ganglia 网页,其中 master2是运行 Gmetad 的主机。 您将只看到 Gmond 节点的基本图表,因为 HBase 还没有配置为向 Ganglia 公开其指标。

它是在 hadoop-metrics.properties配置文件中设置的,用于集成 HBase 和 Ganglia。 请勿更改文件名,因为 HBase 从 Hadoop 继承其监控 API。 在该文件中,我们指示 HBase 使用 org.apache.hadoop.metrics.ganglia.GangliaContext类将服务器进程收集的指标发送到在 master2:8649上运行的 gmond 守护进程,这是我们在前面指定的专用 gmond 节点。

hadoop-metrics.properties同步到从节点,然后重新启动 HBase;您现在可以在 Ganglia 网页上找到 HBase 指标图。

有一些图表您应该特别注意,如下图所示:

  • CPU 和内存使用率
  • JVM GC 计数和时间
  • HBase RegionServer 压缩队列大小
  • HBase RegionServer 刷新队列大小

例如,压缩队列大小指示区域服务器中有多少存储已排队等待压缩。 通常这应该相当低(最多几十个 RegionServer)。 当服务器过载或出现 I/O 问题时,您将在图表上看到一个峰值。

下面的屏幕截图显示了在几轮繁重的写入高峰之后,区域服务器的 CPU 使用率、JVMGC 时间和 HBase 压缩队列大小。 如您所见,CPU 使用率和较长的垃圾收集时间表明服务器超载。 这会显著增加压缩队列大小。

How it works...

还有更多...

Ganglia 也可以用来监控 Hadoop。 其设置类似于我们在本食谱中所描述的。 Ganglia 可以监控以下 Hadoop 指标:

  • HDFS 指标
  • MapReduce 指标
  • JVM 指标
  • Hadoop RPC 指标

另请参阅

在本章中:

  • OpenTSDB-使用 HBase 监控 HBase 群集

OpenTSDB-使用 HBase 监控 HBase 群集

OpenTSDB是构建在 HBase 之上的高度可伸缩的时间序列数据库(TSDB)。 与 Ganglia 类似,OpenTSDB 可用于监视各种系统,包括 HBase。 与将数据存储在 RRDtool 中的 Ganglia 相比,OpenTSDB 利用 HBase 的可伸缩性对其进行更大规模的监控。 以下是 OpenTSDB 主页(opentsdb.net/)的介绍:

由于 HBase 的可伸缩性,OpenTSDB 允许您以高速率(每隔几秒钟)从数千台主机和应用收集数千个指标。 OpenTSDB 永远不会删除或下采样数据,可以轻松存储数十亿个数据点。

要使用 OpenTSDB,我们需要编写一些小脚本来从我们的系统中收集数据,并每隔几秒钟将它们推送到 OpenTSDB 中。 TCollector是一个用于从 Linux、MySQL、Hadoop、HBase 等收集 OpenTSDB 指标的框架。 有趣的是,OpenTSDB 使用 HBase(存储指标)来监控 HBase 本身。

在本食谱中,我们将介绍如何设置 OpenTSDB 和 TCollector,并使用它们来监控我们的 HBase 集群。 在演示中,我们将只启动一个时序守护进程(TSD)。 但是,可以在多台服务器上运行更多 TSD,因为它们彼此独立。

做好准备

您需要一台服务器来运行 TSD。 在我们的演示中,我们将使用 master2作为 TSD 服务器。

在 TSD 服务器(master2)上,添加 tsdb用户作为 TSD 守护进程的所有者。 我们将所有 OpenTSDB 文件和数据存储在 /usr/local/opentsdb:

root# adduser --disabled-login --no-create-home tsdb
root# mkdir /usr/local/opentsdb
root# chown tsdb:tsdb /usr/local/opentsdb

我们将在 /usr/local/tcollector目录下安装 TCollector。

您需要在 TSD 服务器和要监视的所有节点(如 Hadoop DataNodes 和 HBase RegionServers)上拥有 root 权限。

最后,确保您的 HBase 集群正在运行。 我们假设您的 HBASE_HOME环境变量是 /usr/local/hbase/current,并且 ZooKeeper 仲裁运行在 master1:2181

怎么做……

OpenTSDB 和收集器的设置说明如下:

  • **在 TSD 服务器上设置 OpenTSDB:**首先,我们将在 TSD 服务器(master2)上安装和配置 OpenTSDB,如下所示:

    1. 安装依赖项:

      hac@master2$ sudo apt-get install gnuplot
      hac@master2$ sudo apt-get install autoconf
      
      
    2. github.com/stumbleupon…下载最新版本的 OpenTSDB。 我们假设下载的目录是 $TSDB_INSTALL。 要构建和安装 OpenTSDB,请执行以下命令:

      hac@master2$ cd $TSDB_INSTALL
      hac@master2$ PATH=$PATH:$JAVA_HOME/bin
      hac@master2$ ./build.sh
      hac@master2$ cd build
      hac@master2$ sudo make install
      
      
    3. 在 HBase 中创建 OpenTSDB 表:

      hac@master2$ export COMPRESSION=LZO
      hac@master2$ export HBASE_HOME=/usr/local/hbase/current
      hac@master2$ sh $TSDB_INSTALL/src/create_table.sh
      
      
      • 此步骤要求 HBase 群集支持 LZO 压缩。 如果您的集群不支持 LZO,请不要调用第一个命令。 有关如何向 HBase 添加 LZO 支持的信息,请参阅第 8 章基本性能调整中的使用压缩配方。
    4. 创建 OpenTSDB 存储其文件的目录,然后启动 TSD 守护进程:

      hac@master2$ sudo su tsdb
      tsdb@master2$ cd /usr/local/opentsdb
      tsdb@master2$ PATH=$PATH:$JAVA_HOME/bin
      tsdb@master2$ tsdtmp=/usr/local/opentsdb/var
      tsdb@master2$ mkdir -p "$tsdtmp"
      tsdb@master2$ tsdstatic=/usr/local/share/opentsdb/static
      tsdb@master2$ nohup tsdb tsd --port=4242 --staticroot="$tsdstatic"
      --cachedir="$tsdtmp" --zkquorum=master1:2181 &
      
      
    5. 要验证我们的安装,请通过执行以下命令创建 OpenTSDB 自己的指标:

      tsdb@master2$ echo stats | nc -w 1 localhost 4242 \
      | awk '{ print $1 }' | sort -u \
      | xargs tsdb mkmetric
      metrics tsd.compaction.count: [0, 0, 2]
      metrics tsd.connectionmgr.connections: [0, 0, 3]
      metrics tsd.connectionmgr.exceptions: [0, 0, 4]
      metrics tsd.hbase.latency_50pct: [0, 0, 5]
      metrics tsd.hbase.latency_75pct: [0, 0, 6]
      metrics tsd.hbase.latency_90pct: [0, 0, 7]
      metrics tsd.hbase.latency_95pct: [0, 0, 8]
      metrics tsd.hbase.meta_lookups: [0, 0, 9]
      metrics tsd.hbase.root_lookups: [0, 0, 10]
      metrics tsd.http.graph.requests: [0, 0, 11]
      metrics tsd.http.latency_50pct: [0, 0, 12]
      metrics tsd.http.latency_75pct: [0, 0, 13]
      metrics tsd.http.latency_90pct: [0, 0, 14]
      metrics tsd.http.latency_95pct: [0, 0, 15]
      metrics tsd.jvm.ramfree: [0, 0, 1]
      metrics tsd.jvm.ramused: [0, 0, 16]
      metrics tsd.rpc.errors: [0, 0, 17]
      metrics tsd.rpc.exceptions: [0, 0, 18]
      metrics tsd.rpc.received: [0, 0, 19]
      metrics tsd.uid.cache-hit: [0, 0, 20]
      metrics tsd.uid.cache-miss: [0, 0, 21]
      metrics tsd.uid.cache-size: [0, 0, 22]
      
      
    6. 创建一个简单的脚本来收集 OpenTSDB 公开的统计数据,并使用 OpenTSDB 监视自身:

      tsdb@master2$ vi tsdb-status.sh
      #!/bin/bash
      INTERVAL=15
      while :; do
      echo stats || exit
      sleep $INTERVAL
      done | nc -w 30 localhost 4242 \
      | sed 's/^/put /' \
      | nc -w 30 localhost 4242
      tsdb@master2$ chmod 755 tsdb-status.sh
      tsdb@master2$ nohup ./tsdb-status.sh &
      
      
    7. By opening your browser and accessing http://master2:4242/, you will get the OpenTSDB web UI (make sure the 4242 port is open to your client). Enter a time period of the graph to show in the From and To fields, and metric name in the Metric (type tsd., and metrics that start with tsd. will pop up) field, you should get a graph, as shown in the following screenshot:

      How to do it...

  • **设置收集器:**对于您想要监控的所有节点,例如 Hadoop DataNodes 和 HBase RegionServers,我们需要在它们上设置收集器。 需要在要监视的每个节点上执行以下步骤:

    1. github.com/stumbleupon…下载最新版本的收集器,并执行以下命令:

      $ sudo mv tcollector /usr/local
      $ cd /urs/local/tcollector
      
      
    2. 有一个收集器,它附带了一个收集器,用于从 HBase RegionServer 收集指标。 Grep hbase_regionserver_jmx.py中的以下行并修改它们以适合您的环境:

      $ sudo vi collectors/0/hbase_regionserver_jmx.py
      #USER = "hadoop"
      USER = "your_running_user"
      CLASSPATH = [
      # "/usr/lib/jvm/java-6-sun/lib/tools.jar",
      "/your/java_home/lib/tools.jar",
      ]
      jmx = subprocess.Popen(
      # ["java", "-enableassertions", ...
      ["/your/java_home/bin/java", "-enableassertions", ...
      
      
    3. 在收集器的启动脚本中,添加运行 TSD 守护程序的服务器的 DNS 名称:

      $ sudo vi startstop
      TSD_HOST=master2
      
      
    4. 在您的 TSD 服务器上,使用 --auto-metric选项重新启动 TSD 守护进程:

      tsdb@master2$ nohup tsdb tsd --port=4242 --staticroot="$tsdstatic" --cachedir="$tsdtmp" --zkquorum=master1:2181 --auto-metric &
      
      
    5. Start Tcollector to collect metrics and send them to TSD:

      $ sudo /usr/local/tcollector/startstop start
      
      

      一段时间后,您应该能够在 OpenTSDB web UI 上查看 TCollector 收集的指标。 下面的屏幕截图显示了我们的 HBase 集群由收集器收集的指标:

      How to do it...

它是如何工作的.

在前面说明的步骤 1 和 2 中,我们安装了 OpenTSDB 及其依赖项。 因为 OpenTSDB 构建在 HBase 之上,所以我们需要首先在 HBase 中创建 OpenTSDB 的表。 在步骤 3 中,我们将 OpenTSDB 配置为创建支持 LZO 压缩的表。 这需要 HBase 群集支持 LZO。 您还可以使用其他 HBase 支持的压缩,如 Snappy 和 Gzip,但只要确保您的 HBase 集群上有可用的压缩即可。

之后,我们通过设置 HBASE_HOME环境变量来指定 HBase 的安装位置。 然后,我们调用 create_table.sh在 HBase 中实际创建表。 此脚本随 OpenTSDB 一起提供;它创建两个表-TSDB 和 tsdb-uid。 您可以在 HBase 主用户界面上找到这些表。

在步骤 4 中,我们创建了必要的目录,并启动了 OpenTSDB,并提供了使用这些目录的选项。 我们还传递了 --zkquorum=master1:2181选项来指定放置动物园管理员仲裁的位置。

为了验证我们的安装,我们在步骤 5 和 6 中将 OpenTSDB 设置为收集自己的指标。默认情况下,我们需要使用 tsdb mkmetric命令创建一个指标,然后才能将该指标存储到 OpenTSDB 中。 这是为了防止制定太多指标而设计的,因为过多的指标会使指标名称空间变得一团糟。 如我们在步骤 11 中所示,使用 --auto-metric选项启动 TSD 守护进程会将 OpenTSDB 配置为自动生成它收到的指标。

TSD 守护进程接受 stats命令以公开其自己的指标。 在步骤 5 中,我们使用这一点来制定指标。

在步骤 6 中,我们创建了一个简单的脚本,使用 stats命令定期获取 TSD 守护进程的指标,然后使用 put命令将它们放入 OpenTSDB。 如步骤 7 所示,收集的 OpenTSDB 自己的指标在其 Web UI 上显示为图形。

在步骤 8 到 12 中,我们在要监视的每台服务器上设置了收集器。 TCollector 从 Hadoop、HBase 等收集指标,并将它们发送到 TSD 守护进程。 在收集器的启动脚本(startstop)中,我们将 TSD_HOST设置为 TSD 服务器的 DNS 名称,以指定我们应该将指标发送到哪个服务器。

在步骤 11 中,我们使用 --auto-metric选项重新启动了 TSD 守护进程,以便在 OpenTSDB 中自动创建从 TCollector 接收的指标。 正如我们前面提到的,自动创建指标不被认为是一种良好的做法。 您应该知道系统正在收集哪些指标,并手动创建这些指标以确保指标名称空间是干净的。

最后,我们启动了 TCollector,开始收集指标并将其发送到 TSD 守护进程。 指标将存储在 HBase 中,并在 OpenTSDB 的 Web 用户界面上显示为图表。

还有更多...

TSDash是 OpenTSDB 的替代 Web UI/仪表板。 TSDash 提供了与 OpenTSDB web UI 相同的功能,但用户界面略有不同。 以下屏幕截图显示了 TSDash 的 UI 和示例图形:

There's more...

TSDash 可在github.com/facebook/ts…获得。

设置 Nagios 以监视 HBase 进程

监控集群中的 HBase 相关进程是运行 HBase 的重要组成部分。 基本监控是通过对 HBase 进程运行运行状况检查并在任何进程关闭时通知管理员来完成的。

Nagios是一款流行的开源监控软件,用于监视主机、服务和资源,并在出现故障和再次恢复时向用户发出警报。 定制模块可以很容易地扩展 Nagios,这些模块被称为插件check_tcp插件随 Nagios 安装一起提供。 我们可以使用此插件向 Hadoop/HBase 守护进程的 RPC 端口发送 ping 命令,以检查该守护进程是否处于活动状态。

在本食谱中,我们将设置一个运行 Nagios 的监视服务器来监视整个集群中所有与 HBase 相关的进程。 我们将 Nagios 配置为在任何 Hadoop/HBase/zooKeeper 进程关闭时向我们发送电子邮件通知。

做好准备

您需要一个监控服务器来运行 Nagios。 我们假设您使用的是安装最少的 Debian 机器。 监控服务器需要能够通过正确的 TCP 端口与集群中的所有机器通信。 在我们的演示中,我们将使用 master2作为监控服务器。

启动要监视的 HBase 集群,然后登录到监视服务器。 确保您在监视服务器上具有 root 权限。

怎么做……

安装和配置 Nagios 以监视您的 HBase 集群的说明如下:

  1. 使用 Linux 发行版的包管理工具在监视服务器上安装 Nagios:

    root@master2# apt-get install nagios3 nagios-plugins
    
    
    • 在安装过程中,会要求您输入nagiosadmin密码和 Samba 工作组设置;输入您的密码,并将 Samba 工作组设置设为默认设置。
  2. You should be able to access the Nagios admin page from your web browser using the URL http://<monitor_host>/nagios3/.

    系统将要求您输入帐号和密码;使用 nagiosadmin 和您在安装中设置的密码登录到 Nagios 管理页面。 Nagios 管理页面类似于以下屏幕截图:

    How to do it...

  3. 将 HBase 集群中的所有主机添加到 Nagios 主机配置文件:

    root@master2# vi /etc/nagios3/conf.d/hosts_nagios2.cfg
    #master1
    define host{
    use generic-host
    host_name master1
    alias master1
    address 10.160.41.205
    hostgroups masters
    }
    #slave1
    define host{
    use generic-host
    host_name slave1
    alias slave1
    address 10.168.71.224
    hostgroups slaves
    }
    #slave2
    define host{
    use generic-host
    host_name slave2
    alias slave2
    address 10.168.107.28
    hostgroups slaves
    }
    #slave3
    define host{
    use generic-host
    host_name slave3
    alias slave3
    address 10.160.39.197
    hostgroups slaves
    }
    
    
  4. 通过执行以下命令将 mastersslaves主机组添加到 Nagios:

    root@master2# vi /etc/nagios3/conf.d/hostgroups_nagios2.cfg
    # A list of your master servers
    define hostgroup {
    hostgroup_name masters
    alias Master servers
    members master1
    }
    # A list of your slave servers
    define hostgroup {
    hostgroup_name slaves
    alias Slave servers
    members slave1,slave2,slave3
    }
    
    
  5. 配置 Nagios 以监视主节点上的主守护进程。 我们假设 NameNode、ZooKeeper 和 HMaster 守护进程在同一主节点(master1)上运行。

    root@master2# vi /etc/nagios3/conf.d/services_nagios2.cfg
    # check that NameNode is running
    define service{
    use generic-service
    host_name master1
    normal_check_interval 1
    service_description NameNode health
    check_command check_tcp!8020!
    }
    # check that ZooKeeper is running
    define service{
    use generic-service
    host_name master1
    normal_check_interval 1
    service_description Zookeeper health
    check_command check_tcp!2181!
    }
    # check that HMaster is running
    define service{
    use generic-service
    host_name master1
    normal_check_interval 1
    service_description HMaster health
    check_command check_tcp!60000!
    }
    
    
  6. 将 Nagios 配置为监视所有从节点上的从守护进程:

    root@master2# vi /etc/nagios3/conf.d/services_nagios2.cfg
    # check that DataNodes are running
    define service{
    use generic-service
    hostgroup_name slaves
    normal_check_interval 1
    service_description DataNode health
    check_command check_tcp!50010!
    }
    # check that HRegionServers are running
    define service{
    use generic-service
    hostgroup_name slaves
    normal_check_interval 1
    service_description HRegionServer health
    check_command check_tcp!60020!
    }
    
    
  7. 更改通知电子邮件地址;将其设置为您自己的地址:

    root@master2# vi /etc/nagios3/conf.d/contacts_nagios2.cfg
    define contact{
    contact_name root
    alias Root
    service_notification_period 24x7
    host_notification_period 24x7
    service_notification_options w,u,c,r
    host_notification_options d,r
    service_notification_commands notify-service-by-email
    host_notification_commands notify-host-by-email
    email address@example.com
    }
    
    
  8. 安装 Postfix 电子邮件服务器,让 Nagios 发送电子邮件:

    root@master2# apt-get install postfix
    
    
    • 在安装过程中,将 Postfix 配置为Internet Site,并设置将从其接收 Nagios 邮件的域。
  9. 通过执行以下命令验证配置更改:

    root@master2# /usr/sbin/nagios3 -v /etc/nagios3/nagios.cfg
    Total Warnings: 0
    Total Errors: 0
    
    
  10. If everything is fine, restart Nagios to apply the configuration changes:

```scala
root@master2# /etc/init.d/nagios3 restart

```

*   如下面的 Nagios 管理页面屏幕截图所示,Nagios 开始检查我们刚刚配置的与 HBase 相关的进程。 所有主机、Hadoop/HBase/zooKeeper 守护程序及其状态现在都显示在 Nagios 管理页面上:

![How to do it...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/513405e25dbe465c861529c9e2604ccf~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1773139932&x-signature=l8OgauzCN98MaQshgEjhbb2FGig%3D)

11. To test our Nagios settings, we stop the HRegionServer daemon from one of the slave nodes:

```scala
hadoop@slave1$ hbase-daemon.sh stop regionserver

```

*   一段时间后,Nagios 将检测到停机的区域服务器,并在 Nagios 管理页面上显示**Critical**状态,如以下屏幕截图所示:

![How to do it...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/30af0e887e2d4b919e375b7ab8afe609~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1773139932&x-signature=0ISmQx%2B4CHzSWEhPdTyIPTv1UO0%3D)

*   您还将收到一封来自 Nagios 的警报电子邮件,报告某个区域服务器已关闭,如以下屏幕截图所示:

![How to do it...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/63defde6b76b48829b6e16eecb6833e0~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1773139932&x-signature=UNlKtL%2FckYQP2j%2FGpF678gerwNw%3D)

12. 现在再次重新启动 HRegionServer 守护进程,以测试 Nagios 的恢复通知:

```scala
hadoop@slave1$ hbase-daemon.sh start regionserver

```

*   您会发现状态再次更改为**OK**。 您还将收到恢复电子邮件通知。

它是如何工作的.

Nagios 可用于许多 Linux 发行版。 使用发行版的包管理系统可以很容易地安装 Nagios。

Nagios 有一个管理网页,您可以在其中看到正在监视的集群的当前状态。 您可以按主机、主机组、服务和服务组查看状态。 您还可以在管理页面上生成非常详细的可用性和趋势报告。 管理页面的 URL 是 http://<monitor_host>/nagios3/,其中 monitor_host是监视服务器的主机名。

在步骤 3 中,我们将集群的主机定义添加到 Nagios 主机配置文件(hosts_nagios2.cfg),以便 Nagios 可以监控这些远程节点。 在步骤 4 中,我们还设置了两个主机组: mastersslaves主机组。 此设置允许我们以主机组为基础监视服务器。

在步骤 5 中,我们向 services_nagios2.cfg文件添加了几个服务定义,以配置 Nagios 来监视主节点(master1)上运行的主守护进程。 服务由 check_command监视,其中我们使用预定义的 check_tcp命令,将 NameNode/zooKeeper/HMaster 守护进程的 RPC 端口传递给它。

以类似的方式,我们定义了服务来监视在从节点上运行的从守护进程。 请注意,我们使用了之前在这些服务定义中添加的主机组(slaves)。

在步骤 7 中,我们通过编辑 contacts_nagios2.cfg文件将 Nagios 配置为向特定的电子邮件地址发送通知。 在那之后,我们安装了 Postfix 电子邮件服务器,让 Nagios 发送电子邮件。 最后,我们重新启动 Nagios 以应用我们的更改。

Nagios 定期向守护程序的 RPC 端口发送 ping,它正在监视该端口以检查守护程序是否处于活动状态。 如果 Nagios 无法从守护进程获得响应,它将在其管理页面上将守护进程的状态标记为Critical,并向我们指定的地址发送一封警报电子邮件。 此电子邮件包含有关主机名、守护进程状态、何时检测到严重状态以及其他其他信息的详细信息。

还有更多...

使用适当的端口,您还可以配置 Nagios 来监控其他 Hadoop/HBase/zooKeeper 守护进程,比如 MapReduce 的 JobTracker 和 TaskTracker 守护进程。 下表显示了您可能要监视的 Hadoop 守护程序及其默认 RPC/HTTP 端口的快速参考:

|

精灵 / 恶魔 / 守护进程 / 后台程序

|

默认端口是默认端口

|

配置文件配置文件

|

配置参数

| | --- | --- | --- | --- | | NameNode | 8020 | core-site.xml | fs.default.name | | Second DaryNameNode | 50090 | hdfs-site.xml | dfs.secondary.http.address | | JobTracker | 50030 | mapred-site.xml | mapred.job.tracker.http.address | | HMaster | 60000 | hbase-site.xml | hbase.master.port | | 动物园管理员法定人数 | 2181 | zoo.cfg | clientPort | | 数据节点 | 50010 | hdfs-site.xml | dfs.datanode.address | | 任务跟踪器 | 50060 | mapred-site.xml | mapred.task.tracker.http.address | | HRegionServer | 60020 | hbase-site.xml | hbase.regionserver.port |

使用 Nagios 检查 Hadoop/HBase 日志

Hadoop、ZooKeeper 和 HBase 都会生成日志。 这些日志包括有关正常操作、警告/错误输出以及内部诊断数据的信息。 理想的做法是让系统收集和处理所有这些日志,以提取有关集群的有用洞察信息。 最基本的任务是检查这些日志,如果其中显示任何异常情况,就会得到通知。 只需几个简单的步骤,NRPE 和 check_logNagios 插件就可以实现这个简单的目标。

NRPE 插件主页(exchange.nagios.org/directory/A…)的说明如下:

NRPE 允许您在其他 Linux/Unix 计算机上远程执行 Nagios 插件。 这允许您监视远程机器指标(磁盘使用情况、CPU 负载等)。

使用 NRPE,我们可以在集群节点上远程执行 check_logNagios 插件,以检查该节点生成的 Hadoop/HBase 日志。

check_log插件在指定的日志文件中递增地显示特定的查询词。 如果日志文件中的任何行与查询字匹配, check_log将向运行在同一节点上的 NRPE 服务器报告严重状态。 然后,NRPE 将其报告给 Nagios 服务器。

由于本书的范围有限,在本食谱中,我们将只演示如何设置 Nagios 来检查 HBase 的主守护进程日志。 您可以轻松地复制它并进行一些更改,以设置 Nagios 来监视其他日志。

做好准备

我们假设您已经正确设置了 Nagios 监控服务器,如前面的菜谱所述。

check_log插件将保存以前检查的日志,这样它只需要检查新添加的日志。 在主节点上为 check_log插件创建一个目录,以保存其先前检查的日志:

root@master1# mkdir -p /var/nagios/oldlog	

检查您的 HBase log4j 配置文件(log4j.propertie),找出您的 HBase 生成其日志文件的位置。 我们假设它在这个配方中是 /usr/local/hbase/logs/hbase-hadoop-master-master1.log

怎么做……

要使用 Nagios 检查 Hadoop/HBase 日志,请执行以下步骤:

  1. 在监视服务器上安装 NRPE 插件(master2):

    root@master2# apt-get install nagios-nrpe-plugin
    
    
  2. 在 HBase 群集的主节点上安装 NRPE 服务器和插件:

    root@master1# apt-get install nagios-nrpe-server nagios-plugins
    
    
  3. 在主节点上设置 NRPE,以允许监视服务器与其上运行的 NRPE 守护进程通信。 在 nrpe.cfg文件中更改监视服务器的 allowed_hosts设置,然后重新启动 NRPE 守护进程。 此步骤实现如下:

    root@master1# vi /etc/nagios/nrpe.cfg
    #allowed_hosts=127.0.0.1
    allowed_hosts=master2
    root@master1# /etc/init.d/nagios-nrpe-server restart
    
    
  4. 在我们继续更改配置之前,请检查 NRPE 服务。 从监控服务器执行此操作。

    root@master2# /usr/lib/nagios/plugins/check_nrpe -H master1 -c check_users
    
    
    USERS OK - 2 users currently logged in |users=2;5;10;0
    
    
    • 输出应如下所示:
  5. 在主节点上配置 check_log命令以检查 HBase 的主守护进程日志。 将以下命令添加到主节点上的 nrpe.cfg文件中。 您需要更改命令定义的日志文件路径以适合您的环境。

    root@master1# vi /etc/nagios/nrpe.cfg
    command[check_log_hmaster]=/usr/lib/nagios/plugins/ check_log -F /usr/local/hbase/logs/hbase-hadoop- master-master1.log -O/var/nagios/oldlog/hbase-hadoop- master-master1.log -q "ERROR|FATAL"
    
    
  6. 重新启动主节点上的 NRPE 守护进程以应用我们的更改:

    root@master1# /etc/init.d/nagios-nrpe-server restart
    
    
  7. 在监控服务器上添加以下服务定义以检查主日志:

    root@master2# vi /etc/nagios3/conf.d/services_nagios2.cfg
    # check HMaster log
    define service{
    use generic-service
    host_name master1
    normal_check_interval 1
    service_description HMaster log check
    max_check_attempts 1
    notification_options w,u,c
    check_command check_nrpe_1arg!check_log_hmaster
    }
    
    
  8. Restart Nagios on the monitor server to apply the service definitions:

    root@master2# /etc/init.d/nagios3 restart
    
    
    • 您会发现添加的服务显示在您的 Nagios 管理页面上。 Nagios 开始检查主节点上的 HMaster 守护进程的日志。

    How to do it...

  9. Test the setup by adding a FATAL entry to the master daemon log:

    hadoop@master1$ echo "FATAL ..." >> /usr/local/hbase/logs/hbase- hadoop-master-master1.log
    
    
    • 一段时间后,Nagios 会检测到这一情况,并在 Nagios 管理页面上显示Critical状态,如以下屏幕截图所示:

    How to do it...

    • 您还会收到一封来自 Nagios 的警报电子邮件,报告 HBase 的主守护程序日志中有问题,如以下屏幕截图所示:

    How to do it...

它是如何工作的.

首先,我们需要在监视服务器上安装 NRPE 插件,在 HBase 集群中的所有节点上安装 NRPE 服务器和 Nagios 插件。

在步骤 3 中,为了允许监视服务器与远程节点上的 NRPE 守护进程对话,我们编辑了该节点上的 nrpe.cfg文件,将 allowed_hosts设置更改为监视服务器(master2),然后重新启动了 NRPE 守护进程。

在步骤 4 中测试了 NRPE 设置之后,我们在步骤 5 中添加了 check_log_hmaster命令定义。该命令定义被添加到我们要检查的节点(HBase 主节点)上的 NRPE 配置文件(nrpe.cfg)中。 check_log_hmaster命令执行 check_log插件以检查 HBase 的主守护进程日志。

以下语法显示了 check_log插件的用法:

check_log <log_file> <old_log_file> <pattern>

我们传递了 HBase 主日志文件的完整路径、临时旧日志文件名和用于匹配异常状态日志的正则表达式。 我们只在日志文件中搜索 ERRORFATAL,它们是 log4j 记录错误或致命信息时的关键字。

在步骤 7 中,我们在监控服务器上的 services_nagios2.cfg文件中定义了一个服务。 请注意,在服务定义中:

  • max_check_attempts选项应为 1
  • 不要将 r选项添加到 notification_options

这些都是必要的,因为 check_log插件的操作方式。

服务的 check_command选项是 check_nrpe_1arg!check_log_hmaster,这意味着它使用 NRPE 在远程服务器上执行 check_log_hmaster命令。

重新启动 HBase 主节点上的 NRPE 服务器和监控服务器上的 Nagios 守护进程。 您会发现 Nagios 开始监视 HBase 主日志,如果日志文件中出现 ERRORFATAL,则会向我们发送通知。

还有更多...

以下是您可能希望由 Nagios 监视的其他一些日志:

  • 主节点上的 NameNode 日志
  • 第二个 daryNameNode 记录在主节点上
  • 主节点上的 JobTracker 日志
  • 动物园管理员登录所有动物园管理员节点
  • RegionServer 登录所有区域服务器
  • DataNode 记录在所有从节点上
  • TaskTracker 记录在所有从节点上

您只需复制我们在此配方中所做的设置并更改日志文件路径,即可配置 Nagios 来监视这些日志。 如果所有这些日志都由 Nagios 监控,则您的 Nagios 管理页面应该类似于以下屏幕截图:

There's more...

另请参阅

在本章中:

  • 设置 Nagios 以监视 HBase 进程

报告群集状态的简单脚本

除了与 HBase 相关的守护进程及其日志的运行状况外,您可能需要监视集群的当前状态的概览。 该状态主要包括:

  • 显示 HBase 表是否一致的 HBase hbck结果
  • 显示 HDFS 是否正常的 Hadoop fsck结果
  • 剩余的 HDFS 空间

在本食谱中,我们将创建一个 check_hbaseNagios 插件来执行监视任务。 我们将在集群的主节点上安装我们的 check_hbase插件,并使用 NRPE Nagios 插件在监控服务器上使用 Nagios 远程执行它。

做好准备

我们假设您已经在监视器和主服务器上安装并配置了 Nagios NRPE 插件。 如果您尚未安装,请参考前面的食谱了解详细的安装说明。

怎么做……

以下是获取 HBase 集群状态并通过 Nagios 对其进行监控的说明:

  1. 创建如下所示的 check_hbase脚本:

    $ vi check_hbase
    
    #/bin/bash
    bin=`dirname $0`
    bin=`cd $bin;pwd`
    . $bin/utils.sh
    HADOOP_HOME=/usr/local/hadoop/current
    HBASE_HOME=/usr/local/hbase/current
    DFS_REMAINING_WARNING=15
    DFS_REMAINING_CRITICAL=5
    ABNORMAL_QUERY="INCONSISTENT|CORRUPT|FAILED|Exception"
    # hbck and fsck report
    output=/tmp/cluster-status
    $HBASE_HOME/bin/hbase hbck >> $output
    $HADOOP_HOME/bin/hadoop fsck /hbase >> $output
    # check report
    count=`egrep -c "$ABNORMAL_QUERY" $output`
    if [ $count -eq 0 ]; then
    echo "[OK] Cluster is healthy." >> $output
    else
    echo "[ABNORMAL] Cluster is abnormal!" >> $output
    # Get the last matching entry in the report file
    last_entry=`egrep "$ABNORMAL_QUERY" $output | tail -1`
    echo "($count) $last_entry"
    exit $STATE_CRITICAL
    fi
    # HDFS usage
    dfs_remaining=`curl -s http://master1:50070/dfshealth.jsp |egrep - o "DFS Remaining%.*%" | egrep -o "[0-9]*\.[0-9]*"`
    dfs_remaining_word="DFS Remaining%: ${dfs_remaining}%"
    echo "$dfs_remaining_word" >> $output
    # check HDFS usage
    dfs_remaining=`echo $dfs_remaining | awk -F '.' '{print $1}'`
    if [ $dfs_remaining -lt $DFS_REMAINING_CRITICAL ]; then
    echo "Low DFS space. $dfs_remaining_word"
    exit_status=$STATE_CRITICAL
    elif [ $dfs_remaining -lt $DFS_REMAINING_WARNING ]; then
    echo "Low DFS space. $dfs_remaining_word"
    exit_status=$STATE_WARNING
    else
    echo "HBase check OK - DFS and HBase healthy. $dfs_remaining_word"
    exit_status=$STATE_OK
    fi
    exit $exit_status
    
    
  2. 将脚本复制到主节点上的 Nagios 插件文件夹,并更改其执行权限:

    root@master1# cp check_hbase /usr/lib/nagios/plugins
    root@master1# chmod 755 /usr/lib/nagios/plugins/check_hbase
    
    
  3. 通过编辑 nrpe.cfg文件

    root@master1# vi /etc/nagios/nrpe.cfg
    command[check_hbase]=/usr/lib/nagios/plugins/check_hbase
    
    

    ,将 check_hbase命令添加到主节点上的 NRPE 配置中

  4. 重新启动主节点上的 NRPE 守护进程以应用更改:

    root@master1# /etc/init.d/nagios-nrpe-server restart
    
    
  5. 在监控服务器上添加 check_hbase服务定义:

    root@master2# vi /etc/nagios3/conf.d/services_nagios2.cfg
    # check hbck, fsck, and HDFS usage
    define service{
    use generic-service
    host_name master1
    normal_check_interval 5
    service_description hbck/fsck report and DFS usage check
    check_command check_nrpe_1arg!check_hbase
    }
    
    
  6. Restart Nagios to apply the changes:

    root@master2# /etc/init.d/nagios3 restart
    
    
    • 您会发现此服务已添加到您的 Nagios 管理页面,如以下屏幕截图所示:

    How to do it...

  7. 更改警告/严重阈值或异常查询词以测试插件。 例如,如果您将插件中的 DFS_REMAINING_CRITICAL更改为非常高的值,您将在一段时间后收到来自 Nagios 的警报通知。 具体实现如下:

    $ vi check_hbase
    #DFS_REMAINING_CRITICAL=10
    DFS_REMAINING_CRITICAL=40
    
    

如果剩余 HDFS 空间低于 40%,Nagios 将检测到此临界状态,如以下屏幕截图所示:

How to do it...

它是如何工作的.

check_hbase脚本中,我们首先执行 hbase hbck命令来获取 HBase 部署的当前状态报告。 我们还运行 hadoop fsck /hbase命令来检查 /hbase目录下的 HDFS 运行状况,该目录是 HBase 的默认根目录。 这些命令的输出被重定向到临时文件。

我们随后 grep 临时文件(如果找到任何 ABNORMAL_QUERY),并将匹配计数和最后一个匹配条目显示为标准输出,然后以 STATE_CRITICAL状态退出。

剩余的 HDFS 空间从 HDFS 管理 Web URL 获取。 我们访问 URL,并使用正则表达式从 HTML 输出中提取剩余的空间值。 最后,我们将该值与警告/严重阈值进行比较,并生成脚本的正确输出和退出状态。 输出和退出状态随后将用作 Nagios 的监控结果。

在步骤 2 中,我们只是将脚本复制到 Nagios 插件目录,并使其具有足够的可执行性,可以作为 Nagios 插件安装。 然后,在步骤 3 和 4 中,我们添加了 NRPE 命令定义,并在主节点上重新启动了 NRPE 服务器。

在监控服务器上,我们在 services_nagios2.cfg文件中定义了 Nagios 服务,然后重新启动 Nagios 守护进程以应用更改。

如您所见,Nagios 开始使用我们的 check_hbase插件监视集群的状态,如果 hbck结果、 fsck结果或 HDFS 使用情况有任何异常,则发送通知。

还有更多...

您可能还希望监视群集的以下状态:

  • NameNode 存储文件系统映像的目录( hdfs-site.xml)中的dfs.name.di)中的可用空间
  • NameNode 存储事务(编辑)文件的目录中的可用空间( hdfs-site.xml中的dfs.name.edits.dir,默认情况下与 dfs.name.dir相同)
  • 区域服务器托管的区域数量;上限应为 100 左右

这些可以用类似于我们刚才讨论的方式来完成。

另请参阅

  • 在本章中设置 Nagios 以监视 HBase 进程[t1
  • 使用 Nagios 检查本章中的 Hadoop/HBase 日志
  • HBase hbck-使用管理工具检查第 3 章中的 HBase 群集的运行状况

热区-写入诊断

随着数据的不断增长,HBase 集群可能会因为表架构或行键设计不佳或其他一些原因而变得不平衡。 许多请求可能会到达表的一小部分区域。 这通常称为热点区域问题

有两种类型的热点区域问题-热写和热读问题。 热写通常对我们更重要,因为热读将极大地受益于 HBase 内部缓存机制。 热写区问题的一种解决方案是找出热点区域,手动拆分,然后将拆分后的区域分发给其他地域服务器。

HBase 编辑将首先写入区域服务器的预写日志(WAL)。 一旦成功追加 WAL,就会发生对表数据的实际更新。 这种架构使得能够容易地获得近似的写入诊断。

在本食谱中,我们将创建一个 WriteDiagnosis.javaJava 源,以从 Wal 获取写入诊断信息。 在某些情况下,此信息可用于找出 HBase 集群中的热点写入区域。

做好准备

启动您的 HBase 群集并登录到您的 HBase 客户端节点。

怎么做……

诊断您的 HBase 热点区域问题:

  1. 创建一个 WriteDiagnosis.java文件,它有一个 printWriteDiagnosis()方法,如下所示:

    private static void printWriteDiagnosis(String logPath) throws IOException {
    Configuration conf = HBaseConfiguration.create();
    FileSystem fs = FileSystem.get(conf);
    FileStatus[] regionServers = fs.listStatus(new Path(logPath));
    HLog.Reader reader = new SequenceFileLogReader();
    Map<String, Long> result = new HashMap<String, Long>();
    for (FileStatus regionServer : regionServers) {
    Path regionServerPath = regionServer.getPath();
    FileStatus[] logs = fs.listStatus(regionServerPath);
    Map<String, Long> parsed = new HashMap<String, Long>();
    for (FileStatus log : logs) {
    System.out.println("Processing: " + log.getPath().toString());
    reader.init(fs, log.getPath(), conf);
    try {
    HLog.Entry entry;
    while ((entry = reader.next()) != null) {
    String tableName = Bytes.toString(entry.getKey().getTablename());
    String encodedRegionName = Bytes.toString(entry.getKey().getEncodedRegionName());
    String mapkey = tableName + "/" + encodedRegionName;
    Long editNum = parsed.get(mapkey);
    if (editNum == null) {
    editNum = 0L;
    }
    editNum += entry.getEdit().size();
    parsed.put(mapkey, editNum);
    }
    } finally {
    reader.close();
    }
    }
    for (String key : parsed.keySet()) {
    result.put(key, parsed.get(key));
    }
    }
    System.out.println();
    System.out.println("==== HBase Write Diagnosis ====");
    for (String region : result.keySet()) {
    long editNum = result.get(region);
    System.out.println(String.format("Region: %s Edits #: %d", region, editNum));
    }
    }
    
    
  2. 前一个 Java 源代码的 main()方法条目如下所示:

    public static void main(String[] args) {
    try {
    if (args.length < 1) {
    usage();
    System.exit(-1);
    }
    String logPath = args[0];
    printWriteDiagnosis(logPath);
    } catch (Exception e) {
    e.printStackTrace();
    System.exit(-1);
    }
    }
    private static void usage() {
    System.err.println("Usage: WriteDiagnosis <HLOG_PATH>");
    System.err.println("HLOG_PATH:");
    System.err
    .println(" Path on HDFS where HLogs are stored. For example: /hbase/.logs");
    }
    
    
  3. 将其打包为 JAR 文件(hac-chapter5.jar),并使用 hadoop jar命令运行它:

    $HADOOP_HOME/bin/hadoop jar hac-chapter5.jar hac.chapter5.WriteDiagnosis /hbase/.logs
    
    
  4. You will get an output as shown in the following screenshot:

    How to do it...

它是如何工作的.

HBase WAL 存储在 HDFS 的 ${hbase.rootdir}/.logs/<region_server>/目录下。 WAL 以区域服务器为基础进行存储和轮换,这意味着单个 WAL 文件仅包含到同一托管区域服务器的区域的条目,而不包含到其他区域服务器的条目。 WAL 条目包含有关编辑的表格和区域名称以及编辑量的信息。

我们的 WriteDiagnosis.java文件只需遍历特定路径下的所有 WAL,提取表名、区域名称,并从 WAL 中编辑计数,然后打印每个区域的总编辑计数。

主要逻辑在 printWriteDiagnosis()方法中完成。 我们首先创建一个 HLog.Reader实例。 对于每个 WAL 文件,我们调用实例的 init()方法从 WAL 文件读取数据。 WAL 文件的条目由 HLog.Entry类表示。 对于每个条目,我们从其键中获取该条目所属的表名和区域名。 我们还使用 HLog.Entry类的 getEdit().size()方法获取条目的编辑次数。 有了所有这些信息,我们可以按区域汇总编辑总数。

WriteDiagnosis.javamain()方法只从命令行检查日志路径参数,并将其传递给 printWriteDiagnosis()方法。

将 Java 源代码打包为 JAR 文件,并使用 hadoop jar命令运行它。 正如您从输出中看到的, hly_temp表有许多写请求,而表中的一个区域处理的请求是其他两个区域的两倍。 这是数据分布不均匀的典型情况。 您需要对我们刚刚找到的热点区域采取操作,例如手动将其一分为二。

请注意,输出中显示的编辑次数是近似值。 这是因为,如果 Wal 中的所有编辑都已持久化,则 Wal 可能会被后台线程删除;无法知道该已删除 Wal 中的编辑次数。

但是,对于许多情况,近似的写入诊断是足够好的解决方案。 您可以使用 WriteDiagnosis.java帮助查找热点写入区域。 当您关闭簇的自动区域分割时,它特别有用。

还有更多...

编译和执行我们的 WriteDiagnosis.java的一种更方便的方法是通过以下命令:

$ $HBASE_HOME/bin/hbase com.sun.tools.javac.Main WriteDiagno sis.java
$ $HBASE_HOME/bin/hbase WriteDiagnosis /hbase/.logs

另请参阅

  • 使用管理工具中的第 3 章中的使用 HBase Shell 管理群集

六、设备维护和安全

在本章中,我们将重点介绍:

  • 启用 HBase RPC 调试级日志记录
  • 宽限节点停用
  • 将节点添加到群集
  • 滚动重启
  • 用于管理 HBase 进程的简单脚本
  • 简化部署的简单脚本
  • 针对 Hadoop 和 HBase 的 Kerberos 身份验证
  • 使用 Kerberos 配置 HDFS 安全性
  • HBase 安全配置

简介

群集交付运行后,在群集使用期间,维护将是一项必要的持续任务。 典型的维护任务包括查找和纠正故障、更改集群大小、更改配置等。

HBase 最重要的特性之一是它非常容易扩展。 随着您的服务和数据不断增长,您可能需要向群集添加节点。

正常的节点停用和滚动重启也是必要的。 最大限度地减少退役和重启过程中的离线时间是一项重要的任务。 重要的是保持数据分布与重启前相同,保持数据的局部性。

另一项维护任务是管理 HBase 部署。 有很多方法可以将您的 HBase 部署到集群。 最简单的方法是使用基于脚本的方法在整个集群中同步 HBase 安装和配置。

我们将在本章的前六个食谱中介绍这些主题。

本章还将介绍安全性。 随着 HBase 变得越来越流行,不同的用户和群体可能会在一个共享的 HBase 集群中存储更多的数据。 您可能不希望所有用户都拥有对每个 HBase 表的完全权限。 这会给您的数据带来风险;例如,安全风险或丢失的数据操作。 您可能希望验证用户的身份,并根据用户的身份拥有对 HBase 表的访问控制。

在 Hadoop 0.20.203 发布之前,Hadoop 中没有验证用户身份的机制。 Hadoop 使用用户的当前登录名作为其 Hadoop 用户名(即,相当于 whoami))。 HDFS 本身不会验证此用户名是否真实以及是否属于实际操作员。

较新版本的 Hadoop(0.20.203 及更高版本)支持客户端的可选 Kerberos 身份验证。 通过此安全支持,它可以在共享 HDFS 群集上存储敏感数据(如财务数据)。

HBase 利用 HDFS 安全性为其客户端提供安全访问。 HBase 在其 0.92 版本中增加了安全支持。 只有经过身份验证的用户才能访问受保护的 HBase。 还可以在 HBase 中添加基于表或基于列族的访问控制。

在本章的最后三个步骤中,我们将安装 Kerberos,然后使用 Kerberos 设置 HDFS 安全性,最后设置安全的 HBase 客户端访问。

启用 HBase RPC 调试级日志记录

Hadoop 和 HBase 使用 log4j 库来写入它们的日志。 日志记录级别在 log4j.properties文件中设置。 在生产中,日志记录级别通常设置为 INFO 级别,这适用于许多情况。 但是,在某些情况下,您可能希望查看特定 Hadoop/HBase 守护进程的调试信息。

HBase 继承了 Hadoop 的在线日志级别更改功能。 可以从其 Web 用户界面更改 HBase 守护程序的日志记录级别,而无需重新启动该守护程序。

当您需要知道 HBase 守护进程的调试信息但无法重新启动它时,此功能非常有用。 一种典型的情况是对生产 HBase 群集进行故障排除。

在本指南中,我们将介绍如何启用 HBase RPC 调试级日志记录。

做好准备

启动 HBase 群集并从以下 URL 打开 HBase Web UI:

http://<master_host>:60010/master.jsp

怎么做……

无需重新启动 HBase 守护程序即可启用 HBase RPC 调试级日志记录的说明如下:

  1. 通过单击 Region Server 链接,显示 HBase Web UI 中的 Region Server Web UI。

  2. 单击区域服务器 Web 用户界面左上角的Log Level链接。

  3. 获取特定包或类的当前日志记录级别。

  4. Enter a package name (for example, org.apache.hadoop.ipc) in the Log textbox and click on the Get Log Level button. You will get an output as shown in the following screenshot:

    How to do it...

  5. 输入程序包名和日志记录级别,然后单击Set Log Level按钮以设置程序包的日志记录级别(例如,DEBUG)。

  6. You will get an output page, as shown in the following screenshot, that shows Effective level: DEBUG, which means that the package's logging level has been changed to DEBUG:

    How to do it...

  7. 现在您应该能够检查区域服务器的日志文件中的调试日志,如下所示:

    2012-02-10 22:14:42,878 DEBUG org.apache.hadoop.ipc.HBaseClient: IPC Client (47) connection to ip-10-176-201-128.us-west- 1.compute.internal/10.176.201.128:60000 from hadoop sendi
    2012-02-10 22:14:42,879 DEBUG org.apache.hadoop.ipc.HBaseClient: IPC Client (47) connection to ip-10-176-201-128.us-west-1.compute.internal/10.176.201.128:60000 from hadoop got v
    2012-02-10 22:14:42,880 DEBUG org.apache.hadoop.ipc.RPCEngine: Call: regionServerReport 2
    
    

它是如何工作的.

Hadoop 有自己的在线日志更改工具。 可以从 Hadoop 守护程序的 Web 用户界面获取或设置其日志记录级别。 这对于调试不允许重新启动的生产群集很有用。

HBase 只是从 Hadoop 继承了这个功能。 要在特定区域服务器上启用特定 HBase 守护进程的调试级日志记录,我们需要找到该区域服务器的 Web UI,然后显示其日志级别页面。 在此页面上,我们可以获取或设置特定 Java 包的日志记录级别。

在我们的演示中,我们将 HBase IPC(org.apache.hadoop.ipc)包的日志记录级别设置为 DEBUG。 因此,HRegionServer 守护进程开始将其 IPC 调试信息写入其日志文件。

Hadoop/HBase 守护程序可能会在短时间内生成大量调试日志。 在获得足够的调试信息后,不要忘记将其设置回信息级别。

还有更多...

我们还可以使用 hadoop daemonlog命令获取/设置日志记录级别。 以下命令获取在 localhost 上运行的 HMaster 守护程序的 IPC 日志级别:

$ $HADOOP_HOME/bin/hadoop daemonlog -getlevel localhost:60010 org.apache.hadoop.ipc
Connecting to http://localhost:60010/logLevel?log=org.apache.hadoop.ipc
Submitted Log Name: org.apache.hadoop.ipc
Log Class: org.apache.commons.logging.impl.Log4JLogger
Effective level: INFO

不带参数执行 hadoop daemonlog将打印命令的用法。

$ $HADOOP_HOME/bin/hadoop daemonlog
USAGES:
java org.apache.hadoop.log.LogLevel -getlevel <host:port><name>
java org.apache.hadoop.log.LogLevel -setlevel <host:port><name><level>

平稳节点退役

在本食谱中,我们将介绍如何优雅地停止区域服务器。

只需调用以下命令即可停止区域服务器上的 RegionServer 守护程序:

hadoop@slave1$ $HBASE_HOME/bin/hbase-daemon.sh stop regionserver

但是,这种方法有一个缺点,即在停止过程中,部署在停止区域服务器上的区域将会脱机一段时间。 在生产中,特别是对于处理在线请求的集群,预计会优雅地停止区域服务器,以最大限度地减少区域的离线时间。

在本食谱中,我们将描述 HBase 如何支持其优雅的节点退役特性。

做好准备

启动您的 HBase 集群,并以启动集群的用户(在我们的演示中是 hadoop用户)的身份登录到主节点。

怎么做……

正常停用区域服务器的说明如下:

  1. 通过调用以下命令优雅地停止区域服务器:

    hadoop@master1$ $HBASE_HOME/bin/graceful_stop.sh ip-10-160-226- 84.us-west-1.compute.internal
    Disabling balancer!
    HBase Shell; enter 'help<RETURN>' for list of supported commands.
    Type "exit<RETURN>" to leave the HBase Shell
    Version 0.92.0, r1231986, Tue Jan 17 02:30:24 UTC 2012
    balance_switch false
    true
    0 row(s) in 1.3370 seconds
    Unloading ip-10-160-226-84.us-west-1.compute.internal region(s)
    12/01/31 23:32:16 INFO region_mover: Moving 2 region(s) from ip- 10-160-226-84.us-west-1.compute.internal,60020,1328020203720 during this cycle
    12/01/31 23:32:16 INFO region_mover: Moving region 5740a39d9eaa59c4175487c14e0a272a (0 of 2) to server=ip-10-161-83- 13.us-west-1.compute.internal,60020,1328013827479
    12/01/31 23:32:17 INFO region_mover: Moving region f6a1084fc7534c15696f4baa4abf61ce (1 of 2) to server=ip-10-161-83- 13.us-west-1.compute.internal,60020,1328013827479
    12/01/31 23:32:18 INFO region_mover: Wrote list of moved regions to /tmp/ip-10-160-226-84.us-west-1.compute.internal
    Unloaded ip-10-160-226-84.us-west-1.compute.internal region(s)
    ip-10-160-226-84.us-west-1.compute.internal: stopping regionserver...
    
    
  2. 由于 graceful_stop.sh脚本将在实际停止区域服务器守护进程之前关闭 HBase 的负载平衡,因此如果需要,请再次显式启用它:

    hadoop@master1$ echo 'balance_switch true' | $HBASE_HOME/bin/hbase shell
    HBase Shell; enter 'help<RETURN>' for list of supported commands.
    Type "exit<RETURN>" to leave the HBase Shell
    Version 0.92.0, r1231986, Tue Jan 17 02:30:24 UTC 2012
    balance_switch true
    false
    0 row(s) in 1.4450 seconds
    
    

它是如何工作的.

停止区域服务器是以区域服务器为中心的操作。 它关闭区域服务器上部署的区域,并自行停止。 主服务器只能通过删除 ZooKeeper 中的区域服务器的 Znode 来获知区域服务器的消失,区域服务器调用该 Z 节点是它退出的最后一件事。 在关闭期间以及在主服务器得知区域服务器被移除之前,会有一个很大的不可用窗口。 因此,为了最小化此窗口,我们使用了一种优雅的关闭方式。 它一次(优雅地)将区域从区域服务器上移出一个。

graceful_stop.sh脚本将区域移出区域服务器,然后停止它。 由于区域首先移动到其他区域服务器,避免了停止过程中的区域离线时间。

在移动部署在特定区域服务器上的区域之前,脚本将首先关闭集群的负载均衡器。 这一点很重要,因为平衡器可能会在 graceful_stop.sh脚本移动区域的同时平衡集群中的区域。 我们必须通过关掉平衡器来避免这种情况。

从步骤 1 的输出中可以看到,在关闭负载均衡器后,脚本将两个地域从指定的服务器移动到其他地域服务器,最后停止了地域服务器。

由于 graceful_stop.sh脚本关闭了负载均衡器,因此您可能需要在节点停用后再次打开它。 这就是我们在步骤 2 中所做的。

确保将 HBase web UI 上显示的准确主机名传递给 graceful_stop.sh,否则它实际上不会将区域优雅地移动到其他区域服务器。

graceful_stop.sh脚本的全部用法如下所示:

./graceful_stop.sh
Usage: graceful_stop.sh [--config <conf-dir>] [--restart] [-- reload] [--thrift] [--rest] <hostname>
thrift If we should stop/start thrift before/after the hbase stop/start
rest If we should stop/start rest before/after the hbase stop/start
restart If we should restart after graceful stop
reload Move offloaded regions back on to the stopped server
debug Display extra debug logging
hostname Hostname of server we are to stop

还有更多...

您可能已经注意到, graceful_stop.sh脚本有 restartreload选项。 这些选项用于滚动重启 HBase 集群。 稍后我们将在滚动重启配方中对其进行描述。

另请参阅

在本章中:

  • 滚动重新启动

将节点添加到群集

HBase 最重要的特性之一是它具有极强的可伸缩性。 HBase 通过将节点添加到群集进行线性横向扩展。 您可以轻松地从一个小群集开始,并在您的服务和数据增长时向外扩展。 向 HBase 集群添加区域服务器将是管理员的一项重要维护任务。

一个 HBase 群集只能有一个活动的主节点。 但是,我们可以向集群添加一个备份主节点,以使 HBase 主节点高度可用(HA)

在本食谱中,我们将介绍如何向 HBase 集群添加备份主节点。 之后,我们还将介绍如何将区域服务器添加到集群。

做好准备

首先在新的主服务器或区域服务器上下载并安装 HBase。 确保该节点上的 HBase 配置与群集中的其他节点同步。

地域服务器通常运行在 Hadoop 的同一 DataNode/TaskTracker 上。 您可能还想在该节点上安装 Hadoop 并启动 DataNode 和 TaskTracker。

我们假设您已经在该新节点上准备好了所有 Hadoop/HBase 目录、配置和操作系统/用户设置。 有关这些初始设置的详细信息,请参阅第 1 章设置 HBase 群集

怎么做……

将备份主节点添加到群集的说明如下:

  1. 在备份主节点上启动 HBase 主守护进程:

    hadoop@master2$ $HBASE_HOME/bin/hbase-daemon.sh start master
    
    
    • 从主机日志中,您会发现新启动的主机正在等待成为下一个活动主机:

      org.apache.hadoop.hbase.master.ActiveMasterManager: Another master is the active master, ip-10-176-201-128.us-west- 1.compute.internal,60000,1328878644330; waiting to become the next active master
      
      
  2. 将新区域服务器的主机名添加到 $HBASE_HOME/conf目录下的 regionservers文件中。 例如,要将"slave4"添加到集群,我们调用以下命令:

    hadoop@master1$ echo "slave4" >> $HBASE_HOME/conf/regionservers
    
    
  3. 在群集中同步修改后的 regionservers文件。

  4. 登录到新服务器并在那里启动区域服务器守护进程:

    hadoop@slave4$ $HBASE_HOME/bin/hbase-daemon.sh start regionserver
    
    
  5. 也可以通过 HBase Shell 手动触发负载均衡,将部分地域迁移到新的地域服务器上。 您还可以等待平衡器的下一次运行,默认情况下,平衡器每五分钟运行一次。

    hbase> balance_switch true
    hbase> balancer
    
    

它是如何工作的.

在步骤 1 中,我们只需在备份主节点上启动 HBase 主守护进程。 HBase 使用动物园管理员来协调主人选举。 所有主节点都会竞争在 ZooKeeper 中创建 /hbase/masterZ 节点。 赢得选举(成功创建 Znode)的节点将成为群集的活动主节点。 因为现在已经存在一个主节点,所以新的主节点进入空闲模式,并且如果当前的主节点关闭,则等待成为下一个活动的主节点。

要添加区域服务器,首先在步骤 2 中将其主机名添加到 regionservers文件中。下次启动群集时,区域服务器守护进程将在该节点上自动启动。

由于我们没有重启集群,因此我们在步骤 4 中手动启动了新节点上的地域服务器守护进程。地域服务器将查询 ZooKeeper 来查找并加入集群。

步骤 5 是可选的。 由于新区域服务器上部署的区域较少,因此我们可以显式触发负载均衡,将一些区域移到其中。 默认情况下,平衡器每五分钟运行一次,因此我们也可以等待平衡器的下一次运行。

还有更多...

我们还可以通过以下步骤在群集启动时启动备份主机:

  1. 将备份主节点添加到 conf/backup-masters文件:

    hadoop@master1$ echo "master2" >> $HBASE_HOME/conf/backup-masters
    
    
  2. 在群集中同步 backup-masters文件。

  3. 正常启动 HBase,您会发现备份主节点上会启动一个备份 HBase 主节点:

    hadoop@master1$ $HBASE_HOME/bin/start-hbase.sh
    starting master, logging to /usr/local/hbase/logs/hbase-hadoop- master-master1.out
    slave2: starting regionserver, logging to /usr/local/hbase/logs/hbase-hadoop-regionserver-slave2.out
    slave1: starting regionserver, logging to /usr/local/hbase/logs/hbase-hadoop-regionserver-slave1.out
    slave3: starting regionserver, logging to /usr/local/hbase/logs/hbase-hadoop-regionserver-slave3.out
    master2: starting master, logging to /usr/local/hbase/logs/hbase- hadoop-master-master2.out
    
    
    • 备份主机上的主日志表明它是备份主机:

      hadoop@master2$ tail /usr/local/hbase/logs/hbase-hadoop-master-master2.log
      2012-02-10 23:12:07,016 INFO org.apache.hadoop.hbase.master.ActiveMasterManager: Another master is the active master, ip-10-176-201-128.us-west- 1.compute.internal,60000,1328883123244; waiting to become the next active master
      
      

滚动重启

当升级到新的 HBase 版本时,或者当您想要应用一些配置更改时,您可能想要调用滚动重启。 正如优雅节点退役配方中所述,滚动重启可以最大限度地减少停机时间,因为我们一次只离线一个区域,而不是整个集群。 滚动重新启动使区域分布与重新启动前相同。 这对于保持数据的局部性很重要。

备注

新的 HBase 版本并不总是向后兼容。 您可以调用滚动重启来升级次要版本(例如,从 0.92.1 升级到 0.92.2),但不能跨主要版本升级(例如,从 0.92.x 升级到 0.94.x),因为这些版本之间的协议已更改。 这将在 HBase 0.96 中发生变化,届时您将能够让旧客户端与新服务器对话,反之亦然。

有关从一个版本升级到另一个版本的详细信息,请查看以下链接:

http://hbase.apache.org/book.html#upgrading

滚动重新启动包含重新启动主服务器、正常重新启动区域服务器以及在重新启动后检查数据一致性的步骤。 我们将在本食谱中描述这些步骤。

做好准备

启动您的 HBase 集群。 以启动群集的用户身份登录到主节点。

怎么做……

滚动重启 HBase 集群的说明如下:

  1. 运行 hbck以确保群集一致:

    hadoop@master1$ $HBASE_HOME/bin/hbase hbck
    0 inconsistencies detected.
    Status: OK
    
    
  2. 重新启动主后台进程:

    hadoop@master1$ $HBASE_HOME/bin/hbase-daemon.sh stop master
    hadoop@master1$ $HBASE_HOME/bin/hbase-daemon.sh start master
    
    
  3. 禁用负载均衡器:

    hadoop@master1$ echo 'balance_switch false' | $HBASE_HOME/bin/hbase shell
    balance_switch false
    true
    0 row(s) in 1.1680 seconds
    
    
  4. 创建 rolling-restart-rs.sh脚本,如下图所示:

    $ vi rolling-restart-rs.sh
    #!/bin/bash
    HBASE_HOME=/usr/local/hbase/current
    zparent=`$HBASE_HOME/bin/hbase org.apache.hadoop.hbase.util.HBaseConfTool zookeeper.znode.parent`
    if [ "$zparent" == "null" ]; then
    zparent="/hbase"
    fi
    online_regionservers=`$HBASE_HOME/bin/hbase zkcli ls $zparent/rs 2>&1 | tail -1 | sed "s/\[//" | sed "s/\]//"`
    for rs in $online_regionservers
    do
    rs_parts=(${rs//,/ })
    hostname=${rs_parts[0]}
    echo "Gracefully restarting: $hostname"
    $HBASE_HOME/bin/graceful_stop.sh --restart --reload --debug $hostname
    sleep 1
    done
    
    
  5. 使脚本可执行,然后执行它以正常重新启动集群中的每个区域服务器守护进程。 您将获得以下输出:

    hadoop@master1$ chmod +x rolling-restart-rs.sh
    hadoop@master1$ ./rolling-restart-rs.sh
    Gracefully restarting: ip-10-160-41-210.us-west-1.compute.internal
    Disabling balancer!
    HBase Shell; enter 'help<RETURN>' for list of supported commands.
    Type "exit<RETURN>" to leave the HBase Shell
    Version 0.92.0, r1231986, Tue Jan 17 02:30:24 UTC 2012
    balance_switch false
    false
    0 row(s) in 1.2060 seconds
    Unloading ip-10-160-41-210.us-west-1.compute.internal region(s)
    Unloaded ip-10-160-41-210.us-west-1.compute.internal region(s)
    ip-10-160-41-210.us-west-1.compute.internal: stopping regionserver...
    ip-10-160-41-210.us-west-1.compute.internal: starting regionserver, logging to /usr/local/hbase/logs/hbase-hadoop- regionserver-slave1.out
    Reloading ip-10-160-41-210.us-west-1.compute.internal region(s)
    Reloaded ip-10-160-41-210.us-west-1.compute.internal region(s)
    Gracefully restarting: ip-10-166-109-91.us-west-1.compute.internal
    ...
    Gracefully restarting: ip-10-176-79-57.us-west-1.compute.internal
    ...
    Reloaded ip-10-176-79-57.us-west-1.compute.internal region(s)
    
    
  6. 再次启用负载均衡器:

    hadoop@master1$ echo 'balance_switch true' | $HBASE_HOME/bin/hbase shell
    balance_switch true
    false
    0 row(s) in 1.1730 seconds
    
    
  7. 再次运行 hbck以确保群集一致:

    hadoop@master1$ $HBASE_HOME/bin/hbase hbck
    
    

它是如何工作的.

在步骤 1 中,我们运行了 hbck命令,以确保集群在重启之前保持一致。 之后,我们在步骤 2 中重新启动了主守护进程。

在步骤 3 中,在重启地域服务器之前,我们关闭了均衡器,以避免在重启过程中出现均衡的情况。

我们在步骤 4 中创建的 rolling-restart-rs.sh脚本首先通过从 hbase命令调用 org.apache.hadoop.hbase.util.HBaseConfTool类来获取 zooKeeper(Zparent)中的根 Z 节点。 HBaseConfTool是用于获取运行时 HBase 配置的 Java 类。 向其传递 zookeeper.znode.parent将返回 zparent设置(如果已设置)。 如果未设置 zparent,则使用默认值 /hbase

每个在线区域服务器在 ZooKeeper 的 $zparent/rs下都有自己的 Znode。 我们使用它通过调用 hbase zkcli ls命令来获取在线区域服务器的列表。 返回值是一个包含空格分隔的在线区域服务器的字符串,例如 [region_server1,port,startcode region_server2,port,startcode region_server3,port,startcode]。 我们没有从 conf/regionservers文件中获取区域服务器列表。 这是因为,在某些环境中,例如在 Amazon EC2 中使用自己的 DNS 服务的群集,文件中的主机名可能与 HBase 提供的主机名不同。 graceful_stop.sh脚本只接受 HBase 中使用的主机名,该主机名显示在 HBase web 用户界面上。

对于列表中的每个区域服务器,我们调用传递 --restart --reload --debug选项的 graceful_stop.sh命令和服务器的主机名,以正常地重新启动该节点上的区域服务器。

从步骤 5 的输出中可以看到,对于每个在线区域服务器, rolling-restart-rs.sh脚本一次将一个区域移出区域服务器,重新启动它们,然后将移动的区域重新加载回区域服务器。

在所有区域服务器正常重启之后,在步骤 6 中重新启动之前,我们再次将负载均衡器启用到其状态。

最后,在步骤 7 中,我们再次执行 hbck以确保集群一致运行。

还有更多...

请注意,在 $HBASE_HOME/bin目录中有一个 rolling-restart.sh脚本。 我们没有使用此脚本,因为我们希望优雅地重新启动我们的区域服务器,而脚本中没有实现这一点。

备注

有一个补丁可以使 rolling-restart.sh以与本食谱前面描述的方式相同的方式工作。 该修补程序计划用于 0.96 版。 您可以在issues.apache.org/jira/browse…查看它以了解详细信息。

管理 HBase 进程的简单脚本

当集群中的节点不断增长时,您可能希望找到工具来显示和管理集群中运行的与 HBase 相关的进程。 由于 hadoop用户配置为无需密码即可从主节点 SSH 到集群中的每个从节点,因此我们很容易编写一个简单的脚本来完成此任务,只需对每个节点进行 SSH 登录,并显示/管理该节点上正在运行的 HBase 进程。

由于 Hadoop/HBase 进程在**Java 虚拟机(JVM)**中运行,我们的任务是管理集群中的这些 Java 进程。

在本食谱中,我们将创建一个简单的脚本来显示 HBase 集群中 hadoop用户拥有的所有正在运行的 Java 进程。

做好准备

启动您的 HBase 集群。 以启动群集的用户身份登录到主节点。

我们假设您以同一用户(这里的 hadoop用户)身份运行 HDFS 和 HBase。

怎么做……

创建管理 HBase 进程的简单脚本的说明如下:

  1. 创建 cluster-jps.sh脚本,如下图所示:

    $ vi cluster-jps.sh
    #!/bin/bash
    # Show all running Java processes on region servers. Must run on master using HBase owner user.
    JAVA_HOME=/usr/local/jdk1.6
    HBASE_HOME=/usr/local/hbase/current
    IFS=$'\n'
    printf "+------------------------------+----------+--------------------+\n"
    printf "|%-30s|%-10s|%-20s|\n" " HOST" " PID" " PROCESS"
    printf "+------------------------------+----------+--------------------+\n"
    process_count=0
    rs_count=0
    for rs in `cat $HBASE_HOME/conf/regionservers`
    do
    i=1
    for process in `ssh $rs "$JAVA_HOME/bin/jps" | grep -v Jps`
    do
    process_parts=(${process/ /$'\n'})
    pid=${process_parts[0]}
    pname=${process_parts[1]}
    if [ $i -eq 1 ]; then
    host="$rs"
    else
    host=" "
    fi
    printf "|%-30s|%-10s|%-20s|\n" " $host" " $pid" " $pname"
    i=`expr $i + 1`
    process_count=`expr $process_count + 1`
    done
    rs_count=`expr $rs_count + 1`
    printf "+------------------------------+----------+--------------------+\n"
    done
    echo -e "$process_count running Java processes on $rs_count region servers.\n"
    
    
  2. 以在主节点上启动 Hadoop/HBase 的用户身份运行脚本:

    hadoop@master1$ chmod +x cluster-jps.sh
    hadoop@master1$ ./cluster-jps.sh
    
    
  3. You will get an output as shown in the following screenshot:

    How to do it...

  4. 要显示主节点上的主进程,请调用以下命令:

    hadoop@master1$ $JAVA_HOME/bin/jps
    3005 Jps
    1680 QuorumPeerMain
    1781 HMaster
    1538 NameNode
    
    

它是如何工作的.

在此脚本中,我们将从 conf/regionservers文件中获取区域服务器列表。 然后,对于每个区域服务器,SSH 登录到该服务器并在其上运行 jps命令。 Jps是随 JDK 安装一起提供的命令,用于显示用户拥有的正在运行的 Java 进程。 我们需要的最基本信息,**进程 ID(PID)**和每个 Java 进程的名称都包含在 jps命令的输出中。

脚本的其余部分只收集每个节点的 jps命令输出,并以友好的格式显示结果。

正如我们在步骤 4 中所做的那样,我们还可以使用 jps命令来显示在主节点上运行的 Java 进程。 在此脚本中,我们跳过了显示主服务器的 Java 进程的逻辑。

第 5 章监视和诊断设置 Nagios 以监视 HBase 进程配方中所述,您需要确保仔细监视这些 Java 进程。

简化部署的简单脚本

有很多方法可以将您的 HBase 部署到集群。 因为 Hadoop 和 HBase 都是用 Java 编写的,所以大多数部署都是通过简单地将所有文件复制到集群中的节点来完成的。

最简单的方法是使用基于脚本的方法在整个集群中同步 HBase 安装和配置。 与其他现代部署管理工具相比,它可能不那么酷,但对于小型甚至中型集群来说,它工作得很好。

在本食谱中,我们将创建一个简单的脚本来将 HBase 安装从其主节点同步到集群中的所有区域服务器。 此方法也可用于部署 Hadoop。

做好准备

以启动群集的用户身份登录到主节点。 我们假设您已经为用户设置了从主节点到区域服务器的非密码 SSH。

怎么做……

创建简单脚本以简化 HBase 部署的说明如下:

  1. 创建 cluster-deploy.sh脚本,如下图所示:

    $ vi cluster-deploy.sh
    #!/bin/bash
    # Sync HBASE_HOME across the cluster. Must run on master using HBase owner user.
    HBASE_HOME=/usr/local/hbase/current
    for rs in `cat $HBASE_HOME/conf/regionservers`
    do
    echo "Deploying HBase to $rs:"
    rsync -avz --delete --exclude=logs $HBASE_HOME/ $rs:$HBASE_HOME/
    echo
    sleep 1
    done
    echo "Done"
    
    
  2. 以在主节点上启动 Hadoop/HBase 的用户身份运行脚本:

    hadoop@master1$ chmod +x cluster-deploy.sh
    hadoop@master1$ ./cluster-deploy.sh
    Deploying HBase to slave1:
    sending incremental file list
    ./
    conf/
    conf/hbase-site.xml
    sent 40023 bytes received 259 bytes 80564.00 bytes/sec
    total size is 55576486 speedup is 1379.69
    Deploying HBase to slave2:
    ...
    Deploying HBase to slave3:
    ...
    Done
    
    

它是如何工作的.

该脚本使用的事实是, conf/regionservers文件中列出了所有区域服务器。 它从文件中读取每个区域服务器的主机名,然后调用 rsync命令将 HBase 安装目录从主节点同步到该区域服务器。 我们将 --delete选项添加到 rsync命令,因为我们希望从区域服务器中删除不必要的文件。

要使用此脚本,请在主节点上进行一些 HBase 配置更改,然后使用 HBase 所有者用户运行该脚本。

还有更多...

当群集变得更大时,您可能希望尽可能自动执行部署,例如新节点的操作系统和用户设置、获取和部署软件包以及从中心版本管理的配置中心设置文件。

对于这些类型的部署任务,您可能希望尝试使用 Pupppt 或 Chef。 互联网上有一些 HBase 的木偶和厨师配置示例,其 URL 如下:

您可能想尝试的另一个工具是 Apache bigtop,它可以在以下位置找到:

http://incubator.apache.org/bigtop/

Bigtop 是一个开发 Hadoop 生态系统打包和测试的项目。 它还没有准备好进入黄金时间,但是对于轻松构建和部署 Hadoop 和 HBase 来说,它是一个很棒的工具。

针对 Hadoop 和 HBase 的 Kerberos 身份验证

最近发布的 Hadoop 1.0 和 HBase 0.92 增加了安全支持。 启用安全保护后,只有经过身份验证的用户才能访问 Hadoop 和 HBase 群集。 身份验证由受信任管理员管理的单独身份验证服务提供。 这使得 HBase 成为存储金融数据等敏感大数据的一个相当不错的选择。

Hadoop 依靠 Kerberos 身份验证服务提供安全支持。 安全的 HBase 必须在具有安全支持的 HDFS 上运行,因此 HBase 还依赖 Kerberos 为其提供安全支持。

以下是维基百科对 Kerberos 的描述:

Kerberos 是一种计算机网络认证协议,它基于“票证”工作,以允许在非安全网络上通信的节点以安全的方式相互证明其身份。

使用最广泛的 Kerberos 实现是 MIT Kerberos。 在本食谱中,我们将介绍如何安装和设置 MIT Kerberos。 安装包括设置 Kerberos 管理服务器和密钥分发中心(KDC)。

做好准备

安装 MIT Kerberos 需要 Linux 服务器。 确保您在该服务器上具有 root 权限。 在这个配方中,我们假设服务器的主机名是 master2

使用以下命令提前在服务器上创建 Kerberos 日志目录:

$ sudo mkdir /var/log/kerberos

怎么做……

安装 MIT Kerberos 的说明如下:

  1. Install the Kerberos admin server and KDC:

    hac@master2$ sudo apt-get install krb5-{admin-server,kdc}
    
    
    • 在安装过程中,系统将要求您输入默认域名。 Kerberos 领域的标准名称是您的大写域名。 当我们在本书中使用hbase-admin-cookbook.com作为我们的域时,我们将选择HBASE-ADMIN-COOKBOOK.COM作为域名,如以下屏幕截图所示:

    How to do it...

    • 安装过程还会要求您输入 Kerberos 服务器和管理服务器。 在此处输入您的服务器的完全限定域名。 在我们的演示中,它是master2.hbase-admin-cookbook.com.
  2. Create a realm using the following command:

    hac@master2$ sudo krb5_newrealm
    
    

    备注

    该命令将要求提供主密码。 输入您的密码,不要忘记。

  3. 通过编辑 krb5.conf文件配置 Kerberos,如下图所示:

    hac@master2$ sudo vi /etc/krb5.conf
    [realms]
    HBASE-ADMIN-COOKBOOK.COM = {
    kdc = master2.hbase-admin-cookbook.com
    admin_server = master2.hbase-admin-cookbook.com
    default_domain = hbase-admin-cookbook.com
    }
    [domain_realm]
    .hbase-admin-cookbook.com = HBASE-ADMIN-COOKBOOK.COM
    hbase-admin-cookbook.com = HBASE-ADMIN-COOKBOOK.COM
    [logging]
    kdc = FILE:/var/log/kerberos/krb5kdc.log
    admin_server = FILE:/var/log/kerberos/kadmin.log
    default = FILE:/var/log/kerberos/krb5lib.log
    
    
  4. 通过取消注释 kadm5.acl文件中的以下行,授予管理员用户完全权限:

    hac@master2$ sudo vi /etc/krb5kdc/kadm5.acl
    */admin *
    
    
  5. 重新启动 Kerberos 管理服务器和 KDC 以应用更改:

    hac@master2$ sudo invoke-rc.d krb5-admin-server restart
    hac@master2$ sudo invoke-rc.d krb5-kdc restart
    
    
  6. kadmin.local控制台中测试安装和配置:

    hac@master2$ sudo kadmin.local
    Authenticating as principal root/admin@HBASE-ADMIN-COOKBOOK.COM with password.
    kadmin.local: listprincs
    K/M@HBASE-ADMIN-COOKBOOK.COM
    kadmin/admin@HBASE-ADMIN-COOKBOOK.COM
    kadmin/changepw@HBASE-ADMIN-COOKBOOK.COM
    kadmin/history@HBASE-ADMIN-COOKBOOK.COM
    kadmin/ip-10-174-14-251.us-west-1.compute.internal@HBASE-ADMIN- COOKBOOK.COM
    krbtgt/HBASE-ADMIN-COOKBOOK.COM@HBASE-ADMIN-COOKBOOK.COM
    
    
  7. 创建具有管理权限的主体:

    kadmin.local: addprinc root/admin
    WARNING: no policy specified for root/admin@HBASE-ADMIN- COOKBOOK.COM; defaulting to no policy
    Enter password for principal "root/admin@HBASE-ADMIN- COOKBOOK.COM":
    Re-enter password for principal "root/admin@HBASE-ADMIN- COOKBOOK.COM":
    Principal "root/admin@HBASE-ADMIN-COOKBOOK.COM" created.
    
    
  8. 将测试用户帐户(“主体”)添加到 Kerberos:

    kadmin.local: addprinc hac
    
    
  9. 退出 kadmin.local控制台,并通过获取 Kerberos 票证测试测试用户的身份验证:

    kadmin.local: quit
    hac@master2$ klist -5
    klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1002)
    hac@master2$ kinit
    Password for hac@HBASE-ADMIN-COOKBOOK.COM:
    hac@master2$ klist -5
    Ticket cache: FILE:/tmp/krb5cc_1002
    Default principal: hac@HBASE-ADMIN-COOKBOOK.COM
    Valid starting Expires Service principal
    02/05/12 11:48:49 02/05/12 21:48:49 krbtgt/HBASE-ADMIN- COOKBOOK.COM@HBASE-ADMIN-COOKBOOK.COM
    renew until 02/06/12 11:48:46
    
    
  10. 使用以下命令终止缓存的票证:

```scala
hac@master2$ kdestroy
hac@master2$ klist -5
klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_1002)

```

11. 使用以下命令删除测试用户帐户:

```scala
hac@master2$ sudo kadmin.local
kadmin.local: delprinc hac

```

它是如何工作的.

我们在同一台 master2服务器上安装了 Kerberos 管理服务器和 KDC。 在安装期间,我们将 HBASE-ADMIN-COOKBOOK.COM设置为默认领域。 该领域实际上是在步骤 2 中使用 krb5_newrealm命令创建的。

在步骤 3 中,我们在 /etc/krb5.conf文件中配置了 Kerberos 的域、域和日志设置。 在步骤 4 中,我们向管理员用户授予了完全权限。之后,我们重新启动 Kerberos 以应用更改。

为了测试安装和配置,我们在步骤 6 进入了 Kerberos 的 kadmin.local控制台。 kadmin.local是操作 Kerberos 的提示控制台。 只有 Kerberos 管理服务器上的 root用户可以进入 kadmin.local控制台并在那里执行 Kerberos 管理命令。

在步骤 6 中,我们还运行了 listprincs命令来显示 Kerberos 的初始主体。Kerberos 中的唯一标识(用户、主机等)称为主体。 主体的格式为 primary/instance@REALM

在步骤 7 中,我们向 Kerberos 添加了一个管理员用户( root用户)。 通过输入 Kerberos 密码(而不是操作系统密码),来自 Kerberos 客户端的 root用户将能够通过 kadmin控制台执行 Kerberos 的管理命令。 kadmin控制台类似于 kadmin.local,但是可以使用管理员用户从其他 Kerberos 客户端进入。 当您需要授予 admin 用户,但不希望他们拥有对 Kerberos 管理服务器的 root 访问权限时,它很有用。

我们还在步骤 8 中为 hac用户添加了一个测试主体,并从步骤 9 到步骤 11 测试了它的身份验证。

Kerberos 用户需要票证才能访问 Kerberos 经过身份验证的服务。 票证由 KDC 发行票证授予票证(TGT)。 要获得 TGT,用户需要提供他们的 Kerberos 密码来证明他们的身份。 Kerberos TGT 可以缓存,并将在配置的时间之后过期。

在步骤 9 中,我们使用 klist命令显示了 hac用户缓存的 TGT。 结果是空的,这是我们预期的。 然后,我们使用 kinit命令请求 TGT。 之后, klist命令显示缓存的 TGT 及其到期日期。 在步骤 10 中使用 kdestroy命令删除了缓存的 TGT。

还有更多...

在本食谱中,我们进行了基本的 Kerberos 设置。 我们将配置 HDFS 和 HBase 以使用此 Kerberos 安装来提供以下两种方法的安全支持。 Kerberos 的细节超出了本书的范围。 有关详细信息,请参阅以下 URL:

另请参阅

在本章中:

  • 使用 Kerberos 配置 HDFS 安全性
  • HBase 安全配置

使用 Kerberos 配置 HDFS 安全性

较新版本的 Hadoop(0.20.203 及更高版本)支持可选的客户端 Kerberos 身份验证。 此安全支持包括安全 HDFS 和安全 MapReduce 配置。

Hadoop 安全的动机不是为了防御黑客,因为所有大型 Hadoop 集群都在防火墙后面,只允许员工访问它们。 其目的只是允许将敏感数据(如财务数据)存储在共享群集上。

Hadoop 的以前版本已经在 HDFS 中拥有文件所有权和权限;限制是它们没有验证用户身份的机制。 有了这种 Kerberos 安全支持,Kerberos 将验证用户身份,并且只允许经过身份验证的用户访问 HDFS 群集。

由于安全的 HBase 访问预计运行在安全的 HDFS 集群之上,因此设置 HDFS 安全是配置 HBase 安全的先决条件。 在本食谱中,我们将重点介绍如何使用 Kerberos 配置 HDFS 安全性。

做好准备

我们假设您有一个正在工作的Kerberos 密钥分发中心(KDC),并设置了领域。 有关安装和配置 Kerberos 的更多信息,请参阅本章中的用于 Hadoop 和 HBase 的Kerberos 身份验证食谱。

我们假设每个节点上的 root用户在 Kerberos 中具有管理权限。 在此假设下,我们将使用 kadmin控制台执行 Kerberos 管理命令。 如果这一假设不成立,您将需要通过 Kerberos 管理服务器上的 kadmin.local控制台操作 Kerberos。

在群集的每个节点上,使用以下命令创建一个目录来存储 Kerberos 密钥表文件:

$sudo mkdir /etc/hadoop

在执行本食谱中讨论的步骤之前,请关闭您的集群。

怎么做……

要使用 Kerberos 配置 HDFS 安全,请在群集的每个节点上执行以下步骤:

  1. 安装 Kerberos 客户端软件:

    $ sudo apt-get install krb5-{config,user} libpam-krb5
    
    
  2. 使用以下命令进入 kadmin控制台:

    $ sudo kadmin
    
    
  3. hadoop用户主体添加到 Kerberos。 将主体的主机名部分(ip-10-168-46-11.us-west-1.compute.internal)替换为主机的完全限定域名(FQDN):

    kadmin: addprinc -randkey hadoop/ip-10-168-46-11.us-west- 1.compute.internal
    
    
  4. 将主机主体添加到 Kerberos。 将主体的主机名部分替换为主机的 FQDN:

    kadmin: addprinc -randkey host/ip-10-168-46-11.us-west- 1.compute.internal
    
    
  5. 使用以下命令创建密钥表文件:

    kadmin: ktadd -k /etc/hadoop/hadoop.keytab -norandkey hadoop/ip- 10-168-46-11.us-west-1.compute.internal host/ip-10-168-46-11.us- west-1.compute.internal
    
    
  6. 退出 kadmin控制台,确认密钥表文件是否创建正确:

    kadmin: quit
    $ klist -e -k -t /etc/hadoop/hadoop.keytab
    Keytab name: WRFILE:/etc/hadoop/hadoop.keytab
    KVNO Timestamp Principal
    ---- ----------------- ------------------------------------------- -------------
    5 02/05/12 16:03:34 hadoop/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (AES-256 CTS mode with 96-bit SHA-1 HMAC)
    5 02/05/12 16:03:34 hadoop/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (ArcFour with HMAC/md5)
    5 02/05/12 16:03:34 hadoop/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (Triple DES cbc mode with HMAC/sha1)
    5 02/05/12 16:03:34 hadoop/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (DES cbc mode with CRC-32)
    5 02/05/12 16:03:34 host/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (AES-256 CTS mode with 96-bit SHA-1 HMAC)
    5 02/05/12 16:03:34 host/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (ArcFour with HMAC/md5)
    5 02/05/12 16:03:34 host/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (Triple DES cbc mode with HMAC/sha1)
    5 02/05/12 16:03:34 host/ip-10-168-46-11.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM (DES cbc mode with CRC-32)
    
    
  7. 确保密钥表文件仅可由 hadoop用户读取:

    $ sudo chown hadoop:hadoop /etc/hadoop/hadoop.keytab
    $ sudo chmod 400 /etc/hadoop/hadoop.keytab
    
    
  8. Download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6" from the following URL:

    http://www.oracle.com/technetwork/java/javase/downloads/index.html

    按照下载文件中的README文件安装。

  9. 通过将以下配置添加到 core-site.xml文件来启用 Hadoop 安全性:

    $ vi $HADOOP_HOME/conf/core-site.xml
    <property>
    <name>hadoop.security.authentication</name>
    <value>kerberos</value>
    </property>
    <property>
    <name>hadoop.security.authorization</name>
    <value>true</value>
    </property>
    
    
  10. 通过将以下配置添加到 hdfs-site.xml文件来启用 HDFS 安全性:

```scala
$ vi $HADOOP_HOME/conf/hdfs-site.xml<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>

```

11. 将 NameNode 安全配置添加到 hdfs-site.xml文件:

```scala
$ vi $HADOOP_HOME/conf/hdfs-site.xml
<property>
<name>dfs.https.address</name>
<value>${your_namenode_host}:50470</value>
</property>
<property>
<name>dfs.https.port</name>
<value>50470</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/etc/hadoop/hadoop.keytab</value>
</property>
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>hadoop/_HOST@HBASE-ADMIN-COOKBOOK.COM</value>
</property>
<property>
<name>dfs.namenode.kerberos.https.principal</name>
<value>host/_HOST@HBASE-ADMIN-COOKBOOK.COM</value>
</property>

```

12. 将 DataNode 安全配置添加到 hdfs-site.xml文件:

```scala
$ vi $HADOOP_HOME/conf/hdfs-site.xml
<property>
<name>dfs.datanode.data.dir.perm</name>
<value>700</value>
</property>
<!-- secure setup requires privileged ports -->
<property>
<name>dfs.datanode.address</name>
<value>0.0.0.0:1004</value>
</property>
<property>
<name>dfs.datanode.http.address</name>
<value>0.0.0.0:1006</value>
</property>
<property>
<name>dfs.datanode.keytab.file</name>
<value>/etc/hadoop/hadoop.keytab</value>
</property>
<property>
<name>dfs.datanode.kerberos.principal</name>
<value>hadoop/_HOST@HBASE-ADMIN-COOKBOOK.COM</value>
</property>
<property>
<name>dfs.datanode.kerberos.https.principal</name>
<value>host/_HOST@HBASE-ADMIN-COOKBOOK.COM</value>
</property>

```

13. 在主节点上启动 NameNode 守护进程:

```scala
hadoop@master1$ $HADOOP_HOME/bin/hadoop-daemon.sh start namenode

```

*   您将在 NameNode 日志文件中找到类似以下内容的日志:

    ```scala
    2012-02-05 20:26:48,642 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hadoop/ip-10-168-46-11.us-west-1.compute.internal@HBASE-ADMIN-COOKBOOK.COM
    2012-02-05 20:37:19,397 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user host/ip-10-168-46-11.us-west-1.compute.internal@HBASE-ADMIN-COOKBOOK.COM
    2012-02-05 20:37:19,694 INFO org.apache.hadoop.http.HttpServer: Added global filtersafety (class=org.apache.hadoop.http.HttpServer$QuotingInputFilter)
    2012-02-05 20:37:19,705 INFO org.apache.hadoop.http.HttpServer: dfs.webhdfs.enabled = false
    2012-02-05 20:37:19,714 INFO org.apache.hadoop.http.HttpServer: Adding Kerberos filter to getDelegationToken
    2012-02-05 20:37:19,714 INFO org.apache.hadoop.http.HttpServer: Adding Kerberos filter to renewDelegationToken
    2012-02-05 20:37:19,716 INFO org.apache.hadoop.http.HttpServer: Adding Kerberos filter to cancelDelegationToken
    2012-02-05 20:37:19,717 INFO org.apache.hadoop.http.HttpServer: Adding Kerberos filter to fsck
    2012-02-05 20:37:19,718 INFO org.apache.hadoop.http.HttpServer: Adding Kerberos filter to getimage

    ```

*   以下步骤仅适用于 DataNode 节点:

14. 将数据存储目录权限更改为仅由其所有者读取:

```scala
$ chmod -R 700 /usr/local/hadoop/var/dfs/data

```

15. 将日志目录所有者更改为 hadoop用户:

```scala

$ chown -R hadoop:hadoop $HADOOP_HOME/logs

```

16. 通过将以下命令添加到 hadoop-env.sh文件来配置 Hadoop 安全数据节点用户:

```scala
$ vi conf/hadoop-env.sh
HADOOP_SECURE_DN_USER=hadoop

```

17. For 32-bit systems only, build jsvc from source, and then replace the commons-daemon JAR file in the Hadoop lib directory, as described in the following steps:

I.从 Apache Commons Daemon 下载 URL([http://commons.apache.org/daemon/download_daemon.cgi](http://commons.apache.org/daemon/download_daemon.cgi))下载 `jsvc`源文件(`commons-daemon-1.x.y-native-src.tar.gz`),然后按照 tarball 中的 `README`文件构建 `jsvc`。 然后,将构建的 `jsvc`二进制文件复制到 `$HADOOP_HOME/libexec/jsvc.i386`文件。

二、。 另外,使用相同版本的 `jsvc`下载 Commons Daemon JAR 文件(`commons-daemon-1.x.y-bin.tar.gz`)。 将其解压缩并用下载的 JAR 文件替换 `$HADOOP_HOME/lib/commons-daemon-1.0.1.jar`

18. 使用 root用户

```scala
$ sudo $HADOOP_HOME/bin/hadoop-daemon.sh start datanode
```

启动 DataNode
*   如果一切配置良好,应该可以找到日志,如下图所示:

    ```scala
    2012-02-05 21:46:02,925 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hadoop/ip-10-168-106-166.us-west-1.compute.internal@HBASE-ADMIN-COOKBOOK.COM using keytab file /etc/hadoop/hadoop.keytab

    ```

*   启动群集中的所有 DataNode 后,使用以下说明测试我们的安全 HDFS:

19. Test the secure HDFS from its admin web page. Click on the Browse the filesystem link; an error will show on the screen, as seen in the following screenshot:

![How to do it...](https://p6-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/c73868ee765e49c98458b9a10eeab576~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5biD5a6i6aOe6b6Z:q75.awebp?rk3s=f64ab15b&x-expires=1773139932&x-signature=FGMJzcASUOxHJ2zdcdOpsHly5uQ%3D)

20. 从您的客户端节点上的命令行测试安全 HDFS:

```scala
hac@client1$ $HADOOP_HOME/bin/hadoop fs -ls /
12/02/05 23:00:50 ERROR security.UserGroupInformation: PriviledgedActionException as:hac cause:javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
12/02/05 23:00:50 WARN ipc.Client: Exception encountered while connecting to the server : javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
12/02/05 23:00:50 ERROR security.UserGroupInformation: PriviledgedActionException as:hac cause:java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
Bad connection to FS. command aborted. exception: Call to ip-10- 168-46-11.us-west-1.compute.internal/10.168.46.11:8020 failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]

```

21. 验证用户是否可以从 kadmin 控制台访问安全 HDFS:

```scala
 hac@client1$ sudo kadmin
kadmin: addprinc hac/ip-10-160-34-143.us-west-1.compute.internal
kadmin: quit

```

22. 使用以下命令获取用户的 Kerberos 票证:

```scala
hac@client1$ kinit hac/ip-10-160-34-143.us-west-1.compute.internal
Password for hac/ip-10-160-34-143.us-west- 1.compute.internal@HBASE-ADMIN-COOKBOOK.COM:

```

23. 从您的客户端节点上的命令行再次测试身份验证:

```scala
hac@client1$ $HADOOP_HOME/bin/hadoop fs -ls /
Found 6 items
drwxr-xr-x - hadoop supergroup 0 2012-01-08 08:09 /backup
drwxr-xr-x - hadoop supergroup 0 2012-02-04 21:29 /hbase
drwxr-xr-x - hadoop supergroup 0 2011-11-24 17:13 /hbase-b
drwxrwxrwx - hadoop supergroup 0 2012-01-08 22:47 /tmp
drwxr-xr-x - hadoop supergroup 0 2012-01-03 22:12 /user
drwxr-xr-x - hadoop supergroup 0 2012-01-25 11:08 /usr

```

它是如何工作的.

首先,我们在每个 HDFS 节点上安装了 Kerberos 客户端软件。 之后,我们进入 kadmin控制台,为该节点的 hadoop用户和节点本身添加 Kerberos 主体。 由于我们将只使用密钥表文件中的这些主体,因此我们将 -randkey选项添加到 addprinc命令中。

由于我们将在本配方中仅设置 HDFS 安全性,因此我们在这里使用的是 hadoop用户。 如果您还将启用安全 MapReduce,我们建议您对 HDFS 和 MapReduce 使用不同的用户,例如分别为 hdfsmapreduce用户。

这里的另一点是为每个节点上的 hadoop用户添加不同的主体。 尽管可以在 Kerberos 中为所有节点上的 hadoop用户添加单个主体,但不建议这样做。 因为在这种情况下,由于群集将向同一主体(hadoop@YOUR_REALM.COM)发送许多身份验证请求,因此 Kerberos 可能会将其视为攻击而无法进行身份验证。

在步骤 5 中,我们为前面步骤中添加的主体创建了密钥表文件(/etc/hadoop/hadoop.keytab)。 密钥表是一个包含 Kerberos 主体和加密密钥对的文件。 使用此文件,Hadoop 可以在不提示输入密码的情况下登录到 Kerberos。

在步骤 6 中确认密钥表文件之后,我们在步骤 7 中使其只对 hadoop用户可读。

默认情况下,票证使用 AES-256 加密进行加密。 这需要在所有 HDFS 节点和客户端上安装“Java**加密扩展(JCE)**无限强度管辖策略文件 6”。 这就是我们在步骤 8 中所做的。

在步骤 9 和 10 中启用 Hadoop 和 HDFS 安全后,我们在步骤 11 中在 NameNode 上配置了 Kerberos 安全。我们在此步骤中设置密钥表文件路径和主体。 在运行时, _HOST设置值将替换为节点的主机名。

在步骤 12 中添加了 DataNode 安全设置。对于 dfs.datanode.addressdfs.datanode.http.address设置,请注意安全设置需要特权端口(低于 1024 的端口)。

正如您从步骤 13 的输出中看到的,如果一切配置良好, hadoop用户和主节点将在 NameNode 启动过程中由 Kerberos 进行身份验证。

对于 DataNode 节点,我们首先在步骤 14 中将数据存储目录更改为只对 hadoop用户可读。

安全数据节点必须由 root用户启动并由 hadoop用户运行。 这是在步骤 16 中通过将 HADOOP_SECURE_DN_USER=hadoop设置添加到 hadoop-env.sh文件来配置的。

步骤 17 仅对 32 位系统是必需的。 这很简单,因为当前 Hadoop 发行版的 tarball 中没有包含 32 位 jsvc二进制文件。

在集群中的所有 DataNode 都由 root用户启动后,我们现在可以从其 Web UI 和命令行界面测试受保护的 HDFS。

正如您在步骤 19 和 20 中看到的那样,未经身份验证的用户无法从 Web UI 或命令行访问受保护的 HDFS。 这是我们所期待的。 身份(包括 HDFS 本身的组件和客户端)必须由 Kerberos 进行身份验证,然后才能与领域中的其他身份通信。

在步骤 21 中,我们为 HDFS 客户机节点上的 hac用户添加了一个测试主体。 在步骤 22 中获得 Kerberos 票证(经过身份验证)后,用户能够成功访问受保护的 HDFS。

还有更多...

我们刚刚讨论了最基本的 HDFS 安全配置。 由于本书范围有限,我们在此省略了一些步骤,包括:

  • Second DaryNameNode 安全性
  • MapReduce 安全性
  • 启用 WebHDFS 时的 WebHDFS 安全性
  • 用户帐户和组
  • HDFS 和本地文件系统上的目录所有权
  • 向客户端验证数据节点的身份(HDFS-1150)

HBase 安全配置

随着 HBase 变得越来越流行,不同的用户和群体可能会在一个共享的 HBase 集群中存储更多的数据。 您可能不希望所有用户都拥有对每个 HBase 表的完全权限。 这会给您的数据增加风险,例如,安全风险或错过的数据操作。

较新的 HBase 版本(0.92 及更高版本)具有基于 Kerberos 的安全支持。 这样,Kerberos 将验证用户身份,并且只允许经过身份验证的用户访问安全的 HBase 集群中的数据。

在本食谱中,我们将介绍如何配置对 HBase 的安全客户端访问。

做好准备

确保您使用的是启用安全功能的 HBase 版本。 如果你从 HBase 官方网站下载,文件名应该类似于 hbase-0.92.1-security.tar.gz

我们假设您有一个正在工作的Kerberos 密钥分发中心(KDC),并设置了领域。 有关安装和配置 Kerberos 的更多信息,请参阅本章中的用于 Hadoop 和 HBase 的Kerberos 身份验证食谱。

由于安全的 HBase 访问预计将在受保护的 HDFS 集群上运行,因此您还需要提前设置 HDFS 安全性。 有关详细信息,请参阅本章中的使用 Kerberos配置 HDFS 安全性食谱。

因为我们在本书中使用了相同的用户( hadoop用户)来运行 HDFS 和 HBase,所以我们能够共享密钥表文件。 如果您对 HDFS 和 HBase 使用不同的用户,则生成 HBase 所有者自己的密钥表文件。

怎么做……

配置 HBase 安全性的说明如下:

  1. 在集群中的每个节点上,将以下最基本的配置添加到 hbase-site.xml文件:

    $ vi $HBASE_HOME/conf/hbase-site.xml
    <property>
    <name>hbase.regionserver.kerberos.principal</name>
    <value>hadoop/_HOST@HBASE-ADMIN-COOKBOOK.COM</value>
    </property>
    <property>
    <name>hbase.regionserver.keytab.file</name>
    <value>/etc/hadoop/hadoop.keytab</value>
    </property>
    <property>
    <name>hbase.master.kerberos.principal</name>
    <value>hadoop/_HOST@HBASE-ADMIN-COOKBOOK.COM</value></property>
    <property>
    <name>hbase.master.keytab.file</name>
    <value>/etc/hadoop/hadoop.keytab</value>
    </property>
    
    
  2. 在群集中的每个服务器节点上,将以下配置添加到 hbase-site.xml文件:

    $ vi $HBASE_HOME/conf/hbase-site.xml
    <property>
    <name>hbase.security.authentication</name>
    <value>kerberos</value>
    </property>
    <property>
    <name>hbase.security.authorization</name>
    <value>true</value>
    </property>
    <property>
    <name>hbase.rpc.engine</name>
    <value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
    </property>
    <property>
    <name>hbase.coprocessor.region.classes</name>
    <value>org.apache.hadoop.hbase.security.token.TokenProvider </value>
    </property>
    
    
  3. 在每个 HBase 客户端节点上,将以下配置添加到 hbase-site.xml文件:

    $ vi $HBASE_HOME/conf/hbase-site.xml
    <property>
    <name>hbase.security.authentication</name>
    <value>kerberos</value>
    </property>
    <property>
    <name>hbase.rpc.engine</name>
    <value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
    </property>
    
    
  4. 在主节点上启动主守护进程:

    hadoop@master1$ $HBASE_HOME/bin/hbase-daemon.sh start master
    
    
    2012-02-06 00:06:57,524 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hadoop/ip-10-168-46-11.us-west-1.compute.internal@HBASE-ADMIN-COOKBOOK.COM
    
    
    • 如果一切配置正常,您将在主节点上的 HBase 日志文件中找到日志,如下所示:
  5. Start the region server daemon on every region server node:

    hadoop@master1$ $HBASE_HOME/bin/hbase-daemons.sh start regionserver
    
    

    您应该可以在主节点上的 HBase 日志文件中找到日志,如下所示:

    2012-02-06 00:13:10,206 INFO SecurityLogger.org.apache.hadoop.security.authorize.ServiceAuthorizationManager: Authorization successfull for hadoop/ip-10-168-62-63.us-west-1.compute.internal@HBASE-ADMIN-COOKBOOK.COM for protocol=interface org.apache.hadoop.hbase.ipc.HMasterRegionInterface
    
    

    并登录地域服务器,如下所示:

    2012-02-06 00:14:29,276 INFO SecurityLogger.org.apache.hadoop.security.authorize.ServiceAuthorizationManager: Authorization successfull for hadoop/ip-10-168-46-11.us-west-1.compute.internal@HBASE-ADMIN-COOKBOOK.COM for protocol=interface org.apache.hadoop.hbase.ipc.HMasterRegionInterface
    
    
  6. 清除 Kerberos 缓存并测试客户端节点上的安全 HBase 配置。

    hac@client1$ kdestory
    hac@client1$ $HBASE_HOME/bin/hbase shell
    hbase> count 'hly_temp'
    12/02/06 00:21:37 ERROR security.UserGroupInformation: PriviledgedActionException as:hac cause:javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]
    
    
  7. 获取 Kerberos 票证并再次测试:

    hac@client1$ kinit hac/ip-10-160-34-143.us-west-1.compute.internal
    hac@client1$ $HBASE_HOME/bin/hbase shell
    hbase> count 'hly_temp'
    ...
    Current count: 94000, row: USW000948470714 Current count: 95000, row: USW000949080410 95630 row(s) in 22.1700 seconds
    
    

它是如何工作的.

在步骤 1 中,我们在 hbase-site.xlm文件中为 HBase 主服务器和区域服务器配置了 Kerberos 主体及其密钥表文件。 它是服务器节点和客户端节点的通用配置。 与 Hadoop 安全配置类似, _HOST设置值将在运行时替换为节点的主机名。

步骤 2 仅适用于服务器节点。 我们已经在配置中启用了 HBase 身份验证和授权。 我们已经将 HBase 设置为使用 Kerberos 身份验证和基于 HBase 协处理器的授权。 HBase 协处理器是 0.92 版本中的一个新特性,基于 Google 的 Bigtable 协处理器。 它是在区域服务器中的每个区域运行的任意代码。 HBase 协处理器的一个示例用法是实现对 HBase 表的访问控制。

在步骤 3 的客户端,我们只需要配置 Kerberos 的身份验证。

从步骤 4 和 5 的日志中可以看到,HBase 主服务器和区域服务器将在启动过程中由 Kerberos 进行身份验证。

如步骤 6 和 7 所示,未经身份验证的用户无法访问受保护的 HBase。 这是我们所期待的。 身份(包括服务器端组件和客户端)必须由 Kerberos 进行身份验证,然后才能与领域中的其他身份通信。

还有更多...

我们在本食谱中设置了对 HBase 的安全客户端访问。 除此之外,您可能还希望配置 HBase 表的访问控制。 使用前面的设置,实施以下配置以启用访问控制:

  • 配置 ZooKeeper 安全性
  • 启用 AccessController 协处理器
  • 在 HBase Shell 中编辑用户权限

由于本书范围有限,我们省略了这些配置。 有关详细说明,请参阅以下 URL:

https://issues.apache.org/jira/browse/HBASE-4990