Apache HBase Logo

Preface

这是其附带的HBase版本的官方参考指南.

在这里,您可以找到有关HBase主题的权威性文档(指当引用的HBase版本发运时的状态),或者指向JavadocJIRA中可以找到相关信息的位置.

关于本指南

本参考指南正在进行中. 可以在HBase源代码的_src / main / asciidoc目录中找到本指南的源代码. 该参考指南使用AsciiDoc进行了标记, 从中生成了完整的指南作为"站点"构建目标的一部分. 跑

mvn site

生成此文档. 欢迎对文档进行修改和改进. 单击此链接可以针对Apache HBase提交新的文档错误,并预先选择一些值.

撰写文档

有关AsciiDoc的概述以及开始对文档做出贡献的建议,请参阅本文档后面相关部分 .

如果这是您首次涉足分布式计算领域,请注意...

如果这是您首次进入分布式计算的美好世界,那么您将度过一段有趣的时光. 首先,分布式系统很难. 使分布式系统嗡嗡声需要跨越系统(硬件和软件)和网络的不同技能.

群集运行可能会因各种原因而打ic,原因包括:HBase本身的错误,错误配置(HBase的错误配置以及操作系统的错误配置)以及硬件问题(无论是网卡驱动程序中的错误还是RAM总线不足) (要提到两个最近的硬件问题示例,这些问题表现为" HBase缓慢"). 如果您已将计算结果绑定到单个框,则还需要重新校准. 这是一个很好的起点: 分布式计算的谬误 .

也就是说,不客气.
这是一个有趣的地方.
您好,HBase社区.

报告错误

请使用JIRA报告与安全无关的错误.

为了保护现有的HBase安装不受新的漏洞的影响,请不要使用JIRA报告与安全性有关的错误. 而是将您的报告发送到邮件列表private@hbase.apache.org ,该列表允许任何人发送消息,但限制了可以读取消息的人. 该列表中的某人将与您联系以跟进您的报告.

支持和测试期望

在本指南中,短语/ supported /,/不支持/,/ tested /和/ not测试/出现在几个地方. 为了清楚起见,这里简要说明了在HBase上下文中这些短语的一般含义.

许多Hadoop供应商都为Apache HBase提供了商业技术支持. 这不是在Apache HBase项目的上下文中使用术语/ support /的意义. Apache HBase团队对您的HBase集群,您的配置或数据不承担任何责任.
Supported

在Apache HBase的上下文中,/ supported /表示HBase旨在按所述方式工作,并且偏离已定义行为或功能的情况应报告为错误.

Not Supported

在Apache HBase的上下文中,/ notsupported /表示用例或使用模式不起作用,应将其视为反模式. 如果您认为应该为给定的功能或使用模式重新考虑此指定,请提交JIRA或在其中一个邮件列表上进行讨论.

Tested

在Apache HBase的上下文中,/ tested /表示某个功能已包含在单元测试或集成测试中,并且已被证明可以按预期工作.

Not Tested

在Apache HBase的上下文中,/ not testing /表示某个功能或使用模式可能会或可能无法以给定的方式工作,并且可能会或可能不会破坏您的数据或导致操作问题. 这是一个未知数,并且无法保证. 如果您可以提供证明/未测试的功能确实可以通过给定的方式工作的证据,请提交测试和/或度量标准,以便其他用户可以确定此类功能或使用模式.

Getting Started

1. Introduction

快速入门可帮助您在HBase的单节点独立实例上运行.

2. Quick Start - Standalone HBase

本节描述了单节点独立HBase的设置. 一个独立的实例具有所有HBase守护程序-Master,RegionServers和ZooKeeper,它们在单个JVM中运行,并保留在本地文件系统中. 这是我们最基本的部署配置文件. 我们将向您展示如何使用hbase shell CLI在HBase中创建表,如何在表中插入行,对表执行放置和扫描操作,启用或禁用表以及启动和停止HBase.

除了下载HBase之外,此过程还需要不到10分钟的时间.

2.1. JDK Version Requirements

HBase要求安装JDK. 有关受支持的JDK版本的信息,请参见Java .

2.2. Get Started with HBase

过程:以独立模式下载,配置和启动HBase
  1. Apache下载镜像列表中选择一个下载站点. 单击建议的顶部链接. 这将带您了解HBase版本 . 单击名为稳定的文件夹,然后将以.tar.gz结尾的二进制文件下载到本地文件系统. 现在不要下载以src.tar.gz结尾的文件.

  2. 解压缩下载的文件,然后转到新创建的目录.

    $ tar xzvf hbase-2.1.9-bin.tar.gz
    $ cd hbase-2.1.9/
  3. 在启动HBase之前,需要设置JAVA_HOME环境变量. 您可以通过操作系统的常用机制来设置变量,但是HBase提供了一个中心机制conf / hbase-env.sh . 编辑此文件,取消注释以JAVA_HOME开头的行,并将其设置为适合您的操作系统的位置. JAVA_HOME变量应设置为包含可执行文件bin / java的目录 . 大多数现代Linux操作系统都提供了一种机制,例如RHEL或CentOS上的/ usr / bin / alternatives,用于在诸如Java之类的可执行文件版本之间透明地进行切换. 在这种情况下,您可以将JAVA_HOME为包含指向bin / java的符号链接的目录,该目录通常是/ usr .

    JAVA_HOME=/usr
  4. 编辑conf / hbase-site.xml ,这是主要的HBase配置文件. 这时,您需要在本地文件系统上指定HBase和ZooKeeper写入数据的目录并确认一些风险. 默认情况下,在/ tmp下创建一个新目录. 许多服务器配置为在重新引导时删除/ tmp的内容,因此您应该将数据存储在其他位置. 以下配置会将HBase的数据存储在名为testuser的用户的主目录中的hbase目录中. 将<property>标记粘贴在<property> <configuration> <property>标记下方,在新的HBase安装中,该标记应为空.

    例子1.独立HBase的例子hbase-site.xml
    <configuration>
      <property>
        <name>hbase.rootdir</name>
        <value>file:///home/testuser/hbase</value>
      </property>
      <property>
        <name>hbase.zookeeper.property.dataDir</name>
        <value>/home/testuser/zookeeper</value>
      </property>
      <property>
        <name>hbase.unsafe.stream.capability.enforce</name>
        <value>false</value>
        <description>
          Controls whether HBase will check for stream capabilities (hflush/hsync).
    
          Disable this if you intend to run on LocalFileSystem, denoted by a rootdir
          with the 'file://' scheme, but be mindful of the NOTE below.
    
          WARNING: Setting this to false blinds you to potential data loss and
          inconsistent system state in the event of process and/or node failures. If
          HBase is complaining of an inability to use hsync or hflush it's most
          likely not a false positive.
        </description>
      </property>
    </configuration>

    您不需要创建HBase数据目录. HBase将为您完成此任务. 如果创建目录,HBase将尝试进行迁移,这不是您想要的.

    上例中的hbase.rootdir指向本地文件系统中的目录. " file://"前缀是我们表示本地文件系统的方式. 您应该牢记配置示例中的"警告". 在独立模式下,HBase使用Apache Hadoop项目中的本地文件系统抽象. 这种抽象不能提供HBase安全运行所需的持久性保证. 这对于可以很好地控制群集故障成本的本地开发和测试用例来说是不错的选择. 它不适用于生产部署; 最终您将丢失数据.

要将HBase放在现有HDFS实例上,请将hbase.rootdir设置为指向您实例上的目录:例如hdfs://namenode.example.org:8020 / hbase . 有关此变体的更多信息,请参见下面有关基于HDFS的独立HBase的部分.

  1. 提供bin / start-hbase.sh脚本是启动HBase的便捷方法. 发出命令,如果一切顺利,则将一条消息记录到标准输出,显示HBase成功启动. 您可以使用jps命令来验证您是否正在运行一个名为HMaster进程. 在独立模式下,HBase在此单个JVM中运行所有守护程序,即HMaster,单个HRegionServer和ZooKeeper守护程序. 转到http:// localhost:16010查看HBase Web UI.

    Java需要安装并可用. 如果收到指示未安装Java的错误,但它在系统上(可能位于非标准位置),请编辑conf / hbase-env.sh文件并修改JAVA_HOME设置以指向包含bin的目录/ java在您的系统上.
过程:首次使用HBase
  1. 连接到HBase.

    使用hbase shell命令连接到正在运行的HBase实例,该命令位于HBase安装目录的bin /目录中. 在此示例中,省略了启动HBase Shell时打印的一些用法和版本信息. HBase Shell提示符以>字符结束.

    $ ./bin/hbase shell
    hbase(main):001:0>
  2. 显示HBase Shell帮助文本.

    键入help并按Enter,以显示HBase Shell的一些基本用法信息以及一些示例命令. 注意,表名,行,列都必须用引号引起来.

  3. 创建一个表.

    使用create命令创建一个新表. 您必须指定表名称和ColumnFamily名称.

    hbase(main):001:0> create 'test', 'cf'
    0 row(s) in 0.4170 seconds
    
    => Hbase::Table - test
  4. 列出有关表的信息

    使用list命令确认表是否存在

    hbase(main):002:0> list 'test'
    TABLE
    test
    1 row(s) in 0.0180 seconds
    
    => ["test"]

    现在使用describe命令查看详细信息,包括配置默认值

    hbase(main):003:0> describe 'test'
    Table test is ENABLED
    test
    COLUMN FAMILIES DESCRIPTION
    {NAME => 'cf', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE =>
    'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'f
    alse', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE
     => '65536'}
    1 row(s)
    Took 0.9998 seconds
  5. 将数据放入表中.

    要将数据放入表中,请使用put命令.

    hbase(main):003:0> put 'test', 'row1', 'cf:a', 'value1'
    0 row(s) in 0.0850 seconds
    
    hbase(main):004:0> put 'test', 'row2', 'cf:b', 'value2'
    0 row(s) in 0.0110 seconds
    
    hbase(main):005:0> put 'test', 'row3', 'cf:c', 'value3'
    0 row(s) in 0.0100 seconds

    在这里,我们插入三个值,一次插入一个. 第一次插入是在row1 cf:a列,其值为value1 . 在HBase的列由列族前缀的cf在本例中,后面跟着冒号,然后列限定符后缀, a在此情况下.

  6. 一次扫描表中的所有数据.

    从HBase获取数据的一种方法是扫描. 使用scan命令扫描表中的数据. 您可以限制扫描,但是目前,所有数据都已获取.

    hbase(main):006:0> scan 'test'
    ROW                                      COLUMN+CELL
     row1                                    column=cf:a, timestamp=1421762485768, value=value1
     row2                                    column=cf:b, timestamp=1421762491785, value=value2
     row3                                    column=cf:c, timestamp=1421762496210, value=value3
    3 row(s) in 0.0230 seconds
  7. 获取单行数据.

    要一次获取一行数据,请使用get命令.

    hbase(main):007:0> get 'test', 'row1'
    COLUMN                                   CELL
     cf:a                                    timestamp=1421762485768, value=value1
    1 row(s) in 0.0350 seconds
  8. 禁用表格.

    如果要删除表或更改其设置,以及在某些其他情况下,则需要先使用disable命令禁用该表. 您可以使用enable命令重新启用它.

    hbase(main):008:0> disable 'test'
    0 row(s) in 1.1820 seconds
    
    hbase(main):009:0> enable 'test'
    0 row(s) in 0.1770 seconds

    如果您测试了上面的enable命令,请再次禁用该表:

    hbase(main):010:0> disable 'test'
    0 row(s) in 1.1820 seconds
  9. 放下桌子.

    要删除(删除)表,请使用drop命令.

    hbase(main):011:0> drop 'test'
    0 row(s) in 0.1370 seconds
  10. 退出HBase Shell.

    要退出HBase Shell并从群集断开连接,请使用quit命令. HBase仍在后台运行.

过程:停止HBase
  1. 与提供bin / start-hbase.sh脚本以方便地启动所有HBase守护程序相同, bin / stop-hbase.sh脚本将停止它们.

    $ ./bin/stop-hbase.sh
    stopping hbase....................
    $
  2. 发出命令后,关闭进程可能需要几分钟. 使用jps确保HMaster和HRegionServer进程已关闭.

上面显示了如何启动和停止HBase的独立实例. 在下一节中,我们将简要概述hbase部署的其他模式.

2.3. Pseudo-Distributed Local Install

快速入门独立模式下工作之后,您可以将HBase重新配置为以伪分布式模式运行. 伪分布式模式意味着HBase仍完全在单个主机上运行,​​但是每个HBase守护程序(HMaster,HRegionServer和ZooKeeper)作为单独的进程运行:在独立模式下,所有守护程序都在一个jvm进程/实例中运行. 默认情况下,除非您按照快速入门中的说明配置hbase.rootdir属性,否则数据仍存储在/ tmp /中 . 在本演练中,假设您有可用的HDFS,我们将您的数据存储在HDFS中. 您可以跳过HDFS配置,以继续将数据存储在本地文件系统中.

Hadoop配置

此过程假定您已在本地系统和/或远程系统上配置了Hadoop和HDFS,并且它们正在运行并且可用. 它还假定您正在使用Hadoop2.Hadoop文档中有关设置单节点群集的指南是一个很好的起点.

  1. 如果HBase正在运行,请停止它.

    如果您刚刚完成快速入门而HBase仍在运行,请停止它. 此过程将创建一个全新的目录,HBase将在该目录中存储其数据,因此您之前创建的所有数据库都将丢失.

  2. 配置HBase.

    编辑hbase-site.xml配置. 首先,添加以下属性,该属性指示HBase在分布式模式下运行,每个守护程序一个JVM实例.

    <property>
      <name>hbase.cluster.distributed</name>
      <value>true</value>
    </property>

    接下来,使用hdfs://// URI语法将hbase.rootdir从本地文件系统更改为HDFS实例的地址. 在此示例中,HDFS在本地主机上的端口8020上运行.请确保删除hbase.unsafe.stream.capability.enforce的条目或将其设置为true.

    <property>
      <name>hbase.rootdir</name>
      <value>hdfs://localhost:8020/hbase</value>
    </property>

    您无需在HDFS中创建目录. HBase将为您完成此任务. 如果创建目录,HBase将尝试进行迁移,这不是您想要的.

  3. 启动HBase.

    使用bin / start-hbase.sh命令启动HBase. 如果系统配置正确,则jps命令应显示正在运行的HMaster和HRegionServer进程.

  4. 检查HDFS中的HBase目录.

    如果一切正常,HBase将在HDFS中创建其目录. 在上面的配置中,它存储在HDFS上的/ hbase /中. 您可以在Hadoop的bin /目录中使用hadoop fs命令列出该目录.

    $ ./bin/hadoop fs -ls /hbase
    Found 7 items
    drwxr-xr-x   - hbase users          0 2014-06-25 18:58 /hbase/.tmp
    drwxr-xr-x   - hbase users          0 2014-06-25 21:49 /hbase/WALs
    drwxr-xr-x   - hbase users          0 2014-06-25 18:48 /hbase/corrupt
    drwxr-xr-x   - hbase users          0 2014-06-25 18:58 /hbase/data
    -rw-r--r--   3 hbase users         42 2014-06-25 18:41 /hbase/hbase.id
    -rw-r--r--   3 hbase users          7 2014-06-25 18:41 /hbase/hbase.version
    drwxr-xr-x   - hbase users          0 2014-06-25 21:49 /hbase/oldWALs
  5. 创建一个表并用数据填充它.

    您可以使用HBase Shell创建一个表,用数据填充它,扫描并从中获取值,方法与Shell练习相同.

  6. 启动和停止备用HBase主服务器(HMaster)服务器.

    在生产环境中,在同一硬件上运行多个HMaster实例没有任何意义,就像在生产环境中运行伪分布式集群一样. 此步骤仅用于测试和学习目的.

    HMaster服务器控制HBase群集. 您最多可以启动9台备份HMaster服务器,这使10台HMaster总数(包括主HMaster)在内. 要启动备份HMaster,请使用local-master-backup.sh . 对于要启动的每个备份主服务器,添加一个代表该主服务器的端口偏移量的参数. 每个HMaster使用两个端口(默认情况下为16000和16010). 端口偏移量已添加到这些端口,因此使用偏移量2时,备份HMaster将使用端口16002和16012.以下命令使用端口16002 / 16012、16003 / 16013和16005/16015启动3个备份服务器.

    $ ./bin/local-master-backup.sh start 2 3 5

    要杀死备份主服务器而不杀死整个集群,您需要找到其进程ID(PID). PID以类似/tmp/hbase-USER-X-master.pid的名称存储在文件中. 该文件的唯一内容是PID. 您可以使用kill -9命令杀死该PID. 以下命令将杀死端口偏移为1的主服务器,但使集群保持运行状态:

    $ cat /tmp/hbase-testuser-1-master.pid |xargs kill -9
  7. 启动和停止其他RegionServer

    HRegionServer按照HMaster的指示管理其StoreFiles中的数据. 通常,群集中的每个节点都运行一个HRegionServer. 在同一系统上运行多个HRegionServer对于在伪分布式模式下进行测试非常有用. local-regionservers.sh命令允许您运行多个RegionServer. 它的工作方式与local-master-backup.sh命令类似,因为您提供的每个参数都代表实例的端口偏移量. 每个RegionServer需要两个端口,默认端口为16020和16030.由于HBase版本1.1.0,HMaster不使用区域服务器端口,因此留下了10个端口(16020至16029和16030至16039)用于RegionServer. 为了支持其他RegionServer,请在运行脚本local-regionservers.sh之前将环境变量HBASE_RS_BASE_PORT和HBASE_RS_INFO_BASE_PORT设置为适当的值. 例如,对于基本端口,值为16200和16300,可以在服务器上支持99个其他RegionServer. 以下命令启动四个附加的RegionServer,它们在从16022/16032开始的顺序端口(基本端口16020/16030加2)上运行.

    $ .bin/local-regionservers.sh start 2 3 4 5

    要手动停止RegionServer,请使用带有stop参数的local-regionservers.sh命令和要stop的服务器偏移量.

    $ .bin/local-regionservers.sh stop 3
  8. 停止HBase.

    您可以使用bin / stop-hbase.sh命令以与快速入门过程相同的方式停止HBase.

2.4. Advanced - Fully Distributed

实际上,您需要一个完全分布式的配置来全面测试HBase并在实际场景中使用它. 在分布式配置中,集群包含多个节点,每个节点运行一个或多个HBase守护程序. 其中包括主实例和备份Master实例,多个ZooKeeper节点和多个RegionServer节点.

此高级快速入门为集群添加了两个以上的节点. 架构如下:

表1.分布式集群演示架构
节点名称 Master ZooKeeper RegionServer

node-a.example.com

yes

yes

no

node-b.example.com

backup

yes

yes

node-c.example.com

no

yes

yes

This quickstart assumes that each node is a virtual machine and that they are all on the same network. It builds upon the previous quickstart, Pseudo-Distributed Local Install, assuming that the system you configured in that procedure is now node-a. Stop HBase on node-a before continuing.

确保所有节点都具有完全的通信访问权限,并且没有适当的防火墙规则可能阻止它们相互通信. 如果看到任何错误,例如no route to host ,请检查防火墙.
过程:配置无密码SSH访问

node-a需要能够登录到node-bnode-c (以及自身)才能启动守护程序. 完成此操作的最简单方法是在所有主机上使用相同的用户名,并配置从node-a到其他每个node-a密码SSH登录.

  1. node-a ,生成一个密钥对.

    以将要运行HBase的用户身份登录后,使用以下命令生成SSH密钥对:

    $ ssh-keygen -t rsa

    如果命令成功执行,则将密钥对的位置打印到标准输出中. 公钥的默认名称是id_rsa.pub .

  2. 创建将在其他节点上保存共享密钥的目录.

    node-bnode-c ,以HBase用户身份登录,并在用户的主目录中创建.ssh /目录(如果尚不存在). 如果已经存在,请注意它可能已经包含其他密钥.

  3. 将公钥复制到其他节点.

    通过使用scp或其他某种安全方式,将公钥从node-a安全地复制到每个节点. 在其他每个节点上,创建一个名为.ssh / authorized_keys的新文件( 如果尚不存在) ,然后将id_rsa.pub文件的内容附加到文件末尾. 请注意,您还需要对node-a本身执行此操作.

    $ cat id_rsa.pub >> ~/.ssh/authorized_keys
  4. 测试无密码登录.

    如果正确执行了该过程,则当您使用相同的用户名从node-a SSH到其他任何node-a时,不应该提示您输入密码.

  5. 由于node-b将运行备份主服务器,因此重复上述过程,在看到node-a node-b任何地方都替换为node-b . 确保不要覆盖现有的.ssh / authorized_keys文件,而是使用>>运算符而不是>运算符将新密钥连接到现有文件上.

过程:准备node-a -a

node-a将运行您的主要主进程和ZooKeeper进程,但不会运行RegionServer. 停止RegionServer在node-a上启动.

  1. 编辑conf / regionservers并删除包含localhost的行. 为node-bnode-c添加带有主机名或IP地址的行.

    即使您确实想在node-a上运行RegionServer,也应使用其他服务器用来与其通信的主机名来引用它. 在这种情况下,它将是node-a.example.com . 这使您可以将任何主机名冲突将配置分发到群集的每个节点. 保存文件.

  2. 配置HBase以将node-b用作备份主服务器.

    conf /中创建一个名为backup-masters的新文件,并使用node-b的主机名在其中添加新行. 在此演示中,主机名是node-b.example.com .

  3. 配置ZooKeeper

    In reality, you should carefully consider your ZooKeeper configuration. You can find out more about configuring ZooKeeper in zookeeper section. This configuration will direct HBase to start and manage a ZooKeeper instance on each node of the cluster.

    node-a ,编辑conf / hbase-site.xml并添加以下属性.

    <property>
      <name>hbase.zookeeper.quorum</name>
      <value>node-a.example.com,node-b.example.com,node-c.example.com</value>
    </property>
    <property>
      <name>hbase.zookeeper.property.dataDir</name>
      <value>/usr/local/zookeeper</value>
    </property>
  4. 在您已将node-a称为localhost的配置中的任何地方,更改引用以指向其他节点将用来引用node-a的主机名. 在这些示例中,主机名是node-a.example.com .

过程:准备node-bnode-c

node-b将运行一个备份主服务器和一个ZooKeeper实例.

  1. 下载并解压缩HBase.

    将HBase下载并解压缩到node-b ,就像对独立和伪分布式快速入门所做的那样.

  2. 将配置文件从node-a复制到node-bnode-c .

    群集的每个节点都需要具有相同的配置信息. 将conf /目录的内容复制到node-bnode-c上的conf /目录.

过程:启动和测试集群
  1. 确保HBase不在任何节点上运行.

    如果您忘记从先前的测试中停止HBase,则将出现错误. 使用jps命令检查HBase是否在您的任何节点上运行. 查找进程HMasterHRegionServerHQuorumPeer . 如果它们存在,杀死它们.

  2. 启动集群.

    node-a ,发出start-hbase.sh命令. 您的输出将类似于以下内容.

    $ bin/start-hbase.sh
    node-c.example.com: starting zookeeper, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-zookeeper-node-c.example.com.out
    node-a.example.com: starting zookeeper, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-zookeeper-node-a.example.com.out
    node-b.example.com: starting zookeeper, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-zookeeper-node-b.example.com.out
    starting master, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-master-node-a.example.com.out
    node-c.example.com: starting regionserver, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-regionserver-node-c.example.com.out
    node-b.example.com: starting regionserver, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-regionserver-node-b.example.com.out
    node-b.example.com: starting master, logging to /home/hbuser/hbase-0.98.3-hadoop2/bin/../logs/hbase-hbuser-master-nodeb.example.com.out

    ZooKeeper首先启动,然后是主机,然后是RegionServer,最后是备份主机.

  3. 验证进程正在运行.

    在群集的每个节点上,运行jps命令并验证每个服务器上是否正在运行正确的进程. 如果将其他Java进程用于其他目的,则可能还会看到它们在服务器上运行.

    node-a jps Output
    $ jps
    20355 Jps
    20071 HQuorumPeer
    20137 HMaster
    node-b jps Output
    $ jps
    15930 HRegionServer
    16194 Jps
    15838 HQuorumPeer
    16010 HMaster
    node-c jps Output
    $ jps
    13901 Jps
    13639 HQuorumPeer
    13737 HRegionServer
    ZooKeeper进程名称

    HQuorumPeer进程是由HBase控制和启动的ZooKeeper实例. 如果以这种方式使用ZooKeeper,则每个群集节点只能使用一个实例,并且仅适用于测试. 如果ZooKeeper在HBase外部运行,则该过程称为QuorumPeer . 有关ZooKeeper配置的更多信息,包括将外部ZooKeeper实例与HBase一起使用,请参见zookeeper部分.

  4. 浏览到Web UI.

    Web UI端口更改
    Web UI端口更改

    在低于0.98.x的HBase中,HBase Web UI使用的HTTP端口从Master的60010和每个RegionServer的60030变为Master的16010和RegionServer的16030.

    如果一切设置正确,则应该能够连接到主服务器http://node-a.example.com:16010/或辅助主服务器的UI,位于http://node-b.example.com:16010/使用网络浏览器. 如果可以通过localhost主机连接,但不能通过其他主机连接,请检查防火墙规则. 您可以在其IP地址的端口16030上单击每个RegionServer的Web UI,或单击主服务器的Web UI中的链接.

  5. 测试当节点或服务消失时会发生什么.

    使用已配置的三节点群集,情况将不会非常灵活. 您仍然可以通过终止关联的进程并查看日志来测试主要Master或RegionServer的行为.

2.5. Where to go next

下一章configuration提供了有关不同HBase运行模式,运行HBase的系统要求以及用于设置分布式HBase群集的关键配置区域的更多信息.

Apache HBase Configuration

本章在" 入门"一章的基础上进行扩展,以进一步说明Apache HBase的配置. 请仔细阅读本章,尤其是基本先决条件,以确保您的HBase测试和部署顺利进行. 还要熟悉支持和测试期望 .

3. Configuration Files

Apache HBase使用与Apache Hadoop相同的配置系统. 所有配置文件都位于conf /目录中,该文件需要与集群中的每个节点保持同步.

HBase配置文件说明
backup-masters

默认情况下不存在. 一个纯文本文件,其中列出了主机应在其上启动备份主机进程的主机,每行一台主机.

hadoop-metrics2-hbase.properties

用于连接HBase Hadoop的Metrics2框架. 有关Metrics2的更多信息,请参见Hadoop Wiki条目 . 默认情况下仅包含注释掉的示例.

hbase-env.cmd and hbase-env.sh

用于Windows和Linux / Unix环境的脚本,用于设置HBase的工作环境,包括Java的位置,Java选项和其他环境变量. 该文件包含许多注释掉的示例以提供指导.

hbase-policy.xml

RPC服务器用于对客户端请求做出授权决策的默认策略配置文件. 仅在启用HBase 安全性时使用.

hbase-site.xml

The main HBase configuration file. This file specifies configuration options which override HBase’s default configuration. You can view (but do not edit) the default configuration file at docs/hbase-default.xml. You can also view the entire effective configuration for your cluster (defaults and overrides) in the HBase配置 tab of the HBase Web UI.

log4j.properties

通过log4j进行HBase日志记录的配置文件.

regionservers

一个纯文本文件,其中包含应在HBase群集中运行RegionServer的主机列表. 默认情况下,此文件包含单个条目localhost . 它应该包含一个主机名或IP地址的列表,每行一个,并且仅当群集中的每个节点都将在其localhost接口上运行RegionServer时才包含localhost .

检查XML有效性

编辑XML时,最好使用支持XML的编辑器,以确保语法正确且XML格式正确. 您还可以使用xmllint实用程序来检查XML格式是否正确. 默认情况下, xmllint重排并将XML打印到标准输出. 要检查格式是否正确并仅在存在错误的情况下才打印输出,请使用命令xmllint -noout filename.xml .

使配置在整个群集中保持同步

在分布式模式下运行时,对HBase配置进行编辑后,请确保将conf /目录的内容复制到群集的所有节点. HBase不会为您这样做. 使用rsyncscp或其他安全机制将配置文件复制到您的节点. 对于大多数配置,服务器需要重新启动才能获取更改. 动态配置是一个例外,下面将对此进行描述.

4. Basic Prerequisites

本节列出了必需的服务和一些必需的系统配置.

Java

下表总结了在各种Java版本上部署的HBase社区的建议. 输入"是"是指测试的基本水平和愿意帮助诊断和解决您可能遇到的问题的意愿. 同样,输入"否"或"不支持"通常意味着如果您遇到问题,社区可能会要求您在继续提供帮助之前更改Java环境. 在某些情况下,还将注意有关限制的特定指南(例如,编译/单元测试工作,特定的操作问题等).

推荐长期支持JDK

HBase建议下游用户使用来自OpenJDK项目或供应商的标记为长期支持(LTS)的JDK版本. 截至2018年3月,这意味着Java 8是唯一适用的版本,下一个可能进行测试的版本将是2018年第三季度附近的Java 11.

表2.按发行行的Java支持
HBase版本 JDK 7 JDK 8 JDK 9 JDK 10

2.0

Not Supported

yes

Not Supported

Not Supported

1.3

yes

yes

Not Supported

Not Supported

1.2

yes

yes

Not Supported

Not Supported

HBase既不会构建也不会与Java 6一起运行.
您必须在集群的每个节点上设置JAVA_HOME . hbase-env.sh提供了一种方便的机制来执行此操作.
操作系统实用程序
ssh

HBase广泛使用Secure Shell(ssh)命令和实用程序在群集节点之间进行通信. 集群中的每个服务器都必须运行ssh以便可以管理Hadoop和HBase守护程序. 您必须能够使用共享密钥而不是密码通过SSH通过SSH从Master以及任何备份Master连接到所有节点,包括本地节点. 您可以在" 过程:配置无密码SSH访问 "中查看在Linux或Unix系统中进行此类设置的基本方法. 如果您的群集节点使用OS X,请参阅Hadoop Wiki上的SSH:设置远程桌面和启用自登录部分 .

DNS

HBase使用本地主机名自报告其IP地址.

NTP

群集节点上的时钟应同步. 少量的变化是可以接受的,但是较大的偏斜会导致不稳定和意外的行为. 时间同步是检查集群中是否出现无法解释的问题的首要检查之一. 建议您在群集上运行网络时间协议(NTP)服务或其他时间同步机制,并且所有节点都希望使用同一服务进行时间同步. 请参阅Linux文档项目(TLDP)上的" 基本NTP配置 "以设置NTP.

Limits on Number of Files and Processes (ulimit)

Apache HBase是一个数据库. 它要求能够一次打开大量文件. 许多Linux发行版将允许单个用户打开的文件数限制为1024 (在OS X的较早版本上为256 ). 您可以通过以运行HBase的用户身份登录时运行命令ulimit -n来检查服务器上的此限制. 如果限制太低,可能会遇到一些问题,请参阅"故障排除"部分 . 您可能还会注意到以下错误:

2010-04-06 03:04:37,542 INFO org.apache.hadoop.hdfs.DFSClient: Exception increateBlockOutputStream java.io.EOFException
2010-04-06 03:04:37,542 INFO org.apache.hadoop.hdfs.DFSClient: Abandoning block blk_-6935524980745310745_1391901

建议将ulimit至少增加到10,000,但更可能是10,240,因为该值通常以1024的倍数表示.每个ColumnFamily至少具有一个StoreFile,如果该区域处于加载状态,则可能有六个以上的StoreFile. 所需打开文件的数量取决于ColumnFamilies的数量和区域的数量. 以下是用于计算RegionServer上打开文件的潜在数量的粗略公式.

计算打开文件的潜在数量
(StoreFiles per ColumnFamily) x (regions per RegionServer)

例如,假设一个模式每个区域有3个ColumnFamily,每个ColumnFamily平均有3个StoreFiles,并且每个RegionServer有100个区域,那么JVM将打开3 * 3 * 100 = 900文件描述符,不计算打开的JAR文件,配置文件等. 打开文件不会占用太多资源,并且允许用户打开太多文件的风险很小.

另一个相关的设置是允许用户一次运​​行的进程数. 在Linux和Unix中,使用ulimit -u命令设置进程数. 这不应与nproc命令混淆,后者控制给定用户可用的CPU数量. 在负载下, ulimit -u太低会导致OutOfMemoryError异常.

为运行HBase进程的用户配置文件描述符和进程的最大数量是操作系统配置,而不是HBase配置. 确保为实际运行HBase的用户更改设置也很重要. 要查看哪个用户启动了HBase,以及该用户的ulimit配置,请查看该实例的HBase日志的第一行.

例子2. Ubuntu上的ulimit设置

要在Ubuntu上配置ulimit设置,请编辑/etc/security/limits.conf ,这是一个由空格分隔的四列文件. 有关此文件格式的详细信息,请参见limits.conf的手册页. 在下面的示例中,第一行将具有用户名hadoop的操作系统用户的打开文件(nofile)数量的软限制和硬限制都设置为32768. 第二行将同一用户的进程数设置为32000.

hadoop  -       nofile  32768
hadoop  -       nproc   32000

仅当直接使用可插拔身份验证模块(PAM)环境时才应用设置. 要将PAM配置为使用这些限制,请确保/etc/pam.d/common-session文件包含以下行:

session required  pam_limits.so
Linux Shell

HBase附带的所有shell脚本都依赖于GNU Bash shell.

Windows

不建议在Windows计算机上运行生产系统.

4.1. Hadoop

下表总结了每个HBase版本支持的Hadoop版本. 该表中未出现的较旧版本被认为不支持,并且可能缺少必要的功能,而较新版本未经测试,但可能合适.

基于HBase的版本,您应该选择最合适的Hadoop版本. 您可以使用Apache Hadoop或供应商的Hadoop发行版. 这里没有区别. 有关Hadoop供应商的信息,请参见Hadoop Wiki .

推荐使用Hadoop2.x.

Hadoop 2.x速度更快,并且具有诸如短路读取(请参见利用本地数据 )之类的功能,这将有助于改善HBase随机读取配置文件. Hadoop 2.x还包括重要的错误修复,这些错误修复将改善您的整体HBase体验. HBase不支持与Hadoop的早期版本一起运行. 有关特定于不同HBase版本的要求,请参见下表.

Hadoop 3.x仍处于早期访问版本中,尚未通过HBase社区针对生产用例的充分测试.

使用以下图例解释此表:

Hadoop版本支持表
  • " S" =支持

  • " X" =不支持

  • " NT" =未测试

HBase-1.2.x HBase-1.3.x HBase-1.5.x HBase-2.0.x HBase-2.1.x

Hadoop-2.4.x

S

S

X

X

X

Hadoop-2.5.x

S

S

X

X

X

Hadoop-2.6.0

X

X

X

X

X

Hadoop-2.6.1+

S

S

X

S

X

Hadoop-2.7.0

X

X

X

X

X

Hadoop-2.7.1+

S

S

S

S

S

Hadoop-2.8.[0-1]

X

X

X

X

X

Hadoop-2.8.2

NT

NT

NT

NT

NT

Hadoop-2.8.3+

NT

NT

NT

S

S

Hadoop-2.9.0

X

X

X

X

X

Hadoop-2.9.1+

NT

NT

NT

NT

NT

Hadoop-3.0.x

X

X

X

X

X

Hadoop-3.1.0

X

X

X

X

X

Hadoop 2.1.6版和JDK 1.8 Kerberos

在Kerberos环境中使用2.6.1之前的Hadoop版本和JDK 1.8时,由于Kerberos keytab重新登录错误,HBase服务器可能会失败并中止. JDK 1.7的较新版本(1.7.0_80)也存在此问题. 有关其他详细信息,请参见HADOOP-10786 . 在这种情况下,请考虑升级到Hadoop 2.6.1+.

Hadoop 2.6.x

如果您计划在HDFS加密区域上运行HBase,则基于2.6.x行的Hadoop发行版必须已应用HADOOP-11710 . 否则将导致群集故障和数据丢失. 该补丁存在于Apache Hadoop 2.6.1+版本中.

Hadoop 2.y.0版本

从Hadoop 2.7.0版本开始,Hadoop PMC习惯于在其主要版本2发行行中召集新的次要版本,因为它们尚未稳定/尚未准备就绪. 因此,HBase明确建议下游用户避免在这些版本之上运行. 请注意,Hadoop PMC还为2.8.1版本提供了相同的警告. 作为参考,请参阅Apache Hadoop 2.7.0Apache Hadoop 2.8.0Apache Hadoop 2.8.1Apache Hadoop 2.9.0的发行公告.

Hadoop 3.0.x版本

包含应用程序时间轴服务功能的Hadoop发行版可能会导致应用程序类路径中出现意外版本的HBase类. 计划使用HBase运行MapReduce应用程序的用户应确保其YARN服务中存在YARN-7190 (当前在2.9.1+和3.1.0+中已修复).

Hadoop 3.1.0版本

Hadoop PMC称3.1.0版本不稳定/无法投入生产. 因此,HBase明确建议下游用户避免在此版本之上运行. 作为参考,请参阅Hadoop 3.1.0发行公告 .

用HBase替换捆绑的Hadoop!

因为HBase依赖于Hadoop,所以它将Hadoop jar捆绑在其lib目录下. 捆绑的罐子仅可在独立模式下使用. 在分布式模式下,群集上的Hadoop版本与HBase下的Hadoop版本相匹配至关重要 . 将HBase lib目录中找到的hadoop jar替换为您在群集上运行的版本中的等效hadoop jar,以避免版本不匹配的问题. 确保在整个群集中替换HBase下的jar. Hadoop版本不匹配问题有多种表现形式. 如果HBase似乎挂起,请检查是否不匹配.

4.1.1. dfs.datanode.max.transfer.threads

HDFS DataNode可以随时提供服务的文件数量上限. 在执行任何加载之前,请确保已配置Hadoop的conf / hdfs-site.xml ,并将dfs.datanode.max.transfer.threads值至少设置为以下值:

<property>
  <name>dfs.datanode.max.transfer.threads</name>
  <value>4096</value>
</property>

完成上述配置后,请务必重新启动HDFS.

Not having this configuration in place makes for strange-looking failures. One manifestation is a complaint about missing blocks. For example:

10/12/08 20:10:31 INFO hdfs.DFSClient: Could not obtain block
          blk_XXXXXXXXXXXXXXXXXXXXXX_YYYYYYYY from any node: java.io.IOException: No live nodes
          contain current block. Will get new block locations from namenode and retry...

另请参阅casestudies.max.transfer.threads,并注意此属性以前称为dfs.datanode.max.xcievers (例如Hadoop HDFS:由Xciever欺骗 ).

4.2. ZooKeeper Requirements

ZooKeeper 3.4.x是必需的.

5. HBase run modes: Standalone and Distributed

HBase有两种运行模式: 独立运行和分布式运行. 开箱即用,HBase以独立模式运行. 无论使用哪种模式,都需要通过编辑HBase conf目录中的文件来配置HBase. 至少,您必须编辑conf / hbase-env.sh以告知HBase使用哪个Java. 在此文件中,您设置HBase环境变量,例如JVM的heapsize和其他选项,日志文件的首选位置等.将JAVA_HOME设置为指向Java安装的根目录.

5.1. Standalone HBase

这是默认模式. 快速入门部分介绍了独立模式. 在独立模式下,HBase不使用HDFS,而是使用本地文件系统,并且在同一JVM中运行所有HBase守护程序和本地ZooKeeper. ZooKeeper绑定到一个知名端口,因此客户端可以与HBase进行通信.

5.1.1. Standalone HBase over HDFS

在独立的hbase上有时有用的变体是,所有守护程序都在一个JVM中运行,而不是持久化到本地文件系统,而是持久化到HDFS实例.

当您打算使用简单的部署概要文件时,可以考虑使用此概要文件,虽然负载很轻,但是数据必须在节点间来回移动. 写入要复制数据的HDFS可确保后者.

要配置此独立变体,请编辑hbase-site.xml设置hbase.rootdir以指向HDFS实例中的目录,然后将hbase.cluster.distributed设置为false . 例如:

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://namenode.example.org:8020/hbase</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>false</value>
  </property>
</configuration>

5.2. Distributed

Distributed mode can be subdivided into distributed but all daemons run on a single node — a.k.a. pseudo-distributed — and fully-distributed where the daemons are spread across all nodes in the cluster. The pseudo-distributed vs. fully-distributed nomenclature comes from Hadoop.

伪分布式模式可以针对本地文件系统运行,也可以针对Hadoop分布式文件系统 (HDFS)实例运行. 全分布式模式只能在HDFS上运行. 有关如何设置HDFS的信息 ,请参阅Hadoop 文档 . 可在http://www.alexjf.net/blog/distributed-systems/hadoop-yarn-installation-definitive-guide中找到有关在Hadoop 2上设置HDFS的很好的演练.

5.2.1. Pseudo-distributed

伪分布式快速入门

快速入门已添加到快速入门一章. 请参阅quickstart-pseudo . 本节中最初的某些信息已移至此处.

伪分布式模式只是在单个主机上运行的完全分布式模式. 将此HBase配置仅用于测试和原型制作. 不要将此配置用于生产或性能评估.

5.3. Fully-distributed

默认情况下,HBase在独立模式下运行. 提供独立模式和伪分布式模式都是为了进行小型测试. 对于生产环境,建议使用分布式模式. 在分布式模式下,HBase守护程序的多个实例在群集中的多个服务器上运行.

就像在伪分布式模式下一样,完全分布式配置需要将hbase.cluster.distributed属性设置为true . 通常,将hbase.rootdir配置为指向高可用性HDFS文件系统.

此外,还配置了群集,以便多个群集节点可以注册为RegionServers,ZooKeeper QuorumPeers和备份HMaster服务器. 这些配置基础都在quickstart-full-distributed中进行了演示.

分布式RegionServer

Typically, your cluster will contain multiple RegionServers all running on different servers, as well as primary and backup Master and ZooKeeper daemons. The conf/regionservers file on the master server contains a list of hosts whose RegionServers are associated with this cluster. Each host is on a separate line. All hosts listed in this file will have their RegionServer processes started and stopped when the master server starts or stops.

ZooKeeper和HBase

有关HBase的ZooKeeper设置说明,请参见ZooKeeper部分.

例子3.例子分布式HBase集群

这是分布式HBase群集的conf / hbase-site.xml . 用于实际工作的群集将包含更多自定义配置参数. 大多数HBase配置指令都有默认值,除非在hbase-site.xml中覆盖该值,否则将使用默认值. 有关更多信息,请参见" 配置文件 ".

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://namenode.example.org:8020/hbase</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>node-a.example.com,node-b.example.com,node-c.example.com</value>
  </property>
</configuration>

这是一个示例conf / regionservers文件,其中包含应在集群中运行RegionServer的节点的列表. 这些节点需要安装HBase,并且需要使用与主服务器相同的conf /目录内容

node-a.example.com
node-b.example.com
node-c.example.com

这是示例conf / backup-masters文件,其中包含应运行备份Master实例的每个节点的列表. 除非主主实例不可用,否则备份主实例将处于空闲状态.

node-b.example.com
node-c.example.com
分布式HBase快速入门

有关具有多个ZooKeeper,备份HMaster和RegionServer实例的简单三节点群集配置的演练,请参阅快速分发 .

过程:HDFS客户端配置
  1. 值得注意的是,如果您在Hadoop集群上进行了HDFS客户端配置更改(例如HDFS客户端的配置指令),而不是服务器端配置,则必须使用以下方法之一使HBase能够查看和使用这些配置更改:

    1. 一个指向您的加入HADOOP_CONF_DIRHBASE_CLASSPATHhbase-env.sh环境变量.

    2. $ {HBASE_HOME} / conf下添加hdfs-site.xml (或hadoop-site.xml )或更佳的符号链接的副本 ,或

    3. 如果只有一小部分HDFS客户端配置,请将其添加到hbase-site.xml .

此类HDFS客户端配置的示例是dfs.replication . 例如,如果要以5的复制因子运行,除非您执行上述操作以使配置可用于HBase,否则HBase将创建默认值为3的文件.

6. Running and Confirming Your Installation

确保HDFS首先运行. 通过在HADOOP_HOME目录中运行bin / start-hdfs.sh来启动和停止Hadoop HDFS守护程序. 您可以通过测试put文件放入Hadoop文件系统中的putget来确保它正确启动. HBase通常不使用MapReduce或YARN守护程序. 这些不需要启动.

如果您正在管理自己的ZooKeeper,请启动它并确认它正在运行,否则HBase将在启动过程中为您启动ZooKeeper.

使用以下命令启动HBase:

bin/start-hbase.sh

HBASE_HOME目录运行以上HBASE_HOME .

您现在应该拥有一个正在运行的HBase实例. HBase日志可在logs子目录中找到. 检查它们,特别是如果HBase无法启动.

HBase还建立了一个列出重要属性的UI. 默认情况下,它部署在主主机上的端口16010上(HBase RegionServers默认在端口16020上侦听,并在端口16030上建立一个信息性HTTP服务器). 如果主master.example.org在默认端口上的名为master.example.org的主机上运行,​​请将浏览器指向http://master.example.org:16010以查看Web界面.

HBase启动后,请参阅外壳练习部分,以了解如何创建表,添加数据,扫描插入内容以及最后禁用和删除表.

要在退出HBase Shell之后停止HBase,请输入

$ ./bin/stop-hbase.sh
stopping hbase...............

关机可能需要一些时间才能完成. 如果群集由多台计算机组成,则可能需要更长的时间. 如果您正在运行分布式操作,请确保等到HBase完全关闭后再停止Hadoop守护程序.

7. Default Configuration

7.1. hbase-site.xml and hbase-default.xml

就像在Hadoop中将特定于站点的HDFS配置添加到hdfs-site.xml文件中一样,针对HBase,特定于站点的自定义项也放入文件conf / hbase-site.xml中 . 有关可配置属性的列表,请参见下面的hbase默认配置 ,或在src / main / resources的HBase源代码中查看原始的hbase-default.xml源文件.

并非所有配置选项都将其显示在hbase-default.xml中 . 有些配置只会出现在源代码中. 识别这些更改的唯一方法是通过代码审查.

当前,此处的更改将要求HBase重新启动群集以注意到更改.

7.2. HBase Default Configuration

以下文档是使用默认的hbase配置文件hbase-default.xml作为源生成的.

hbase.tmp.dir
Description

本地文件系统上的临时目录. 更改此设置以指向比'/ tmp'更永久的位置(java.io.tmpdir的通常解析方法),因为在重新启动计算机时会清除'/ tmp'目录.

Default

${java.io.tmpdir}/hbase-${user.name}

hbase.rootdir
Description

区域服务器共享的目录,HBase保留在该目录中. URL应该是"完全限定"的,以包括文件系统方案. 例如,要指定HDFS目录" / hbase",其中HDFS实例的namenode在端口9000上的namenode.example.org上运行,请将此值设置为:hdfs://namenode.example.org:9000 / hbase. 默认情况下,我们也会写入也设置了$ {hbase.tmp.dir}的内容(通常是/ tmp),因此请更改此配置,否则所有数据都会在计算机重新启动时丢失.

Default

${hbase.tmp.dir}/hbase

hbase.cluster.distributed
Description

群集将处于的模式.对于独立模式,可能的值为false;对于分布式模式,可能的值为true. 如果为false,则启动将在一个JVM中同时运行所有HBase和ZooKeeper守护程序.

Default

false

hbase.zookeeper.quorum
Description

ZooKeeper集成中服务器的逗号分隔列表(此配置应已命名为hbase.zookeeper.ensemble). 例如," host1.mydomain.com,host2.mydomain.com,host3.mydomain.com". 默认情况下,对于本地和伪分布式操作模式,此设置为localhost. 对于完全分布式的设置,应将其设置为ZooKeeper集成服务器的完整列表. 如果在hbase-env.sh中设置了HBASE_MANAGES_ZK,这是hbase在集群启动/停止过程中将启动/停止ZooKeeper的服务器列表. 在客户端,我们将获取此集成成员列表,并将其与hbase.zookeeper.property.clientPort配置一起. 并将其作为connectString参数传递到zookeeper构造函数中.

Default

localhost

zookeeper.recovery.retry.maxsleeptime
Description

重试动物园管理员操作之前的最大睡眠时间(以毫秒为单位),此处需要一个最大时间,以使睡眠时间不会无限制地增长

Default

60000

hbase.local.dir
Description

本地文件系统上用作本地存储的目录.

Default

${hbase.tmp.dir}/local/

hbase.master.port
Description

HBase主站应绑定的端口.

Default

16000

hbase.master.info.port
Description

HBase Master Web UI的端口. 如果您不希望运行UI实例,请设置为-1.

Default

16010

hbase.master.info.bindAddress
Description

HBase Master Web UI的绑定地址

Default

0.0.0.0

hbase.master.logcleaner.plugins
Description

LogsCleaner服务调用的以逗号分隔的BaseLogCleanerDelegate列表. 这些WAL清理程序是按顺序调用的,因此将修剪最多文件的清理程序放在前面. 要实现自己的BaseLogCleanerDelegate,只需将其放在HBase的类路径中,然后在此处添加完全限定的类名. 始终在列表中添加上述默认日志清除器.

Default

org.apache.hadoop.hbase.master.cleaner.TimeToLiveLogCleaner,org.apache.hadoop.hbase.master.cleaner.TimeToLiveProcedureWALCleaner

hbase.master.logcleaner.ttl
Description

WAL在存档({hbase.rootdir} / oldWALs)目录中保留多长时间,之后它将由主线程清除. 该值以毫秒为单位.

Default

600000

hbase.master.procedurewalcleaner.ttl
Description

过程WAL将在存档目录中保留多长时间,之后将由主线程将其清除. 该值以毫秒为单位.

Default

604800000

hbase.master.hfilecleaner.plugins
Description

由HFileCleaner服务调用的BaseHFileCleanerDelegate的逗号分隔列表. 这些HFiles清理程序是按顺序调用的,因此将修剪大多数文件的清理程序放在前面. 要实现自己的BaseHFileCleanerDelegate,只需将其放在HBase的类路径中,然后在此处添加完全限定的类名. 请始终在列表中添加上述默认日志清除器,因为它们将在hbase-site.xml中被覆盖.

Default

org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner

hbase.master.infoserver.redirect
Description

Master是否侦听Master Web UI端口(hbase.master.info.port)并将请求重定向到Master和RegionServer共享的Web UI服务器. 配置 当Master服务于区域(不是默认值)时,这很有意义.

Default

true

hbase.master.fileSplitTimeout
Description

分割区域,在中止尝试之前要等待文件分割步骤多长时间. 默认值:600000.此设置以前在hbase-1.x中称为hbase.regionserver.fileSplitTimeout. 现在,Split在主端运行,因此重命名(如果找到了" hbase.master.fileSplitTimeout"设置,它将使用它来初始化当前的" hbase.master.fileSplitTimeout"配置.

Default

600000

hbase.regionserver.port
Description

HBase RegionServer绑定到的端口.

Default

16020

hbase.regionserver.info.port
Description

The port for the HBase RegionServer web UI Set to -1 if you do not want the RegionServer UI to run.

Default

16030

hbase.regionserver.info.bindAddress
Description

The address for the HBase RegionServer web UI

Default

0.0.0.0

hbase.regionserver.info.port.auto
Description

Master或RegionServer UI是否应搜索要绑定的端口. 如果hbase.regionserver.info.port已在使用中,则启用自动端口搜索. 对于测试很有用,默认情况下处于关闭状态.

Default

false

hbase.regionserver.handler.count
Description

在RegionServer上旋转的RPC侦听器实例数. Master使用相同的属性来计算master处理程序的数量. 过多的处理程序可能适得其反. 使它成为CPU计数的倍数. 如果大多数情况下是只读的,则处理程序计数接近cpu计数的效果很好. 从两倍的CPU计数开始,然后从那里进行调整.

Default

30

hbase.ipc.server.callqueue.handler.factor
Description

确定呼叫队列数量的因素. 值为0表示所有处理程序之间共享一个队列. 值为1表示每个处理程序都有自己的队列.

Default

0.1

hbase.ipc.server.callqueue.read.ratio
Description

将呼叫队列拆分为读写队列. 指定的时间间隔(应在0.0到1.0之间)将乘以呼叫队列的数量. 值为0表示不拆分呼叫队列,这意味着读取和写入请求都将被推送到同一组队列中. 小于0.5的值表示读队列少于写队列. 值为0.5表示将有相同数量的读取和写入队列. 大于0.5的值表示将有比写队列更多的读队列. 值1.0表示除一个队列外的所有队列均用于调度读取请求. 示例:给定呼叫队列总数为10,read.ratio为0表示:10个队列将包含两个读/写请求. read.ratio为0.3表示:3个队列仅包含读取请求,而7个队列仅包含写入请求. read.ratio为0.5表示:5个队列仅包含读取请求,而5个队列仅包含写入请求. read.ratio为0.8表示:8个队列仅包含读取请求,而2个队列仅包含写入请求. read.ratio为1表示:9个队列仅包含读取请求,而1个队列仅包含写入请求.

Default

0

hbase.ipc.server.callqueue.scan.ratio
Description

给定读取呼叫队列的数量(根据呼叫队列总数乘以callqueue.read.ratio计算得出),scan.ratio属性会将读取呼叫队列分为小读取队列和长读取队列. 小于0.5的值表示长读队列少于短读队列. 值0.5表示将有相同数量的短读和长读队列. 大于0.5的值表示长读取队列比短读取队列多.值为0或1表示使用相同的队列进行获取和扫描. 示例:假设读取呼叫队列的总数为8,则scan.ratio为0或1表示:8个队列将同时包含长读取请求和短读取请求. scan.ratio为0.3表示:2个队列将仅包含长读请求,而6个队列将仅包含短读请求. scan.ratio为0.5表示:4个队列将仅包含长读请求,而4个队列将仅包含短读请求. scan.ratio为0.8表示:6个队列将仅包含长读请求,而2个队列将仅包含短读请求.

Default

0

hbase.regionserver.msginterval
Description

从RegionServer到Master的消息之间的时间间隔(以毫秒为单位).

Default

3000

hbase.regionserver.logroll.period
Description

无论提交多少编辑,我们都会滚动提交日志的时间段.

Default

3600000

hbase.regionserver.logroll.errors.tolerated
Description

在触发服务器异常终止之前,我们将允许的连续WAL关闭错误数. 如果在日志滚动过程中关闭当前WAL编写器失败,则设置为0将导致区域服务器中止. 即使是很小的值(2或3),也可以使区域服务器克服瞬态HDFS错误.

Default

2

hbase.regionserver.hlog.reader.impl
Description

WAL文件阅读器实现.

Default

org.apache.hadoop.hbase.regionserver.wal.ProtobufLogReader

hbase.regionserver.hlog.writer.impl
Description

WAL文件编写器实现.

Default

org.apache.hadoop.hbase.regionserver.wal.ProtobufLogWriter

hbase.regionserver.global.memstore.size
Description

在阻止新更新并强制进行刷新之前,区域服务器中所有内存存储区的最大大小. 默认为堆的40%(0.4). 阻止更新并强制执行刷新,直到区域服务器中所有内存存储的大小达到hbase.regionserver.global.memstore.size.lower.limit. 此配置中的默认值有意保留为空,以保留旧的hbase.regionserver.global.memstore.upperLimit属性(如果存在).

Default

none

hbase.regionserver.global.memstore.size.lower.limit
Description

强制刷新之前,区域服务器中所有内存存储区的最大大小. 默认为hbase.regionserver.global.memstore.size(0.95)的95%. 如果由于内存存储限制而阻止更新,则此值的100%值将导致最小的刷新发生. 此配置中的默认值有意保留为空,以使用旧的hbase.regionserver.global.memstore.lowerLimit属性(如果存在).

Default

none

hbase.systemtables.compacting.memstore.type
Description

确定用于系统表(例如META,名称空间表等)的内存存储的类型.默认情况下,类型为NONE,因此我们对所有系统表使用默认的内存存储. 如果我们需要对系统表使用压缩存储区,则将此属性设置为BASIC / EAGER

Default

NONE

hbase.regionserver.optionalcacheflushinterval
Description

编辑内容在自动刷新之前保留在内存中的最长时间. 默认值1小时. 将其设置为0以禁用自动刷新.

Default

3600000

hbase.regionserver.dns.interface
Description

区域服务器应从中报告其IP地址的网络接口的名称.

Default

default

hbase.regionserver.dns.nameserver
Description

区域服务器应使用该名称服务器(DNS)的主机名或IP地址来确定主服务器用于通信和显示目的的主机名.

Default

default

hbase.regionserver.region.split.policy
Description

拆分策略确定何时应拆分区域. 当前可用的其他各种拆分策略为BusyRegionSplitPolicy,ConstantSizeRegionSplitPolicy,DisabledRegionSplitPolicy,DelimitedKeyPrefixRegionSplitPolicy,KeyPrefixRegionSplitPolicy和SteppingSplitPolicy. DisabledRegionSplitPolicy阻止手动区域划分.

Default

org.apache.hadoop.hbase.regionserver.SteppingSplitPolicy

hbase.regionserver.regionSplitLimit
Description

区域数量的限制,之后将不再进行区域划分. 这不是对区域数量的硬限制,但可作为区域服务器在特定限制后停止拆分的准则. 默认设置为1000.

Default

1000

zookeeper.session.timeout
Description

ZooKeeper会话超时(以毫秒为单位). 它以两种不同的方式使用. 首先,在HBase用于连接到集成体的ZK客户端中使用此值. HBase在启动ZK服务器时也使用它,并将其作为" maxSessionTimeout"传递. 请参阅https://zookeeper.apache.org/doc/current/zookeeperProgrammers.html#ch_zkSessions . 例如,如果HBase区域服务器连接到同样由HBase管理的ZK集成,则会话超时将是此配置指定的会话超时. 但是,连接到使用不同配置管理的集成服务器的区域服务器将受到该集成服务器的maxSessionTimeout的影响. 因此,即使HBase可能建议使用90秒,该集合的最大超时值也可以低于此值,并且它将具有优先权. ZK附带的当前默认maxSessionTimeout为40秒,比HBase的默认值低.

Default

90000

zookeeper.znode.parent
Description

ZooKeeper中用于HBase的根ZNode. 配置有相对路径的所有HBase的ZooKeeper文件都将位于此节点下. 默认情况下,所有HBase的ZooKeeper文件路径都配置有相对路径,因此除非更改,否则它们都将位于此目录下.

Default

/hbase

zookeeper.znode.acl.parent
Description

根ZNode用于访问控制列表.

Default

acl

hbase.zookeeper.dns.interface
Description

ZooKeeper服务器应从其报告其IP地址的网络接口的名称.

Default

default

hbase.zookeeper.dns.nameserver
Description

ZooKeeper服务器应使用其名称服务器(DNS)的主机名或IP地址来确定主服务器用于通信和显示目的的主机名.

Default

default

hbase.zookeeper.peerport
Description

ZooKeeper对等方用来互相通信的端口. 有关更多信息,请参见https://zookeeper.apache.org/doc/r3.3.3/zookeeperStarted.html#sc_RunningReplicatedZooKeeper .

Default

2888

hbase.zookeeper.leaderport
Description

ZooKeeper用于领导者选举的端口. 有关更多信息,请参见https://zookeeper.apache.org/doc/r3.3.3/zookeeperStarted.html#sc_RunningReplicatedZooKeeper .

Default

3888

hbase.zookeeper.property.initLimit
Description

Property from ZooKeeper’s config zoo.cfg. The number of ticks that the initial synchronization phase can take.

Default

10

hbase.zookeeper.property.syncLimit
Description

ZooKeeper的配置zoo.cfg中的属性. 发送请求和获得确认之间可以经过的滴答声数量.

Default

5

hbase.zookeeper.property.dataDir
Description

ZooKeeper的配置zoo.cfg中的属性. 快照存储的目录.

Default

${hbase.tmp.dir}/zookeeper

hbase.zookeeper.property.clientPort
Description

ZooKeeper的配置zoo.cfg中的属性. 客户端将连接的端口.

Default

2181

hbase.zookeeper.property.maxClientCnxns
Description

ZooKeeper的配置zoo.cfg中的属性. 限制单个客户端通过IP地址标识到ZooKeeper集成中的单个成员的并发连接数(在套接字级别). 设置为高值可以避免独立运行和伪分布式运行的zk连接问题.

Default

300

hbase.client.write.buffer
Description

BufferedMutator写缓冲区的默认大小(以字节为单位). 较大的缓冲区会占用更多内存(在客户端和服务器端都需要,因为服务器会实例化传递的写缓冲区以对其进行处理),但是较大的缓冲区大小会减少制作的RPC数量. 要估算服务器端使用的内存,请评估hbase.client.write.buffer * hbase.regionserver.handler.count

Default

2097152

hbase.client.pause
Description

常规客户端暂停值. 在运行重试失败的获取,区域查找等之前,主要用作等待值.请参见hbase.client.retries.number,以获取有关我们如何从此初始暂停量回退以及此暂停如何进行重试的描述.

Default

100

hbase.client.pause.cqtbe
Description

是否对CallQueueTooBigException(cqtbe)使用特殊的客户端暂停. 如果您观察到来自同一RegionServer的CQTBE频繁并且那里的呼叫队列保持满状态,则将此属性设置为比hbase.client.pause高的值.

Default

none

hbase.client.retries.number
Description

Maximum retries. Used as maximum for all retryable operations such as the getting of a cell’s value, starting a row update, etc. Retry interval is a rough function based on hbase.client.pause. At first we retry at this interval but then with backoff, we pretty quickly reach retrying every ten seconds. See HConstants#RETRY_BACKOFF for how the backup ramps up. Change this setting and hbase.client.pause to suit your workload.

Default

15

hbase.client.max.total.tasks
Description

The maximum number of concurrent mutation tasks a single HTable instance will send to the cluster.

Default

100

hbase.client.max.perserver.tasks
Description

单个HTable实例将发送到单个区域服务器的最大并发变异任务数.

Default

2

hbase.client.max.perregion.tasks
Description

客户将维护到一个区域的最大并发变异任务数. 也就是说,如果已经对该区域进行了hbase.client.max.perregion.tasks写入,则在完成某些写入操作之前,不会将新的puts发送到该区域.

Default

1

hbase.client.perserver.requests.threshold
Description

所有客户端线程(进程级别)中一台服务器的并发暂挂请求的最大数量. 超出的请求将立即引发ServerTooBusyException,以防止仅一台慢速区域服务器占用和阻止用户的线程. 如果您使用固定数量的线程以同步方式访问HBase,请将其设置为与线程数量相关的合适值将对您有所帮助. 有关详细信息,请参见https://issues.apache.org/jira/browse/HBASE-16388 .

Default

2147483647

hbase.client.scanner.caching
Description

如果未从(本地,客户端)内存提供服务,则在扫描器上调用next时尝试获取的行数. 此配置与hbase.client.scanner.max.result.size一起使用,以尝试有效地使用网络. 默认情况下,默认值为Integer.MAX_VALUE,因此网络将填充hbase.client.scanner.max.result.size定义的块大小,而不是受特定的行数限制,因为行的大小因表而异. 如果您提前知道一次扫描不需要多于一定数量的行,则应通过Scan#setCaching将此配置设置为该行限制. 较高的缓存值将启用更快的扫描程序,但会消耗更多的内存,并且当缓存为空时,对next的某些调用可能会花费越来越长的时间. 请勿将此值设置为使得两次调用之间的时间大于扫描程序超时. 即hbase.client.scanner.timeout.period

Default

2147483647

hbase.client.keyvalue.maxsize
Description

指定KeyValue实例的组合最大允许大小. 这是为存储文件中保存的单个条目设置上限. 由于无法拆分它们,因此有助于避免由于数据太大而无法进一步拆分区域. 将其设置为最大区域大小的一小部分似乎是明智的. 将其设置为零或更少将禁用检查.

Default

10485760

hbase.server.keyvalue.maxsize
Description

单个单元格的最大允许大小,包括值和所有关键组件. 小于或等于0的值将禁用该检查. 默认值为10MB. 这是一项安全设置,可以保护服务器免受OOM情况的影响.

Default

10485760

hbase.client.scanner.timeout.period
Description

客户端扫描程序的租用期限(以毫秒为单位).

Default

60000

hbase.client.localityCheck.threadPoolSize
Default

2

hbase.bulkload.retries.number
Description

最大重试次数. 这是面对分裂操作时尝试进行的原子批量加载的最大迭代次数0表示永不放弃.

Default

10

hbase.master.balancer.maxRitPercent
Description

平衡时过渡区域的最大百分比. 默认值为1.0. 因此,没有平衡器节流. 如果将此配置设置为0.01,则表示平衡时最多有1%的过渡区域. 然后,平衡时群集的可用性至少为99%.

Default

1.0

hbase.balancer.period
Description

区域平衡器在主服务器中运行的时间段.

Default

300000

hbase.normalizer.period
Description

区域规范化器在主服务器中运行的时间段.

Default

300000

hbase.regions.slop
Description

如果任何区域服务器具有平均+(平均*斜率)区域,则重新平衡. 在StochasticLoadBalancer(默认负载均衡器)中,此参数的默认值为0.001,而在其他负载均衡器(即SimpleLoadBalancer)中,默认值为0.2.

Default

0.001

hbase.server.thread.wakefrequency
Description

两次搜索工作之间的睡眠时间(以毫秒为单位). 由服务线程(例如对数辊)用作睡眠间隔.

Default

10000

hbase.server.versionfile.writeattempts
Description

在中止之前重试几次尝试写入版本文件. 每次尝试都由hbase.server.thread.wakefrequency毫秒分隔.

Default

3

hbase.hregion.memstore.flush.size
Description

Memstore will be flushed to disk if size of the memstore exceeds this number of bytes. Value is checked by a thread that runs every hbase.server.thread.wakefrequency.

Default

134217728

hbase.hregion.percolumnfamilyflush.size.lower.bound.min
Description

如果使用了FlushLargeStoresPolicy并且有多个列族,那么每次我们达到内存存储区的总限制时,我们都会找出其内存存储区超出"下限"的所有列族,并仅刷新它们,同时将其他存储区保留在内存中. 默认情况下,"下界"将为" hbase.hregion.memstore.flush.size / column_family_number",除非该属性的值大于该值. 如果没有一个家族的内存大小超过下限,则将刷新所有内存(就像往常一样).

Default

16777216

hbase.hregion.preclose.flush.size
Description

如果在关闭时某个区域中的内存大小等于或大于此大小,请在设置区域已关闭标志并使该区域脱机之前运行"预冲洗"以清除内存. 关闭时,在关闭标志下运行刷新以清空内存. 在这段时间内,该地区处于离线状态,我们没有进行任何写操作. 如果内存存储区内容很大,则刷新可能需要很长时间才能完成. 预刷新的目的是在放置关闭标志并使区域脱机之前清理掉大部分的内存存储,因此在关闭标志下运行的刷新几乎无济于事.

Default

5242880

hbase.hregion.memstore.block.multiplier
Description

如果memstore具有hbase.hregion.memstore.block.multiplier乘以hbase.hregion.memstore.flush.size字节,则阻止更新. 防止更新流量激增期间失控的存储器. 如果没有上限,则内存存储将进行填充,以便在刷新结果刷新文件时需要花费很长时间来压缩或拆分,或更糟糕的是,我们OOME.

Default

4

hbase.hregion.memstore.mslab.enabled
Description

启用MemStore-Local Allocation Buffer,该功能可防止在重写入负载下发生堆碎片. 这可以减少大堆上停止世界GC暂停的频率.

Default

true

hbase.hregion.max.filesize
Description

最大HFile大小. 如果区域的HFiles大小的总和超过了该值,则该区域将一分为二.

Default

10737418240

hbase.hregion.majorcompaction
Description

两次大压实之间的时间,以毫秒为单位. 设置为0将禁用基于时间的自动专业压缩. 用户请求的基于大小的大型压缩仍将运行. 将该值乘以hbase.hregion.majorcompaction.jitter会导致压缩在给定的时间范围内在某个随机时间开始. 默认值为7天,以毫秒为单位. 如果大型压缩在环境中造成破坏,则可以将其配置为在部署的非高峰时间运行,或者通过将此参数设置为0来禁用基于时间的大型压缩,然后在cron作业或其他作业中运行大型压缩外部机制.

Default

604800000

hbase.hregion.majorcompaction.jitter
Description

应用于hbase.hregion.majorcompaction的乘数,使压缩在hbase.hregion.majorcompaction的任一侧发生给定的时间. 数值越小,紧缩将发生在hbase.hregion.majorcompaction间隔上.

Default

0.50

hbase.hstore.compactionThreshold
Description

如果在任何一个商店中都存在超过此数目的StoreFile(每次刷新MemStore都会写入一个StoreFile),则会运行压缩以将所有StoreFile重写为一个StoreFile. 较大的值会延迟压缩,但是当确实发生压缩时,则需要更长的时间才能完成.

Default

3

hbase.hstore.flusher.count
Description

The number of flush threads. With fewer threads, the MemStore flushes will be queued. With more threads, the flushes will be executed in parallel, increasing the load on HDFS, and potentially causing more compactions.

Default

2

hbase.hstore.blockingStoreFiles
Description

如果在任何一个商店中都存在超过此数目的StoreFile(每次MemStore刷新都写入一个StoreFile),则该区域的更新将被阻止,直到压缩完成或超过hbase.hstore.blockingWaitTime.

Default

16

hbase.hstore.blockingWaitTime
Description

达到hbase.hstore.blockingStoreFiles定义的StoreFile限制后,区域将阻止更新的时间. 经过这段时间后,即使压缩尚未完成,该区域也将停止阻止更新.

Default

90000

hbase.hstore.compaction.min
Description

The minimum number of StoreFiles which must be eligible for compaction before compaction can run. The goal of tuning hbase.hstore.compaction.min is to avoid ending up with too many tiny StoreFiles to compact. Setting this value to 2 would cause a minor compaction each time you have two StoreFiles in a Store, and this is probably not appropriate. If you set this value too high, all the other values will need to be adjusted accordingly. For most cases, the default value is appropriate. In previous versions of HBase, the parameter hbase.hstore.compaction.min was named hbase.hstore.compactionThreshold.

Default

3

hbase.hstore.compaction.max
Description

无论合格的StoreFiles数量如何,一次较小的压缩将选择的StoreFiles的最大数量. 有效地,hbase.hstore.compaction.max的值控制完成一次压缩的时间长度. 将其设置为更大意味着压缩中将包含更多StoreFiles. 在大多数情况下,默认值为适当.

Default

10

hbase.hstore.compaction.min.size
Description

小于此大小的StoreFile(或使用ExploringCompactionPolicy时选择的StoreFiles)始终可以进行较小的压缩. 大小更大的HFile由hbase.hstore.compaction.ratio评估以确定它们是否合格. 因为此限制表示所有小于此值的StoreFiles的"自动包含"限制,所以在需要大量写入1-2 MB范围的StoreFiles的写繁重环境中,可能需要减小此值,因为每个StoreFile都将作为目标进行压缩,生成的StoreFiles可能仍小于最小大小,需要进一步压缩. 如果降低此参数,则比率检查会更快地触发. 这解决了早期版本的HBase中遇到的一些问题,但是在大多数情况下不再需要更改此参数. 默认值:128 MB,以字节为单位.

Default

134217728

hbase.hstore.compaction.max.size
Description

大于此大小的StoreFile(或使用ExploringCompactionPolicy时选择的StoreFiles)将被排除在压缩之外. 提高hbase.hstore.compaction.max.size的效果较小,而较大的StoreFiles则不会经常压缩. 如果您认为压缩过于频繁而没有太多好处,则可以尝试提高此值. 默认值:LONG.MAX_VALUE的值,以字节为单位.

Default

9223372036854775807

hbase.hstore.compaction.ratio
Description

对于较小的压缩,此比率用于确定大于hbase.hstore.compaction.min.size的给定StoreFile是否适合压缩. 它的作用是限制大型StoreFiles的压缩. hbase.hstore.compaction.ratio的值表示为浮点十进制. 很大的比例(例如10)将产生一个巨大的StoreFile. 相反,较低的值(例如.25)将产生类似于BigTable压缩算法的行为,从而产生四个StoreFiles. 建议在1.0到1.4之间使用一个适中的值. 调整此值时,您要在写入成本和读取成本之间取得平衡. 将值提高(到1.4之类)会增加写入成本,因为您将压缩更大的StoreFiles. 但是,在读取期间,HBase将需要搜索较少的StoreFiles来完成读取. 如果您无法利用布隆过滤器,请考虑使用这种方法. 否则,您可以将此值降低到1.0之类,以减少写入的背景成本,并使用Bloom过滤器控制读取期间接触到的StoreFiles的数量. 在大多数情况下,默认值为适当.

Default

1.2F

hbase.hstore.compaction.ratio.offpeak
Description

允许您设置不同的比率(默认情况下,更具侵略性)以确定在非高峰时段压缩中是否包括较大的StoreFiles. 以与hbase.hstore.compaction.ratio相同的方式工作. 仅在同时启用了hbase.offpeak.start.hour和hbase.offpeak.end.hour的情况下适用.

Default

5.0F

hbase.hstore.time.to.purge.deletes
Description

延迟清除带有未来时间戳记的删除标记的时间. 如果未设置或设置为0,则所有删除标记(包括带有未来时间戳记的标记)将在下一次主要压缩期间清除. 否则,将保留删除标记,直到在标记的时间戳加上此设置的值之后发生的主要压缩为止(以毫秒为单位).

Default

0

hbase.offpeak.start.hour
Description

非高峰时间的开始,表示为0到23之间的一个整数(包括0和23). 设置为-1以禁用非峰值.

Default

-1

hbase.offpeak.end.hour
Description

非高峰时间的结束时间,以0到23之间的整数表示(包括0和23). 设置为-1以禁用非峰值.

Default

-1

hbase.regionserver.thread.compaction.throttle
Description

有两种不同的线程池用于压缩,一种用于大压缩,另一种用于小压缩. 这有助于保持精简表(例如hbase:meta)的紧缩. 如果压缩大于此阈值,它将进入大型压缩池. 在大多数情况下,默认值为适当. 默认值:2 x hbase.hstore.compaction.max x hbase.hregion.memstore.flush.size(默认为128MB). 值字段假定hbase.hregion.memstore.flush.size的值与默认值保持不变.

Default

2684354560

hbase.regionserver.majorcompaction.pagecache.drop
Description

Specifies whether to drop pages read/written into the system page cache by major compactions. Setting it to true helps prevent major compactions from polluting the page cache, which is almost always required, especially for clusters with low/moderate memory to storage ratio.

Default

true

hbase.regionserver.minorcompaction.pagecache.drop
Description

指定是否通过较小的压缩将读取/写入的页面丢弃到系统页面缓存中. 将其设置为true有助于防止较小的压缩污染页面缓存,这在内存与存储比率低或写入量很大的群集中最有用. 当大量读取都在最近写入的数据上时,您可能希望在中等到较低的写入工作量下将其设置为false.

Default

true

hbase.hstore.compaction.kv.max
Description

刷新或压缩时要批量读取和写入的KeyValue的最大数量. 如果您有较大的键值和内存不足异常问题,请将其设置为较低,如果行宽且较小的行,请将其设置为较高.

Default

10

hbase.storescanner.parallel.seek.enable
Description

在StoreScanner中启用StoreFileScanner并行查找功能,该功能可以减少特殊情况下的响应延迟.

Default

false

hbase.storescanner.parallel.seek.threads
Description

如果启用了并行查找功能,则为默认线程池大小.

Default

10

hfile.block.cache.size
Description

分配给StoreFile使用的块缓存的最大堆百分比(-Xmx设置). 默认值为0.4表示分配40%. 设置为0禁用,但不建议使用; 您至少需要足够的缓存来保存存储文件索引.

Default

0.4

hfile.block.index.cacheonwrite
Description

这允许在写入索引时将非根多级索引块放入块高速缓存中.

Default

false

hfile.index.block.max.size
Description

当多级块索引中的叶级,中间级或根级索引块的大小增长到该大小时,将写出该块并开始一个新块.

Default

131072

hbase.bucketcache.ioengine
Description

存储桶式缓存内容的位置. 其中之一:堆,文件,文件或mmap. 如果有一个或多个文件,请将其设置为file:PATH_TO_FILE. mmap表示内容将在mmaped文件中. 使用mmap:PATH_TO_FILE. 有关更多信息,请参见http://hbase.apache.org/book.html#offheap.blockcache .

Default

none

hbase.bucketcache.size
Description

EITHER表示要提供给缓存的堆总内存大小的百分比的浮点数(如果<1.0),或者,它是BucketCache的总容量(以兆字节为单位). 默认值:0.0

Default

none

hbase.bucketcache.bucket.sizes
Description

以逗号分隔的存储区的存储区大小列表. 可以是多种尺寸. 按从小到大的顺序列出块大小. 您使用的大小将取决于您的数据访问模式. 必须为256的倍数,否则当您从缓存中读取数据时,将遇到" java.io.IOException:无效的HFile块魔术". 如果在此处未指定任何值,则将选择代码中设置的默认存储桶大小(请参见BucketAllocator#DEFAULT_BUCKET_SIZES).

Default

none

hfile.format.version
Description

用于新文件的HFile格式版本. 第3版增加了对hfiles中标签的支持(请参阅http://hbase.apache.org/book.html#hbase.tags ). 另请参阅配置" hbase.replication.rpc.codec".

Default

3

hfile.block.bloom.cacheonwrite
Description

为复合Bloom筛选器的内联块启用写时缓存.

Default

false

io.storefile.bloom.block.size
Description

复合布隆过滤器的单个块("块")的大小(以字节为单位). 此大小是近似值,因为Bloom块只能插入数据块边界,并且每个数据块的键数有所不同.

Default

131072

hbase.rs.cacheblocksonwrite
Description

块完成后是否应将HFile块添加到块缓存中.

Default

false

hbase.rpc.timeout
Description

这是用于RPC层的,用于定义HBase客户端应用程序花费多长时间(毫秒)来进行远程调用以使超时. 它使用ping来检查连接,但最终将抛出TimeoutException.

Default

60000

hbase.client.operation.timeout
Description

操作超时是一个顶级限制(毫秒),可确保Table中的阻止操作不会超过此限制. 在每个操作中,如果rpc请求由于超时或其他原因而失败,它将重试直到成功或抛出RetriesExhaustedException. 但是,如果阻塞的总时间在重试用尽之前达到了操作超时,它将提前中断并抛出SocketTimeoutException.

Default

1200000

hbase.cells.scanned.per.heartbeat.check
Description

在两次心跳检查之间扫描的细胞数. 心跳检查在扫描处理期间进行,以确定服务器是否应该停止扫描以便将心跳消息发送回客户端. 心跳消息用于在长时间运行的扫描期间保持客户端-服务器连接保持活动状态. 较小的值表示心跳检查将更频繁地发生,因此将对扫描的执行时间提供更严格的限制. 较大的值表示心跳检查发生的频率较低

Default

10000

hbase.rpc.shortoperation.timeout
Description

这是" hbase.rpc.timeout"的另一个版本. 对于集群内的那些RPC操作,我们依靠此配置为短操作设置短超时限制. 例如,区域服务器尝试向活动主服务器报告的短rpc超时可以使主服务器故障转移过程更快.

Default

10000

hbase.ipc.client.tcpnodelay
Description

设置rpc套接字连接没有延迟. 参见http://docs.oracle.com/javase/1.5.0/docs/api/java/net/Socket.html#getTcpNoDelay(

Default

true

hbase.regionserver.hostname
Description

This config is for experts: don’t set its value unless you really know what you are doing. When set to a non-empty value, this represents the (external facing) hostname for the underlying server. See https://issues.apache.org/jira/browse/HBASE-12954 for details.

Default

none

hbase.regionserver.hostname.disable.master.reversedns
Description

此配置适用于专家:除非您真的知道自己在做什么,否则请不要设置其值. 设置为true时,regionserver将使用当前节点的主机名作为服务器名,HMaster将跳过反向DNS查找,而是使用regionserver发送的主机名. 请注意,此配置和hbase.regionserver.hostname是互斥的. 有关更多详细信息,请参见https://issues.apache.org/jira/browse/HBASE-18226 .

Default

false

hbase.master.keytab.file
Description

kerberos keytab文件的完整路径,用于登录已配置的HMaster服务器主体.

Default

none

hbase.master.kerberos.principal
Description

例如 " hbase/_HOST@EXAMPLE.COM". 用来运行HMaster进程的Kerberos主体名称. 主体名称应采用以下格式:user / hostname @ DOMAIN. 如果将" _HOST"用作主机名部分,它将被正在运行的实例的实际主机名替换.

Default

none

hbase.regionserver.keytab.file
Description

kerberos keytab文件的完整路径,用于登录配置的HRegionServer服务器主体.

Default

none

hbase.regionserver.kerberos.principal
Description

例如 " hbase/_HOST@EXAMPLE.COM". 用来运行HRegionServer进程的kerberos主体名称. 主体名称应采用以下格式:user / hostname @ DOMAIN. 如果将" _HOST"用作主机名部分,它将被正在运行的实例的实际主机名替换. 该主体的条目必须存在于hbase.regionserver.keytab.file中指定的文件中

Default

none

hadoop.policy.file
Description

RPC服务器用来对客户端请求做出授权决策的策略配置文件. 仅在启用HBase安全性时使用.

Default

hbase-policy.xml

hbase.superuser
Description

跨集群的用户或组(以逗号分隔)的列表,无论存储的ACL是什么,这些用户或组都被授予完全特权. 仅在启用HBase安全性时使用.

Default

none

hbase.auth.key.update.interval
Description

服务器中认证令牌的主密钥的更新间隔(以毫秒为单位). 仅在启用HBase安全性时使用.

Default

86400000

hbase.auth.token.max.lifetime
Description

认证令牌到期后的最大生命周期(以毫秒为单位). 仅在启用HBase安全性时使用.

Default

604800000

hbase.ipc.client.fallback-to-simple-auth-allowed
Description

当客户端配置为尝试安全连接,但尝试连接到不安全的服务器时,该服务器可能会指示客户端切换到SASL SIMPLE(不安全)身份验证. 此设置控制客户端是否将接受来自服务器的此指令. 如果为false(默认值),则客户端将不允许回退到SIMPLE身份验证,并将中止连接.

Default

false

hbase.ipc.server.fallback-to-simple-auth-allowed
Description

当服务器配置为需要安全连接时,它将使用SASL SIMPLE(不安全)身份验证拒绝来自客户端的连接尝试. 此设置允许安全服务器在客户端请求时接受来自客户端的SASL SIMPLE连接. 如果为false(默认值),则服务器将不允许回退到SIMPLE身份验证,并且将拒绝连接. 警告:在将客户端转换为安全身份验证时,仅应将此设置用作临时措施. 为了安全操作,必须将其禁用.

Default

false

hbase.display.keys
Description

如果将其设置为true,则webUI会显示所有开始/结束键,作为表详细信息,区域名称等的一部分.如果将其设置为false,则键将被隐藏.

Default

true

hbase.coprocessor.enabled
Description

启用或禁用协处理器加载. 如果为" false"(禁用),则将忽略任何其他与协处理器相关的配置.

Default

true

hbase.coprocessor.user.enabled
Description

启用或禁用用户(aka表)协处理器加载. 如果为" false"(禁用),则将忽略表描述符中的任何表协处理器属性. 如果" hbase.coprocessor.enabled"为" false",则此设置无效.

Default

true

hbase.coprocessor.region.classes
Description

默认情况下,在所有表上加载的逗号分隔的协处理器列表. 对于任何覆盖协处理器方法,将按顺序调用这些类. 在实现自己的协处理器之后,只需将其放在HBase的类路径中,然后在此处添加完全限定的类名. 也可以通过设置HTableDescriptor来按需加载协处理器.

Default

none

hbase.coprocessor.master.classes
Description

逗号分隔的org.apache.hadoop.hbase.coprocessor.MasterObserver协处理器列表,默认情况下在活动HMaster进程中加载​​. 对于任何已实现的协处理器方法,将按顺序调用列出的类. 在实现自己的MasterObserver之后,只需将其放入HBase的类路径中,然后在此处添加完全限定的类名.

Default

none

hbase.coprocessor.abortonerror
Description

设置为true会导致在协处理器无法加载,初始化失败或引发意外的Throwable对象时导致托管服务器(主服务器或区域服务器)中止. 将其设置为false将允许服务器继续执行,但是相关协处理器的系统范围状态将变得不一致,因为它将仅在一部分服务器中正确执行,因此这仅对调试最有用.

Default

true

hbase.rest.port
Description

HBase REST服务器的端口.

Default

8080

hbase.rest.readonly
Description

定义启动REST服务器的模式.可能的值是:false:允许所有HTTP方法-GET / PUT / POST / DELETE. true:仅允许GET方法.

Default

false

hbase.rest.threads.max
Description

REST服务器线程池的最大线程数. 池中的线程被重用以处理REST请求. 这控制了并发处理的最大请求数. 这可能有助于控制REST服务器使用的内存,以避免OOM问题. 如果线程池已满,则传入的请求将排队,并等待一些空闲线程.

Default

100

hbase.rest.threads.min
Description

REST服务器线程池的最小线程数. 线程池始终至少具有这些线程数,因此REST服务器已准备就绪,可以处理传入的请求.

Default

2

hbase.rest.support.proxyuser
Description

允许运行REST服务器以支持代理用户模式.

Default

false

hbase.defaults.for.version.skip
Description

设置为true可跳过" hbase.defaults.for.version"检查. 将其设置为true可能在Maven生成的另一端以外的环境中有用. 即在IDE中运行. 您需要将此布尔值设置为true,以避免看到RuntimeException投诉:" hbase-default.xml文件似乎适用于旧版本的HBase(\ $ {hbase.version}),此版本为XXX-SNAPSHOT"

Default

false

hbase.table.lock.enable
Description

设置为true以启用将锁锁定在zookeeper中以进行模式更改操作. 来自主服务器的表锁定可防止将并行模式修改为损坏的表状态.

Default

true

hbase.table.max.rowsize
Description

未设置行内扫描标志的"获取"或"扫描"单行的最大大小(以字节为单位)(默认为1 Gb). 如果行大小超出此限制,则将RowTooBigException抛出给客户端.

Default

1073741824

hbase.thrift.minWorkerThreads
Description

线程池的"核心大小". 在每个连接上都会创建新线程,直到创建了这么多线程.

Default

16

hbase.thrift.maxWorkerThreads
Description

线程池的最大大小. 当挂起的请求队列溢出时,将创建新线程,直到它们的数量达到该数量为止. 此后,服务器开始断开连接.

Default

1000

hbase.thrift.maxQueuedRequests
Description

队列中正在等待的未决Thrift连接的最大数量. 如果池中没有空闲线程,则服务器会将请求排队. 仅当队列溢出时,才添加新线程,直到hbase.thrift.maxQueuedRequests线程.

Default

1000

hbase.regionserver.thrift.framed
Description

在服务器端使用Thrift TFramedTransport. 对于节俭服务器,这是建议的传输方式,并且在客户端需要类似的设置. 将其更改为false将选择默认传输方式,当由于THRIFT-601发出格式错误的请求时,该传输方式容易受到DoS攻击.

Default

false

hbase.regionserver.thrift.framed.max_frame_size_in_mb
Description

使用成帧传输时的默认帧大小,以MB为单位

Default

2

hbase.regionserver.thrift.compact
Description

使用Thrift TCompactProtocol二进制序列化协议.

Default

false

hbase.rootdir.perms
Description

安全(kerberos)设置中根数据子目录的FS权限. 当master启动时,它将使用此权限创建rootdir或在权限不匹配时设置权限.

Default

700

hbase.wal.dir.perms
Description

安全(kerberos)设置中的根WAL目录的FS权限. 当master启动时,它将使用此权限创建WAL目录,或者在不匹配时设置权限.

Default

700

hbase.data.umask.enable
Description

启用(如果为true),应将文件权限分配给由regionserver写入的文件

Default

false

hbase.data.umask
Description

hbase.data.umask.enable为true时应用于写入数据文件的文件权限

Default

000

hbase.snapshot.enabled
Description

设置为true以允许拍摄/还原/克隆快照.

Default

true

hbase.snapshot.restore.take.failsafe.snapshot
Description

设置为true以在还原操作之前进行快照. 如果发生故障,将使用拍摄的快照来还原以前的状态. 在还原操作结束时,此快照将被删除

Default

true

hbase.snapshot.restore.failsafe.name
Description

还原操作获取的故障安全快照的名称. 您可以使用{snapshot.name},{table.name}和{restore.timestamp}变量根据要还原的内容创建名称.

Default

hbase-failsafe-{snapshot.name}-{restore.timestamp}

hbase.server.compactchecker.interval.multiplier
Description

该数字确定我们进行扫描以查看是否有必要进行压缩的频率. 通常,压缩是在某些事件(例如memstore刷新)之后完成的,但是如果区域一段时间未收到大量写入,或者由于不同的压缩策略,则可能有必要定期对其进行检查. 检查之间的间隔是hbase.server.compactchecker.interval.multiplier乘以hbase.server.thread.wakefrequency.

Default

1000

hbase.lease.recovery.timeout
Description

在放弃之前,我们等待dfs租赁恢复的总时间为多长时间.

Default

900000

hbase.lease.recovery.dfs.timeout
Description

dfs之间恢复租约调用的时间. 应该大于namenode作为datanode的一部分发出块恢复命令所花费的时间的总和; dfs.heartbeat.interval以及主数据节点所花费的时间,在死数据节点上执行块恢复到超时; 通常是dfs.client.socket-timeout. 有关更多信息,请参见HBASE-8389的末尾.

Default

64000

hbase.column.max.version
Description

新的列族描述符将使用此值作为要保留的默认版本数.

Default

1

dfs.client.read.shortcircuit
Description

如果设置为true,则此配置参数启用短路本地读取.

Default

false

dfs.domain.socket.path
Description

如果dfs.client.read.shortcircuit设置为true,这是UNIX域套接字的路径,该套接字将用于DataNode与本地HDFS客户端之间的通信. 如果此路径中存在字符串" _PORT",它将被DataNode的TCP端口替换. 请注意托管共享域套接字的目录的权限; dfsclient将向HBase用户以外的其他用户开放.

Default

none

hbase.dfs.client.read.shortcircuit.buffer.size
Description

如果未设置DFSClient配置dfs.client.read.shortcircuit.buffer.size,我们将使用此处配置的短路读取默认直接字节缓冲区大小. DFSClient本机默认值为1MB;默认值为1MB. HBase保持其HDFS文件处于打开状态,因此文件块数* 1MB很快就开始增加,并由于直接内存不足而威胁了OOME. 因此,我们将其设置为默认值. 使其>在HColumnDescriptor中设置的默认hbase块大小,通常为64k.

Default

131072

hbase.regionserver.checksum.verify
Description

如果设置为true(默认值),则HBase会验证hfile块的校验和. HBase在写出hfile时,将校验和与数据内联. HDFS(在撰写本文时)将校验和写入数据文件之外的单独文件,这需要额外的查找. 设置该标志可节省一些I / O. 设置此标志时,将在hfile流上内部禁用HDFS的校验和验证. 如果hbase-checksum验证失败,我们将切换回使用HDFS校验和(因此请不要禁用HDFS校验和!此外,此功能仅适用于hfile,不适用于WAL). 如果将此参数设置为false,则hbase将不会验证任何校验和,而是取决于HDFS客户端中进行的校验和验证.

Default

true

hbase.hstore.bytes.per.checksum
Description

hfile块中HBase级别校验和的新创建校验和块中的字节数.

Default

16384

hbase.hstore.checksum.algorithm
Description

用于计算校验和的算法的名称. 可能的值为NULL,CRC32,CRC32C.

Default

CRC32C

hbase.client.scanner.max.result.size
Description

调用扫描仪的下一个方法时返回的最大字节数. 请注意,当单行大于此限制时,该行仍将完全返回. 默认值为2MB,适合1ge网络. 对于更快和/或更高延迟的网络,此值应增加.

Default

2097152

hbase.server.scanner.max.result.size
Description

调用扫描仪的下一个方法时返回的最大字节数. 请注意,当单行大于此限制时,该行仍将完全返回. 默认值为100MB. 这是一项安全设置,可以保护服务器免受OOM情况的影响.

Default

104857600

hbase.status.published
Description

此设置激活主服务器发布区域服务器状态. 当区域服务器停止运行并开始恢复时,主服务器会将此信息推送到客户端应用程序,以使它们立即断开连接,而不必等待超时.

Default

false

hbase.status.publisher.class
Description

使用多播消息实现状态发布.

Default

org.apache.hadoop.hbase.master.ClusterStatusPublisher$MulticastPublisher

hbase.status.listener.class
Description

使用多播消息实现状态侦听器.

Default

org.apache.hadoop.hbase.client.ClusterStatusListener$MulticastListener

hbase.status.multicast.address.ip
Description

用于通过多播发布状态的多播地址.

Default

226.1.1.3

hbase.status.multicast.address.port
Description

组播端口,用于通过组播发布状态.

Default

16100

hbase.dynamic.jars.dir
Description

区域服务器无需重新启动即可从其动态加载自定义过滤器JAR的目录. 但是,已经加载的过滤器/协处理器类不会被卸载. 有关更多详细信息,请参见HBASE-1936. 不适用于协处理器.

Default

${hbase.rootdir}/lib

hbase.security.authentication
Description

控制是否为HBase启用安全身份验证. 可能的值为"简单"(不进行身份验证)和" kerberos".

Default

simple

hbase.rest.filter.classes
Description

REST服务的Servlet过滤器.

Default

org.apache.hadoop.hbase.rest.filter.GzipFilter

hbase.master.loadbalancer.class
Description

在周期发生时用于执行区域平衡的类. 有关其工作原理的更多信息,请参见类注释.http://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/master/balancer/StochasticLoadBalancer.html它将DefaultLoadBalancer替换为默认值(因为重命名为SimpleLoadBalancer ).

Default

org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer

hbase.master.loadbalance.bytable
Description

平衡器运行时的因子表名称. 默认值:false.

Default

false

hbase.master.normalizer.class
Description

发生周期时用于执行区域规范化的类. 有关其工作原理的更多信息,请参见类注释.http://hbase.apache.org/devapidocs/org/apache/hadoop/hbase/master/normalizer/SimpleRegionNormalizer.html

Default

org.apache.hadoop.hbase.master.normalizer.SimpleRegionNormalizer

hbase.rest.csrf.enabled
Description

设置为true以启用针对跨站点请求伪造(CSRF)的保护

Default

false

hbase.rest-csrf.browser-useragents-regex
Description

通过将hbase.rest.csrf.enabled设置为true为REST服务器启用跨站点请求伪造(CSRF)保护时,用逗号分隔的正则表达式列表,用于与HTTP请求的User-Agent标头匹配. 如果传入的User-Agent与这些正则表达式中的任何一个匹配,则认为该请求是由浏览器发送的,因此强制执行CSRF预防. 如果请求的User-Agent与这些正则表达式都不匹配,则认为该请求是由浏览器以外的其他设备(例如脚本自动化)发送的. 在这种情况下,CSRF并不是潜在的攻击媒介,因此无法执行预防措施. 这有助于实现与尚未更新为发送CSRF预防标头的现有自动化的向后兼容性.

Default

Mozilla.,Opera.

hbase.security.exec.permission.checks
Description

如果启用此设置并且基于ACL的访问控制处于活动状态(AccessController协处理器作为系统协处理器或作为表协处理器安装在表上),那么如果所有相关用户需要执行协处理器终结点的能力,则必须授予他们所有EXEC特权电话. 像任何其他权限一样,EXEC特权可以全局授予用户,也可以基于每个表或每个命名空间授予用户. 有关协处理器端点的更多信息,请参见HBase在线手册的协处理器部分. 有关使用AccessController授予或撤消权限的更多信息,请参见HBase在线手册的安全性部分.

Default

false

hbase.procedure.regionserver.classes
Description

逗号分隔的org.apache.hadoop.hbase.procedure.RegionServerProcedureManager过程管理器列表,默认情况下在活动HRegionServer进程中加载​​. 生命周期方法(init / start / stop)将由活动的HRegionServer进程调用以执行特定的全局受阻过程​​. 在实现自己的RegionServerProcedureManager之后,只需将其放在HBase的类路径中,然后在此处添加完全限定的类名即可.

Default

none

hbase.procedure.master.classes
Description

逗号分隔的org.apache.hadoop.hbase.procedure.MasterProcedureManager过程管理器列表,默认情况下在活动HMaster进程上加载. 过程由其签名标识,用户可以使用签名和即时名称来触发全局障碍过程的执行. 在实现自己的MasterProcedureManager之后,只需将其放在HBase的类路径中,然后在此处添加完全限定的类名即可.

Default

none

hbase.coordinated.state.manager.class
Description

实现协调状态管理器的类的全限定名称.

Default

org.apache.hadoop.hbase.coordination.ZkCoordinatedStateManager

hbase.regionserver.storefile.refresh.period
Description

刷新辅助区域的存储文件的时间段(以毫秒为单位). 0表示此功能被禁用. 一旦二级区域刷新了该区域中的文件列表(没有通知机制),二级区域就会从主区域看到新文件(通过刷新和压缩). 但是过于频繁的刷新可能会导致额外的Namenode压力. 如果文件刷新的时间不能超过HFile TTL(hbase.master.hfilecleaner.ttl),则拒绝请求. 还建议通过此设置将HFile TTL配置为更大的值.

Default

0

hbase.region.replica.replication.enabled
Description

是否启用了到辅助区域副本的异步WAL复制. 如果启用此功能,将创建一个名为" region_replica_replication"的复制对等方,它将复制日志尾部并将突变复制到区域复制> 1的表的区域副本中.如果启用一次,则禁用此复制还需要禁用复制使用Shell或Admin java类的对等体. 到辅助区域副本的复制通过标准的群集间复制进行.

Default

false

hbase.http.filter.initializers
Description

用逗号分隔的类名称列表. 列表中的每个类都必须扩展org.apache.hadoop.hbase.http.FilterInitializer. 相应的过滤器将被初始化. 然后,该筛选器将应用于所有面向用户的jsp和servlet网页. 列表的顺序定义了过滤器的顺序. 默认的StaticUserWebFilter添加一个由hbase.http.staticuser.user属性定义的用户主体.

Default

org.apache.hadoop.hbase.http.lib.StaticUserWebFilter

hbase.security.visibility.mutations.checkauths
Description

如果启用此属性,将检查可见性表达式中的标签是否与发出突变的用户相关联

Default

false

hbase.http.max.threads
Description

HTTP Server将在其ThreadPool中创建的最大线程数.

Default

16

hbase.replication.rpc.codec
Description

启用复制时要使用的编解码器,以便也复制标签. 与HFileV3一起使用,后者支持其中的标签. 如果未使用标签,或者使用的hfile版本为HFileV2,则可以将KeyValueCodec用作复制编解码器. 请注意,在没有标签的情况下使用KeyValueCodecWithTags进行复制不会造成任何危害.

Default

org.apache.hadoop.hbase.codec.KeyValueCodecWithTags

hbase.replication.source.maxthreads
Description

任何复制源用于将编辑并行传送到接收器的最大线程数. 这也限制了每个复制批处理分成的块数. 较大的值可以提高主群集和从群集之间的复制吞吐量. 默认值10几乎不需要更改.

Default

10

hbase.http.staticuser.user
Description

呈现内容时在静态Web筛选器上作为筛选条件的用户名. HDFS Web UI(用于浏览文件的用户)是一个示例用法.

Default

dr.stack

hbase.regionserver.handler.abort.on.error.percent
Description

区域服务器RPC线程无法中止RS的百分比. -1禁用中止; 0即使有一个处理程序死亡,也中止; 0.x仅在此百分比的处理程序已死亡时才中止; 1只有中止所有处理程序的人都死了.

Default

0.5

hbase.mob.file.cache.size
Description

要缓存的已打开文件处理程序的数量. 更大的值将为每个mob文件缓存提供更多的文件处理程序,从而有利于读取,并减少频繁的文件打开和关闭操作. 但是,如果将其设置得太高,则可能导致"打开的文件处理程序太多".默认值为1000.

Default

1000

hbase.mob.cache.evict.period
Description

暴民缓存逐出已缓存的暴徒文件之前的时间(以秒为单位). 默认值为3600秒.

Default

3600

hbase.mob.cache.evict.remain.ratio
Description

当缓存的mob文件的数量超过hbase.mob.file.cache.size时,将触发逐出后保留的缓存文件的比率(介于0.0和1.0之间). 默认值为0.5f.

Default

0.5f

hbase.master.mob.ttl.cleaner.period
Description

ExpiredMobFileCleanerChore运行的周期. 单位是第二. 默认值为一天. MOB文件名仅使用其中文件创建时间的日期部分. 我们用这段时间来确定文件的TTL到期时间. 因此,TTL过期文件的删除可能会延迟. 最大延迟可能是24小时.

Default

86400

hbase.mob.compaction.mergeable.threshold
Description

如果mob文件的大小小于此值,则将其视为小文件,需要在mob压缩中合并. 默认值为1280MB.

Default

1342177280

hbase.mob.delfile.max.count
Description

mob压缩中允许的最大del文件数. 在mob压缩中,当现有del文件的数量大于此值时,它们将合并,直到del文件的数量不大于该值. 预设值为3.

Default

3

hbase.mob.compaction.batch.size
Description

一批mob压缩中允许的mob文件的最大数量. 暴民压缩将小暴民文件合并为大暴民文件. 如果小文件的数量很大,则合并中可能会导致"打开的文件处理程序过多". 合并必须分为几批. 此值限制在一批mob压缩中选择的mob文件的数量. 默认值为100.

Default

100

hbase.mob.compaction.chore.period
Description

MobCompactionChore运行的时间. 单位是第二. 默认值为一周.

Default

604800

hbase.mob.compactor.class
Description

实现mob压缩器,默认之一是PartitionedMobCompactor.

Default

org.apache.hadoop.hbase.mob.compactions.PartitionedMobCompactor

hbase.mob.compaction.threads.max
Description

MobCompactor中使用的最大线程数.

Default

1

hbase.snapshot.master.timeout.millis
Description

Timeout for master for the snapshot procedure execution.

Default

300000

hbase.snapshot.region.timeout
Description

区域服务器将线程保持在快照请求池中的等待时间.

Default

300000

hbase.rpc.rows.warning.threshold
Description

批处理操作中的行数,超过此行将记录警告.

Default

5000

hbase.master.wait.on.service.seconds
Description

默认值为5分钟. 进行30秒的测试. 有关某些上下文,请参见HBASE-19794.

Default

30

7.3. hbase-env.sh

在此文件中设置HBase环境变量. 示例包括在HBase守护程序启动时传递JVM的选项,例如堆大小和垃圾收集器配置. 您还可以为HBase配置,日志目录,niceness,ssh选项,进程pid文件的放置位置等设置配置.在conf / hbase-env.sh中打开文件并仔细阅读其内容. 每个选项都有充分的文档记录. 如果希望在启动时由HBase守护程序读取它们,请在此处添加您自己的环境变量.

此处的更改将要求群集重新启动,以便HBase注意到更改.

7.4. log4j.properties

编辑此文件以更改HBase文件的滚动速率并更改HBase记录消息的级别.

尽管可以通过HBase UI更改特定守护程序的日志级别,但此处的更改将要求HBase重新启动集群以注意到更改.

7.5. Client configuration and dependencies connecting to an HBase cluster

如果您以独立模式运行HBase,则无需配置任何配置即可让客户端正常工作,前提是它们都在同一台计算机上.

由于HBase主服务器可能会四处移动,因此客户端可以通过向ZooKeeper查找当前的关键位置来进行引导. ZooKeeper是保留所有这些值的位置. 因此,客户在执行其他任何操作之前,需要先确定ZooKeeper合奏的位置. 通常,此集合位置保留在hbase-site.xml中 ,并由客户端从CLASSPATH拾取.

如果正在配置要运行HBase客户端的IDE,则应在类路径中包含conf /目录,以便可以找到hbase-site.xml设置(或添加src / test / resources来选择使用的hbase-site.xml通过测试).

对于使用Maven的Java应用程序,建议在连接到集群时包括hbase-shaded-client模块依赖项:

<dependency>
  <groupId>org.apache.hbase</groupId>
  <artifactId>hbase-shaded-client</artifactId>
  <version>2.0.0</version>
</dependency>

仅用于客户端的基本示例hbase-site.xml可能如下所示:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>example1,example2,example3</value>
    <description>The directory shared by region servers.
    </description>
  </property>
</configuration>

7.5.1. Java client configuration

Java客户端使用的配置保留在HBaseConfiguration实例中.

HBaseConfiguration的工厂方法, HBaseConfiguration.create(); 调用时,将读取在客户端的CLASSPATH上找到的第一个hbase-site.xml的内容(如果存在)(调用还将考虑找到的任何hbase-default.xmlhbase-default.xml随附在hbase.XXXjar ). 还可以直接指定配置,而不必从hbase-site.xml中读取. 例如,以编程方式为集群设置ZooKeeper集成,请执行以下操作:

Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "localhost");  // Here we are running zookeeper locally

如果多个ZooKeeper实例组成了ZooKeeper集合,则可以在用逗号分隔的列表中指定它们(就像在hbase-site.xml文件中一样). 然后可以将此填充的Configuration实例传递给Table ,依此类推.

7.6. Timeout settings

HBase提供了各种超时设置,以限制各种远程操作的执行时间.

  • hbase.rpc.timeout

  • hbase.rpc.read.timeout

  • hbase.rpc.write.timeout

  • hbase.client.operation.timeout

  • hbase.client.meta.operation.timeout

  • hbase.client.scanner.timeout.period

hbase.rpc.timeout属性限制了单个RPC调用在超时之前可以运行多长时间. 要微调与读取或写入相关的RPC超时,请设置hbase.rpc.read.timeouthbase.rpc.write.timeout配置属性. 如果没有这些属性,将使用hbase.rpc.timeout .

较高级别的超时是hbase.client.operation.timeout ,它对于每个客户端调用均有效. 例如,由于hbase.rpc.timeout而导致RPC调用因超时而hbase.rpc.timeout ,它将重试,直到达到hbase.client.operation.timeout . 可以通过设置hbase.client.meta.operation.timeout配置值来微调系统表的客户端操作超时. 如果未设置,则使用hbase.client.operation.timeout .

Timeout for scan operations is controlled differently. Use hbase.client.scanner.timeout.period property to set this timeout.

8. Example Configurations

8.1. Basic Distributed HBase Install

这是分布式十节点群集的基本配置示例:*在此示例中,节点通过节点example9命名为example0example1等. * HBase主站和HDFS NameNode在节点example0上运行. * RegionServers在节点example1 - example9上运行. * 3节点ZooKeeper集合在默认端口上的example1example2example3上运行. * ZooKeeper数据保留在目录/ export / zookeeper中 .

下面,我们显示在HBase conf目录中找到的主要配置文件-hbase-site.xmlregionservershbase-env.sh .

8.1.1. hbase-site.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>example1,example2,example3</value>
    <description>The directory shared by RegionServers.
    </description>
  </property>
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/export/zookeeper</value>
    <description>Property from ZooKeeper config zoo.cfg.
    The directory where the snapshot is stored.
    </description>
  </property>
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://example0:8020/hbase</value>
    <description>The directory shared by RegionServers.
    </description>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
    <description>The mode the cluster will be in. Possible values are
      false: standalone and pseudo-distributed setups with managed ZooKeeper
      true: fully-distributed with unmanaged ZooKeeper Quorum (see hbase-env.sh)
    </description>
  </property>
</configuration>

8.1.2. regionservers

在此文件中,您将列出将运行RegionServers的节点. 在我们的例子中,这些节点是example1 - example9 .

example1
example2
example3
example4
example5
example6
example7
example8
example9

8.1.3. hbase-env.sh

hbase-env.sh文件中的以下几行显示了如何设置JAVA_HOME环境变量(HBase必需)以及如何将堆设置为4 GB(而不是默认值1 GB). 如果复制并粘贴此示例,请确保调整JAVA_HOME以适合您的环境.

# The java implementation to use.
export JAVA_HOME=/usr/java/jdk1.8.0/

# The maximum amount of heap to use. Default is left to JVM default.
export HBASE_HEAPSIZE=4G

使用rsync将conf目录的内容复制到群集的所有节点.

9. The Important Configurations

下面我们列出了一些重要的配置. 我们将本节分为所需的配置和值得一看的推荐配置.

9.1. Required Configurations

查看oshadoop部分.

9.1.1. Big Cluster Configurations

如果您的群集具有很多区域,则在主服务器启动后,Regionserver可能会短暂签入,而所有其他RegionServer都将滞后. 该第一台要签入的服务器将被分配所有非最佳区域. 为防止发生上述情况,请将hbase.master.wait.on.regionservers.mintostart属性从其默认值1开始.请参见HBASE-6389修改条件,以确保主服务器在启动区域之前等待足够数量的Region Server.作业以获取更多详细信息.

zookeeper.session.timeout

默认超时为90秒(以毫秒为单位). 这意味着如果服务器崩溃,则要在主服务器注意到崩溃并开始恢复之前的90秒. 您可能需要将超时调整为一分钟或更短,以便主服务器可以更快地注意到故障. 在更改此值之前,请确保已控制JVM垃圾收集配置,否则,持续超过ZooKeeper会话超时的长时间垃圾收集将占用RegionServer. (这样做可能很好-如果RegionServer长时间处于GC中,您可能希望在服务器上开始恢复).

要更改此配置,请编辑hbase-site.xml ,在群集中复制更改的文件,然后重新启动.

我们将此值设置得很高,以免我们不得不在邮件列表中提出问题,询问在大规模导入期间RegionServer为什么停机. 通常的原因是未调整其JVM,并且它们正在运行很长时间的GC暂停. 我们的想法是,当用户熟悉HBase时,我们不必为他们省去了解其所有复杂性. 之后,当他们建立起一定的信心时,他们便可以使用这样的配置.

Number of ZooKeeper Instances

See zookeeper.

9.2.2. HDFS Configurations

dfs.datanode.failed.volumes.tolerated

这是hdfs-default.xml描述中的`` ...在DataNode停止提供服务之前允许失败的卷数.默认情况下,任何卷故障都会导致数据节点关闭''. 您可能希望将其设置为可用磁盘数量的一半.

hbase.regionserver.handler.count

此设置定义保持打开状态以响应对用户表的传入请求的线程数. 经验法则是,当每个请求的有效负载接近MB时(大放置,使用大缓存进行扫描),此数字应保持较低;当有效负载较小(获取,小放置,ICV,删除)时,请保持较高的数字. 正在进行的查询的总大小受设置hbase.ipc.server.max.callqueue.size限制.

如果他们的有效负载很小,则可以安全地将该数目设置为最大数量的传入客户端,典型示例是为网站提供服务的集群,因为通常不对put进行缓冲,并且大多数操作都可以得到.

将该设置保持在较高状态是危险的,原因是区域服务器中当前正在发生的所有put的总大小可能会对其内存施加过多压力,甚至触发OutOfMemoryError. 在内存不足的情况下运行的RegionServer会触发其JVM的垃圾收集器更频繁地运行,直到达到明显的GC暂停为止(原因是,用于保留所有请求有效负载的所有内存都不能被废弃,垃圾收集器尝试). 一段时间后,整个群集吞吐量会受到影响,因为命中该RegionServer的每个请求都将花费更长的时间,从而使问题更加严重.

通过在单个RegionServer上rpc.logging然后拖尾其日志(排队的请求会消耗内存),您可以了解您是否拥有过多的处理程序.

9.2.3. Configuration for large memory machines

HBase带有合理,保守的配置,几乎可以在人们可能要测试的所有计算机类型上使用. 如果您拥有更大的计算机(HBase具有8G和更大的堆),那么以下配置选项可能会有所帮助. 去做.

9.2.4. Compression

您应该考虑启用ColumnFamily压缩. 有几个选项几乎是无摩擦的,在大多数情况下,它们通过减小StoreFiles的大小从而减少I / O来提高性能.

有关更多信息,请参见压缩 .

9.2.5. Configuring the size and number of WAL files

如果RS发生故障,HBase使用wal恢复尚未刷新到磁盘的内存存储数据. 这些WAL文件应配置为略小于HDFS块(默认情况下,HDFS块为64Mb,WAL文件为〜60Mb).

HBase对WAL文件的数量也有限制,旨在确保在恢复过程中永远不会重放过多的数据. 需要根据memstore配置设置此限制,以便所有必需的数据都适合. 建议分配足够的WAL文件以至少存储那么多的数据(当所有内存存储都快用完时). 例如,对于16Gb RS堆,默认内存存储设置(0.4)和默认WAL文件大小(〜60Mb),16Gb * 0.4 / 60,WAL文件计数的起点是〜109. 但是,由于并非所有存储器都一直都在装满,因此可以分配较少的WAL文件.

9.2.6. Managed Splitting

HBase通常根据hbase-default.xmlhbase-site.xml配置文件中的设置来处理区域划分 . 重要设置包括hbase.regionserver.region.split.policyhbase.hregion.max.filesizehbase.regionserver.regionSplitLimit . 拆分的一种简化视图是,当区域增长到hbase.hregion.max.filesize ,将对其进行拆分. 对于大多数使用模式,应使用自动拆分. 有关手动区域分割的更多信息,请参见手动区域分割决策 .

您可以选择自己管理拆分,而不是让HBase自动拆分区域. 如果您非常了解密钥空间,则可以手动管理拆分,否则让HBase为您确定拆分位置. 手动拆分可以减轻区域创建和负载下的移动. 它还使区域边界是已知且不变的(如果禁用区域分割). 如果使用手动拆分,则进行基于时间的交错压缩会更容易分散您的网络IO负载.

禁用自动拆分

要禁用自动拆分,您可以在群集配置或表配置中将区域拆分策略设置为org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy

推荐自动分割

如果禁用自动拆分以诊断问题或在数据快速增长期间,建议在情况变得更稳定时重新启用它们. 管理区域分裂自己的潜在好处并非没有争议.

确定预分割区域的最佳数量

The optimal number of pre-split regions depends on your application and environment. A good rule of thumb is to start with 10 pre-split regions per server and watch as data grows over time. It is better to err on the side of too few regions and perform rolling splits later. The optimal number of regions depends upon the largest StoreFile in your region. The size of the largest StoreFile will increase with time if the amount of data grows. The goal is for the largest region to be just large enough that the compaction selection algorithm only compacts it during a timed major compaction. Otherwise, the cluster can be prone to compaction storms with a large number of regions under compaction at the same time. It is important to understand that the data growth causes compaction storms and not the manual split decision.

如果将区域分成太多大区域,则可以通过配置HConstants.MAJOR_COMPACTION_PERIOD来增加主要压缩间隔. org.apache.hadoop.hbase.util.RegionSplitter实用程序还提供所有区域的网络IO安全滚动拆分.

9.2.7. Managed Compactions

默认情况下,大型压缩计划为每7天运行一次.

如果您需要精确控制大型压缩的时间和频率,可以禁用托管大型压缩. 有关详细信息,请参见compaction.parameters表中的hbase.hregion.majorcompaction条目.

不要禁用重大压实

对于StoreFile清理,绝对必需进行大压缩. 请勿完全禁用它们. 您可以通过HBase Shell或Admin API手动运行主要压缩.

有关压缩和压缩文件选择过程的更多信息,请参见压缩.

9.2.8. Speculative Execution

默认情况下,MapReduce任务的推测执行是打开的,对于HBase群集,通常建议在系统级关闭推测执行,除非在特定情况下需要它,可以在每个作业中对其进行配置. 将属性mapreduce.map.speculativemapreduce.reduce.speculative为false.

9.3. Other Configurations

9.3.1. Balancer

平衡器是一种定期操作,在主服务器上运行,以重新分配群集上的区域. 它是通过hbase.balancer.period配置的,默认值为300000(5分钟).

有关LoadBalancer的更多信息,请参见master.processes.loadbalancer .

9.3.2. Disabling Blockcache

不要关闭块缓存(您可以通过将hfile.block.cache.size设置hfile.block.cache.size来实现). 目前,如果您这样做的话,我们做得并不好,因为RegionServer将花费所有的时间来一次又一次地加载HFile索引. 如果您的工作组对块缓存不利,请至少调整块缓存的大小,以使HFile索引保留在缓存中(您可以通过调查RegionServer UI来大致了解所需的大小;您将请参阅网页顶部附近的索引块大小).

9.3.3. Nagle’s or the small package problem

如果在针对HBase的操作中偶尔出现40ms左右的延迟,请尝试Nagles的设置. 例如,请参阅用户邮件列表线程," 将缓存设置为1的不一致的扫描性能"和其中引用的问题,其中设置notcpdelay提高扫描速度. 您可能还会在HBASE-7008的尾部看到这些图, 将扫描仪缓存设置为更好的默认值 ,其中我们的Lars Hofhansl尝试打开和关闭Nagle来测量效果的各种数据大小.

9.3.4. Better Mean Time to Recover (MTTR)

本节介绍的配置将使服务器在出现故障后更快地恢复. 有关简要介绍,请参见Deveraj Das和Nicolas Liochon博客文章HBase简介平均恢复时间(MTTR) .

HBASE-8354强制Namenode进入具有租约恢复请求的循环的过程很麻烦,但是在低超时以及如何导致更快的恢复(包括引用添加到HDFS的修复程序)的末尾有很多很好的讨论. 阅读Varun Sharma的评论. 以下建议的配置是Varun的建议经过提炼和测试的. 确保您在最新版本的HDFS上运行,因此您具有他所引用的修复程序,并且自己添加了可帮助HBase MTTR的HDFS(例如HDFS-3703,HDFS-3712和HDFS-4791-Hadoop 2肯定具有它们以及Hadoop 1后期有一些). 在RegionServer中设置以下内容.

<property>
  <name>hbase.lease.recovery.dfs.timeout</name>
  <value>23000</value>
  <description>How much time we allow elapse between calls to recover lease.
  Should be larger than the dfs timeout.</description>
</property>
<property>
  <name>dfs.client.socket-timeout</name>
  <value>10000</value>
  <description>Down the DFS timeout from 60 to 10 seconds.</description>
</property>

在NameNode / DataNode端,设置以下内容以启用HDFS-3703,HDFS-3912中引入的"陈旧性".

<property>
  <name>dfs.client.socket-timeout</name>
  <value>10000</value>
  <description>Down the DFS timeout from 60 to 10 seconds.</description>
</property>
<property>
  <name>dfs.datanode.socket.write.timeout</name>
  <value>10000</value>
  <description>Down the DFS timeout from 8 * 60 to 10 seconds.</description>
</property>
<property>
  <name>ipc.client.connect.timeout</name>
  <value>3000</value>
  <description>Down from 60 seconds to 3.</description>
</property>
<property>
  <name>ipc.client.connect.max.retries.on.timeouts</name>
  <value>2</value>
  <description>Down from 45 seconds to 3 (2 == 3 retries).</description>
</property>
<property>
  <name>dfs.namenode.avoid.read.stale.datanode</name>
  <value>true</value>
  <description>Enable stale state in hdfs</description>
</property>
<property>
  <name>dfs.namenode.stale.datanode.interval</name>
  <value>20000</value>
  <description>Down from default 30 seconds</description>
</property>
<property>
  <name>dfs.namenode.avoid.write.stale.datanode</name>
  <value>true</value>
  <description>Enable stale state in hdfs</description>
</property>

9.3.5. JMX

JMX(Java管理扩展)提供了内置的工具,使您可以监视和管理Java VM. 要从远程系统启用监视和管理,在启动Java VM时,需要设置系统属性com.sun.management.jmxremote.port (要启用JMX RMI连接的端口号). 有关更多信息,请参见官方文档 . 从历史上看,除了上述端口之外,JMX还打开了两个附加的随机TCP侦听端口,这可能会导致端口冲突问题. (有关详细信息,请参见HBASE-10289

或者,您可以使用HBase提供的基于协处理器的JMX实现. 要启用它,请在hbase-site.xml中添加以下属性:

<property>
  <name>hbase.coprocessor.regionserver.classes</name>
  <value>org.apache.hadoop.hbase.JMXListener</value>
</property>
请勿同时为Java VM设置com.sun.management.jmxremote.port .

当前,它支持Master和RegionServer Java VM. 默认情况下,JMX侦听TCP端口10102,您可以使用以下属性进一步配置端口:

<property>
  <name>regionserver.rmi.registry.port</name>
  <value>61130</value>
</property>
<property>
  <name>regionserver.rmi.connector.port</name>
  <value>61140</value>
</property>

在大多数情况下,注册表端口可以与连接器端口共享,因此您只需要配置regionserver.rmi.registry.port. 但是,如果要使用SSL通信,则必须将2个端口配置为不同的值.

默认情况下,密码验证和SSL通信是禁用的. 要启用密码身份验证,您需要像下面这样更新hbase-env.sh

export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.authenticate=true                  \
                       -Dcom.sun.management.jmxremote.password.file=your_password_file   \
                       -Dcom.sun.management.jmxremote.access.file=your_access_file"

export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE "
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE "

请参阅$ JRE_HOME / lib / management下的示例密码/访问文件.

要通过密码验证启用SSL通信,请执行以下步骤:

#1. generate a key pair, stored in myKeyStore
keytool -genkey -alias jconsole -keystore myKeyStore

#2. export it to file jconsole.cert
keytool -export -alias jconsole -keystore myKeyStore -file jconsole.cert

#3. copy jconsole.cert to jconsole client machine, import it to jconsoleKeyStore
keytool -import -alias jconsole -keystore jconsoleKeyStore -file jconsole.cert

然后像下面这样更新hbase-env.sh

export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.ssl=true                         \
                       -Djavax.net.ssl.keyStore=/home/tianq/myKeyStore                 \
                       -Djavax.net.ssl.keyStorePassword=your_password_in_step_1       \
                       -Dcom.sun.management.jmxremote.authenticate=true                \
                       -Dcom.sun.management.jmxremote.password.file=your_password file \
                       -Dcom.sun.management.jmxremote.access.file=your_access_file"

export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE "
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE "

最后,使用密钥库在客户端上启动jconsole

jconsole -J-Djavax.net.ssl.trustStore=/home/tianq/jconsoleKeyStore
要在Master上启用HBase JMX实现,还需要在hbase-site.xml中添加以下属性:
<property>
  <name>hbase.coprocessor.master.classes</name>
  <value>org.apache.hadoop.hbase.JMXListener</value>
</property>

端口配置的相应属性是master.rmi.registry.port (默认为10101)和master.rmi.connector.port (默认与master.rmi.connector.port相同)

10. Dynamic Configuration

可以更改配置的子集而无需重新启动服务器. 在HBase Shell中,操作update_configupdate_all_config将提示一个服务器或所有服务器重新加载配置.

当前,正在运行的服务器中只能更改所有配置的一部分. 这些是这些配置:

表3.配置支持动态更改
Key

hbase.ipc.server.fallback-to-simple-auth-allowed

hbase.cleaner.scan.dir.concurrent.size

hbase.regionserver.thread.compaction.large

hbase.regionserver.thread.compaction.small

hbase.regionserver.thread.split

hbase.regionserver.throughput.controller

hbase.regionserver.thread.hfilecleaner.throttle

hbase.regionserver.hfilecleaner.large.queue.size

hbase.regionserver.hfilecleaner.small.queue.size

hbase.regionserver.hfilecleaner.large.thread.count

hbase.regionserver.hfilecleaner.small.thread.count

hbase.regionserver.hfilecleaner.thread.timeout.msec

hbase.regionserver.hfilecleaner.thread.check.interval.msec

hbase.regionserver.flush.throughput.controller

hbase.hstore.compaction.max.size

hbase.hstore.compaction.max.size.offpeak

hbase.hstore.compaction.min.size

hbase.hstore.compaction.min

hbase.hstore.compaction.max

hbase.hstore.compaction.ratio

hbase.hstore.compaction.ratio.offpeak

hbase.regionserver.thread.compaction.throttle

hbase.hregion.majorcompaction

hbase.hregion.majorcompaction.jitter

hbase.hstore.min.locality.to.skip.major.compact

hbase.hstore.compaction.date.tiered.max.storefile.age.millis

hbase.hstore.compaction.date.tiered.incoming.window.min

hbase.hstore.compaction.date.tiered.window.policy.class

hbase.hstore.compaction.date.tiered.single.output.for.minor.compaction

hbase.hstore.compaction.date.tiered.window.factory.class

hbase.offpeak.start.hour

hbase.offpeak.end.hour

hbase.oldwals.cleaner.thread.size

hbase.oldwals.cleaner.thread.timeout.msec

hbase.oldwals.cleaner.thread.check.interval.msec

hbase.procedure.worker.keep.alive.time.msec

hbase.procedure.worker.add.stuck.percentage

hbase.procedure.worker.monitor.interval.msec

hbase.procedure.worker.stuck.threshold.msec

hbase.regions.slop

hbase.regions.overallSlop

hbase.balancer.tablesOnMaster

hbase.balancer.tablesOnMaster.systemTablesOnly

hbase.util.ip.to.rack.determiner

hbase.ipc.server.max.callqueue.length

hbase.ipc.server.priority.max.callqueue.length

hbase.ipc.server.callqueue.type

hbase.ipc.server.callqueue.codel.target.delay

hbase.ipc.server.callqueue.codel.interval

hbase.ipc.server.callqueue.codel.lifo.threshold

hbase.master.balancer.stochastic.maxSteps

hbase.master.balancer.stochastic.stepsPerRegion

hbase.master.balancer.stochastic.maxRunningTime

hbase.master.balancer.stochastic.runMaxSteps

hbase.master.balancer.stochastic.numRegionLoadsToRemember

hbase.master.loadbalance.bytable

hbase.master.balancer.stochastic.minCostNeedBalance

hbase.master.balancer.stochastic.localityCost

hbase.master.balancer.stochastic.rackLocalityCost

hbase.master.balancer.stochastic.readRequestCost

hbase.master.balancer.stochastic.writeRequestCost

hbase.master.balancer.stochastic.memstoreSizeCost

hbase.master.balancer.stochastic.storefileSizeCost

hbase.master.balancer.stochastic.regionReplicaHostCostKey

hbase.master.balancer.stochastic.regionReplicaRackCostKey

hbase.master.balancer.stochastic.regionCountCost

hbase.master.balancer.stochastic.primaryRegionCountCost

hbase.master.balancer.stochastic.moveCost

hbase.master.balancer.stochastic.maxMovePercent

hbase.master.balancer.stochastic.tableSkewCost

Upgrading

升级时不能跳过主要版本. 如果要从0.98.x版本升级到2.x,则必须先从0.98.x升级到1.2.x,然后再从1.2.x升级到2.x.

查看Apache HBase配置 ,尤其是 Hadoop的 . 熟悉支持和测试期望 .

11. HBase version number and compatibility

11.1. Aspirational Semantic Versioning

从1.0.0版本开始,HBase正在为其版本版本进行语义版本控制. 综上所述:

给定版本号MAJOR.MINOR.PATCH,增加:
  • 当您进行不兼容的API更改时的主要版本,

  • 以向后兼容的方式添加功能时的MINOR版本,并且

  • 进行向后兼容的错误修复时的PATCH版本.

  • 可以使用预发布和构建元数据的其他标签作为MAJOR.MINOR.PATCH格式的扩展名.

Compatibility Dimensions

除了通常的API版本控制注意事项之外,HBase还具有我们需要考虑的其他兼容性维度.

客户端-服务器有线协议兼容性
  • 允许更新客户端和服务器不同步.

  • 我们只能先升级服务器. 也就是说,服务器将向后兼容旧客户端,这样新的API就可以了.

  • 示例:用户应该能够使用旧客户端连接到升级的群集.

服务器-服务器协议兼容性
  • 不同版本的服务器可以共存于同一群集中.

  • 服务器之间的有线协议兼容.

  • 复制和日志拆分等分布式任务的工作程序可以共存于同一群集中.

  • 相关协议(例如使用ZK进行协调)也不会更改.

  • 示例:用户可以执行滚动升级.

文件格式兼容性
  • 支持文件格式向后和向前兼容

  • 示例:作为HBase升级的一部分,文件,ZK编码,目录布局会自动升级. 用户可以降级到较旧的版本,并且一切将继续工作.

客户端API兼容性
  • 允许更改或删除现有的客户端API.

  • 我们需要在整个主要版本中弃用API,然后再进行更改/删除.

    • 例如:API在2.0.1中已弃用,并在4.0.0中被标记为删除. 另一方面,在2.0.0中弃用的API可以在3.0.0中删除.

  • 修补程序版本中提供的API将在所有更高的修补程序版本中提供. 但是,可能会添加新的API,这些API在较早的修补程序版本中将不可用.

  • 补丁版本中引入的新API将仅以与源代码兼容的方式添加[ 1 ] :即,实现公共API的代码将继续编译.

    • 示例:使用新近弃用的API的用户不需要使用HBase API调用即可修改应用程序代码,直到下一个主要版本. *

客户端二进制兼容性
  • 写入给定补丁程序版本中可用的API的客户端代码可以针对更高版本的补丁程序的新jar保持不变(无需重新编译).

  • 写入给定修补程序版本中可用的API的客户端代码可能无法与早期修补程序版本中的旧jar一起运行.

    • 示例:旧的已编译客户端代码将与新的jar一起使用.

  • 如果客户端实现了HBase接口,则可能需要重新编译才能升级到较新的次要版本(有关不兼容更改的警告,请参阅发行说明). 将尽一切努力提供默认的实现,因此不会出现这种情况.

服务器端受限API兼容性(取自Hadoop)
  • 内部API被标记为稳定,不断发展或不稳定

  • 这意味着协处理器和插件(可插拔的类,包括复制)的二进制兼容性,只要它们仅使用标记的接口/类即可.

  • 示例:旧的编译的协处理器,过滤器或插件代码将与新的jar一起使用.

依赖相容性
  • HBase的升级将不需要对依赖项目进行不兼容的升级,除了Apache Hadoop.

  • HBase的升级将不需要Java运行时的不兼容升级.

  • 示例:将HBase升级到支持依赖关系兼容性的版本不需要您升级Apache ZooKeeper服务.

  • 示例:如果当前的HBase版本支持在JDK 8上运行,则升级到支持Dependency Compatibility的版本也将在JDK 8上运行.

Hadoop版本

以前,我们尝试维护底层Hadoop服务的依赖项兼容性,但在过去几年中,这已证明是站不住脚的. 当HBase项目尝试维护对Hadoop较早版本的支持时,我们删除了"支持的"次要版本的标识符,这些子版本无法继续查看发行版. 此外,Hadoop项目有一套自己的兼容性指南,这意味着在某些情况下,必须更新到较新的受支持的次要版本,可能会破坏我们的一些兼容性承诺.

操作兼容性
  • 指标变化

  • 服务的行为变化

  • 通过/jmx/端点公开的JMX API

Summary
  • 修补程序升级是一种替代产品. 不允许进行任何非Java二进制和源兼容的更改. [ 2 ]修补程序版本中的降级版本可能不兼容.

  • 较小的升级不需要修改应用程序/客户端代码. 理想情况下,这将是直接替换,但如果使用新的jar,则必须重新编译客户端代码,协处理器,过滤器等.

  • 重大升级使HBase社区可以进行重大更改.

表4.兼容性列表[ 3 ]

Major

Minor

Patch

客户端-服务器线兼容性

N

Y

Y

服务器-服务器兼容性

N

Y

Y

文件格式兼容性

N [4]

Y

Y

客户端API兼容性

N

Y

Y

客户二进制兼容性

N

N

Y

服务器端受限API兼容性

Stable

N

Y

Y

Evolving

N

N

Y

Unstable

N

N

N

Dependency Compatibility

N

Y

Y

操作兼容性

N

N

Y

11.1.1. HBase API Surface

HBase有很多API要点,但是对于上面的兼容性矩阵,我们区分了Client API,Limited Private API和Private API. HBase使用Apache Yetus受众注释来指导下游对稳定性的期望.

  • InterfaceAudience( javadocs ):捕获目标受众,可能的值包括:

    • 公共:对最终用户和外部项目安全

    • LimitedPrivate:用于我们希望可插拔的内部组件,例如协处理器

    • 私有:严格用于HBase本身定义为IA.Private类可用作声明为IA.LimitedPrivate接口的参数或返回值. 将IA.Private对象视为不透明; 不要尝试直接访问其方法或字段.

  • InterfaceStability( javadocs ):描述允许哪些类型的接口更改. 可能的值包括:

    • 稳定:接口固定,预计不会改变

    • 不断发展:将来的次要版本可能会更改界面

    • 不稳定:界面可能随时更改

请记住HBase项目中InterfaceAudienceInterfaceStability批注之间的以下交互:

  • IA.Public类具有固有的稳定性,并遵守与升级类型(主要,次要或补丁)有关的稳定性保证.

  • IA.LimitedPrivate类应始终使用给定的InterfaceStability值之一进行注释. 如果不是,则应假定它们是IS.Unstable .

  • IA.Private类应视为隐式不稳定,不能保证发行版之间的稳定性.

HBase Client API

HBase客户端API包含所有标有InterfaceAudience.Public接口的类或方法. hbase-client和从属模块中的所有主要类都具有InterfaceAudience.Public,InterfaceAudience.LimitedPrivate或InterfaceAudience.Private标记. 并非其他模块(hbase-server等)中的所有类都具有标记. 如果一个类未使用其中之一进行注释,则假定该类为InterfaceAudience.Private类.

HBase LimitedPrivate API

LimitedPrivate批注带有一组接口的目标使用者. 这些使用者是协处理器,凤凰,复制终结点实现或类似者. 此时,HBase仅保证补丁程序版本之间的这些接口的源和二进制兼容性.

HBase Private API

所有使用InterfaceAudience进行注释的类.私有或不具有注释的所有类仅供HBase内部使用. 接口和方法签名可以随时更改. 如果您依赖于标记为"专用"的特定接口,则应打开吉拉,建议将接口更改为"公共"或"有限私有",或为此目的公开的接口.

二进制兼容性

当我们说两个HBase版本是兼容的时,我们的意思是这些版本是有线和二进制兼容的. 兼容的HBase版本意味着客户端可以与兼容但版本不同的服务器通信. 这也意味着您可以换掉一个版本的jar,然后用另一个兼容版本的jar替换它们,所有这些都可以使用. 除非另有说明,否则HBase点版本(主要)是二进制兼容的. 您可以安全地在二进制兼容版本之间进行滚动升级. 即跨维护版本:例如从1.2.4到1.2.6. 请参阅HBase开发邮件列表上的链接:[版本之间的兼容性是否还意味着二进制兼容性?].

11.2. Rolling Upgrades

滚动升级是一次更新群集中的服务器的过程. 如果它们是二进制或有线兼容的,则可以跨HBase版本滚动升级. 有关这意味着什么的更多信息,请参见在二进制/有线兼容版本之间滚动升级 . 粗略地讲,滚动升级是每个服务器的正常停止,更新软件然后重新启动. 您为集群中的每个服务器执行此操作. 通常,先升级主服务器,然后再升级RegionServers. 请参阅滚动重启,以获取有助于使用滚动升级过程的工具.

例如,在下面的内容中,HBase被符号链接到实际的HBase安装. 升级时,在对群集进行滚动重启之前,我们将符号链接更改为指向新的HBase软件版本,然后运行

$ HADOOP_HOME=~/hadoop-2.6.0-CRC-SNAPSHOT ~/hbase/bin/rolling-restart.sh --config ~/conf_hbase

滚动重新启动脚本将首先正常停止并重新启动主服务器,然后依次停止每个RegionServer. 由于符号链接已更改,因此在重新启动时,服务器将使用新的HBase版本启动. 随着滚动升级的进行,请检查日志中是否有错误.

二进制/有线兼容版本之间的滚动升级

除非另有说明,否则HBase次要版本是二进制兼容的. 您可以在HBase点版本之间进行滚动升级 . 例如,您可以通过在整个群集中进行滚动升级来从1.2.6升级到1.2.4,将1.2.4二进制文件替换为1.2.6二进制文件.

在下面的次要版本特别部分中,我们指出了那些版本与线路/协议兼容的地方,在这种情况下,还可以进行滚动升级 .

12. Rollback

有时,尝试升级时事情并没有按计划进行. 本节说明了如何回滚到较早的HBase版本. 请注意,仅在主要版本和某些次要版本之间才需要这样做. 您应该始终能够在同一次要版本的HBase Patch版本之间进行降级 . 这些说明可能要求您在开始升级过程之前采取步骤,因此请务必先通读本节.

12.1. Caveats

回滚与降级

本节介绍如何在HBase次要版本和主要版本之间升级时执行回滚 . 在本文档中,回滚指的是获取升级后的集群并将其还原到旧版本, 同时丢失自upgrade以来发生的所有更改的过程 . 相比之下,集群降级会将升级后的集群还原到旧版本,同时保留自升级以来写入的所有数据. 当前,我们仅提供回滚HBase群集的说明. 此外,只有在执行升级之前遵循以下说明时,回滚才有效.

当这些说明讨论先决条件群集服务(即HDFS)的回滚与降级时,应将服务版本与降级的退化情况相同.

Replication

除非您执行所有服务回滚,否则HBase群集将丢失用于HBase复制的所有已配置对等项. 如果将群集配置为进行HBase复制,则在遵循这些说明之前,应记录所有复制对等体. 执行回滚后,您应该将每个记录的对等方添加回群集中. 有关启用HBase复制,列出对等方以及添加对等方的更多信息,请参阅《 管理和配置群集复制》 . 还要注意,自升级以来写入集群的数据可能已经复制或可能尚未复制到任何对等点. 确定哪些对等点(如果有)已看到复制数据并回滚这些对等点中的数据,超出了本指南的范围.

数据局部性

除非您执行所有服务回滚,否则执行回滚过程可能会破坏Region Server的所有位置. 您应该期望性能下降,直到群集有时间进行压缩以恢复数据局部性为止. (可选)您可以强制压缩以加快生成群集负载的速度,从而加快此过程.

可配置位置

以下说明假定HBase数据目录和HBase znode的默认位置. 这两个位置都是可配置的,在继续操作之前,您应该验证集群中使用的值. 如果您使用不同的值,只需将默认值替换为在配置中找到的值即可.* HBase数据目录是通过键" hbase.rootdir"配置的,其默认值为" / hbase". * HBase znode是通过键'zookeeper.znode.parent'配置的,其默认值为'/ hbase'.

12.2. All service rollback

如果要同时执行HDFS和ZooKeeper服务的回滚,则HBase的数据将在此过程中回滚.

Requirements
  • 能够回滚HDFS和ZooKeeper

升级前

升级前不需要其他步骤. 作为一种额外的预防措施,您可能希望使用distcp从要升级的群集中备份HBase数据. 为此,请遵循" HDFS降级后回滚"的"升级前"部分中的步骤,但复制到另一个HDFS实例,而不是复制到同一实例中.

执行回滚
  1. 停止HBase

  2. Perform a rollback for HDFS and ZooKeeper (HBase should remain stopped)

  3. 将已安装的HBase版本更改为以前的版本

  4. 启动HBase

  5. 验证HBase内容-使用HBase Shell列出表并扫描一些已知值.

12.3. Rollback after HDFS rollback and ZooKeeper downgrade

如果您要回滚HDFS但要通过ZooKeeper降级,则HBase将处于不一致状态. 您必须确保集群没有启动,直到完成此过程.

Requirements
  • 能够回滚HDFS

  • 降级ZooKeeper的能力

升级前

升级前不需要其他步骤. 作为一种额外的预防措施,您可能希望使用distcp从要升级的群集中备份HBase数据. 为此,请遵循" HDFS降级后回滚"的"升级前"部分中的步骤,但复制到另一个HDFS实例,而不是复制到同一实例中.

执行回滚
  1. 停止HBase

  2. 对HDFS执行回滚,对ZooKeeper进行降级(HBase应该保持停止状态)

  3. 将已安装的HBase版本更改为以前的版本

  4. 清除与HBase相关的ZooKeeper信息. 警告:此步骤将永久破坏所有复制对等. 有关更多信息,请参见"警告"下有关" HBase复制"的部分.

    Clean HBase information out of ZooKeeper
    [hpnewton@gateway_node.example.com ~]$ zookeeper-client -server zookeeper1.example.com:2181,zookeeper2.example.com:2181,zookeeper3.example.com:2181
    Welcome to ZooKeeper!
    JLine support is disabled
    rmr /hbase
    quit
    Quitting...
  5. 启动HBase

  6. 验证HBase内容-使用HBase Shell列出表并扫描一些已知值.

12.4. Rollback after HDFS downgrade

如果要执行HDFS降级,则无论ZooKeeper是经过回滚,降级还是重新安装,都需要遵循这些说明.

Requirements
  • 能够降级HDFS

  • 升级前集群必须能够运行MapReduce作业

  • HDFS超级用户访问

  • HDFS中至少有两个HBase数据目录副本的足够空间

升级前

在开始升级过程之前,您必须完整备份HBase的后备数据. 以下说明涵盖了备份当前HDFS实例中的数据. 或者,您可以使用distcp命令将数据复制到另一个HDFS群集.

  1. 停止HBase集群

  2. 使用distcp命令以HDFS超级用户身份将HBase数据目录复制到备份位置(如下所示,在启用安全性的群集上)

    使用distcp备份HBase数据目录
    [hpnewton@gateway_node.example.com ~]$ kinit -k -t hdfs.keytab hdfs@EXAMPLE.COM
    [hpnewton@gateway_node.example.com ~]$ hadoop distcp /hbase /hbase-pre-upgrade-backup
  3. Distcp将启动mapreduce作业以处理以分布式方式复制文件. 检查distcp命令的输出,以确保此作业成功完成.

执行回滚
  1. 停止HBase

  2. 对HDFS执行降级,对ZooKeeper执行降级/回滚(HBase应该保持停止状态)

  3. 将已安装的HBase版本更改为以前的版本

  4. 以HDFS超级用户的身份从升级之前还原HBase数据目录(如下所示,在启用安全性的群集上). 如果您将数据备份到另一个HDFS群集上而不是本地上,则需要使用distcp命令将其复制回当前HDFS群集上.

    恢复HBase数据目录
    [hpnewton@gateway_node.example.com ~]$ kinit -k -t hdfs.keytab hdfs@EXAMPLE.COM
    [hpnewton@gateway_node.example.com ~]$ hdfs dfs -mv /hbase /hbase-upgrade-rollback
    [hpnewton@gateway_node.example.com ~]$ hdfs dfs -mv /hbase-pre-upgrade-backup /hbase
  5. 清除与HBase相关的ZooKeeper信息. 警告:此步骤将永久破坏所有复制对等. 有关更多信息,请参见"警告"下有关" HBase复制"的部分.

    从ZooKeeper中清除HBase信息
    [hpnewton@gateway_node.example.com ~]$ zookeeper-client -server zookeeper1.example.com:2181,zookeeper2.example.com:2181,zookeeper3.example.com:2181
    Welcome to ZooKeeper!
    JLine support is disabled
    rmr /hbase
    quit
    Quitting...
  6. 启动HBase

  7. 验证HBase内容-使用HBase Shell列出表并扫描一些已知值.

13. Upgrade Paths

13.1. Upgrading from 1.x to 2.x

在本节中,我们将首先指出与之前的稳定HBase版本相比的重大更改,然后介绍升级过程. 请务必仔细阅读前者,以免出现意外.

13.1.1. Changes of Note!

首先,我们将介绍在升级到HBase 2.0+时可能会遇到的部署/操作更改. 之后,我们将调出下游应用程序的更改. 请注意,"操作"部分介绍了协处理器. 另请注意,本节并不旨在传达您可能感兴趣的有关新功能的信息. 有关更改的完整摘要,请参阅源版本工件中计划升级到的版本的CHANGES.txt文件.

更新到HBase 2.0+中的基本前提条件最低要求

如" 基本必备条件 "部分所述,HBase 2.0+至少需要Java 8和Hadoop 2.6. HBase社区建议确保在升级HBase版本之前,先决条件已完成所有必需的升级.

HBCK必须与HBase服务器版本匹配

不得针对HBase 2.0+群集使用HBCK的HBase 1.x版本. HBCK与HBase服务器版本紧密相关. 对HBase 2.0+群集使用较早版本的HBCK工具将以不可恢复的方式破坏性地更改该群集.

从HBase 2.0开始,HBCK(又名HBCK1hbck1 )是一种只读工具,可以报告某些非公共系统内部组件的状态. 您不应该依赖这些内部组件的格式或内容来在HBase版本之间保持一致.

要了解有关HBCK替换的信息,请参阅Apache HBase Operational Management中的 HBase HBCK2 .

HBase 2.0+中不再包含配置设置

The following configuration settings are no longer applicable or available. For details, please see the detailed release notes.

  • hbase.config.read.zookeeper.config(有关迁移的详细信息,请参阅不再从zoo.cfg中读取的ZooKeeper配置

  • hbase.zookeeper.useMulti(HBase现在始终使用ZK的多功能功能)

  • hbase.rpc.client.threads.max

  • hbase.rpc.client.nativetransport

  • hbase.fs.tmp.dir

  • hbase.bucketcache.combinedcache.enabled

  • hbase.bucketcache.ioengine不再支持"堆"值.

  • hbase.bulkload.staging.dir

  • 严格来说,hbase.balancer.tablesOnMaster并未删除,但其含义已发生根本变化,用户不应进行设置. 有关详细信息,请参见"主机托管区域"部分,该部分已损坏且不受支持 .

  • hbase.master.distributed.log.replay有关详细信息,请参见"分布式日志重播"功能部分,该功能已被删除和删除 .

  • hbase.regionserver.disallow.writes.when.recovering有关详细信息,请参见"分布式日志重播"功能部分,该功能已被删除和删除 .

  • hbase.regionserver.wal.logreplay.batch.size有关详细信息,请参见"分布式日志重播"功能部分,该功能已被删除和删除 .

  • hbase.master.catalog.timeout

  • hbase.regionserver.catalog.timeout

  • hbase.metrics.exposeOperationTimes

  • hbase.metrics.showTableName

  • hbase.online.schema.update.enable(HBase现在始终支持此功能)

  • hbase.thrift.htablepool.size.max

Configuration properties that were renamed in HBase 2.0+

以下属性已重命名. 尝试设置旧属性将在运行时被忽略.

表5.重命名的属性
旧名 新名字

hbase.rpc.server.nativetransport

hbase.netty.nativetransport

hbase.netty.rpc.server.worker.count

hbase.netty.worker.count

hbase.hfile.compactions.discharger.interval

hbase.hfile.compaction.discharger.interval

hbase.hregion.percolumnfamilyflush.size.lower.bound

hbase.hregion.percolumnfamilyflush.size.lower.bound.min

HBase 2.0+中具有不同默认值的配置设置

以下配置设置更改了其默认值. 在适用的情况下,给出了用于还原HBase 1.2行为的值.

  • hbase.security.authorization现在默认为false. 设置为true可恢复与以前的默认行为相同的行为.

  • hbase.client.retries.number现在设置为10.以前是35.建议下游用户按照" 超时设置"部分中的说明使用客户端超时.

  • hbase.client.serverside.retries.multiplier现在设置为3.以前是10.建议下游用户按照" 超时设置"部分中的说明使用客户端超时 .

  • hbase.master.fileSplitTimeout现在设置为10分钟. 以前是30秒.

  • hbase.regionserver.logroll.multiplier现在设置为0.5. 以前是0.95. 此更改与以下块大小加倍相关. 结合起来,这两个配置更改应该使WAL的大小与hbase-1.x中的WAL大小相同,但是小块的发生率应该降低,因为在达到块大小阈值之前我们无法滚动WAL. 有关讨论,请参见HBASE-19148 .

  • hbase.regionserver.hlog.blocksize的默认值是WAL目录的HDFS默认块大小的2倍. 以前,它等于WAL目录的HDFS默认块大小.

  • hbase.client.start.log.errors.counter更改为5.以前是9.

  • hbase.ipc.server.callqueue.type更改为" fifo". 在HBase 1.0-1.2版本中,这是"最后期限". 在1.x之前和之后的版本中,它已经默认为'fifo'.

  • 默认情况下,hbase.hregion.memstore.chunkpool.maxsize为1.0. 以前是0.0. 实际上,这意味着以前在内存存储处于堆状态时我们不会使用块池,而现在我们会使用. 有关MSLAB块池的更多信息,请参见长时间GC暂停部分.

  • hbase.master.cleaner.interval现在设置为10分钟. 以前是1分钟.

  • 现在,hbase.master.procedure.threads将默认为可用CPU数量的1/4,但不少于16个线程. 以前,线程数量等于CPU数量.

  • hbase.hstore.blockingStoreFiles现在是16.以前是10.

  • hbase.http.max.threads现在是16.以前是10.

  • hbase.client.max.perserver.tasks现在是2.以前是5.

  • hbase.normalizer.period现在是5分钟. 以前是30分钟.

  • hbase.regionserver.region.split.policy现在是SteppingSplitPolicy. 以前它是InreasingToUpperBoundRegionSplitPolicy.

  • Replication.source.ratio现在为0.5. 以前是0.1.

"主托管区域"功能已损坏且不受支持

HBase 1.y中可用的功能" Master充当区域服务器"和相关的后续工作在HBase 2.y中不起作用,并且由于Master初始化上的死锁,不应在生产设置中使用. 建议下游用户将相关配置设置视为实验性功能,而该功能不适合生产设置.

相关更改的简要摘要:

  • 主人默认不再携带地区

  • hbase.balancer.tablesOnMaster是一个布尔值,默认为false(如果它持有表的HBase 1.x列表,则默认为false)

  • hbase.balancer.tablesOnMaster.systemTablesOnly是布尔值,可将用户表保持为主状态. 默认为假

  • 那些希望复制旧服务器列表配置的用户应该部署一个独立的RegionServer进程,然后依赖Region Server Groups

损坏的"分布式日志重播"功能已删除

分布式日志重播功能已损坏,已从HBase 2.y +中删除. 结果,所有相关的配置,指标,RPC字段和日志记录也已删除. 请注意,发现该功能在运行HBase 1.0时不可靠,默认情况下未使用,并且当我们开始忽略将其打开的配置( HBASE-14465 )时,已在HBase 1.2.0中将其有效删除. 如果您当前正在使用该功能,请确保执行干净关机,确保所有DLR工作已完成,并在升级之前禁用该功能.

前缀树编码已删除

前缀树编码已从HBase 2.0.0( HBASE-19179 )中删除. 在hbase-1.2.7,hbase-1.4.0和hbase-1.3.2中已弃用(最新!).

This feature was removed because it as not being actively maintained. If interested in reviving this sweet facility which improved random read latencies at the expensive of slowed writes, write the HBase developers list at hbase dot apache dot org的开发人员.

在升级到HBase 2.0+之前,需要从所有表中删除前缀树编码. 为此,首先需要将编码从PREFIX_TREE更改为HBase 2.0支持的其他格式. 之后,您必须对以前使用PREFIX_TREE编码的表进行压缩. 要检查哪些列族正在使用不兼容的数据块编码,可以使用Pre-Upgrade Validator .

更改指标

以下指标已更改名称:

  • 以前以" AssignmentManger" [sic]的名义发布的指标现在以" AssignmentManager"的名义发布

以下指标已更改其含义:

  • 基于每个区域服务器发布的度量标准" blockCacheEvictionCount"不再包括由于其所在的hfile无效(例如,通过压缩)而从缓存中删除的块.

  • 指标" totalRequestCount"每个请求增加一次; 之前,它增加了请求中执行的Actions数; 例如,如果一个请求,一个multi由四个获取和两个看跌期权,我们就会增加"totalRequestCount"六; 现在无论如何我们都加一. 期望在hbase-2.0.0中看到该指标的较低值.

  • 现在," readRequestCount"对返回非空行的读取进行计数,在较旧的hbase中,无论是否为Result,我们都会增加" readRequestCount". 如果对不存在的行的请求,此更改将使读取请求图的配置文件平坦. YCSB读取繁重的工作负载可以执行此操作,具体取决于数据库的加载方式.

以下指标已删除:

  • 与分布式日志重播功能有关的指标不再存在. 通常在区域服务器上下文中以"重播"名称找到它们. 有关详细信息,请参见"分布式日志重播"部分,该部分已被断开和删除 .

The following metrics have been added:

  • " totalRowActionRequestCount"是区域行操作的总数,该操作汇总了读写操作.

更改日志

HBase-2.0.0现在使用slf4j作为其日志记录前端. 以前,我们使用log4j(1.2) . 对于大多数情况而言,过渡应该是无缝的. slf4j很好地解释了log4j.properties日志记录配置文件,这样您就不会注意到日志系统发出的任何差异.

就是说,您的log4j.properties可能需要刷新. 例如,请参见HBASE-20351 ,其中,过时的日志配置文件表现为netty配置,并在DEBUG级别上作为每个shell命令调用的前导转储.

ZooKeeper配置不再从zoo.cfg中读取

HBase不再选择读取与ZooKeeper相关的配置设置的'zoo.cfg'文件. 如果以前使用" hbase.config.read.zookeeper.config"配置来实现此功能,则应在添加前缀" hbase.zookeeper.property"的同时将所有需要的设置迁移到hbase-site.xml文件. 每个属性名称.

权限变更

以下与权限相关的更改是更改的语义或默认设置:

  • 现在,授予用户的权限将与该用户的现有权限合并,而不是覆盖它们. (有关详细信息,请参见HBASE-17472的发行说明

  • 区域服务器组命令(在1.4.0中添加)现在需要管理员权限.

大多数Admin API不适用于HBase 2.0之前的客户端的HBase 2.0+群集

从HBase 2.0之前的客户端使用许多管理命令时,这些命令不起作用. 这包括一个具有HBase 2.0之前版本的库jar的HBase Shell. 您将需要计划中断使用管理API和命令,直到您还可以更新到所需的客户端版本.

从HBase 2.0之前的客户端执行以下客户端操作不适用于HBase 2.0+群集:

  • list_procedures

  • split

  • merge_region

  • list_quotas

  • enable_table_replication

  • disable_table_replication

  • 快照相关命令

在1.0中不推荐使用的管理命令已被删除.

在1.0中不推荐使用的以下命令已被删除. 如果适用,将列出替换命令.

  • 'hlog'命令已被删除. 下游用户应改为使用" wal"命令.

区域服务器内存消耗发生变化.

从HBase 1.4之前的版本升级的用户应阅读" 区域服务器内存消耗更改"部分中的说明. .

此外,HBase 2.0更改了跟踪内存存储器以进行刷新决策的方式. 以前,数据大小和存储开销都用于计算刷新阈值的利用率. 现在,仅使用数据大小来做出这些按区域的决策. 在全球范围内,存储开销的增加用于做出有关强制刷新的决策.

用于拆分和合并的Web UI对行前缀进行操作

以前,Web UI在表状态页上包含功能,可以根据编码的区域名称合并或拆分. 在HBase 2.0中,该功能通过使用行前缀来起作用.

从HBase 1.4之前的复制用户的特殊升级

使用复制的用户在运行1.4.0发行版之前的HBase版本时,请务必阅读复制对等方的TableCFs config部分中的说明.

HBase Shell变更

HBase shell命令依赖于捆绑的JRuby实例. 捆绑的JRuby已从1.6.8版本更新到9.1.10.0版本. 表示从Ruby 1.8到Ruby 2.3.3的更改,后者为用户脚本引入了不兼容的语言更改.

现在,HBase Shell命令将忽略早期HBase 1.4发行版中的" --return-values"标志. 相反,shell始终像传递该标志一样运行. 如果希望避免在控制台中打印表达式结果,则应按照irbrc部分中的说明更改IRB配置.

HBase 2.0+中的协处理器API已更改

对所有协处理器API进行了重构,以提高对二进制API兼容性的支持性,以支持HBase的未来版本. 如果您或您依赖的应用程序具有自定义的HBase协处理器,则应阅读HBASE-18169的发行说明,以了解升级到HBase 2.0+之前需要进行的更改的详细信息.

例如,如果您在HBase 1.2中具有BaseRegionObserver,则至少需要对其进行更新以实现RegionObserver和RegionCoprocessor并添加方法

...
  @Override
  public Optional<RegionObserver> getRegionObserver() {
    return Optional.of(this);
  }
...
HBase 2.0+无法再写入HFile v2文件.

HBase简化了我们内部的HFile处理. 结果,我们不能再写比默认版本3更早的HFile版本.升级用户之前,应确保hbase-site.xml中的hfile.format.version未设置为2. 否则,将导致区域服务器故障. HBase仍可以读取以旧版本2格式编写的HFile.

HBase 2.0+无法再读取基于序列文件的WAL文件.

HBase无法再读取以Apache Hadoop序列文件格式编写的不赞成使用的WAL文件. 应该将hbase.regionserver.hlog.reader.impl和hbase.regionserver.hlog.reader.impl配置条目设置为使用基于Protobuf的WAL读取器/写入器类. 自HBase 0.96起,此实现已成为默认设置,因此对于大多数下游用户而言,旧的WAL文件不应该成为问题.

干净关闭群集应确保没有WAL文件. 如果不确定给定的WAL文件格式,则可以在HBase群集脱机时使用hbase wal命令解析文件. 在HBase 2.0+中,此命令将无法读取基于序列文件的WAL. 有关该工具的更多信息,请参见WALPrettyPrinter部分.

过滤器行为的变化

过滤器ReturnCode NEXT_ROW已重新定义为跳至当前族的下一行,而不是所有族的下一行. 这更合理,因为ReturnCode是商店级别的概念,而不是区域级别的概念.

下游HBase 2.0+用户应使用阴影客户端

强烈建议下游用户在运行时使用Maven坐标org.apache.hbase:hbase-shaded-client. 该工件包含与HBase集群通信时所需的所有实现细节,同时最大程度地减少了公开的第三方依赖项的数量.

请注意,此工件在org.apache.hadoop包空间(egoahconfiguration.Configuration)中公开了一些类,以便我们可以维护与公共API的源兼容性. 包括了这些类,以便可以对其进行更改以使用与其余HBase客户端代码相同的重新定位的第三方依赖关系. 在你需要在你的代码使用Hadoop的情况下,你应该确保所有的Hadoop相关的罐子在classpath中先于HBase的客户端jar.

MapReduce的下游HBase 2.0+用户必须切换到新工件

HBase与Apache Hadoop MapReduce集成的下游用户必须切换到依赖org.apache.hbase:hbase-shaded-mapreduce模块进行运行时使用. 从历史上看,下游用户依赖于这些类的org.apache.hbase:hbase-server或org.apache.hbase:hbase-shaded-server工件. 不再支持这两种用法,并且在大多数情况下将在运行时失败.

请注意,此工件在org.apache.hadoop包空间(egoahconfiguration.Configuration)中公开了一些类,以便我们可以维护与公共API的源兼容性. 包括了这些类,以便可以对其进行更改以使用与其余HBase客户端代码相同的重新定位的第三方依赖关系. 在你需要在你的代码使用Hadoop的情况下,你应该确保所有的Hadoop相关的罐子在classpath中先于HBase的客户端jar.

对运行时类路径的重大更改

HBase的许多内部依赖项已从运行时类路径中更新或删除. 不遵循下游HBase 2.0+用户指南的下游客户端用户应使用阴影客户端,必须检查Maven引入的依赖项集是否有影响. LimitedPrivate协处理器API的下游用户将需要检查运行时环境的影响. 有关我们过去一直在协调兼容的运行时版本方面遇到问题的第三方库的新处理方法的详细信息,请参见参考指南中的hbase-thirdparty依赖关系和着色/重定位 .

客户端API的源和二进制兼容性的多项重大更改

用于HBase的Java客户端API进行了许多更改,这些更改破坏了源代码兼容性和二进制兼容性,有关详细信息,请参阅要升级到的版本的兼容性检查报告.

跟踪实施变更

HBase跟踪功能的支持实现已从Apache HTrace 3更新为HTrace 4,其中包括一些重大更改. 尽管HTrace 3和HTrace 4可以在同一运行时中共存,但它们不会彼此集成,从而导致跟踪信息脱节.

升级期间对HBase进行的内部更改足以进行编译,但是尚未确认跟踪功能没有任何退步. 请考虑此功能在不久的将来过期.

如果您以前依赖于与HBase操作集成的客户端跟踪,则建议您也将用法升级到HTrace 4.

HFile失去向前兼容性

由2.0.0、2.0.1、2.1.0生成的HFile与1.4.6-,1.3.2.1-,1.2.6.1-和其他非活动版本不向前兼容. 为什么HFile失去兼容性是新版本(2.0.0、2.0.1、2.1.0)中的hbase使用protobuf序列化/反序列化TimeRangeTracker(TRT),而旧版本使用DataInput / DataOutput. 为了解决这个问题,我们必须将HBASE-21012放入2.x,并将HBASE-21013放入1.x. 有关更多信息,请检查HBASE-21008 .

Performance

考虑到读写路径已发生重大变化,升级到hbase-2.0.0时,性能概要文件可能会发生变化. 在发布时,取决于上下文,写入可能会变慢,而读取大约相同或好得多. 准备花时间进行重新调整(请参阅Apache HBase性能调整 ). 性能也是一个需要积极审查的领域,因此希望在以后的发行版中有所改进(请参阅HBASE-20188测试性能 ).

默认压缩吞吐量

HBase 2.x带有默认的压缩执行速度限制. 此限制是按RegionServer定义的. 在以前的HBase版本中,默认情况下压缩的运行速度没有限制. 对压缩的吞吐量施加限制应确保来自RegionServer的操作更加稳定.

请注意,此限制是针对RegionServer的 ,而不是针对压缩的 .

吞吐量限制定义为每秒写入的字节范围,并允许在给定的上下限内变化. RegionServers观察压实的当前吞吐量,并应用线性公式相对于外部压力在上下限内调整允许的吞吐量. 对于压实,外部压力定义为相对于允许的最大存储文件数的存储文件数. 存储文件越多,压实压力越高.

此吞吐量的配置由以下属性控制.

  • 下限由hbase.hstore.compaction.throughput.lower.bound定义,默认为10 MB / s( 10485760 ).

  • 上限由hbase.hstore.compaction.throughput.higher.bound定义,默认为20 MB / s( 20971520 ).

要将这种行为恢复为早期版本的HBase的无限压缩吞吐量,请将以下属性设置为对压缩没有限制的实现.

hbase.regionserver.throughput.controller=org.apache.hadoop.hbase.regionserver.throttle.NoLimitThroughputController

13.1.2. Upgrading Coprocessors to 2.0

协处理器在2.0中进行了重大更改,从类层次结构中的顶级设计更改到更改/删除的方法,接口等(父级JiraHBASE-18169协处理器在2.0.0发行版之前的修复和清理 ). 如此广泛的变化的一些原因:

  1. 通过接口代替实现; 例如,TableDescriptor代替HTableDescriptor,Region代替HRegion( HBASE-18241 ,将client.Table和client.Admin更改为不使用HTableDescriptor).

  2. 设计重构,因此实现者需要填写的模板更少,因此我们可以进行更多的编译时检查( HBASE-17732

  3. Purge Protocol Buffers from Coprocessor API (HBASE-18859, HBASE-16769, etc)

  4. 减少我们向协处理器公开的内容,删除过于私有而无法公开的内部挂钩(例如, HBASE-18453 CompactionRequest不应直接公开给用户; HBASE-18298 RegionServerServices CP公开的接口清理等)

要在2.0中使用协处理器,应针对新的API重建它们,否则它们将无法加载且HBase进程将死亡.

升级协处理器的建议更改顺序:

  1. 直接实现观察者接口,而不是扩展Base * Observer类. 更改Foo extends BaseXXXObserverFoo implements XXXObserver . ( HBASE-17312 ).

  2. 通过遵循以下示例,适应从继承到合成( HBASE-17732 )的设计更改.

  3. getTable()已从CoprocessorEnvrionment中删除,协处理器应自我管理Table实例.

书写新的API协处理器的一些例子可以在HBase的,例如模块可以找到这里 .

最后,如果一个api被更改/删除以一种无法弥补的方式打扰了您,并且有充分的理由将其重新添加,请通知我们( dev@hbase.apache.org ).

13.1.3. Rolling Upgrade from 1.x to 2.x

滚动升级目前是一项实验功能. 他们的测试很有限. 我们有限的经验中可能还没有发现一些极端的情况,因此,如果您走这条路线,请务必小心. 下一节" 从1.x升级到2.x的过程"中描述的停止/升级/启动是最安全的方法.

也就是说,以下是1.4群集滚动升级的说明.

Pre-Requirements
  • 升级到最新的1.4.x版本. 1.4版之前的版本也可能有效,但未经测试,因此,除非您是专家并且熟悉区域分配和崩溃处理,否则请先升级到1.4.3+,再升级到2.x. 有关如何升级到1.4.x的信息,请参阅从1.4之前的版本升级到1.4+.

  • 确保启用了无zk分配,即,将hbase.assignment.usezk设置为false . 这是最重要的. 它允许1.x主服务器向/ x 2.x区域服务器分配/取消分配区域. 请参阅HBASE-11059的发行说明部分,以了解如何从基于zk的分配迁移到不包含zk的分配.

  • 我们已经测试了从1.4.3到2.1.0的滚动升级,但是如果您想升级到2.0.x,它也应该起作用.

Instructions
  1. 卸载区域服务器并将其升级到2.1.0. 使用HBASE-17931后,元区域和其他系统表的区域将立即移到该区域服务器. 如果没有,请手动将它们移动到新的区域服务器. 这很重要,因为

    • meta区域的模式是硬编码的,如果meta在旧的区域服务器上,则新的区域服务器无法访问它,因为它没有某些族,例如表状态.

    • 较低版本的客户端可以与较高版本的服务器进行通信,反之亦然. 如果元区域位于旧区域服务器上,则新区域服务器将使用具有较高版本的客户端与具有较低版本的服务器进行通信,这可能会带来奇怪的问题.

  2. 滚动升级所有其他区域服务器.

  3. 升级大师.

在滚动升级过程中,区域服务器会崩溃是可以的. 1.x主服务器可以将区域分配给1.x和2.x区域服务器,并且HBASE-19166解决了一个问题,因此1.x区域服务器也可以读取由2.x区域服务器编写的WAL并将其拆分.

请阅读变更说明! 滚动升级之前,请仔细阅读. 确保不使用2.0中已删除的功能,例如,前缀树编码,旧的hfile格式等.它们都可能导致升级失败,并使群集处于中间状态并且难以恢复.
如果您成功执行此处方,请向开发人员列表发送一份有关您的经验的注释,并/或使用可能发生的任何偏差更新以上内容,以便其他人从您的努力中受益.

13.1.4. Upgrade process from 1.x to 2.x

要升级现有的HBase 1.x群集,您应该:

  • 彻底关闭现有1.x群集

  • 更新协处理器

  • 首先升级主角色

  • 升级RegionServers

  • (最终)升级客户端

13.2. Upgrading from pre-1.4 to 1.4+

13.2.1. Region Server memory consumption changes.

从HBase 1.4之前的版本升级的用户应注意,对于最大32G的堆大小(使用CompressedOops),记忆库对象(KeyValue,对象和数组标头大小等)对堆使用情况的估计已更加精确,从而导致实际上,它们下降了10-50%. 由于"屑"冲洗,这也导致较少的冲洗和压实. YMMV. 结果,在刷新之前,memstore的实际堆使用量可能最多增加100%. 如果已根据观察到的使用情况调整了区域服务器的配置内存限制,则此更改可能导致更糟的GC行为,甚至导致OutOfMemory错误. 将环境属性(不是hbase-site.xml)" hbase.memorylayout.use.unsafe"设置为false以禁用.

13.2.2. Replication peer’s TableCFs config

Before 1.4, the table name can’t include namespace for replication peer’s TableCFs config. It was fixed by add TableCFs to ReplicationPeerConfig which was stored on Zookeeper. So when upgrade to 1.4, you have to update the original ReplicationPeerConfig data on Zookeeper firstly. There are four steps to upgrade when your cluster have a replication peer with TableCFs config.

  • 禁用复制对等方.

  • 如果master具有写复制对等znode的权限,则直接滚动更新master. 如果不是,请使用TableCFsUpdater工具更新复制对等方的配置.

$ bin/hbase org.apache.hadoop.hbase.replication.master.TableCFsUpdater update
  • 滚动更新区域服务器.

  • 启用复制对等方.

Notes:

  • 无法使用旧客户端(1.4之前的版本)更改复制对等方的配置. 由于客户端将配置直接写入Zookeeper,因此旧客户端将丢失TableCFs的配置. 并且旧客户端将TableCFs配置写入旧tablecfs znode,它将不适用于新版本的regionserver.

13.2.3. Raw scan now ignores TTL

Doing a raw scan will now return results that have expired according to TTL settings.

13.3. Upgrading from pre-1.3 to 1.3+

如果在Kerberos下运行集成测试,请参阅[upgrade2.0.it.kerberos] .

13.4. Upgrading to 1.x

请参阅专门针对要升级到的HBase版本发布的文档,以获取有关升级过程的详细信息.

The Apache HBase Shell

Apache HBase Shell是(J)Ruby的IRB,其中添加了一些HBase特定命令. 在IRB中可以执行的任何操作,都应该可以在HBase Shell中执行.

要运行HBase Shell,请执行以下操作:

$ ./bin/hbase shell

键入help ,然后输入<RETURN>以查看Shell命令和选项的列表. 至少浏览帮助输出末尾的段落,以了解如何将变量和命令参数输入HBase shell; 特别注意表名,行和列等必须加引号.

请参阅shell练习 ,例如基本的shell操作.

这是Rajeshbabu Chintaguntla编写的所有shell命令的格式良好的清单.

14. Scripting with Ruby

有关编写Apache HBase脚本的示例,请查看HBase bin目录. 查看以* .rb结尾的文件. 要运行这些文件之一,请执行以下操作:

$ ./bin/hbase org.jruby.Main PATH_TO_SCRIPT

15. Running the Shell in Non-Interactive Mode

新的非交互模式已添加到HBase Shell( HBASE-11658) . 非交互模式捕获HBase Shell命令的退出状态(成功或失败),并将该状态传递回命令解释器. 如果您使用普通交互模式,则HBase Shell将仅返回其自己的退出状态,为成功,该退出状态几乎始终为0 .

要调用非交互模式,请将-n--non-interactive选项传递给HBase Shell.

16. HBase Shell in OS Scripts

您可以在操作系统脚本解释器(例如Bash shell)中使用HBase shell,而Bash shell是大多数Linux和UNIX发行版的默认命令解释器. 以下准则使用Bash语法,但可以进行调整以与c样式的shell(例如csh或tcsh)一起使用,并且可以进行修改以与Microsoft Windows脚本解释器一起使用. 欢迎提交.

以这种方式生成HBase Shell命令的速度很慢,因此在决定何时将HBase操作与操作系统命令行结合使用时要牢记这一点.
例子4.将命令传递给HBase Shell

您可以使用echo命令和|以非交互方式将命令传递到HBase Shell(请参见hbase.shell.noninteractive| (管道)运算符. 确保在HBase命令中转义字符,否则这些字符会被Shell解释. 下面的示例已截断了某些调试级别的输出.

$ echo "describe 'test1'" | ./hbase shell -n

Version 0.98.3-hadoop2, rd5e65a9144e315bb0a964e7730871af32f5018d5, Sat May 31 19:56:09 PDT 2014

describe 'test1'

DESCRIPTION                                          ENABLED
 'test1', {NAME => 'cf', DATA_BLOCK_ENCODING => 'NON true
 E', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0',
  VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIO
 NS => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS =>
 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false'
 , BLOCKCACHE => 'true'}
1 row(s) in 3.2410 seconds

要取消所有输出,请将其回显到/ dev / null:

$ echo "describe 'test'" | ./hbase shell -n > /dev/null 2>&1
例子5.检查脚本命令的结果

由于脚本并非旨在以交互方式运行,因此您需要一种方法来检查命令是失败还是成功. HBase的外壳采用返回的值的标准约定0成功的命令,并为失败的命令一些非零值. Bash将命令的返回值存储在称为$?的特殊环境变量中$? . 由于该变量每次外壳程序运行任何命令时都会被覆盖,因此您应将结果存储在脚本定义的其他变量中.

这是一个幼稚的脚本,它显示了一种存储返回值并基于该值进行决策的方法.

#!/bin/bash

echo "describe 'test'" | ./hbase shell -n > /dev/null 2>&1
status=$?
echo "The status was " $status
if ($status == 0); then
    echo "The command succeeded"
else
    echo "The command may have failed."
fi
return $status

16.1. Checking for Success or Failure In Scripts

退出代码为0表示您编写的命令肯定成功. 但是,获得非零的退出代码并不一定意味着命令失败. 该命令可能已经成功,但是客户端失去了连接,或者其他事件掩盖了其成功. 这是因为RPC命令是无状态的. 确保操作状态的唯一方法是检查. 例如,如果您的脚本创建了一个表,但是返回了一个非零的退出值,则应在再次尝试创建表之前检查该表是否已真正创建.

17. Read HBase Shell Commands from a Command File

您可以将HBase Shell命令输入到文本文件中,每行一个命令,然后将该文件传递给HBase Shell.

示例命令文件
create 'test', 'cf'
list 'test'
put 'test', 'row1', 'cf:a', 'value1'
put 'test', 'row2', 'cf:b', 'value2'
put 'test', 'row3', 'cf:c', 'value3'
put 'test', 'row4', 'cf:d', 'value4'
scan 'test'
get 'test', 'row1'
disable 'test'
enable 'test'
例子6.指示HBase Shell执行命令

将路径传递到命令文件作为hbase shell命令的唯一参数. 每个命令都会执行,并显示其输出. 如果脚本中未包含exit命令,则会返回到HBase shell提示符. 无法以编程方式检查每个命令的成功或失败. 同样,尽管您看到了每个命令的输出,但命令本身并未回显到屏幕上,因此很难将命令与其输出对齐.

$ ./hbase shell ./sample_commands.txt
0 row(s) in 3.4170 seconds

TABLE
test
1 row(s) in 0.0590 seconds

0 row(s) in 0.1540 seconds

0 row(s) in 0.0080 seconds

0 row(s) in 0.0060 seconds

0 row(s) in 0.0060 seconds

ROW                   COLUMN+CELL
 row1                 column=cf:a, timestamp=1407130286968, value=value1
 row2                 column=cf:b, timestamp=1407130286997, value=value2
 row3                 column=cf:c, timestamp=1407130287007, value=value3
 row4                 column=cf:d, timestamp=1407130287015, value=value4
4 row(s) in 0.0420 seconds

COLUMN                CELL
 cf:a                 timestamp=1407130286968, value=value1
1 row(s) in 0.0110 seconds

0 row(s) in 1.5630 seconds

0 row(s) in 0.4360 seconds

18. Passing VM Options to the Shell

您可以使用HBASE_SHELL_OPTS环境变量将VM选项传递给HBase Shell. 您可以在环境中进行设置,例如通过编辑〜/ .bashrc ,或将其设置为启动HBase Shell的命令的一部分. 以下示例仅在运行HBase Shell的VM的生命周期内设置了几个与垃圾回收相关的变量. 该命令应全部在一行上运行,但为了便于阅读,请用\字符打断.

$ HBASE_SHELL_OPTS="-verbose:gc -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCDateStamps \
  -XX:+PrintGCDetails -Xloggc:$HBASE_HOME/logs/gc-hbase.log" ./bin/hbase shell

19. Overriding configuration starting the HBase Shell

从hbase-2.0.5 / hbase-2.1.3 / hbase-2.2.0 / hbase-1.4.10 / hbase-1.5.0开始,您可以通过传递或覆盖hbase-*.xml指定的hbase配置在命令行上以-D为前缀的键/值,如下所示:

$ ./bin/hbase shell -Dhbase.zookeeper.quorum=ZK0.remote.cluster.example.org,ZK1.remote.cluster.example.org,ZK2.remote.cluster.example.org -Draining=false
...
hbase(main):001:0> @shell.hbase.configuration.get("hbase.zookeeper.quorum")
=> "ZK0.remote.cluster.example.org,ZK1.remote.cluster.example.org,ZK2.remote.cluster.example.org"
hbase(main):002:0> @shell.hbase.configuration.get("raining")
=> "false"

20. Shell Tricks

20.1. Table variables

HBase 0.95添加了Shell命令,这些命令为表提供了jruby样式的面向对象的引用. 以前,作用于表的所有shell命令都具有一种程序样式,该程序样式始终将表的名称作为参数. HBase 0.95引入了将表分配给jruby变量的功能. 该表引用可用于执行数据读写操作,例如放置,扫描以及获取良好的管理功能,例如禁用,删除,描述表.

例如,以前您总是要指定一个表名:

hbase(main):000:0> create 't', 'f'
0 row(s) in 1.0970 seconds
hbase(main):001:0> put 't', 'rold', 'f', 'v'
0 row(s) in 0.0080 seconds

hbase(main):002:0> scan 't'
ROW                                COLUMN+CELL
 rold                              column=f:, timestamp=1378473207660, value=v
1 row(s) in 0.0130 seconds

hbase(main):003:0> describe 't'
DESCRIPTION                                                                           ENABLED
 't', {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_ true
 SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2
 147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false
 ', BLOCKCACHE => 'true'}
1 row(s) in 1.4430 seconds

hbase(main):004:0> disable 't'
0 row(s) in 14.8700 seconds

hbase(main):005:0> drop 't'
0 row(s) in 23.1670 seconds

hbase(main):006:0>

现在,您可以将表分配给变量,并在jruby shell代码中使用结果.

hbase(main):007 > t = create 't', 'f'
0 row(s) in 1.0970 seconds

=> Hbase::Table - t
hbase(main):008 > t.put 'r', 'f', 'v'
0 row(s) in 0.0640 seconds
hbase(main):009 > t.scan
ROW                           COLUMN+CELL
 r                            column=f:, timestamp=1331865816290, value=v
1 row(s) in 0.0110 seconds
hbase(main):010:0> t.describe
DESCRIPTION                                                                           ENABLED
 't', {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_ true
 SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2
 147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false
 ', BLOCKCACHE => 'true'}
1 row(s) in 0.0210 seconds
hbase(main):038:0> t.disable
0 row(s) in 6.2350 seconds
hbase(main):039:0> t.drop
0 row(s) in 0.2340 seconds

如果已经创建了表,则可以使用get_table方法将表分配给变量:

hbase(main):011 > create 't','f'
0 row(s) in 1.2500 seconds

=> Hbase::Table - t
hbase(main):012:0> tab = get_table 't'
0 row(s) in 0.0010 seconds

=> Hbase::Table - t
hbase(main):013:0> tab.put 'r1' ,'f', 'v'
0 row(s) in 0.0100 seconds
hbase(main):014:0> tab.scan
ROW                                COLUMN+CELL
 r1                                column=f:, timestamp=1378473876949, value=v
1 row(s) in 0.0240 seconds
hbase(main):015:0>

列表功能也得到了扩展,以便它以字符串形式返回表名列表. 然后,您可以使用jruby根据这些名称对表操作进行脚本编写. list_snapshots命令的行为也类似.

hbase(main):016 > tables = list('t.*')
TABLE
t
1 row(s) in 0.1040 seconds

=> #<#<Class:0x7677ce29>:0x21d377a4>
hbase(main):017:0> tables.map { |t| disable t ; drop  t}
0 row(s) in 2.2510 seconds

=> [nil]
hbase(main):018:0>

20.2. irbrc

在您的主目录中为自己创建一个.irbrc文件. 添加自定义项. 命令历史是一个有用的命令,因此命令可在Shell调用之间保存:

$ more .irbrc
require 'irb/ext/save-history'
IRB.conf[:SAVE_HISTORY] = 100
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-save-history"

如果要避免将对每个表达式求值的结果打印到stderr,例如,从" list"命令返回的表数组:

$ echo "IRB.conf[:ECHO] = false" >>~/.irbrc

请参阅.irbrcruby文档以了解其他可能的配置.

20.3. LOG data to timestamp

要将日期" 08/08/16 20:56:29"从hbase日志转换为时间戳,请执行以下操作:

hbase(main):021:0> import java.text.SimpleDateFormat
hbase(main):022:0> import java.text.ParsePosition
hbase(main):023:0> SimpleDateFormat.new("yy/MM/dd HH:mm:ss").parse("08/08/16 20:56:29", ParsePosition.new(0)).getTime() => 1218920189000

要走另一个方向:

hbase(main):021:0> import java.util.Date
hbase(main):022:0> Date.new(1218920189000).toString() => "Sat Aug 16 20:56:29 UTC 2008"

要输出与HBase日志格式完全相同的格式,将使SimpleDateFormat有点混乱.

20.4. Query Shell Configuration

hbase(main):001:0> @shell.hbase.configuration.get("hbase.rpc.timeout")
=> "60000"

要在外壳中设置配置:

hbase(main):005:0> @shell.hbase.configuration.setInt("hbase.rpc.timeout", 61010)
hbase(main):006:0> @shell.hbase.configuration.get("hbase.rpc.timeout")
=> "61010"

20.5. Pre-splitting tables with the HBase Shell

通过HBase Shell create命令创建表时,可以使用各种选项来预分割表.

最简单的方法是在创建表时指定分割点数组. 请注意,当将字符串文字指定为拆分点时,它们将基于字符串的基础字节表示形式创建拆分点. 因此,当指定分割点" 10"时,实际上是在指定字节分割点" \ x31 \ 30".

分割点将定义n+1区域,其中n是分割点的数量. 最低的区域将包含从最低可能的按键到第一个分割点按键的所有按键,但不包括这些按键. 下一个区域将包含从第一个分割点到下一个分割点的键,但不包括下一个分割点的键. 这将对所有拆分点一直持续到最后. 从最后的分割点到最大可能的键将定义最后一个区域.

hbase>create 't1','f',SPLITS => ['10','20','30']

在上面的示例中,表" t1"将使用列族" f"创建,并被预分割为四个区域. 请注意,第一个区域将包含从'\ x00'到'\ x30'的所有键(因为'\ x31'是'1'的ASCII码).

您可以使用以下变体在文件中传递分割点. 在此示例中,从与本地文件系统上的本地路径相对应的文件中读取拆分. 文件中的每一行都指定一个分割点键.

hbase>create 't14','f',SPLITS_FILE=>'splits.txt'

其他选项是根据所需的区域数量和分割算法自动计算分割. HBase提供了用于基于统一拆分或基于十六进制密钥拆分密钥范围的算法,但是您可以提供自己的拆分算法来细分密钥范围.

# create table with four regions based on random bytes keys
hbase>create 't2','f1', { NUMREGIONS => 4 , SPLITALGO => 'UniformSplit' }

# create table with five regions based on hex keys
hbase>create 't3','f1', { NUMREGIONS => 5, SPLITALGO => 'HexStringSplit' }

由于HBase Shell实际上是Ruby环境,因此您可以使用简单的Ruby脚本通过算法计算拆分.

# generate splits for long (Ruby fixnum) key range from start to end key
hbase(main):070:0> def gen_splits(start_key,end_key,num_regions)
hbase(main):071:1>   results=[]
hbase(main):072:1>   range=end_key-start_key
hbase(main):073:1>   incr=(range/num_regions).floor
hbase(main):074:1>   for i in 1 .. num_regions-1
hbase(main):075:2>     results.push([i*incr+start_key].pack("N"))
hbase(main):076:2>   end
hbase(main):077:1>   return results
hbase(main):078:1> end
hbase(main):079:0>
hbase(main):080:0> splits=gen_splits(1,2000000,10)
=> ["\000\003\r@", "\000\006\032\177", "\000\t'\276", "\000\f4\375", "\000\017B<", "\000\022O{", "\000\025\\\272", "\000\030i\371", "\000\ew8"]
hbase(main):081:0> create 'test_splits','f',SPLITS=>splits
0 row(s) in 0.2670 seconds

=> Hbase::Table - test_splits

Note that the HBase Shell command truncate effectively drops and recreates the table with default options which will discard any pre-splitting. If you need to truncate a pre-split table, you must drop and recreate the table explicitly to re-specify custom split options.

20.6. Debug

20.6.1. Shell debug switch

您可以在外壳程序中设置调试开关,以在运行命令时查看更多输出(例如,更多有关异常的堆栈跟踪):

hbase> debug <RETURN>

20.6.2. DEBUG log level

要在外壳中启用DEBUG级别的日志记录,请使用-d选项启动它.

$ ./bin/hbase shell -d

20.7. Commands

20.7.1. count

Count命令返回表中的行数. 当配置正确的CACHE时,速度非常快

hbase> count '<tablename>', CACHE => 1000

上面的计数一次获取1000行. 如果行很大,请将CACHE降低. 默认值为一次获取​​一行.

Data Model

在HBase中,数据存储在具有行和列的表中. 这是与关系数据库(RDBMS)的术语重叠,但这并不是一个有用的类比. 相反,将HBase表视为多维映射可能会有所帮助.

HBase数据模型术语
Table

一个HBase表由多行组成.

Row

HBase中的一行由行键和一列或多列与它们相关联的值组成. 行在存储时按行键按字母顺序排序. 因此,行键的设计非常重要. 目标是以相关行彼此靠近的方式存储数据. 常见的行密钥模式是网站域. 如果行键是域,则应该将它们反向存储(org.apache.www,org.apache.mail,org.apache.jira). 这样,所有Apache域在表中彼此靠近,而不是根据子域的第一个字母散布开来.

Column

HBase中的列由列族和列限定符组成,它们由:冒号)字符分隔.

Column Family

Column families physically colocate a set of columns and their values, often for performance reasons. Each column family has a set of storage properties, such as whether its values should be cached in memory, how its data is compressed or its row keys are encoded, and others. Each row in a table has the same column families, though a given row might not store anything in a given column family.

Column Qualifier

将列限定符添加到列族,以提供给定数据段的索引. 给定列族content ,列限定符可能是content:html ,另一个可能是content:pdf . 尽管列族在创建表时是固定的,但列限定符是可变的,并且行之间的差异可能很大.

Cell

单元格是行,列族和列限定符的组合,并包含一个值和一个时间戳,代表该值的版本.

Timestamp

时间戳记与每个值一起写入,并且是值的给定版本的标识符. 默认情况下,时间戳表示写入数据时在RegionServer上的时间,但是在将数据放入单元格时可以指定其他时间戳值.

21. Conceptual View

您可以在Jim R. Wilson的博客文章《 了解HBase和BigTable》中阅读有关HBase数据模型的非常容易理解的解释. Amandeep Khurana的PDF 《基本模式设计简介》中提供了另一个很好的解释.

可能有助于阅读不同的观点,以便对HBase模式设计有深入的了解. 链接的文章所涵盖的内容与本节中的内容相同.

以下示例是BigTable论文第2页上的形式的略微修改形式. 有一个名为webtable的表,该表包含两行( com.cnn.wwwcom.example.www )以及三个名为contentsanchorpeople列族. 在此示例中,对于第一行( com.cnn.www ), anchor包含两列( anchor:cssnsi.comanchor:my.look.ca ), contents包含一列( anchor:my.look.ca contents:html ). 本示例包含具有行键com.cnn.www的行的5个版本和具有行键com.example.www的行的一个版本. contents:html列限定符包含给定网站的整个HTML. anchor列族的限定词均包含链接到该行表示的站点的外部站点,以及在其链接的锚定中使用的文本. people列族代表与该站点关联的人员.

列名

按照惯例,列名由其列族前缀和限定符组成 . 例如, contents:html列由列族contentshtml限定符组成. 冒号( : )划界柱族预选赛柱族.

表6.表webtable
行键 时标 ColumnFamily contents ColumnFamily anchor ColumnFamily people

"com.cnn.www"

t9

锚:cnnsi.com =" CNN"

"com.cnn.www"

t8

anchor:my.look.ca =" CNN.com"

"com.cnn.www"

t6

contents:html =" <html>…

"com.cnn.www"

t5

contents:html =" <html>…

"com.cnn.www"

t3

contents:html =" <html>…

"com.example.www"

t5

contents:html =" <html>…

people:author =" John Doe"

该表中看起来为空的单元格在HBase中不占用空间,或者实际上不存在. 这就是使HBase"稀疏"的原因. 表格视图不是查看HBase中数据的唯一可能方法,甚至不是最准确的方法. 以下代表与多维地图相同的信息. 这仅是出于说明目的的模型,可能并非严格准确.

{
  "com.cnn.www": {
    contents: {
      t6: contents:html: "<html>..."
      t5: contents:html: "<html>..."
      t3: contents:html: "<html>..."
    }
    anchor: {
      t9: anchor:cnnsi.com = "CNN"
      t8: anchor:my.look.ca = "CNN.com"
    }
    people: {}
  }
  "com.example.www": {
    contents: {
      t5: contents:html: "<html>..."
    }
    anchor: {}
    people: {
      t5: people:author: "John Doe"
    }
  }
}

22. Physical View

尽管从概念上讲,表可以看作是行的稀疏集合,但它们实际上是按列族存储的. 可以随时将新的列限定符(column_family:column_qualifier)添加到现有的列族中.

表7. ColumnFamily anchor
行键 时标 列族anchor

"com.cnn.www"

t9

anchor:cnnsi.com = "CNN"

"com.cnn.www"

t8

anchor:my.look.ca = "CNN.com"

表8. ColumnFamily的contents
行键 时标 ColumnFamily contents:

"com.cnn.www"

t6

contents:html =" <html>…

"com.cnn.www"

t5

contents:html =" <html>…

"com.cnn.www"

t3

contents:html =" <html>…

The empty cells shown in the conceptual view are not stored at all. Thus a request for the value of the contents:html column at time stamp t8 would return no value. Similarly, a request for an anchor:my.look.ca value at time stamp t9 would return no value. However, if no timestamp is supplied, the most recent value for a particular column would be returned. Given multiple versions, the most recent is also the first one found, since timestamps are stored in descending order. Thus a request for the values of all columns in the row com.cnn.www if no timestamp is specified would be: the value of contents:html from timestamp t6, the value of anchor:cnnsi.com from timestamp t9, the value of anchor:my.look.ca from timestamp t8.

有关Apache HBase如何存储数据的内部信息,请参阅regions.arch .

23. Namespace

命名空间是表的逻辑分组,类似于关系数据库系统中的数据库. 这种抽象为即将到来的多租户相关功能奠定了基础:

  • 配额管理( HBASE-8410 )-限制名称空间可以消耗的资源(即区域,表)数量.

  • 命名空间安全管理( HBASE-9206 )-为租户提供另一级别的安全管理.

  • 区域服务器组( HBASE-6721 )-可以将名称空间/表固定到RegionServers的子集上,从而保证了粗略的隔离级别.

23.1. Namespace management

可以创建,删除或更改名称空间. 命名空间成员资格是在表创建期间通过指定以下格式的标准表名来确定的:

<table namespace>:<table qualifier>
例子7.例子
#Create a namespace
create_namespace 'my_ns'
#create my_table in my_ns namespace
create 'my_ns:my_table', 'fam'
#drop namespace
drop_namespace 'my_ns'
#alter namespace
alter_namespace 'my_ns', {METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}

23.2. Predefined namespaces

有两个预定义的特殊名称空间:

  • hbase-系统名称空间,用于包含HBase内部表

  • 默认-没有显式指定名称空间的表将自动落入该名称空间

例子8.例子
#namespace=foo and table qualifier=bar
create 'foo:bar', 'fam'

#namespace=default and table qualifier=bar
create 'bar', 'fam'

24. Table

表在架构定义时预先声明.

25. Row

Row keys are uninterpreted bytes. Rows are lexicographically sorted with the lowest order appearing first in a table. The empty byte array is used to denote both the start and end of a tables' namespace.

26. Column Family

Apache HBase中的被分组为列族 . 列族的所有列成员都具有相同的前缀. 例如,列courses:historycourses:math都是courses列族的成员. 冒号( : )划界柱族预选赛柱族. 列族前缀必须由可打印字符组成. 限定尾部(列族限定符 )可以由任意字节组成. 列族必须在架构定义时预先声明,而不必在架构时定义列,但可以在表启动并运行时即时对其进行构想.

实际上,所有列族成员都一起存储在文件系统上. 由于调整和存储规范是在列族级别上完成的,因此建议所有列族成员具有相同的常规访问模式和大小特征.

27. Cells

{行,列,版本}元组精确地指定了HBase中的一个cell . 单元格内容是未解释的字节

28. Data Model Operations

四个主要的数据模型操作是"获取","放置","扫描"和"删除". 通过Table实例应用操作.

28.1. Get

获取指定行的返回属性. 通过Table.get执行获取

28.2. Put

Put可以将新行添加到表中(如果键是新键),也可以更新现有行(如果键已经存在). 通过Table.put (非writeBuffer)或Table.batch (非writeBuffer)执行看跌期权

28.3. Scans

扫描允许对指定属性的多行迭代.

以下是"扫描表"实例的示例. 假定一个表中填充了键为" row1"," row2"," row3"的行,然后填充了另一组键为" abc1"," abc2"和" abc3"的行. 以下示例显示如何设置Scan实例以返回以" row"开头的行.

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...

Table table = ...      // instantiate a Table instance

Scan scan = new Scan();
scan.addColumn(CF, ATTR);
scan.setRowPrefixFilter(Bytes.toBytes("row"));
ResultScanner rs = table.getScanner(scan);
try {
  for (Result r = rs.next(); r != null; r = rs.next()) {
    // process result...
  }
} finally {
  rs.close();  // always close the ResultScanner!
}

请注意,通常,为扫描指定特定停止点的最简单方法是使用InclusiveStopFilter类.

28.4. Delete

删除从表中删除一行. 删除是通过Table.delete执行的.

HBase不会就地修改数据,因此删除操作是通过创建称为墓碑的新标记来进行的. 这些墓碑以及固定价格将在大型压实中清理.

有关删除列版本的更多信息,请参见version.delete ;有关压缩的更多信息,请参见压缩.

29. Versions

{行,列,版本}元组精确地指定了HBase中的一个cell . 可能会有无数个单元格,其中行和列相同,但单元格地址仅在其版本维度上有所不同.

当行键和列键表示为字节时,使用长整数指定版本. 通常,此long包含一些时间实例,例如java.util.Date.getTime()System.currentTimeMillis()返回的那些实例,即: 当前时间与1970年1月1日午夜之间的差(以毫秒为单位) .

HBase版本维以降序存储,因此从存储文件中读取时,将首先找到最新值.

在HBase中,关于cell版本的语义存在很多混乱. 特别是:

  • 如果对一个单元的多次写入具有相同版本,则只有最后一次写入是可获取的.

  • 可以按非递增版本顺序写入单元格.

下面我们描述HBase中版本维度当前的工作方式. 有关HBase版本的讨论,请参见HBASE-2406 . HBase中的弯曲时间使您可以更好地阅读HBase中的版本或时间维度. 它比此处提供的版本详细信息更多.

在撰写本文时,HBase中不再存在本文中提到的在现有时间戳上覆盖值的限制. 这部分基本上是Bruno Dumon撰写的这篇文章的提要.

29.1. Specifying the Number of Versions to Store

给定列存储的最大版本数是列模式的一部分,并在创建表时指定,或通过alter命令通过HColumnDescriptor.DEFAULT_VERSIONS . 在HBase 0.96之前,保留的默认版本数是3 ,但在0.96和更高版本中已更改为1 .

示例9.修改列族的最大版本数

本示例使用HBase Shell保留列族f1中所有列的最多5个版本. 您也可以使用HColumnDescriptor .

hbase> alter ‘t1′, NAME => ‘f1′, VERSIONS => 5
例子10.修改一个列族的最小版本数

您还可以指定每个列系列要存储的最小版本数. 默认情况下,它设置为0,这意味着该功能被禁用. 以下示例通过HBase Shell将列族f1所有列的最小版本数设置为2 . 您也可以使用HColumnDescriptor .

hbase> alter ‘t1′, NAME => ‘f1′, MIN_VERSIONS => 2

从HBase 0.98.2开始,可以通过在hbase-site.xml中设置hbase.column.max.version来为所有新创建的列保留的最大版本数指定全局默认值. 参见hbase.column.max.version .

29.2. Versions and HBase Operations

在本节中,我们研究每个核心HBase操作的版本维度的行为.

29.2.1. Get/Scan

获取是在扫描之上实现的. 以下有关Get的讨论同样适用于Scans .

默认情况下,即,如果您未指定显式版本,则在执行get ,将返回其版本具有最大值的单元格(该单元格可能不是最新写入的单元格,请参阅稍后). 可以通过以下方式修改默认行为:

  • 返回多个版本,请参见Get.setMaxVersions()

  • 返回除最新版本以外的版本,请参见Get.setTimeRange()

    To retrieve the latest version that is less than or equal to a given value, thus giving the 'latest' state of the record at a certain point in time, just use a range from 0 to the desired version and set the max versions to 1.

29.2.2. Default Get Example

以下"获取"将仅检索该行的当前版本

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Get get = new Get(Bytes.toBytes("row1"));
Result r = table.get(get);
byte[] b = r.getValue(CF, ATTR);  // returns current version of value

29.2.3. Versioned Get Example

下面的Get将返回该行的最后3个版本.

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Get get = new Get(Bytes.toBytes("row1"));
get.setMaxVersions(3);  // will return last 3 versions of row
Result r = table.get(get);
byte[] b = r.getValue(CF, ATTR);  // returns current version of value
List<KeyValue> kv = r.getColumn(CF, ATTR);  // returns all versions of this column

29.2.4. Put

做一个看跌总是会创建一个新版本的cell ,在一定的时间戳记. 默认情况下,系统使用服务器的currentTimeMillis ,但是您可以在每个列级别上currentTimeMillis指定版本(=长整数). 这意味着您可以分配过去或将来的时间,或将long值用于非时间目的.

要覆盖现有值,请在与要覆盖的单元格完全相同的行,列和版本上进行放置.

Implicit Version Example

HBase将使用当前时间对以下Put进行隐式版本控制.

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Put put = new Put(Bytes.toBytes(row));
put.add(CF, ATTR, Bytes.toBytes( data));
table.put(put);
Explicit Version Example

下面的Put具有明确设置的版本时间戳.

public static final byte[] CF = "cf".getBytes();
public static final byte[] ATTR = "attr".getBytes();
...
Put put = new Put( Bytes.toBytes(row));
long explicitTimeInMs = 555;  // just an example
put.add(CF, ATTR, explicitTimeInMs, Bytes.toBytes(data));
table.put(put);

注意:HBase在内部使用版本时间戳来进行生存时间计算. 通常最好避免自己设置此时间戳. 首选使用行的单独时间戳属性,或将时间戳作为行键的一部分,或两者兼而有之.

29.2.5. Delete

有三种不同类型的内部删除标记. 请参阅Lars Hofhansl的博客,以了解有关他尝试添加其他内容( 在HBase中扫描:前缀删除标记)的尝试.

  • 删除:用于特定版本的列.

  • 删除列:适用于列的所有版本.

  • 删除族:针对特定ColumnFamily的所有列

When deleting an entire row, HBase will internally create a tombstone for each ColumnFamily (i.e., not each individual column).

通过创建逻辑删除标记来删除工作. 例如,假设我们要删除一行. 为此,您可以指定一个版本,否则默认使用currentTimeMillis . 这意味着删除版本小于或等于此版本的所有单元格 . HBase永远不会在适当位置修改数据,例如,删除操作不会立即删除(或标记为已删除)存储文件中与删除条件相对应的条目. 而是写了一个所谓的墓碑 ,它将掩盖已删除的值. 当HBase进行重大压缩时,将处理逻辑删除以实际删除无效值以及逻辑删除本身. 如果删除行时指定的版本大于该行中任何值的版本,则可以考虑删除整个行.

有关删除和版本控制如何交互的信息性讨论,请参见线程在用户邮件列表上出现" 放置时间/时间戳"→Deleteall→"放置时间/时间戳"失败 .

另请参阅键值 ,以获取有关内部键值格式的更多信息.

除非在列族中设置了KEEP_DELETED_CELLS选项,否则在KEEP_DELETED_CELLS商店的主要压缩期间将删除删除标记(请参见保留已删除的单元格 ). 要使删除保持可配置的时间,可以通过hbase-site.xml中的hbase.hstore.time.to.purge.deletes属性设置删除TTL. 如果未设置hbase.hstore.time.to.purge.deletes或将其设置为0,则在下一次主要压缩期间将清除所有删除标记,包括将来带有时间戳的标记. 否则,将保留将来带有时间戳的删除标记,直到在该标记的时间戳加上hbase.hstore.time.to.purge.deletes的值所表示的时间之后的主要压缩hbase.hstore.time.to.purge.deletes (以毫秒为单位).

此行为表示对HBase 0.94中引入的意外更改的修复,并在HBASE-10118中进行了修复 . 所做的更改已反向移植到HBase 0.94和更新的分支中.

29.3. Optional New Version and Delete behavior in HBase-2.0.0

hbase-2.0.0 ,操作员可以通过将列描述符属性NEW_VERSION_BEHAVIOR设置为true来指定备用版本并删除处理(要在列族描述符上设置属性,必须首先禁用表,然后更改列族描述符;有关在列族描述符上编辑属性的示例,请参见" 保留已删除的单元格 ".

"新版本行为"消除了以下列出的限制,即在相同位置(即,相同的行,列族,限定词和时间戳记),无论哪个先到达," Delete总是"都会使" Put蒙上阴影. 版本记帐也将更改,因为已删除的版本将被视为总版本数. 这样做是为了确保在进行重大压实时不会改变结果. 有关讨论,请参见HBASE-15968和链接的问题.

目前,使用此新配置运行需要花费很多; 我们在每次比较时都将Cell MVCC计入因素,因此可以消耗更多的CPU. 减速将取决于. 在测试中,我们发现性能下降了0%到25%.

如果要复制,建议您现在使用新的串行复制功能(请参阅HBASE-9465 ;串行复制功能未将其放入hbase-2.0.0但应在后续的hbase-2.x版本中提供)突变到达的顺序是一个因素.

29.4. Current Limitations

hbase-2.0.0中解决了以下限制. 请参阅上面的HBase-2.0.0中的可选新版本和删除行为部分 .

29.4.1. Deletes mask Puts

删除蒙版看跌期权,甚至是输入删除后发生的看跌期权. 参见HBASE-2256 . 请记住,删除操作会写入一个墓碑,该墓碑只有在下一次重大压缩运行后才会消失. 假设您删除了所有内容⇐T.之后,您将使用时间戳⇐T进行新的放置.此放置,即使它在删除后发生,也会被删除逻辑删除掩盖. 进行认沽不会失败,但是当您进行认沽时,您会注意到认沽没有任何效果. 在大型压实运行之后,它将重新开始工作. 如果您对新的看跌期权连续使用不断增加的版本,这些问题应该不会成为问题. 但是,即使您不在乎时间,它们也可能发生:只需删除并立即放置就可以了,它们有可能在同一毫秒内发生.

29.4.2. Major compactions change query results

…在t1,t2和t3处创建三个单元格版本,最大版本设置为2.因此,在获取所有版本时,将仅返回t2和t3处的值. 但是,如果您在t2或t3删除版本,则t1的版本会再次出现. 显然,一旦进行了重大压实,这种情况就不再存在了...... (See 垃圾收集 in Bending time in HBase.)

30. Sort Order

All data model operations HBase return data in sorted order. First by row, then by ColumnFamily, followed by column qualifier, and finally timestamp (sorted in reverse, so newest records are returned first).

31. Column Metadata

在ColumnFamily的内部KeyValue实例之外没有任何列元数据存储. 因此,尽管HBase不仅可以支持每行大量列,而且还可以支持行之间的异构列集,但是您有责任跟踪列名.

获取ColumnFamily存在的一组完整列的唯一方法是处理所有行. 有关HBase如何在内部存储数据的更多信息,请参见keyvalue .

32. Joins

HBase是否支持联接是dist-list上的一个常见问题,并且有一个简单的答案:至少在RDBMS支持联接的方式上(例如,在SQL中使用等联接或外部联接) ). 如本章所述,HBase中的读取数据模型操作是Get和Scan.

但是,这并不意味着您的应用程序不支持等效的联接功能,而是您必须自己做. 两种主要策略是在写入HBase时对数据进行非规范化,或者在应用程序或MapReduce代码中具有查找表并在HBase表之间进行联接(正如RDBMS所演示的那样,有多种策略可用于此操作,具体取决于表,例如,嵌套循环与哈希联接). 那么哪种方法最好呢? 这取决于您要执行的操作,因此,没有一个适用于每个用例的答案.

33. ACID

请参阅ACID语义 . Lars Hofhansl还在HBase中撰写了有关ACID的说明.

HBase and Schema Design

可以在Ian Varley的硕士论文《 无关系:非关系数据库的混合祝福》中找到有关各种非rdbms数据存储的优缺点建模的很好的介绍. 如果您有一点时间了解HBase模式建模与RDBMS中的建模方法有何不同,那么现在它有点过时了,但是请阅读大量的背景知识. 另外,读键值为HBase的存储如何在内部数据,并在部分schema.casestudies .

Cloud Bigtable网站上的文档" Designing Schema "是相关的,并且做得很好,在那里获得的经验教训同样适用于HBase. 只需将所有引用的值除以〜10即可得到适用于HBase的值:例如,其中指出单个值的大小约为10MB,HBase可以做类似的事情-可能的话最好减小它-并说最大为100 Cloud Bigtable中的列族,在HBase上建模时大约需要10个.

另请参阅Robert Yokota的HBase应用程序原型 (其他HBasers完成的工作的更新),以获取对在HBase模型之上运行良好的用例的有用分类.

34. Schema Creation

可以使用Apache HBase Shell或Java API中的Admin创建或更新HBase模式.

进行ColumnFamily修改时,必须禁用表,例如:

Configuration config = HBaseConfiguration.create();
Admin admin = new Admin(conf);
TableName table = TableName.valueOf("myTable");

admin.disableTable(table);

HColumnDescriptor cf1 = ...;
admin.addColumn(table, cf1);      // adding new ColumnFamily
HColumnDescriptor cf2 = ...;
admin.modifyColumn(table, cf2);    // modifying existing ColumnFamily

admin.enableTable(table);

有关配置客户端连接的更多信息,请参见客户端依赖性 .

0.92.x代码库支持联机模式更改,但是0.90.x代码库要求禁用该表.

34.1. Schema Updates

当对Tables或ColumnFamilies进行更改(例如,区域大小,块大小)时,这些更改将在下次进行重大压缩时生效,并且StoreFiles将被重写.

有关StoreFiles的更多信息,请参见store .

35. Table Schema Rules Of Thumb

有许多不同的数据集,具有不同的访问模式和服务级别期望. 因此,这些经验法则只是一个概述. 阅读完此列表后,请阅读本章的其余部分以获取更多详细信息.

  • 旨在具有10到50 GB之间的区域.

  • 力争使单元格不超过10 MB,如果使用mob则不超过50 MB. 否则,请考虑将单元数据存储在HDFS中,并将指向数据的指针存储在HBase中.

  • 典型的架构每个表具有1到3个列族. HBase表不应设计为模仿RDBMS表.

  • 对于带有1或2个列族的表,大约50-100个区域是一个不错的数字. 请记住,区域是列族的连续段.

  • 列的姓氏应尽量短. 将为每个值存储列族名称(忽略前缀编码). 它们不应像典型的RDBMS中那样具有自我说明性和描述性.

  • 如果要存储基于时间的机器数据或日志记录信息,并且行键是基于设备ID或服务ID加上时间的,则您可能会遇到一种模式,即较旧的数据区域在特定时间范围内永远不会进行其他写入. 在这种情况下,最终会遇到少量活动区域和大量较旧的区域,而这些区域没有新的写入操作. 对于这些情况,您可以容忍更多区域,因为资源消耗仅由活动区域驱动.

  • 如果只有一个列族忙于写操作,则只有该列族会占用内存. 分配资源时要注意写模式.

RegionServer Sizing Rules of Thumb

Lars Hofhansl写了一篇很棒的博客文章,介绍RegionServer内存大小. 结果是您可能需要比您认为需要的更多的内存. 他探讨了区域大小,存储区大小,HDFS复制因子以及其他要检查的因素的影响.

就我个人而言,除非您的工作负载非常繁重,否则我将把每台机器可以由HBase专门提供的最大磁盘空间放在6T左右. 在这种情况下,Java堆应为32GB(20G区域,128M内存存储,其余为默认值).

-拉斯·霍夫汉斯
http://hadoop-hbase.blogspot.com/2013/01/hbase-region-server-memory-sizing.html

36. On the number of column families

HBase当前不能很好地处理超过两个或三个列族的任何事物,因此请保持架构中列族的数量少. 当前,刷新和压缩是在每个区域的基础上进行的,因此,如果一个列族正在承载大量要进行刷新的数据,即使相邻族也将被刷新,即使它们携带的数据量很小. 当存在许多色谱柱系列时,冲洗和压实相互作用会导致大量不必要的I / O(通过更改冲洗和压实以在每个色谱柱族的基础上解决). 有关压缩的更多信息,请参见压缩 .

如果可以,请尝试使用一个列族. 仅在通常以列为范围的数据访问的情况下才引入第二和第三列族. 即,您查询一个列族或另一个列族,但一次却不是两个都查询.

36.1. Cardinality of ColumnFamilies

在单个表中存在多个ColumnFamilies的地方,请注意基数(即行数). 如果ColumnFamilyA具有100万行,而ColumnFamilyB具有10亿行,则ColumnFamilyA的数据可能会分布在许多区域(以及RegionServers)中. 这使得对ColumnFamilyA进行批量扫描的效率较低.

37. Rowkey Design

37.1. Hotspotting

HBase中的行按行键按字典顺序排序. 该设计针对扫描进行了优化,使您可以将相关行或将一起读取的行彼此靠近存储. 但是,设计不当的行键是引起热点的常见原因 . 当大量客户端流量定向到群集的一个节点或仅几个节点时,就会发生热点. 此流量可能表示读取,写入或其他操作. 流量使负责托管该区域的单台计算机不堪重负,从而导致性能下降并可能导致区域不可用. 这也可能对由同一区域服务器托管的其他区域产生不利影响,因为该主机无法满足请求的负载. 设计数据访问模式很重要,这样才能充分,均匀地利用群集.

为防止写入时出现热点,请设计行键,使确实确实需要在同一区域中的行存在,但从更大的角度看,数据将被写入群集中的多个区域,而不是一次写入一个区域. 下面介绍了一些避免热点的常用技术,以及它们的一些优点和缺点.

Salting

从这种意义上讲,加盐与加密无关,而是指将随机数据添加到行密钥的开头. 在这种情况下,加盐是指在行键上添加一个随机分配的前缀,以使其排序不同于其他方式. 可能的前缀数量对应于您要分布数据的区域数量. 如果您在其他分布更均匀的行中反复出现一些"热"行键模式,则盐析会有所帮助. 考虑下面的示例,该示例表明加盐可以将写入负载分散到多个RegionServer上,并说明对读取的某些负面影响.

例子11.加盐的例子

假设您具有以下行键列表,并且对表进行了拆分,以使字母表中的每个字母都有一个区域. 前缀" a"是一个区域,前缀" b"是另一个区域. 在此表中,所有以'f'开头的行都在同一区域中. 本示例重点介绍具有以下键的行:

foo0001
foo0002
foo0003
foo0004

现在,假设您想将这些分布在四个不同的区域. 您决定使用四种不同的盐: abcd . 在这种情况下,这些字母前缀中的每个字母将位于不同的区域. 应用盐后,将改为使用以下行键. 由于您现在可以写入四个单独的区域,因此从理论上讲,您在写入时的吞吐量是所有写入相同区域时的吞吐量的四倍.

a-foo0003
b-foo0001
c-foo0004
d-foo0002

然后,如果您添加另一行,则会为该行随机分配四个可能的盐值之一,并最终靠近现有行之一.

a-foo0003
b-foo0001
c-foo0003
c-foo0004
d-foo0002

由于此分配是随机的,因此,如果要按字典顺序检索行,则需要做更多的工作. 这样,盐化会尝试增加写入的吞吐量,但会在读取期间增加成本.

Hashing

代替随机分配,您可以使用单向散列 ,该散列将使给定的行始终使用相同的前缀"加盐",以这种方式将负载分散到RegionServer上,但允许在读取期间进行可预测性. 使用确定性哈希可以使客户端重建完整的行键,并使用Get操作正常检索该行.

例子12.散列例子
鉴于上面的盐析例如同样的情况,你可以改为应用单向散列会导致与键行foo0003总是和预见的是,收到a前缀. 然后,要检索该行,您将已经知道密钥. 您还可以优化事物,例如使某些对密钥始终位于同一区域.
倒转钥匙

防止热点的第三个常见技巧是反转固定宽度或数字行键,以便最频繁更改(最低有效数字)的部分位于第一位. 这有效地使行键随机化,但牺牲了行排序属性.

请参阅https://communities.intel.com/community/itpeernetwork/datastack/blog/2013/11/10/discussion-on-designing-hbase-tables以及有关 Phoenix项目中的咸表的文章 ,以及有关避免热点的更多信息,请参见HBASE-11682的注释.

37.2. Monotonically Increasing Row Keys/Timeseries Data

在汤姆·怀特(Tom White)的《 Hadoop:权威指南》 (O'Reilly)的HBase章节中,有一个优化注释,用于注意一种现象,在该现象中,导入过程与所有客户齐心协力地敲击桌子的一个区域(因此是单个节点),然后移至下一个区域,依此类推.随着单调增加行键(即使用时间戳),这种情况将会发生. 请参阅IKai Lan的漫画,内容是为什么单调递增的行键在类似BigTable的数据存储区中会出现问题: 单调递增的值很糟糕 . 可以通过将输入记录随机化为不按排序顺序来缓解单调递增键在单个区域上的堆积,但是通常最好避免使用时间戳或序列(例如1、2、3)作为行键.

如果确实需要将时间序列数据上传到HBase,则应学习OpenTSDB作为成功的示例. 它的页面描述了它在HBase中使用的架构 . OpenTSDB中的密钥格式实际上是[metric_type] [event_timestamp],乍一看似乎与先前关于不使用时间戳作为密钥的建议相矛盾. 但是,区别在于时间戳不在密钥的主导位置,而设计假设是有数十个或数百个(或更多)不同的度量标准类型. 因此,即使连续输入数据流混合使用各种度量标准类型,Put也会分布在表中区域的各个点上.

有关某些行键设计示例,请参见schema.casestudies .

37.3. Try to minimize row and column sizes

在HBase中,值总是随其坐标一起传送; 当单元格值通过系统时,将始终伴随其行,列名和时间戳. 如果行名和列名很大,尤其是与单元格值的大小相比,则可能会遇到一些有趣的情况. Marc Limotte在HBASE-3551的尾部描述了这种情况(推荐!). 其中,为方便随机访问而保存在HBase存储文件( StoreFile(HFile) )上的索引可能最终会占用HBase分配的RAM的大块,因为单元值坐标很大. 上面引用的注释中的Mark建议增加块大小,以便存储文件索引中的条目以较大的间隔发生,或者修改表模式,以便使用较小的行和列名. 压缩还将使索引更大. 请在用户邮件列表中查看有关问题storefileIndexSize的线程.

在大多数情况下,效率低下并不重要. 不幸的是,这是他们这样做的情况. 无论为ColumnFamilies,属性和行键选择什么模式,它们都可以在数据中重复数十亿次.

有关HBase内部存储数据的更多信息,请参见keyvalue ,以了解为什么这很重要.

37.3.1. Column Families

尝试使ColumnFamily名称尽可能小,最好是一个字符(例如," d"表示数据/默认值).

有关HBase内部存储数据的更多信息,请参见KeyValue ,以了解为什么这很重要.

37.3.2. Attributes

尽管详细的属性名称(例如" myVeryImportantAttribute")更易于阅读,但更喜欢使用较短的属性名称(例如" via")存储在HBase中.

有关HBase内部存储数据的更多信息,请参见keyvalue ,以了解为什么这很重要.

37.3.3. Rowkey Length

使其尽可能短,以使它们仍可用于所需的数据访问(例如,获取与扫描). 对于数据访问无用的短键并不比具有更好的获取/扫描属性的长键更好. 设计行键时需要权衡取舍.

37.3.4. Byte Patterns

长为8个字节. 您可以在这八个字节中存储最多18,446,744,073,709,551,615个无符号数. 如果将此数字存储为字符串(假定每个字符一个字节),则需要将近3倍的字节.

不服气吗? 下面是一些示例代码,您可以自己运行.

// long
//
long l = 1234567890L;
byte[] lb = Bytes.toBytes(l);
System.out.println("long bytes length: " + lb.length);   // returns 8

String s = String.valueOf(l);
byte[] sb = Bytes.toBytes(s);
System.out.println("long as string length: " + sb.length);    // returns 10

// hash
//
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(Bytes.toBytes(s));
System.out.println("md5 digest bytes length: " + digest.length);    // returns 16

String sDigest = new String(digest);
byte[] sbDigest = Bytes.toBytes(sDigest);
System.out.println("md5 digest as string length: " + sbDigest.length);    // returns 26

不幸的是,使用类型的二进制表示形式会使您的数据难以在代码外部读取. 例如,这是在增加值时在外壳中看到的内容:

hbase(main):001:0> incr 't', 'r', 'f:q', 1
COUNTER VALUE = 1

hbase(main):002:0> get 't', 'r'
COLUMN                                        CELL
 f:q                                          timestamp=1369163040570, value=\x00\x00\x00\x00\x00\x00\x00\x01
1 row(s) in 0.0310 seconds

外壳程序会尽力打印字符串,在这种情况下,它决定只打印十六进制. 区域名称内的行键也会发生同样的情况. 如果您知道要存储的内容,可以这样做,但是如果可以将任意数据放在相同的单元格中,则可能也无法读取. 这是主要的权衡.

37.4. Reverse Timestamps

反向扫描API

HBASE-4811实现了一个API,可以反向扫描表或表中的范围,从而减少了为进行正向或反向扫描而优化架构的需求. HBase 0.98和更高版本中提供了此功能. 有关更多信息,请参见Scan.setReversed() .

数据库处理中的一个常见问题是快速找到值的最新版本. 使用反向时间戳作为键的一部分的技术可以在此问题的特殊情况下极大地帮助您. 该技术还可以在汤姆·怀特(Tom White)的《 Hadoop:权威指南》(O'Reilly)的HBase一章中找到,该技术包括将( Long.MAX_VALUE - timestamp )附加到任何键的末尾,例如[key] [reverse_timestamp].

通过执行[key]扫描并获取第一条记录,可以找到表中[key]的最新值. 由于HBase键是按排序顺序排列的,因此此键在[key]的任何较旧的行键之前进行排序,因此是第一个.

将使用该技术代替使用"版本号",以"永久"(或很长时间)保留所有版本,并同时使用相同的"扫描"技术快速获取对任何其他版本的访问权限.

37.5. Rowkeys and ColumnFamilies

行键的作用域为ColumnFamilies. 因此,相同的行键可以存在于表中的每个ColumnFamily中而不会发生冲突.

37.6. Immutability of Rowkeys

行键不能更改. 可以在表中"更改"它们的唯一方法是删除该行然后将其重新插入. 这是HBase dist列表上的一个相当普遍的问题,因此第一次(和/或在插入大量数据之前)正确获取行键是值得的.

37.7. Relationship Between RowKeys and Region Splits

如果您预先分割了表格,那么了解行键如何在区域边界上分布至关重要 . 作为为什么如此重要的示例,请考虑使用可显示的十六进制字符作为键的开头位置的示例(例如," 0000000000000000"到" ffffffffffffffff"). 通过Bytes.split (这是在Admin.createTable(byte[] startKey, byte[] endKey, numRegions)创建区域时使用的分割策略Admin.createTable(byte[] startKey, byte[] endKey, numRegions)来运行10个区域的键范围将生成以下分割...

48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48                                // 0
54 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10 -10                 // 6
61 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -67 -68                 // =
68 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -124 -126  // D
75 75 75 75 75 75 75 75 75 75 75 75 75 75 75 72                                // K
82 18 18 18 18 18 18 18 18 18 18 18 18 18 18 14                                // R
88 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -40 -44                 // X
95 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -97 -102                // _
102 102 102 102 102 102 102 102 102 102 102 102 102 102 102 102                // f

(请注意:引导字节在右侧列为注释.)鉴于第一个拆分为'0',最后一个拆分为'f',一切都很好,对吗? 没那么快.

问题在于所有数据都将在前两个区域和最后一个区域堆积,从而造成"块状"(可能还有"热")区域问题. 要了解原因,请参考ASCII表 . " 0"是字节48,而" f"是字节102,但是字节值(字节58至96)之间存在巨大差异,该间隙永远不会出现在此键空间中,因为唯一的值是[0-9]和[af ]. 因此,中间区域将永远不会被使用. 为了使该示例键空间可以进行预拆分,需要自定义拆分定义(即,不依赖于内置的split方法).

第1课:预拆分表通常是最佳实践,但是您需要以可在键空间中访问所有区域的方式预拆分表. 尽管此示例演示了十六进制键空间的问题,但任何键空间都可能发生相同的问题. 了解您的数据.

第2课:虽然通常不建议这样做,但是只要在键空间中可访问所有创建的区域,使用十六进制键(更常见的是可显示的数据)仍可与预分割表一起使用.

To conclude this example, the following is an example of how appropriate splits can be pre-created for hex-keys:.

public static boolean createTable(Admin admin, HTableDescriptor table, byte[][] splits)
throws IOException {
  try {
    admin.createTable( table, splits );
    return true;
  } catch (TableExistsException e) {
    logger.info("table " + table.getNameAsString() + " already exists");
    // the table already exists...
    return false;
  }
}

public static byte[][] getHexSplits(String startKey, String endKey, int numRegions) {
  byte[][] splits = new byte[numRegions-1][];
  BigInteger lowestKey = new BigInteger(startKey, 16);
  BigInteger highestKey = new BigInteger(endKey, 16);
  BigInteger range = highestKey.subtract(lowestKey);
  BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions));
  lowestKey = lowestKey.add(regionIncrement);
  for(int i=0; i < numRegions-1;i++) {
    BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));
    byte[] b = String.format("%016x", key).getBytes();
    splits[i] = b;
  }
  return splits;
}

38. Number of Versions

38.1. Maximum Number of Versions

通过HColumnDescriptor为每个列系列配置了要存储的最大行版本数. 为最大版本默认值为1.这是一个重要的参数,因为在描述数据模型部分HBase的覆盖行的值,而是通过时间(和限定),而存储每行不同的值. 大型压缩期间将删除多余的版本. 取决于应用程序的需要,最大版本的数量可能需要增加或减少.

不建议将最大版本数设置得过高(例如,数百个或更多),除非您非常喜欢那些旧值,因为这会大大增加StoreFile的大小.

38.2. Minimum Number of Versions

与最大行版本数一样,通过HColumnDescriptor为每个列系列配置要保留的最小行版本数. 最低版本的默认值为0,这表示该功能已禁用. 参数与时间的生存参数一起使用,并且可以与行版本的数量参数,以允许配置,例如"保留的数据的最后Ť分钟值得,至多N个版本进行组合行版本的最小数量, 但至少保持M个版本在 " 附近 "(其中M是最小行版本数的值,M <N). 仅当为列系列启用生存时间时才应设置此参数,并且该参数必须小于行版本的数量.

39. Supported Datatypes

HBase通过PutResult支持" bytes-in / bytes-out"接口,因此任何可以转换为字节数组的内容都可以存储为值. 输入可以是字符串,数字,复杂的对象,甚至是图像,只要它们可以呈现为字节即可.

值的大小有实际限制(例如,在HBase中存储10-50MB的对象可能要求太多); 在邮件列表中搜索有关此主题的对话. HBase中的所有行均符合Data Model ,其中包括版本控制. 设计时要考虑到这一点,以及ColumnFamily的块大小.

39.1. Counters

需要特别提及的一种受支持的数据类型是"计数器"(即执行原子原子递增数字的功能). 请参阅Table 增量 .

计数器同步在RegionServer上完成,而不在客户端上完成.

40. Joins

如果您有多个表,请不要忘记将Joins纳入架构设计的可能性.

41. Time To Live (TTL)

ColumnFamilies can set a TTL length in seconds, and HBase will automatically delete rows once the expiration time is reached. This applies to all versions of a row - even the current one. The TTL time encoded in the HBase for the row is specified in UTC.

较小的压缩会删除仅包含过期行的存储文件. 将hbase.store.delete.expired.storefile设置为false将禁用此功能. 将最小版本数设置为非0也会禁用此功能.

有关更多信息,请参见HColumnDescriptor .

HBase的最新版本还支持设置每个单元的生存时间. 有关更多信息,请参见HBASE-10560 . 使用mutation#setTTL将单元TTL作为属性提交给突变请求(追加,增量,放置等). 如果设置了TTL属性,它将应用于通过该操作在服务器上更新的所有单元. 单元TTL处理和ColumnFamily TTL之间有两个显着差异:

  • 单元TTL以毫秒为单位而不是秒.

  • 单元TTL不能将单元的有效寿命延长到ColumnFamily级别TTL设置之外.

42. Keeping Deleted Cells

默认情况下,删除标记可追溯到时间的开始. 因此,即使"获取"或"扫描"操作指示放置删除标记之前的时间范围," 获取"或" 扫描"操作也不会看到已删除的单元格(行或列).

ColumnFamilies可以选择保留已删除的单元格. 在这种情况下,只要这些操作指定的时间范围在会影响该单元格的任何删除的时间戳记之前结束,仍然可以检索已删除的单元格. 即使存在删除操作,这也可以进行时间点查询.

删除的单元格仍然受TTL的限制,并且删除的单元格永远不会超过"最大版本数". 新的"原始"扫描选项返回所有已删除的行和删除标记.

使用HBase Shell更改KEEP_DELETED_CELLS的值
hbase> hbase> alter ‘t1′, NAME => ‘f1′, KEEP_DELETED_CELLS => true
例13.使用API​​更改KEEP_DELETED_CELLS的值
...
HColumnDescriptor.setKeepDeletedCells(true);
...

让我们说明在表上设置KEEP_DELETED_CELLS属性的基本效果.

首先,没有:

create 'test', {NAME=>'e', VERSIONS=>2147483647}
put 'test', 'r1', 'e:c1', 'value', 10
put 'test', 'r1', 'e:c1', 'value', 12
put 'test', 'r1', 'e:c1', 'value', 14
delete 'test', 'r1', 'e:c1',  11

hbase(main):017:0> scan 'test', {RAW=>true, VERSIONS=>1000}
ROW                                              COLUMN+CELL
 r1                                              column=e:c1, timestamp=14, value=value
 r1                                              column=e:c1, timestamp=12, value=value
 r1                                              column=e:c1, timestamp=11, type=DeleteColumn
 r1                                              column=e:c1, timestamp=10, value=value
1 row(s) in 0.0120 seconds

hbase(main):018:0> flush 'test'
0 row(s) in 0.0350 seconds

hbase(main):019:0> scan 'test', {RAW=>true, VERSIONS=>1000}
ROW                                              COLUMN+CELL
 r1                                              column=e:c1, timestamp=14, value=value
 r1                                              column=e:c1, timestamp=12, value=value
 r1                                              column=e:c1, timestamp=11, type=DeleteColumn
1 row(s) in 0.0120 seconds

hbase(main):020:0> major_compact 'test'
0 row(s) in 0.0260 seconds

hbase(main):021:0> scan 'test', {RAW=>true, VERSIONS=>1000}
ROW                                              COLUMN+CELL
 r1                                              column=e:c1, timestamp=14, value=value
 r1                                              column=e:c1, timestamp=12, value=value
1 row(s) in 0.0120 seconds

请注意如何释放删除单元格.

现在,让我们仅在表上设置了KEEP_DELETED_CELLS的情况下运行相同的测试(您可以执行表或每个列的家庭):

hbase(main):005:0> create 'test', {NAME=>'e', VERSIONS=>2147483647, KEEP_DELETED_CELLS => true}
0 row(s) in 0.2160 seconds

=> Hbase::Table - test
hbase(main):006:0> put 'test', 'r1', 'e:c1', 'value', 10
0 row(s) in 0.1070 seconds

hbase(main):007:0> put 'test', 'r1', 'e:c1', 'value', 12
0 row(s) in 0.0140 seconds

hbase(main):008:0> put 'test', 'r1', 'e:c1', 'value', 14
0 row(s) in 0.0160 seconds

hbase(main):009:0> delete 'test', 'r1', 'e:c1',  11
0 row(s) in 0.0290 seconds

hbase(main):010:0> scan 'test', {RAW=>true, VERSIONS=>1000}
ROW                                                                                          COLUMN+CELL
 r1                                                                                          column=e:c1, timestamp=14, value=value
 r1                                                                                          column=e:c1, timestamp=12, value=value
 r1                                                                                          column=e:c1, timestamp=11, type=DeleteColumn
 r1                                                                                          column=e:c1, timestamp=10, value=value
1 row(s) in 0.0550 seconds

hbase(main):011:0> flush 'test'
0 row(s) in 0.2780 seconds

hbase(main):012:0> scan 'test', {RAW=>true, VERSIONS=>1000}
ROW                                                                                          COLUMN+CELL
 r1                                                                                          column=e:c1, timestamp=14, value=value
 r1                                                                                          column=e:c1, timestamp=12, value=value
 r1                                                                                          column=e:c1, timestamp=11, type=DeleteColumn
 r1                                                                                          column=e:c1, timestamp=10, value=value
1 row(s) in 0.0620 seconds

hbase(main):013:0> major_compact 'test'
0 row(s) in 0.0530 seconds

hbase(main):014:0> scan 'test', {RAW=>true, VERSIONS=>1000}
ROW                                                                                          COLUMN+CELL
 r1                                                                                          column=e:c1, timestamp=14, value=value
 r1                                                                                          column=e:c1, timestamp=12, value=value
 r1                                                                                          column=e:c1, timestamp=11, type=DeleteColumn
 r1                                                                                          column=e:c1, timestamp=10, value=value
1 row(s) in 0.0650 seconds

KEEP_DELETED_CELLS是避免将单元格从HBase中删除的唯一原因是删除标记. 因此,启用KEEP_DELETED_CELLS后,如果您编写的版本超过配置的最大值,或者您拥有TTL并且单元格超出配置的超时时间,则删除的单元格将被删除.

43. Secondary Indexes and Alternate Query Paths

这部分也可以题为"如果我的表rowkey看起来是这样 ,但我也希望我的查询表那样 ." dist列表上的一个常见示例是其中行键的格式为" user-timestamp",但是对于特定时间范围内的用户活动有报告要求. 因此,由用户进行选择很容易,因为它处于键的引导位置,而时间却不然.

解决这一问题的最佳方法没有一个答案,因为这取决于...

  • 用户数

  • 数据大小和数据到达率

  • 报告要求的灵活性(例如,完全临时的日期选择与预配置的范围)

  • 所需的查询执行速度(例如,对于某些临时报告,90秒对于某些人来说可能是合理的,而对于另一些报告则可能太长)

解决方案还受群集大小以及必须在解决方案上投入多少处理能力的影响. 常用技术在下面的小节中. 这是方法的综合列表,但并不详尽.

二级索引需要额外的群集空间和处理也就不足为奇了. 这正是RDBMS中发生的事情,因为创建备用索引的操作需要空间和处理周期来进行更新. RDBMS产品在这方面更先进,可以立即处理替代索引管理. 但是,HBase在较大数据量时可更好地扩展,因此这是一个功能折衷.

实施任何一种方法时,请注意Apache HBase性能调优 .

此外,请在此dist-list线程HBase中查看David Butler的响应,邮件#用户-Stargate + hbase

43.1. Filter Query

根据情况,使用Client Request Filters是合适的. 在这种情况下,不会创建二级索引. 但是,请勿尝试从应用程序(即单线程客户端)对大型表进行完全扫描.

43.2. Periodic-Update Secondary Index

可以在另一个表中创建二级索引,该表通过MapReduce作业定期更新. 该作业可以在一天之内执行,但是根据负载策略,它仍可能与主数据表不同步.

有关更多信息,请参见mapreduce.example.readwrite .

43.3. Dual-Write Secondary Index

另一种策略是在将数据发布到群集时构建辅助索引(例如,写入数据表,写入索引表). 如果在已存在数据表之后采用这种方法,则对于具有MapReduce作业的辅助索引,将需要进行引导(请参见secondary.indexes.periodic ).

43.4. Summary Tables

在时间范围很广的地方(例如,长达一年的报告),并且数据量很大,因此汇总表是一种常见的方法. 这些将通过MapReduce作业生成到另一个表中.

有关更多信息,请参见mapreduce.example.summary .

43.5. Coprocessor Secondary Index

协处理器的行为类似于RDBMS触发器. 这些以0.92添加. 有关更多信息,请参见协处理器.

44. Constraints

HBase当前在传统(SQL)数据库中支持"约束". 约束的建议用法是针对表中的属性强制执行业务规则(例如,确保值在1到10的范围内). 约束也可以用于强制引用完整性,但是强烈建议不要这样做,因为它将大大降低启用完整性检查的表的写吞吐量. 从0.94版开始,可以在Constraint上找到有关使用Constraints的大量文档.

45. Schema Design Case Studies

下面将描述一些使用HBase的典型数据摄取用例,以及如何进行行键设计和构造. 注意:这仅是潜在方法的说明,而不是详尽的清单. 了解您的数据,并了解您的处理要求.

强烈建议您在阅读这些案例研究之前先阅读HBase和Schema Design的其余部分.

描述了以下案例研究:

  • 日志数据/时间序列数据

  • 在类固醇上记录数据/时间序列

  • Customer/Order

  • 高/宽/中方案设计

  • 清单资料

45.1. Case Study - Log Data and Timeseries Data

假设正在收集以下数据元素.

  • Hostname

  • Timestamp

  • 记录事件

  • Value/message

我们可以将它们存储在名为LOG_DATA的HBase表中,但是行键是什么? 从这些属性中,行键将是主机名,时间戳和日志事件的某种组合-但是具体是什么?

45.1.1. Timestamp In The Rowkey Lead Position

行键[timestamp][hostname][log-event]遭受单调增加行键/时间序列数据中描述的单调增加行键问题.

通过在时间戳上执行mod操作,在dist列表中经常提到另一种关于"存储桶"时间戳的模式. 如果面向时间的扫描很重要,那么这可能是一种有用的方法. 必须注意存储桶的数量,因为这将需要相同数量的扫描才能返回结果.

long bucket = timestamp % numBuckets;

构建:

[bucket][timestamp][hostname][log-event]

如上所述,要为特定时间范围选择数据,将需要为每个存储桶执行一次扫描. 例如,100个存储桶将在键空间中提供广泛的分布,但是需要100次扫描才能获得单个时间戳的数据,因此需要权衡取舍.

45.1.2. Host In The Rowkey Lead Position

如果有大量主机在键空间上分布写入和读取操作,则行键[hostname][log-event][timestamp]是候选. 如果按主机名扫描是优先级,则此方法将很有用.

45.1.3. Timestamp, or Reverse Timestamp?

如果最重要的访问路径是提取最新事件,则将时间戳存储为反向时间戳(例如, timestamp = Long.MAX_VALUE – timestamp )将创建能够对[hostname][log-event]以获取最近捕获的事件.

两种方法都没有错,仅取决于最适合该情况的方法.

反向扫描API

HBASE-4811实现了一个API,可以反向扫描表或表中的范围,从而减少了为进行正向或反向扫描而优化架构的需求. HBase 0.98和更高版本中提供了此功能. 有关更多信息,请参见Scan.setReversed() .

45.1.4. Variable Length or Fixed Length Rowkeys?

重要的是要记住,行键标记在HBase的每一列上. 如果主机名是a并且事件类型是e1则结果行键将非常小. 但是,如果提取的主机名是myserver1.mycompany.com ,事件类型是com.package1.subpackage2.subsubpackage3.ImportantService ,该com.package1.subpackage2.subsubpackage3.ImportantService办?

在行键中使用某些替换可能很有意义. 至少有两种方法:散列和数字. 在"行键引导位置的主机名"示例中,它可能看起来像这样:

带有哈希的复合行键:

  • [主机名的MD5哈希] = 16个字节

  • [事件类型的MD5哈希] = 16个字节

  • [时间戳记] = 8个字节

带有数字替换的复合行键:

对于这种方法,除了LOG_DATA外,还需要另一个查询表,称为LOG_TYPES. LOG_TYPES的行键为:

  • [type] (例如,指示主机名与事件类型的字节)

  • [bytes]原始主机名或事件类型的可变长度字节.

此行键的列可以是带有指定数字的长整数,可以通过使用HBase计数器获得该数字

因此,生成的复合行键将为:

  • [用主机名替换长] = 8个字节

  • [事件类型的长整数替换] = 8个字节

  • [时间戳记] = 8个字节

在散列或数字替换方法中,主机名和事件类型的原始值可以存储为列.

45.2. Case Study - Log Data and Timeseries Data on Steroids

这实际上是OpenTSDB方法. OpenTSDB所做的是重写数据并将行在某些时间段内打包到列中. 有关详细说明,请参见: http ://opentsdb.net/schema.html,以及从HBaseCon2012的OpenTSDB中获得的经验教训 .

但这就是一般概念的工作原理:例如以这种方式摄取数据...

[hostname][log-event][timestamp1]
[hostname][log-event][timestamp2]
[hostname][log-event][timestamp3]

每个详细事件都有单独的行键,但是像这样重写...

[hostname][log-event][timerange]

并将上述每个事件转换为以相对于开始时间范围的时间偏移(例如,每5分钟)存储的列. 这显然是一种非常先进的处理技术,但是HBase使这成为可能.

45.3. Case Study - Customer/Order

假设HBase用于存储客户和订单信息. 提取了两种核心记录类型:客户记录类型和订单记录类型.

客户记录类型将包括您通常期望的所有内容:

  • 顾客号码

  • 顾客姓名

  • 地址(例如,城市,州,邮政编码)

  • 电话号码等

订单记录类型将包括以下内容:

  • 顾客号码

  • 订单号

  • 销售日期

  • 一系列嵌套对象,用于运送位置和订单项(有关详细信息,请参阅订购对象设计

假设客户编号和销售订单的组合唯一地标识了一个订单,那么这两个属性将组成行键,特别是一个组合键,例如:

[customer number][order number]

用于ORDER表. 但是,还有更多的设计决策: 原始值是行键的最佳选择吗?

Log Data用例中的相同设计问题在这里也面临着我们. 客户编号的键空间是什么,格式是什么(例如,数字?字母数字?),因为在HBase中使用固定长度的键以及可以在键空间中支持合理分布的键是有利的,类似选项出现:

带有哈希的复合行键:

  • [客户编号的MD5] = 16字节

  • [订单号的MD5] = 16个字节

复合数字/哈希组合行键:

  • [用客户编号代替长号] = 8个字节

  • [订单号的MD5] = 16个字节

45.3.1. Single Table? Multiple Tables?

传统的设计方法将为客户和销售提供单独的表格. 另一个选择是将多个记录类型打包到一个表中(例如CUSTOMER ++).

客户记录类型行键:

  • [customer-id]

  • [type] =表示客户记录类型为" 1"的类型

订单记录类型行键:

  • [customer-id]

  • [type] =指示订单记录类型为" 2"的类型

  • [order]

这种特定的CUSTOMER ++方法的优点是,可以通过客户ID组织许多不同的记录类型(例如,一次扫描可以为您提供有关该客户的所有信息). 缺点是扫描特定的记录类型并不容易.

45.3.2. Order Object Design

现在我们需要解决如何对Order对象建模. 假定类结构如下:

Order

(一个订单可以有多个发货地点

LineItem

(一个ShippingLocation可以有多个LineItem

存储此数据有多种选择.

Completely Normalized

使用这种方法,将有单独的表用于ORDER,SHIPPING_LOCATION和LINE_ITEM.

上面描述了ORDER表的行键: schema.casestudies.custorder

SHIPPING_LOCATION的复合行键将如下所示:

  • [order-rowkey]

  • [shipping location number] (例如,第一地点,第二地点等)

LINE_ITEM表的复合行键如下所示:

  • [order-rowkey]

  • [shipping location number] (例如,第一地点,第二地点等)

  • [line item number] (例如,第一项,第二项等)

这种标准化模型很可能是RDBMS的方法,但这不是HBase的唯一选择. 这种方法的缺点是要检索有关任何订单的信息,您将需要:

  • 进入订单的ORDER表

  • 在SHIPPING_LOCATION表上扫描该订单以获取ShippingLocation实例

  • 在LINE_ITEM上扫描每个送货地点

当然,这是RDBMS会在后台进行的操作,但是由于HBase中没有联接,因此您只需要了解这一事实.

Single Table With Record Types

使用这种方法,将存在一个单个表ORDER,其中包含

订单行键已在上面进行了描述: schema.casestudies.custorder

  • [order-rowkey]

  • [ORDER record type]

ShippingLocation复合行键将如下所示:

  • [order-rowkey]

  • [SHIPPING record type]

  • [shipping location number] (例如,第一地点,第二地点等)

LineItem复合行键将如下所示:

  • [order-rowkey]

  • [LINE record type]

  • [shipping location number] (例如,第一地点,第二地点等)

  • [line item number] (例如,第一项,第二项等)

Denormalized

"带有记录类型的单表"方法的一种变体是对某些对象层次结构进行非规范化和扁平化,例如将ShippingLocation属性折叠到每个LineItem实例上.

LineItem复合行键将如下所示:

  • [order-rowkey]

  • [LINE record type]

  • [line item number] (例如,第一个[line item number] ,第二个[line item number]等,必须注意整个订单中的商品是唯一的)

而LineItem列将如下所示:

  • itemNumber

  • quantity

  • price

  • shipToLine1(从ShippingLocation规范化)

  • shipToLine2(从ShippingLocation规范化)

  • shipToCity(从ShippingLocation规范化)

  • shipToState(从ShippingLocation规范化)

  • shipToZip(从ShippingLocation规范化)

这种方法的优点是对象层次结构不太复杂,但是缺点之一是万一这些信息发生更改,更新就会变得更加复杂.

Object BLOB

通过这种方法,整个Order对象图以一种或另一种方式被视为BLOB. 例如,上面描述了ORDER表的行键: schema.casestudies.custorder和一个名为" order"的列将包含一个可以反序列化的对象,该对象包含容器Order,ShippingLocations和LineItems.

这里有许多选项:JSON,XML,Java序列化,Avro,Hadoop可写文件等.它们都是相同方法的变体:将对象图编码为字节数组. 如果对象模型发生更改,以确保仍可以从HBase中读取较旧的持久化结构,则应谨慎使用此方法以确保向后兼容.

专业人士能够以最少的I / O管理复杂的对象图(例如,在此示例中为每个订单获取单个HBase Get),但是缺点包括上述关于序列化向后兼容性,序列化的语言依赖性(例如Java序列化)的警告仅适用于Java客户端),必须对整个对象进行反序列化以在BLOB中获取任何信息这一事实,以及使诸如Hive之类的框架无法与此类自定义对象一起使用的困难.

45.4. Case Study - "Tall/Wide/Middle" Schema Design Smackdown

本节将描述dist列表中出现的其他架构设计问题,特别是有关高大桌子的问题. 这些是一般准则,而不是法律-每个应用程序都必须考虑自己的需求.

45.4.1. Rows vs. Versions

一个常见的问题是,是应该使用行还是HBase的内置版本控制. 上下文通常是要保留行的"很多"版本的位置(例如,该位置明显高于HBase默认的1个最大版本). 行方法将需要在行键的某些部分中存储时间戳,以便它们不会在每次连续更新时被覆盖.

首选项:行(通常而言).

45.4.2. Rows vs. Columns

另一个常见的问题是,人们应该选择行还是列. 该上下文通常在宽表的极端情况下使用,例如具有1行具有1百万个属性,或具有1百万行具有1个每列的属性.

首选项:行(通常而言). 需要明确的是,该指导原则是在非常广泛的情况下使用的,而不是在需要存储几十或数百列的标准用例中使用的. 但是,这两个选项之间还存在一条中间路径,即"行作为列".

45.4.3. Rows as Columns

行与列之间的中间路径是将某些行的数据打包成独立的行. OpenTSDB是这种情况的最佳示例,其中单行代表定义的时间范围,然后将离散事件视为列. 这种方法通常更复杂,并且可能需要重新写入数据的额外复杂性,但是具有I / O高效的优势. 有关此方法的概述,请参见schema.casestudies.log-steroids .

45.5. Case Study - List Data

以下是来自用户dist-list的一个常见问题的交换:如何在Apache HBase中处理每个用户的列表数据.

  • QUESTION *

我们正在研究如何在HBase中存储大量(每用户)列表数据,并且试图找出哪种访问模式最有意义. 一种选择是将大多数数据存储在一个密钥中,因此我们可以得到以下内容:

<FixedWidthUserName><FixedWidthValueId1>:"" (no value)
<FixedWidthUserName><FixedWidthValueId2>:"" (no value)
<FixedWidthUserName><FixedWidthValueId3>:"" (no value)

The other option we had was to do this entirely using:

<FixedWidthUserName><FixedWidthPageNum0>:<FixedWidthLength><FixedIdNextPageNum><ValueId1><ValueId2><ValueId3>...
<FixedWidthUserName><FixedWidthPageNum1>:<FixedWidthLength><FixedIdNextPageNum><ValueId1><ValueId2><ValueId3>...

每行将包含多个值. 因此,在一种情况下,读取前三十个值将是:

scan { STARTROW => 'FixedWidthUsername' LIMIT => 30}

在第二种情况下

get 'FixedWidthUserName\x00\x00\x00\x00'

一般的使用模式是只读取这些列表的前30个值,而很少的访问量会更深入地读取列表. 在这些列表中,某些用户的总价值为⇐30,而某些用户的百万价值(即幂律分布)

单值格式似乎会在HBase上占用更多空间,但会提供一些改进的检索/分页灵活性. 通过获取进行分页与通过扫描进行分页是否会有任何显着的性能优势?

我最初的理解是,如果我们的分页大小未知(并且缓存设置适当),则扫描应该更快,但是如果我们始终需要相同的页面大小,则扫描应该更快. 我最终听到不同的人告诉我关于性能的相反的事情. 我认为页面大小会相对一致,因此对于大多数用例,我们可以保证在固定页面长度的情况下只需要一页数据. 我还要假设我们不经常进行更新,但是可能在这些列表的中间插入了插入(这意味着我们需要更新所有后续行).

感谢您的帮助/建议/后续问题.

  • ANSWER *

如果我理解正确,那么您最终将尝试以"用户,valueid,值"的形式存储三元组,对吗? 例如,类似:

"user123, firstname, Paul",
"user234, lastname, Smith"

(但是用户名是固定宽度,而valueid是固定宽度).

而且,您的访问模式如下:"对于用户X,列出下30个值,以valueid Y开头". 那正确吗? 这些值应该按valueid排序返回吗?

tl; dr版本是每个用户+值可能只包含一行,并且除非您确实确定需要,否则不要自己构建复杂的行内分页方案.

您的两个选择反映了人们在设计HBase模式时遇到的一个常见问题:我应该"高"还是"宽"? 您的第一个架构是"高层":每一行代表一个用户一个值,因此表中有很多行针对每个用户; 行键是用户+ valueid,并且(大概)将有一个单列限定符,表示"值". 如果您要按行键按排序顺序扫描行(这是我上面的问题,关于这些ID是否正确排序),这很好. 您可以在任何用户名+值id处开始扫描,然后阅读下一个30并完成. 您要放弃的是能够为一个用户在所有行上拥有事务保证,但这听起来并不是您需要的. 通常建议以这种方式进行操作(请参见https://hbase.apache.org/book.html#schema.smackdown ).

第二个选项是"宽":使用不同的限定符(其中的限定符是valueid)将一堆值存储在一行中. 这样做的简单方法是仅将一个用户的所有值存储在一行中. 我猜您跳到了"分页"版本,因为您假设在单行中存储数百万列会降低性能,这可能是正确的,也可能不是正确的. 只要您不打算在单个请求中执行太多操作,或者执行诸如扫描并返回该行中所有单元格之类的操作,那么从根本上讲应该不会更糟. 客户端具有允许您获取特定列切片的方法.

请注意,两种情况都不会从根本上使用更多的磁盘空间. 您只是将标识信息的一部分"左移"(左移至选项1中的行键中)或向右(右移至选项2中的列限定符中). 在幕后,每个键/值仍存储整个行键和列族名称. (如果这有点令人困惑,请花一个小时,观看Lars George的精彩视频,内容涉及了解HBase架构设计: http : //www.youtube.com/watch?v= _HLoH_PgrLk).

如您所注意到的,手动分页版本具有更多的复杂性,例如必须跟踪每个页面中有多少东西,如果插入新值则需要重新排序等等.这似乎要复杂得多. 在极高的吞吐量下,它可能具有一些轻微的速度优势(或劣势!),要真正知道这一点,唯一的方法就是尝试一下. 如果您没有时间同时构建和比较它,我的建议是从最简单的选项开始(每个用户+值一行). 从简单开始并进行迭代! :)

46. Operational and Performance Configuration Options

46.1. Tune HBase Server RPC Handling

  • hbase.regionserver.handler.count (在hbase-site.xml )设置为核心x纺锤,以实现并发.

  • (可选)将呼叫队列分为不同的读取和写入队列以区分服务. 参数hbase.ipc.server.callqueue.handler.factor指定呼叫队列的数量:

    • 0表示单个共享队列

    • 1表示每个处理程序一个队列.

    • 01之间的值与处理程序的数量成比例地分配队列的数量. 例如,值.5在每两个处理程序之间共享一个队列.

  • 使用hbase.ipc.server.callqueue.read.ratio (0.98中的hbase.ipc.server.callqueue.read.share )将调用队列拆分为读写队列:

    • 0.5表示将有相同数量的读写队列

    • < 0.5表示读写多

    • > 0.5 for more write than read

  • 设置hbase.ipc.server.callqueue.scan.ratio (HBase 1.0+)以将读取的呼叫队列拆分为小读取和长读取队列:

    • 0.5表示短读和长读队列的数目相同

    • < 0.5以获取更多短读

    • > 0.5可获得更长的阅读时间

46.2. Disable Nagle for RPC

禁用Nagle的算法. 延迟的ACK可能会使RPC往返时间增加约200毫秒. 设置以下参数:

  • 在Hadoop的core-site.xml

    • ipc.server.tcpnodelay = true

    • ipc.client.tcpnodelay = true

  • 在HBase的hbase-site.xml

    • hbase.ipc.client.tcpnodelay = true

    • hbase.ipc.server.tcpnodelay = true

46.3. Limit Server Failure Impact

尽快检测到区域服务器故障. 设置以下参数:

  • hbase-site.xml ,将zookeeper.session.timeout设置为30秒或更短以进行绑定故障检测(20-30秒是一个好的开始).

    • 注意: tickTimesessionTimeout限制在tickTime 2倍至20倍tickTime (ZooKeeper使用的基本时间单位为毫秒,默认值为2000ms,用于执行心跳,最小会话超时将是tickTime的两倍) .

  • 检测并避免不健康或出现故障的HDFS数据hbase-site.xml :在hdfs-site.xmlhbase-site.xml ,设置以下参数:

    • dfs.namenode.avoid.read.stale.datanode = true

    • dfs.namenode.avoid.write.stale.datanode = true

46.4. Optimize on the Server Side for Low Latency

当RegionServer通过利用HDFS的" 短路本地读取"功能从HDFS读取数据时,跳过网络上的本地块. 请注意如何在连接的datanode端和dfsclient端都必须完成设置,即在RegionServer上,以及两端如何都需要加载hadoop本机.so库. 在配置好hadoop之后,将dfs.client.read.shortcircuit设置为true ,并将dfs.domain.socket.path路径配置为datanode和dfsclient共享并重新启动,然后配置regionserver / dfsclient端.

  • hbase-site.xml ,设置以下参数:

    • dfs.client.read.shortcircuit = true

    • dfs.client.read.shortcircuit.skip.checksum = true所以我们不会将校验和加倍(HBase自己执行校验和以保存在i / os上.有关更多信息,请参见hbase.regionserver.checksum.verify .

    • dfs.domain.socket.path匹配为数据dfs.domain.socket.path设置的内容.

    • dfs.client.read.shortcircuit.buffer.size = 131072对于避免OOME很重要-hbase有一个默认值,如果未设置,则使用它,请参见hbase.dfs.client.read.shortcircuit.buffer.size ; 其默认值为131072.

  • 确保数据局部性. 在hbase-site.xml ,将hbase.hstore.min.locality.to.skip.major.compact = 0.7设置hbase.hstore.min.locality.to.skip.major.compact = 0.7 (意味着0.7 <= n <= 1)

  • 确保DataNode具有足够的处理程序以进行块传输. 在hdfs-site.xml ,设置以下参数:

    • dfs.datanode.max.xcievers >= 8192

    • dfs.datanode.handler.count =主轴数

重新启动后检查RegionServer日志. 如果配置错误,您应该只会看到投诉. 否则,短路读取将在后台安静地运行. 它没有提供度量标准,因此没有光学手段可以证明它的有效性,但是读取延迟应该显示出明显的改善,尤其是如果良好的数据局部性,大量的随机读取以及数据集大于可用缓存时.

您可能会使用的其他高级配置,尤其是在日志中抱怨短路功能的情况下,包括dfs.client.read.shortcircuit.streams.cache.sizedfs.client.socketcache.capacity . 这些选项的文档很少. 您必须阅读源代码.

有关短路读取的更多信息,请参阅Colin推出的旧博客, 《改进的短路本地读取如何为Hadoop带来更好的性能和安全性》 . HDFS-347问题还引起了有趣的阅读,显示了HDFS社区处于最佳状态(有一些评论).

46.5. JVM Tuning

46.5.1. Tune JVM GC for low collection latencies

  • 使用CMS收集器: -XX:+UseConcMarkSweepGC

  • 保持伊甸园空间尽可能小,以最小化平均收集时间. 例:

    -XX:CMSInitiatingOccupancyFraction=70
  • 针对低收集延迟而不是吞吐量进行优化: -Xmn512m

  • 并行收集eden: -XX:+UseParNewGC

  • 避免在压力下收集: -XX:+UseCMSInitiatingOccupancyOnly

  • Limit per request scanner result sizing so everything fits into survivor space but doesn’t tenure. In hbase-site.xml, set hbase.client.scanner.max.result.size to 1/8th of eden space (with -Xmn512m this is ~51MB )

  • 设置max.result.size X handler.count不到生存空间

46.5.2. OS-Level Tuning

  • 关闭透明大页面(THP):

    echo never > /sys/kernel/mm/transparent_hugepage/enabled
    echo never > /sys/kernel/mm/transparent_hugepage/defrag
  • Set vm.swappiness = 0

  • vm.min_free_kbytes设置为至少1GB(在较大的内存系统上为8GB)

  • 使用vm.zone_reclaim_mode = 0禁用NUMA区域回收

47. Special Cases

47.1. For applications where failing quickly is better than waiting

  • 在客户端的hbase-site.xml ,设置以下参数:

    • Set hbase.client.pause = 1000

    • Set hbase.client.retries.number = 3

    • 如果要跨越拆分和区域移动,请大幅增加hbase.client.retries.number (> = 20)

    • 设置RecoverableZookeeper重试计数: zookeeper.recovery.retry = 1 (不重试)

  • 在服务器端的hbase-site.xml ,设置Zookeeper会话超时以检测服务器故障: zookeeper.session.timeout秒(20-30很好).

47.2. For applications that can tolerate slightly out of date information

HBase时间线一致性(HBASE-10070)启用只读副本后,区域(副本)的只读副本将分布在整个群集上. 一个RegionServer服务于默认副本或主副本,这是唯一可以服务于写操作的副本. 其他RegionServer服务于辅助副本,跟在主要RegionServer之后,并且仅查看已提交的更新. 辅助副本是只读的,但可以在主副本进行故障转移时立即为读取提供服务,从而将读取可用性的时间从几秒钟缩短到了几毫秒. 自4.4.0起,Phoenix支持时间轴一致性.

  • 部署HBase 1.0.0或更高版本.

  • 在服务器端启用时间轴一致的副本.

  • 使用以下方法之一设置时间轴一致性:

    • Use ALTER SESSION SET CONSISTENCY = 'TIMELINE’

    • 在JDBC连接字符串中将连接属性Consistency设置为timeline

47.3. More Information

有关操作和性能模式设计选项的更多信息,请参阅"性能"部分perf.schema ,例如Bloom Filters,Table配置的regionizes,压缩和blockizes.

HBase and MapReduce

Apache MapReduce是用于分析大量数据的软件框架. 它由Apache Hadoop提供. MapReduce本身不在本文档的范围之内. https://hadoop.apache.org/docs/r2.6.0/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html是开始使用MapReduce的好地方. MapReduce版本2(MR2)现在是YARN的一部分.

本章讨论在HBase中对数据使用MapReduce时需要采取的特定配置步骤. 此外,它还讨论了HBase和MapReduce作业之间的其他交互和问题. 最后,它讨论了Cascading ,这是MapReduce的替代API .

mapred and mapreduce

There are two mapreduce packages in HBase as in MapReduce itself: org.apache.hadoop.hbase.mapred and org.apache.hadoop.hbase.mapreduce. The former does old-style API and the latter the new mode. The latter has more facility though you can usually find an equivalent in the older package. Pick the package that goes with your MapReduce deploy. When in doubt or starting over, pick org.apache.hadoop.hbase.mapreduce. In the notes below, we refer to o.a.h.h.mapreduce but replace with o.a.h.h.mapred if that is what you are using.

48. HBase, MapReduce, and the CLASSPATH

默认情况下,部署到MapReduce群集的MapReduce作业无法访问$HBASE_CONF_DIR下的HBase配置或HBase类.

要为MapReduce作业提供所需的访问权限,可以将hbase-site.xml_添加到_ $ HADOOP_HOME / conf并将HBase jar添加到$ HADOOP_HOME / lib目录. 然后,您需要在整个集群中复制这些更改. 或者,您可以编辑$ HADOOP_HOME / conf / hadoop-env.sh并将hbase依赖项添加到HADOOP_CLASSPATH变量中. 不推荐使用这两种方法,因为这会使用HBase引用污染您的Hadoop安装. 它还要求您重新启动Hadoop群集,然后Hadoop才能使用HBase数据.

推荐的方法是让HBase添加其依赖项jar并使用HADOOP_CLASSPATH-libjars .

从HBase 0.90.x ,HBase将其依赖项JAR添加到作业配置本身. 依赖项仅需要在本地CLASSPATH上可用,然后从这里将它们拾取并捆绑到部署到MapReduce集群的胖作业jar中. 一个基本技巧就是将完整的hbase类路径(所有hbase和从属jar以及配置)传递给mapreduce作业运行程序,让hbase实用程序从完整的类路径中挑选出将它们添加到MapReduce作业配置中所需的内容(请参阅源代码).在TableMapReduceUtil#addDependencyJars(org.apache.hadoop.mapreduce.Job)了解如何完成此操作).

下面的示例运行捆绑在一起的HBase RowCounter对一个表名为MapReduce工作usertable . 它将hbase需要在MapReduce上下文中运行的jars(包括配置文件,例如hbase-site.xml)设置为HADOOP_CLASSPATH . 确保为您的系统使用正确版本的HBase JAR. 使用本地hbase安装版本替换下面的命令行中的VERSION字符串. 反引号( `符号)使外壳程序执行子命令,从而将hbase classpath的输出设置为HADOOP_CLASSPATH . 本示例假定您使用兼容BASH的外壳.

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-VERSION.jar \
  org.apache.hadoop.hbase.mapreduce.RowCounter usertable

The above command will launch a row counting mapreduce job against the hbase cluster that is pointed to by your local configuration on a cluster that the hadoop configs are pointing to.

hbase-mapreduce.jar的主要驱动程序是驱动程序,列出了hbase附带的一些基本mapreduce任务. 例如,假设您的安装是hbase 2.0.0-SNAPSHOT

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.0-SNAPSHOT.jar
An example program must be given as the first argument.
Valid program names are:
  CellCounter: Count cells in HBase table.
  WALPlayer: Replay WAL files.
  completebulkload: Complete a bulk data load.
  copytable: Export a table from local cluster to peer cluster.
  export: Write table data to HDFS.
  exportsnapshot: Export the specific snapshot to a given FileSystem.
  import: Import data written by Export.
  importtsv: Import data in TSV format.
  rowcounter: Count rows in HBase table.
  verifyrep: Compare the data from tables in two different clusters. WARNING: It doesn't work for incrementColumnValues'd cells since the timestamp is changed after being appended to the log.

您可以将上面列出的短名称用于mapreduce作业,就像下面重新运行行计数器作业一样(同样,假设您的安装是hbase 2.0.0-SNAPSHOT ):

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
  ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-mapreduce-2.0.0-SNAPSHOT.jar \
  rowcounter usertable

您可能会发现感兴趣的更具选择性的hbase mapredcp工具输出; 它列出了针对hbase安装运行基本mapreduce作业所需的最少jar集合. 它不包括配置. 如果希望MapReduce作业找到目标集群,则可能需要添加它们. 一旦开始执行任何实质操作,您可能还必须将指针添加到额外的jar. 只需在运行hbase mapredcp时通过传递系统-Dtmpjars指定其他功能.

对于不打包其依赖项或不调用TableMapReduceUtil#addDependencyJars ,以下命令结构是必需的:

$ HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase mapredcp`:${HBASE_HOME}/conf hadoop jar MyApp.jar MyJobMainClass -libjars $(${HBASE_HOME}/bin/hbase mapredcp | tr ':' ',') ...

如果您从其构建目录而不是安装位置运行HBase,则该示例可能无法正常工作. 您可能会看到类似以下的错误:

java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper

如果发生这种情况,请尝试按以下方式修改命令,以便它使用构建环境中target /目录中的HBase JAR.

$ HADOOP_CLASSPATH=${HBASE_BUILD_HOME}/hbase-mapreduce/target/hbase-mapreduce-VERSION-SNAPSHOT.jar:`${HBASE_BUILD_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar ${HBASE_BUILD_HOME}/hbase-mapreduce/target/hbase-mapreduce-VERSION-SNAPSHOT.jar rowcounter usertable
在0.96.1至0.98.4之间通知HBase的MapReduce用户

使用HBase的某些MapReduce作业无法启动. 该症状是与以下类似的异常:

Exception in thread "main" java.lang.IllegalAccessError: class
    com.google.protobuf.ZeroCopyLiteralByteString cannot access its superclass
    com.google.protobuf.LiteralByteString
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at
    org.apache.hadoop.hbase.protobuf.ProtobufUtil.toScan(ProtobufUtil.java:818)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.convertScanToString(TableMapReduceUtil.java:433)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:186)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:147)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:270)
    at
    org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil.initTableMapperJob(TableMapReduceUtil.java:100)
...

这是由HBASE-9867中引入的优化引起的,该优化无意中引入了类加载器依赖项.

这会同时使用-libjars选项和"胖罐"(将其运行时依赖项打包在嵌套的lib文件夹中的那些文件)影响这两个作业.

为了满足新的类加载器要求,必须将hbase-protocol.jar包含在Hadoop的类路径中. 有关解决类路径错误的最新建议,请参见HBase,MapReduce和CLASSPATH . 出于历史目的包括以下内容.

可以通过符号链接或将jar复制到新位置,在Hadoop的lib目录中包含对hbase-protocol.jar的引用来在系统范围内解决此问题.

通过在作业提交时将其包含在HADOOP_CLASSPATH环境变量中,也可以基于每个作业启动它. 启动打包其依赖关系的作业时,以下所有三个作业启动命令均满足此要求:

$ HADOOP_CLASSPATH=/path/to/hbase-protocol.jar:/path/to/hbase/conf hadoop jar MyJob.jar MyJobMainClass
$ HADOOP_CLASSPATH=$(hbase mapredcp):/path/to/hbase/conf hadoop jar MyJob.jar MyJobMainClass
$ HADOOP_CLASSPATH=$(hbase classpath) hadoop jar MyJob.jar MyJobMainClass

对于不打包依赖项的jar,以下命令结构是必需的:

$ HADOOP_CLASSPATH=$(hbase mapredcp):/etc/hbase/conf hadoop jar MyApp.jar MyJobMainClass -libjars $(hbase mapredcp | tr ':' ',') ...

有关此问题的进一步讨论,请参见HBASE-10304 .

49. MapReduce Scan Caching

TableMapReduceUtil现在恢复在传入的Scan对象上设置扫描程序缓存(将结果返回给客户端之前缓存的行数)的选项.由于HBase 0.95( HBASE-11558 )中的错误,该功能丢失了,对于HBase 0.98.5和0.96.3是固定的. 选择扫描仪缓存的优先顺序如下:

  1. 在扫描对象上设置的缓存设置.

  2. 通过配置选项hbase.client.scanner.caching指定的缓存设置,可以在hbase-site.xml中手动设置,也可以通过辅助方法TableMapReduceUtil.setScannerCaching() .

  3. 默认值HConstants.DEFAULT_HBASE_CLIENT_SCANNER_CACHING设置为100 .

优化缓存设置是客户端等待结果的时间与客户端需要接收的结果集数量之间的平衡. 如果缓存设置太大,则客户端可能会等待很长时间,甚至请求可能会超时. 如果设置太小,则扫描需要分多次返回结果. 如果您将扫描视为铲子,则较大的缓存设置类似于较大的铲子,较小的缓存设置等效于进行更多铲斗以填充铲斗.

上面提到的优先级列表允许您设置一个合理的默认值,并为特定操作覆盖它.

有关更多详细信息,请参见Scan的API文档.

50. Bundled HBase MapReduce Jobs

HBase JAR还可以用作某些捆绑的MapReduce作业的驱动程序. 要了解捆绑的MapReduce作业,请运行以下命令.

$ ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/hbase-mapreduce-VERSION.jar
An example program must be given as the first argument.
Valid program names are:
  copytable: Export a table from local cluster to peer cluster
  completebulkload: Complete a bulk data load.
  export: Write table data to HDFS.
  import: Import data written by Export.
  importtsv: Import data in TSV format.
  rowcounter: Count rows in HBase table

每个有效的程序名称都是捆绑的MapReduce作业. 要运行作业之一,请在以下示例之后对命令建模.

$ ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/hbase-mapreduce-VERSION.jar rowcounter myTable

51. HBase as a MapReduce Job Data Source and Data Sink

HBase可用作MapReduce作业的数据源TableInputFormat和数据接收器TableOutputFormatMultiTableOutputFormat . 编写MapReduce作业以读取或写入HBase时,建议将TableMapper和/或TableReducer子类 . 有关基本用法,请参见无作用传递类IdentityTableMapperIdentityTableReducer . 有关更多示例,请参阅RowCounter或查看org.apache.hadoop.hbase.mapreduce.TestTableMapReduce单元测试.

如果运行使用HBase作为源或接收器的MapReduce作业,则需要在配置中指定源和接收器表及列的名称.

当您从HBase读取时, TableInputFormat向HBase请求区域列表,并生成一个地图,该地图可以是map-per-region地图或mapreduce.job.maps地图,以较小者为准. 如果您的工作只有两个地图,请将mapreduce.job.maps增大到大于区域数的数字. 如果您在每个节点上运行TaskTracer / NodeManager和RegionServer,则地图将在相邻的TaskTracker / NodeManager上运行. 写入HBase时,应避免执行Reduce步骤,然后从地图中写回HBase. 当您的工作不需要MapReduce对地图发出的数据执行的排序和排序规则时,此方法有效. 插入时,HBase会进行"排序",因此除非有必要,否则就不会进行点双重排序(并在MapReduce集群周围进行数据改组). 如果不需要精简,则地图可能会在作业结束时发出为报告而处理的记录计数,或者将精简数量设置为零并使用TableOutputFormat. 如果在您的情况下运行Reduce步骤有意义,则通常应使用多个reducer,以便将负载分散在HBase群集上.

一个新的HBase分区程序HRegionPartitioner可以运行与现有区域数一样多的reducer. HRegionPartitioner适用于表较大且上传完成后不会大大改变现有区域数的情况. 否则,请使用默认分区程序.

52. Writing HFiles Directly During Bulk Import

如果要导入到新表中,则可以绕过HBase API并将内容直接写入文件系统,并格式化为HBase数据文件(HFiles). 您的导入将运行得更快,也许要快一个数量级. 有关此机制如何工作的更多信息,请参见批量加载 .

53. RowCounter Example

所包含的RowCounter的MapReduce作业使用TableInputFormat并执行指定表中的所有行数. 要运行它,请使用以下命令:

$ ./bin/hadoop jar hbase-X.X.X.jar

这将调用HBase MapReduce驱动程序类. 从提供的作业中选择行rowcounter . 这会将行计数器使用建议打印到标准输出. 指定表名,要计数的列和输出目录. 如果您遇到类路径错误,请参见HBase,MapReduce和CLASSPATH .

54. Map-Task Splitting

54.1. The Default HBase MapReduce Splitter

当使用TableInputFormat来在MapReduce作业中获取HBase表时,其拆分器将为该表的每个区域创建一个映射任务. 因此,如果表中有100个区域,则该作业将有100个映射任务-无论在"扫描"中选择了多少列族.

54.2. Custom Splitters

对于那些对实现自定义拆分器感兴趣的人,请参见getSplits中的getSplits方法. 这就是映射任务分配的逻辑所在.

55. HBase MapReduce Examples

55.1. HBase MapReduce Read Example

以下是以只读方式将HBase用作MapReduce源的示例. 具体来说,有一个Mapper实例,但没有Reducer,并且没有从Mapper发出任何东西. 该工作的定义如下...

Configuration config = HBaseConfiguration.create();
Job job = new Job(config, "ExampleRead");
job.setJarByClass(MyReadJob.class);     // class that contains mapper

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs
...

TableMapReduceUtil.initTableMapperJob(
  tableName,        // input HBase table name
  scan,             // Scan instance to control CF and attribute selection
  MyMapper.class,   // mapper
  null,             // mapper output key
  null,             // mapper output value
  job);
job.setOutputFormatClass(NullOutputFormat.class);   // because we aren't emitting anything from mapper

boolean b = job.waitForCompletion(true);
if (!b) {
  throw new IOException("error with job!");
}

...而mapper实例将扩展TableMapper ...

public static class MyMapper extends TableMapper<Text, Text> {

  public void map(ImmutableBytesWritable row, Result value, Context context) throws InterruptedException, IOException {
    // process data for the row from the Result instance.
   }
}

55.2. HBase MapReduce Read/Write Example

以下是通过MapReduce将HBase用作源和接收器的示例. 此示例将简单地将数据从一个表复制到另一个表.

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleReadWrite");
job.setJarByClass(MyReadWriteJob.class);    // class that contains mapper

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
  sourceTable,      // input table
  scan,             // Scan instance to control CF and attribute selection
  MyMapper.class,   // mapper class
  null,             // mapper output key
  null,             // mapper output value
  job);
TableMapReduceUtil.initTableReducerJob(
  targetTable,      // output table
  null,             // reducer class
  job);
job.setNumReduceTasks(0);

boolean b = job.waitForCompletion(true);
if (!b) {
    throw new IOException("error with job!");
}

需要解释TableMapReduceUtil功能,特别是对于reducer. TableOutputFormat用作outputFormat类,并且在配置上设置了几个参数(例如TableOutputFormat.OUTPUT_TABLE ),并将reducer输出键设置为ImmutableBytesWritable而reducer值设置为Writable . 这些可以由程序员在job和conf上设置,但是TableMapReduceUtil试图使事情变得更容易.

以下是示例映射器,它将创建一个Put并匹配输入的Result并将其发出. 注意:这就是CopyTable实用程序的作用.

public static class MyMapper extends TableMapper<ImmutableBytesWritable, Put>  {

  public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
    // this example is just copying the data from the source table...
      context.write(row, resultToPut(row,value));
    }

    private static Put resultToPut(ImmutableBytesWritable key, Result result) throws IOException {
      Put put = new Put(key.get());
      for (KeyValue kv : result.raw()) {
        put.add(kv);
      }
      return put;
    }
}

实际上没有TableOutputFormat步骤,因此TableOutputFormat负责Put发送到目标表.

这只是一个示例,开发人员可以选择不使用TableOutputFormat并自己连接到目标表.

55.3. HBase MapReduce Read/Write Example With Multi-Table Output

TODO: example for MultiTableOutputFormat.

55.4. HBase MapReduce Summary to HBase Example

以下示例将HBase用作MapReduce源和接收器,并进行汇总. 本示例将对一个表中某个值的不同实例的数量进行计数,并将这些汇总计数写入另一个表中.

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleSummary");
job.setJarByClass(MySummaryJob.class);     // class that contains mapper and reducer

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
  sourceTable,        // input table
  scan,               // Scan instance to control CF and attribute selection
  MyMapper.class,     // mapper class
  Text.class,         // mapper output key
  IntWritable.class,  // mapper output value
  job);
TableMapReduceUtil.initTableReducerJob(
  targetTable,        // output table
  MyTableReducer.class,    // reducer class
  job);
job.setNumReduceTasks(1);   // at least one, adjust as required

boolean b = job.waitForCompletion(true);
if (!b) {
  throw new IOException("error with job!");
}

在此示例映射器中,选择具有字符串值的列作为要汇总的值. 该值用作从映射器发出的键,并且IntWritable表示实例计数器.

public static class MyMapper extends TableMapper<Text, IntWritable>  {
  public static final byte[] CF = "cf".getBytes();
  public static final byte[] ATTR1 = "attr1".getBytes();

  private final IntWritable ONE = new IntWritable(1);
  private Text text = new Text();

  public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
    String val = new String(value.getValue(CF, ATTR1));
    text.set(val);     // we can only emit Writables...
    context.write(text, ONE);
  }
}

在reducer中,对" 1"进行计数(就像其他任何执行此操作的MR示例一样),然后发出Put .

public static class MyTableReducer extends TableReducer<Text, IntWritable, ImmutableBytesWritable>  {
  public static final byte[] CF = "cf".getBytes();
  public static final byte[] COUNT = "count".getBytes();

  public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    int i = 0;
    for (IntWritable val : values) {
      i += val.get();
    }
    Put put = new Put(Bytes.toBytes(key.toString()));
    put.add(CF, COUNT, Bytes.toBytes(i));

    context.write(null, put);
  }
}

55.5. HBase MapReduce Summary to File Example

这与上面的摘要示例非常相似,不同的是,它使用HBase作为MapReduce源,但使用HDFS作为接收器. 区别在于作业设置和减速机. 映射器保持不变.

Configuration config = HBaseConfiguration.create();
Job job = new Job(config,"ExampleSummaryToFile");
job.setJarByClass(MySummaryFileJob.class);     // class that contains mapper and reducer

Scan scan = new Scan();
scan.setCaching(500);        // 1 is the default in Scan, which will be bad for MapReduce jobs
scan.setCacheBlocks(false);  // don't set to true for MR jobs
// set other scan attrs

TableMapReduceUtil.initTableMapperJob(
  sourceTable,        // input table
  scan,               // Scan instance to control CF and attribute selection
  MyMapper.class,     // mapper class
  Text.class,         // mapper output key
  IntWritable.class,  // mapper output value
  job);
job.setReducerClass(MyReducer.class);    // reducer class
job.setNumReduceTasks(1);    // at least one, adjust as required
FileOutputFormat.setOutputPath(job, new Path("/tmp/mr/mySummaryFile"));  // adjust directories as required

boolean b = job.waitForCompletion(true);
if (!b) {
  throw new IOException("error with job!");
}

如上所述,在此示例中,先前的Mapper可以保持不变. 至于Reducer,它是一个"通用" Reducer,而不是扩展TableMapper和发出Puts.

public static class MyReducer extends Reducer<Text, IntWritable, Text, IntWritable>  {

  public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    int i = 0;
    for (IntWritable val : values) {
      i += val.get();
    }
    context.write(key, new IntWritable(i));
  }
}

55.6. HBase MapReduce Summary to HBase Without Reducer

如果将HBase用作化简器,也可以不使用化简器执行摘要.

HBase目标表将需要存在以用于作业摘要. Table方法incrementColumnValue将用于原子地递增值. 从性能的角度来看,最好保留一个值映射,并为每个映射任务增加其值,并在映射器的cleanup方法期间对每个键进行一次更新. 但是,您的里程可能会有所不同,具体取决于要处理的行数和唯一键.

In the end, the summary results are in HBase.

55.7. HBase MapReduce Summary to RDBMS

有时,为RDBMS生成摘要更为合适. 对于这些情况,可以通过定制化简器直接向RDBMS生成摘要. setup方法可以连接到RDBMS(可以通过上下文中的自定义参数传递连接信息),而cleanup方法可以关闭连接.

It is critical to understand that number of reducers for the job affects the summarization implementation, and you’ll have to design this into your reducer. Specifically, whether it is designed to run as a singleton (one reducer) or multiple reducers. Neither is right or wrong, it depends on your use-case. Recognize that the more reducers that are assigned to the job, the more simultaneous connections to the RDBMS will be created - this will scale, but only to a point.

public static class MyRdbmsReducer extends Reducer<Text, IntWritable, Text, IntWritable>  {

  private Connection c = null;

  public void setup(Context context) {
    // create DB connection...
  }

  public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
    // do summarization
    // in this example the keys are Text, but this is just an example
  }

  public void cleanup(Context context) {
    // close db connection
  }

}

最后,汇总结果将写入您的RDBMS表.

56. Accessing Other HBase Tables in a MapReduce Job

尽管该框架当前允许一个HBase表作为MapReduce作业的输入,但可以通过在Mapper的setup方法中创建Table实例,在MapReduce作业中将其他HBase表作为查找表等进行访问.

public class MyMapper extends TableMapper<Text, LongWritable> {
  private Table myOtherTable;

  public void setup(Context context) {
    // In here create a Connection to the cluster and save it or use the Connection
    // from the existing table
    myOtherTable = connection.getTable("myOtherTable");
  }

  public void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
    // process Result...
    // use 'myOtherTable' for lookups
  }

57. Speculative Execution

对于使用HBase作为源的MapReduce作业,通常建议关闭推测执行. 这可以通过属性在每个作业的基础上完成,也可以在整个集群上完成. 特别是对于长时间运行的作业,推测性执行将创建重复的映射任务,这会将您的数据双重写入HBase. 这可能不是您想要的.

有关更多信息,请参见spec.ex.

58. Cascading

Cascading is an alternative API for MapReduce, which actually uses MapReduce, but allows you to write your MapReduce code in a simplified way.

以下示例显示了将数据"下沉"到HBase集群中的层叠Flow . 同样的hBaseTap API也可以用于"来源"数据.

// read data from the default filesystem
// emits two fields: "offset" and "line"
Tap source = new Hfs( new TextLine(), inputFileLhs );

// store data in an HBase cluster
// accepts fields "num", "lower", and "upper"
// will automatically scope incoming fields to their proper familyname, "left" or "right"
Fields keyFields = new Fields( "num" );
String[] familyNames = {"left", "right"};
Fields[] valueFields = new Fields[] {new Fields( "lower" ), new Fields( "upper" ) };
Tap hBaseTap = new HBaseTap( "multitable", new HBaseScheme( keyFields, familyNames, valueFields ), SinkMode.REPLACE );

// a simple pipe assembly to parse the input into fields
// a real app would likely chain multiple Pipes together for more complex processing
Pipe parsePipe = new Each( "insert", new Fields( "line" ), new RegexSplitter( new Fields( "num", "lower", "upper" ), " " ) );

// "plan" a cluster executable Flow
// this connects the source Tap and hBaseTap (the sink Tap) to the parsePipe
Flow parseFlow = new FlowConnector( properties ).connect( source, hBaseTap, parsePipe );

// start the flow, and block until complete
parseFlow.complete();

// open an iterator on the HBase table we stuffed data into
TupleEntryIterator iterator = parseFlow.openSink();

while(iterator.hasNext())
  {
  // print out each tuple from HBase
  System.out.println( "iterator.next() = " + iterator.next() );
  }

iterator.close();

Securing Apache HBase

报告安全漏洞
为了保护现有的HBase安装不受攻击,请不要使用JIRA报告与安全性有关的错误. 而是将您的报告发送到邮件列表private@hbase.apache.org ,该列表允许任何人发送消息,但限制了可以读取消息的人. 该列表中的某人将与您联系以跟进您的报告.

HBase遵守Apache Software Foundation关于报告的漏洞的政策,该政策可从http://apache.org/security/获得 .

如果您希望发送加密的报告,则可以使用为常规ASF安全列表提供的GPG详细信息. 这可能会增加对报告的响应时间.

59. Web UI Security

HBase提供了一些机制来保护HBase的各个组件和方面以及它与Hadoop基础结构的其余部分以及Hadoop外部的客户端和资源之间的关系.

59.1. Using Secure HTTP (HTTPS) for the Web UI

默认的HBase安装会为主服务器和区域服务器的Web UI使用不安全的HTTP连接. 要启用,而不是安全的HTTP(HTTPS)连接,设置hbase.ssl.enabledtrueHBase的-site.xml中 . 这不会更改Web UI使用的端口. 要更改给定HBase组件的Web UI的端口,请在hbase-site.xml中配置该端口的设置. 这些设置是:

  • hbase.master.info.port

  • hbase.regionserver.info.port

如果启用HTTPS,客户端应避免使用非安全的HTTP连接.

如果启用安全HTTP,则客户端应使用https:// URL连接到HBase. 使用http:// URL的客户端将收到200的HTTP响应,但不会收到任何数据. 记录以下异常:

javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?

这是因为同一端口用于HTTP和HTTPS.

HBase将Jetty用于Web UI. 如果不修改Jetty本身,似乎无法配置Jetty将一个端口重定向到同一主机上的另一个端口. 有关更多信息,请参见Nick Dimiduk在此Stack Overflow线程上的贡献. 如果您知道如何解决此问题而又没有为HTTPS打开第二个端口,那么不胜感激.

59.2. Using SPNEGO for Kerberos authentication with Web UIs

Kerberos-authentication to HBase Web UIs can be enabled via configuring SPNEGO with the hbase.security.authentication.ui property in hbase-site.xml. Enabling this authentication requires that HBase is also configured to use Kerberos authentication for RPCs (e.g hbase.security.authentication = kerberos).

<property>
  <name>hbase.security.authentication.ui</name>
  <value>kerberos</value>
  <description>Controls what kind of authentication should be used for the HBase web UIs.</description>
</property>
<property>
  <name>hbase.security.authentication</name>
  <value>kerberos</value>
  <description>The Kerberos keytab file to use for SPNEGO authentication by the web server.</description>
</property>

存在许多属性,可以为Web服务器配置SPNEGO身份验证:

<property>
  <name>hbase.security.authentication.spnego.kerberos.principal</name>
  <value>HTTP/_HOST@EXAMPLE.COM</value>
  <description>Required for SPNEGO, the Kerberos principal to use for SPNEGO authentication by the
  web server. The _HOST keyword will be automatically substituted with the node's
  hostname.</description>
</property>
<property>
  <name>hbase.security.authentication.spnego.kerberos.keytab</name>
  <value>/etc/security/keytabs/spnego.service.keytab</value>
  <description>Required for SPNEGO, the Kerberos keytab file to use for SPNEGO authentication by the
  web server.</description>
</property>
<property>
  <name>hbase.security.authentication.spnego.kerberos.name.rules</name>
  <value></value>
  <description>Optional, Hadoop-style `auth_to_local` rules which will be parsed and used in the
  handling of Kerberos principals</description>
</property>
<property>
  <name>hbase.security.authentication.signature.secret.file</name>
  <value></value>
  <description>Optional, a file whose contents will be used as a secret to sign the HTTP cookies
  as a part of the SPNEGO authentication handshake. If this is not provided, Java's `Random` library
  will be used for the secret.</description>
</property>

59.3. Defining administrators of the Web UI

在上一节中,我们介绍了如何通过SPNEGO启用Web UI的身份验证. 但是,Web UI的某些部分可用于影响HBase群集的可用性和性能. 因此,希望确保只有那些具有适当权限的人员才能与这些敏感端点进行交互.

HBase允许通过hbase-site.xml中的用户名或组列表定义管理员

<property>
  <name>hbase.security.authentication.spnego.admin.users</name>
  <value></value>
</property>
<property>
  <name>hbase.security.authentication.spnego.admin.groups</name>
  <value></value>
</property>

给定core-site.xml中的Hadoop auth_to_local规则,用户名是Kerberos身份映射到的用户名. 这里的组是与映射的用户名关联的Unix组.

请考虑以下情形,以描述配置属性的运行方式. 考虑在Kerberos KDC中定义的三个用户:

  • alice@COMPANY.COM

  • bob@COMPANY.COM

  • charlie@COMPANY.COM

缺省的Hadoop auth_to_local规则将这些主体映射到"短名称":

  • alice

  • bob

  • charlie

Unix groups membership define that alice is a member of the group admins. bob and charlie are not members of the admins group.

<property>
  <name>hbase.security.authentication.spnego.admin.users</name>
  <value>charlie</value>
</property>
<property>
  <name>hbase.security.authentication.spnego.admin.groups</name>
  <value>admins</value>
</property>

根据上述配置,由于aliceadmins组的成员,因此允许其访问Web UI中的敏感端点. 还允许charlie访问敏感的端点,因为在配置中将charlie明确列为管理员. 不允许bob访问敏感端点,因为他既不是admins组的成员,也不通过hbase.security.authentication.spnego.admin.users被列为显式管理员用户,但仍可以使用hbase.security.authentication.spnego.admin.users任何非敏感端点Web UI.

如果不言而喻:未经身份验证的用户将无法访问Web UI的任何部分.

尽管这对于HBase开发人员而言是明显的反模式,但是开发人员承认HBase配置(包括Hadoop配置文件)可能包含敏感信息. 这样,用户可能会发现他们不想向所有经过身份验证的用户公开HBase服务级别的配置. 他们可能将HBase配置为要求用户必须是管理员才能通过HBase UI访问服务级别配置. 默认情况下,此配置为false (任何经过身份验证的用户都可以访问该配置).

希望更改此设置的用户可以在其hbase-site.xml中设置以下内容:

<property>
  <name>hbase.security.authentication.ui.config.protected</name>
  <value>true</value>
</property>

60. Secure Client Access to Apache HBase

较新的Apache HBase版本(> = 0.92)支持客户端的可选SASL身份验证. 另请参见Matteo Bertozzi的文章, 了解Apache HBase中的用户身份验证和授权 .

这说明了如何设置Apache HBase和客户端以连接到安全的HBase资源.

60.1. Prerequisites

Hadoop Authentication Configuration

要使用强身份验证运行HBase RPC,必须将hbase.security.authentication设置为kerberos . 在这种情况下,还必须在core-site.xml中将hadoop.security.authentication设置为kerberos . 否则,您将对HBase使用强身份验证,而不对基础HDFS使用强身份验证,这将抵消任何好处.

Kerberos KDC

您需要有一个有效的Kerberos KDC.

60.2. Server-side Configuration for Secure Operation

首先,请参阅security.prerequisites,并确保基础HDFS配置是安全的.

将以下内容添加到群集中每台服务器计算机上的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.coprocessor.region.classes</name>
  <value>org.apache.hadoop.hbase.security.token.TokenProvider</value>
</property>

部署这些配置更改时,需要完全关闭并重新启动HBase服务.

60.3. Client-side Configuration for Secure Operation

首先,请参阅先决条件,并确保基础HDFS配置是安全的.

将以下内容添加到每个客户端的hbase-site.xml文件中:

<property>
  <name>hbase.security.authentication</name>
  <value>kerberos</value>
</property>

在2.2.0版之前,必须先通过kinit命令从KDC或keytab登录客户端环境,然后才能与HBase群集进行通信.

从2.2.0开始,客户端可以在hbase-site.xml指定以下配置:

<property>
  <name>hbase.client.keytab.file</name>
  <value>/local/path/to/client/keytab</value>
</property>

<property>
  <name>hbase.client.keytab.principal</name>
  <value>foo@EXAMPLE.COM</value>
</property>

然后,应用程序可以自动执行登录和凭据续订作业,而不会受到客户端的干扰.

这是可选功能,升级到2.2.0的客户端只要保持未设置hbase.client.keytab.filehbase.client.keytab.principal ,仍可以保持其登录和凭证续订逻辑.

请注意,如果客户端和服务器端站点文件中的hbase.security.authentication不匹配,则客户端将无法与群集进行通信.

一旦为安全的RPC配置了HBase,就可以选择配置加密的通信. 为此,请将以下内容添加到每个客户端的hbase-site.xml文件中:

<property>
  <name>hbase.rpc.protection</name>
  <value>privacy</value>
</property>

也可以在每个连接的基础上设置此配置属性. 在提供给TableConfiguration中进行Configuration

Configuration conf = HBaseConfiguration.create();
Connection connection = ConnectionFactory.createConnection(conf);
conf.set("hbase.rpc.protection", "privacy");
try (Connection connection = ConnectionFactory.createConnection(conf);
     Table table = connection.getTable(TableName.valueOf(tablename))) {
  .... do your stuff
}

预计加密通信的性能会降低约10%.

60.4. Client-side Configuration for Secure Operation - Thrift Gateway

将以下内容添加到每个Thrift网关的hbase-site.xml文件中:

<property>
  <name>hbase.thrift.keytab.file</name>
  <value>/etc/hbase/conf/hbase.keytab</value>
</property>
<property>
  <name>hbase.thrift.kerberos.principal</name>
  <value>$USER/_HOST@HADOOP.LOCALDOMAIN</value>
  <!-- TODO: This may need to be  HTTP/_HOST@<REALM> and _HOST may not work.
   You may have  to put the concrete full hostname.
   -->
</property>
<!-- Add these if you need to configure a different DNS interface from the default -->
<property>
  <name>hbase.thrift.dns.interface</name>
  <value>default</value>
</property>
<property>
  <name>hbase.thrift.dns.nameserver</name>
  <value>default</value>
</property>

分别用适当的凭据和$ keytab替换$ USER$ KEYTAB .

为了使用Thrift API主体与HBase进行交互,还必须将hbase.thrift.kerberos.principal添加到acl表中. 例如,要给Thrift API主体thrift_server管理访问,这样的命令就足够了:

grant 'thrift_server', 'RWCA'

有关ACL的更多信息,请参见访问控制标签(ACL)部分.

Thrift网关将使用提供的凭据对HBase进行身份验证. Thrift网关本身不会执行任何身份验证. 所有通过Thrift网关的客户端访问都将使用Thrift网关的凭据并拥有其特权.

60.5. Configure the Thrift Gateway to Authenticate on Behalf of the Client

安全操作的客户端配置-Thrift网关介绍了如何使用固定用户向HBase认证Thrift客户端. 或者,您可以配置Thrift网关代表客户端对HBase进行身份验证,并使用代理用户访问HBase. 这在实施HBASE-11349为节俭1,和HBASE-11474为节俭2.

节俭式运输的局限性

如果您使用框架传输,则您将无法利用此功能,因为SASL目前不适用于Thrift框架传输.

要启用它,请执行以下操作.

  1. 通过遵循安全操作客户端配置-Thrift Gateway中描述的过程,确保Thrift在安全模式下运行.

  2. 确保将HBase配置为允许代理用户,如REST网关模拟配置中所述 .

  3. 在每个运行Thrift网关的群集节点的hbase-site.xml中,将属性hbase.thrift.security.qop设置为以下三个值之一:

    • privacy -身份验证,完整性和机密性检查.

    • integrity -身份验证和完整性检查

    • authentication -仅验证检查

  4. 重新启动Thrift网关进程以使更改生效. 如果节点正在运行Thrift,则jps命令的输出将列出ThriftServer进程. 要在节点上停止Thrift,请运行命令bin/hbase-daemon.sh stop thrift . 要在节点上启动Thrift,请运行命令bin/hbase-daemon.sh start thrift .

60.6. Configure the Thrift Gateway to Use the doAs Feature

配置Thrift网关代表客户端进行身份验证介绍了如何配置Thrift网关代表客户端对HBase进行身份验证以及如何使用代理用户访问HBase. 此方法的局限性在于,在使用特定的一组凭据初始化客户端之后,客户端无法在会话期间更改这些凭据. doAs功能提供了一种使用同一客户端模拟多个主体的灵活方法. 此功能已在HBASE-12640中为Thrift 1实现,但当前不适用于Thrift 2.

启用doAs功能, add the following to the hbase-site.xml file for every Thrift gateway:

<property>
  <name>hbase.regionserver.thrift.http</name>
  <value>true</value>
</property>
<property>
  <name>hbase.thrift.support.proxyuser</name>
  <value>true/value>
</property>

在使用doAs模拟时允许代理用户 ,请将以下内容添加到每个HBase节点的hbase-site.xml文件中:

<property>
  <name>hadoop.security.authorization</name>
  <value>true</value>
</property>
<property>
  <name>hadoop.proxyuser.$USER.groups</name>
  <value>$GROUPS</value>
</property>
<property>
  <name>hadoop.proxyuser.$USER.hosts</name>
  <value>$GROUPS</value>
</property>

查看演示客户端,以了解如何在客户端中使用此功能的总体思路.

60.7. Client-side Configuration for Secure Operation - REST Gateway

将以下内容添加到每个REST网关的hbase-site.xml文件中:

<property>
  <name>hbase.rest.keytab.file</name>
  <value>$KEYTAB</value>
</property>
<property>
  <name>hbase.rest.kerberos.principal</name>
  <value>$USER/_HOST@HADOOP.LOCALDOMAIN</value>
</property>

分别用适当的凭据和$ keytab替换$ USER$ KEYTAB .

REST网关将使用提供的凭据向HBase进行身份验证.

为了使用REST API主体与HBase进行交互,还必须将hbase.rest.kerberos.principal添加到acl表中. 例如,要授予REST API主体rest_server管理访问权限,只需执行以下命令即可:

grant 'rest_server', 'RWCA'

有关ACL的更多信息,请参见访问控制标签(ACL)部分.

HBase REST网关支持SPNEGO HTTP身份验证 ,以使客户端可以访问网关. 要为客户端访问启用REST网关Kerberos身份验证,请将以下内容添加到每个REST网关的hbase-site.xml文件中.

<property>
  <name>hbase.rest.support.proxyuser</name>
  <value>true</value>
</property>
<property>
  <name>hbase.rest.authentication.type</name>
  <value>kerberos</value>
</property>
<property>
  <name>hbase.rest.authentication.kerberos.principal</name>
  <value>HTTP/_HOST@HADOOP.LOCALDOMAIN</value>
</property>
<property>
  <name>hbase.rest.authentication.kerberos.keytab</name>
  <value>$KEYTAB</value>
</property>
<!-- Add these if you need to configure a different DNS interface from the default -->
<property>
  <name>hbase.rest.dns.interface</name>
  <value>default</value>
</property>
<property>
  <name>hbase.rest.dns.nameserver</name>
  <value>default</value>
</property>

将keytab替换为$ KEYTAB的 HTTP.

HBase REST网关支持不同的" hbase.rest.authentication.type":简单,kerberos. 您还可以通过实现Hadoop AuthenticationHandler来实现自定义身份验证,然后将完整的类名称指定为" hbase.rest.authentication.type"值. 有关更多信息,请参阅SPNEGO HTTP身份验证 .

60.8. REST Gateway Impersonation Configuration

默认情况下,REST网关不支持模拟. 它以上一节中配置的用户身份代表客户端访问HBase. 对于HBase服务器,所有请求均来自REST网关用户. 实际用户未知. 您可以打开模拟支持. 通过模拟,REST网关用户是代理用户. HBase服务器知道每个请求的实际/实际用户. 因此,它可以应用适当的授权.

要打开REST网关模拟,我们需要配置HBase服务器(主服务器和区域服务器)以允许代理用户. 配置REST网关以启用模拟.

要允许代理用户,请将以下内容添加到每个HBase服务器的hbase-site.xml文件中:

<property>
  <name>hadoop.security.authorization</name>
  <value>true</value>
</property>
<property>
  <name>hadoop.proxyuser.$USER.groups</name>
  <value>$GROUPS</value>
</property>
<property>
  <name>hadoop.proxyuser.$USER.hosts</name>
  <value>$GROUPS</value>
</property>

将REST网关代理用户替换为$ USER ,并将允许的组列表替换为$ GROUPS .

To enable REST gateway impersonation, add the following to the hbase-site.xml file for every REST gateway.

<property>
  <name>hbase.rest.authentication.type</name>
  <value>kerberos</value>
</property>
<property>
  <name>hbase.rest.authentication.kerberos.principal</name>
  <value>HTTP/_HOST@HADOOP.LOCALDOMAIN</value>
</property>
<property>
  <name>hbase.rest.authentication.kerberos.keytab</name>
  <value>$KEYTAB</value>
</property>

将keytab替换为$ KEYTAB的 HTTP.

61. Simple User Access to Apache HBase

较新的Apache HBase版本(> = 0.92)支持客户端的可选SASL身份验证. 另请参见Matteo Bertozzi的文章, 了解Apache HBase中的用户身份验证和授权 .

这描述了如何设置Apache HBase和客户端以简化用户对HBase资源的访问.

61.1. Simple versus Secure Access

以下部分显示了如何设置简单的用户访问. 简单的用户访问不是操作HBase的安全方法. 此方法用于防止用户犯错误. 它可以用来模拟在开发系统上使用的访问控制,而无需设置Kerberos.

此方法不用于防止恶意或黑客尝试. 要使HBase抵御这些类型的攻击,必须为安全操作配置HBase. 请参考" 对Apache HBase的安全客户端访问 "部分并完成此处描述的所有步骤.

61.2. Prerequisites

None

61.3. Server-side Configuration for Simple User Access Operation

将以下内容添加到群集中每台服务器计算机上的hbase-site.xml文件中:

<property>
  <name>hbase.security.authentication</name>
  <value>simple</value>
</property>
<property>
  <name>hbase.security.authorization</name>
  <value>true</value>
</property>
<property>
  <name>hbase.coprocessor.master.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
<property>
  <name>hbase.coprocessor.region.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
<property>
  <name>hbase.coprocessor.regionserver.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>

对于0.94,请将以下内容添加到群集中每台服务器计算机上的hbase-site.xml文件中:

<property>
  <name>hbase.rpc.engine</name>
  <value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
</property>
<property>
  <name>hbase.coprocessor.master.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
<property>
  <name>hbase.coprocessor.region.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>

部署这些配置更改时,需要完全关闭并重新启动HBase服务.

61.4. Client-side Configuration for Simple User Access Operation

将以下内容添加到每个客户端的hbase-site.xml文件中:

<property>
  <name>hbase.security.authentication</name>
  <value>simple</value>
</property>

For 0.94, add the following to the hbase-site.xml file on every server machine in the cluster:

<property>
  <name>hbase.rpc.engine</name>
  <value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
</property>

请注意,如果客户端和服务器端站点文件中的hbase.security.authentication不匹配,则客户端将无法与群集进行通信.

61.4.1. Client-side Configuration for Simple User Access Operation - Thrift Gateway

Thrift网关用户将需要访问. 例如,要给Thrift API用户thrift_server管理访问,这样的命令就足够了:

grant 'thrift_server', 'RWCA'

有关ACL的更多信息,请参见访问控制标签(ACL)部分.

Thrift网关将使用提供的凭据对HBase进行身份验证. Thrift网关本身不会执行任何身份验证. 所有通过Thrift网关的客户端访问都将使用Thrift网关的凭据并拥有其特权.

61.4.2. Client-side Configuration for Simple User Access Operation - REST Gateway

The REST gateway will authenticate with HBase using the supplied credential. No authentication will be performed by the REST gateway itself. All client access via the REST gateway will use the REST gateway’s credential and have its privilege.

REST网关用户将需要访问. 例如,要给REST API用户rest_server管理访问,这样的命令就足够了:

grant 'rest_server', 'RWCA'

有关ACL的更多信息,请参见访问控制标签(ACL)部分.

客户端应该可以通过SPNEGO HTTP身份验证通过REST网关通过HBase群集进行身份验证. 这是未来的工作.

62. Securing Access to HDFS and ZooKeeper

安全的HBase需要安全的ZooKeeper和HDFS,以便用户无法从HBase下访问和/或修改元数据和数据. HBase使用HDFS(或配置的文件系统)来保留其数据文件以及预写日志(WAL)和其他数据. HBase使用ZooKeeper来存储一些用于操作的元数据(主地址,表锁,恢复状态等).

62.1. Securing ZooKeeper Data

ZooKeeper具有可插入的身份验证机制,以允许使用不同方法从客户端进行访问. ZooKeeper甚至可以同时允许经过身份验证和未经身份验证的客户端. 可以通过为每个znode提供访问控制列表(ACL)来限制对znode的访问. ACL包含两个组件,身份验证方法和主体. ACL不是分层实施的. 有关详细信息,请参见ZooKeeper程序员指南 .

HBase守护程序通过SASL和kerberos向ZooKeeper进行身份验证 (请参阅使用ZooKeeper的SASL身份验证 ). HBase设置znode ACL,以便只有HBase用户和配置的hbase superuser( hbase.superuser )可以访问和修改数据. 在将ZooKeeper用于服务发现或与客户端共享状态的情况下,由HBase创建的znode也将允许任何人(无论身份验证如何)读取这些znode(clusterId,主地址,元位置等),但只能读取HBase.用户可以修改它们.

62.2. Securing File System (HDFS) Data

所有受管理的数据都保存在文件系统( hbase.rootdir )的根目录下. 应该限制​​对文件系统中数据和WAL文件的访问,以使用户无法绕过HBase层,并可以窥视文件系统中的基础数据文件. HBase假定使用的文件系统(HDFS或其他文件系统)强制执行权限. 如果没有提供足够的文件系统保护(授权和身份验证),则HBase级别授权控制(ACL,可见性标签等)将毫无意义,因为用户始终可以从文件系统访问数据.

HBase对其根目录强制执行类似posix的权限700( rwx------ ). 这意味着只有HBase用户可以读取或写入FS中的文件. 可以通过在hbase-site.xml中配置hbase.rootdir.perms来更改默认设置. 需要重新启动活动主服务器,以便更改使用的权限. 对于1.2.0之前的版本,可以检查是否提交了HBASE-13780,如果没有提交,则可以根据需要手动设置根目录的权限. 使用HDFS,命令将是:

sudo -u hdfs hadoop fs -chmod 700 /hbase

如果使用其他hbase.rootdir则应更改/hbase hbase.rootdir .

在安全模式下,应配置SecureBulkLoadEndpoint并将其用于正确地将从MR作业创建的用户文件移交给HBase守护程序和HBase用户. 用于批量加载的分布式文件系统中的登台目录( hbase.bulkload.staging.dir ,默认为/tmp/hbase-staging )应该具有(模式711或rwx—​x—​x ),以便用户可以访问在该父目录下创建的暂存目录,但不能执行任何其他操作. 有关如何配置SecureBulkLoadEndPoint的信息,请参阅安全大容量加载 .

63. Securing Access To Your Data

在HBase客户端与服务器进程和网关之间配置了安全身份验证之后,需要考虑数据本身的安全性. HBase提供了几种保护数据的策略:

  • 基于角色的访问控制(RBAC)使用熟悉的角色范例来控制哪些用户或组可以读写给定的HBase资源或执行协处理器端点.

  • 可见性标签使您可以标记单元格并控制对标记单元格的访问,以进一步限制谁可以读取或写入数据的某些子集. 可见性标签存储为标签. 有关更多信息,请参见hbase.tags .

  • Transparent encryption of data at rest on the underlying filesystem, both in HFiles and in the WAL. This protects your data at rest from an attacker who has access to the underlying filesystem, without the need to change the implementation of the client. It can also protect against data leakage from improperly disposed disks, which can be important for legal and regulatory compliance.

下面讨论了每个功能的服务器端配置,管理和实现细节,以及所有性能折衷. 最后给出了一个示例安全配置,以显示这些功能一起使用,就像它们在现实世界中一样.

HBase中的安全性的各个方面都在积极开发中,并且正在迅速发展. 您为数据安全性采用的任何策略均应进行彻底测试. 此外,其中一些功能仍处于试验开发阶段. 要利用其中的许多功能,您必须正在运行HBase 0.98+并使用HFile v3文件格式.
Protecting Sensitive Files

本节中的几个过程要求您在群集节点之间复制文件. 复制密钥,配置文件或其他包含敏感字符串的文件时,请使用诸如ssh类的安全方法,以避免泄漏敏感数据.

过程:基本服务器端配置
  1. 启用HFILE V3,通过设置hfile.format.versionHBase的-site.xml中以3. 这是HBase 1.0及更高版本的默认设置.

    <property>
      <name>hfile.format.version</name>
      <value>3</value>
    </property>
  2. 启用RPC和ZooKeeper的SASL和Kerberos身份验证,如security.prerequisites使用ZooKeeper的SASL身份验证中所述.

63.1. Tags

标签是HFile v3的功能. 标签是元数据的一部分,它是单元的一部分,与键,值和版本分开. 标签是一种实现细节,它为其他与安全相关的功能(如单元级ACL和可见性标签)奠定了基础. 标记存储在HFiles本身中. 将来可能会使用标签来实现其他HBase功能. 您无需对标签有太多了解即可使用它们启用的安全功能.

63.1.1. Implementation Details

每个单元格可以具有零个或多个标签. 每个标签都有一个类型和实际的标签字节数组.

正如可以对行键,列族,限定符和值进行编码(请参阅data.block.encoding.types )一样,也可以对标签进行编码. 您可以在列族级别启用或禁用标记编码,并且默认情况下启用. 使用HColumnDescriptor#setCompressionTags(boolean compressTags)方法来管理列族的编码设置. 您还需要为列系列启用DataBlockEncoder,以使标签编码生效.

如果还启用了WAL压缩,则可以通过将hbase-site.xml中hbase.regionserver.wal.tags.enablecompression的值设置为true来启用WAL中每个标签的压缩. 标签压缩使用字典编码.

在RegionServers上服务器端运行的协处理器可以对单元标签执行get和set操作. 在发送回读响应之前,标记在RPC层被剥离,因此客户端看不到这些标记. 使用WAL加密时,不支持标签压缩.

63.2. Access Control Labels (ACLs)

63.2.1. How It Works

HBase中的ACL基于用户在组中的成员身份或从组中排除,以及给定的组访问给定资源的权限. ACL被实现为称为AccessController的协处理器.

HBase不维护私有组映射,而是依赖Hadoop组映射器 ,该映射在LDAP或Active Directory等目录中的实体与HBase用户之间进行映射. 任何受支持的Hadoop组映射器都将起作用. 然后,向用户授予针对资源(全局,名称空间,表,单元或端点)的特定权限(读取,写入,执行,创建,管理).

启用Kerberos和访问控制后,将对客户端对HBase的访问进行身份验证,并且用户数据为私有数据,除非已明确授予访问权限.

HBase具有比关系数据库更简单的安全模型,尤其是在客户端操作方面. 例如,插入(新记录)和更新(现有记录)之间没有区别,因为两者都折叠成Put.

Understanding Access Levels

HBase访问级别彼此独立授予,并允许在给定范围内进行不同类型的操作.

  • 读(R) -可以在给定范围内读取数据

  • 写入(W) -可以在给定范围内写入数据

  • 执行(X) -可以在给定范围内执行协处理器端点

  • 创建(C) -可以在给定范围内创建表或删除表(甚至包括未创建的表)

  • 管理员(A) -可以执行群集操作,例如平衡群集或在给定范围内分配区域

可能的范围是:

  • 超级用户 -超级用户可以对任何资源执行HBase中可用的任何操作. 在群集上运行HBase的用户是超级用户,在HMaster的hbase-site.xml中分配给配置属性hbase.superuser任何主体也是如此.

  • 全局 -在全局范围内授予的权限允许管理员对集群的所有表进行操作.

  • 命名空间 -在命名空间范围内授予的权限适用于给定命名空间内的所有表.

  • -在范围内授予的权限适用于给定表内的数据或元数据.

  • ColumnFamily-ColumnFamily范围内授予的权限适用于该ColumnFamily中的单元格.

  • 单元格 -在单元格范围内授予的权限适用于该确切的单元格坐标(键,值,时间戳记). 这允许策略与数据一起发展.

    要更改特定单元格上的ACL,请使用新ACL将更新后的单元格写入原始单元格的精确坐标.

    如果您具有多版本架构,并且想要在所有可见版本上更新ACL,则需要为所有可见版本编写新的单元格. 该应用程序可以完全控制策略的演变.

    上述规则的例外是appendincrement处理. 追加和递增操作中可以携带ACL. 如果该操作中包含一个,则它将应用于appendincrement的结果. 否则,将保留要追加或增加的现有单元的ACL.

访问级别和范围的组合创建了可以授予用户的可能访问级别的矩阵. 在生产环境中,根据完成特定工作所需的条件来考虑访问级别很有用. 下表描述了一些常见HBase用户类型的访问级别. 重要的是,不要授予超出给定用户执行其所需任务所需权限的访问权限.

  • 超级用户 -在生产系统中,只有HBase用户应具有超级用户访问权限. 在开发环境中,管理员可能需要超级用户访问权限才能快速控制和管理集群. 但是,这种类型的管理员通常应该是全局管理员,而不是超级用户.

  • 全局管理员 -全局管理员可以执行任务并访问HBase中的每个表. 在典型的生产环境中,管理员不应具有对表中数据的读取或写入权限.

  • 具有管理员权限的全局管理员可以在群集上执行群集范围内的操作,例如平衡,分配或取消分配区域,或调用显式主要压缩. 这是操作角色.

  • 具有"创建"权限的全局管理员可以在HBase中创建或删除任何表. 这更像是DBA类型的角色.

    In a production environment, it is likely that different users will have only one of Admin and Create permissions.

    在当前实现中,具有Admin权限的Global Admin可以授予他自己对表的ReadWrite权限,并可以访问该表的数据. 因此,仅将Global Admin权限授予实际需要它们的受信任用户.

    还应注意,具有" Create权限的Global Admin可以在ACL表上执行" Put操作,模拟grantrevoke并绕过对Global Admin权限的授权检查.

    由于这些问题,请谨慎授予Global Admin特权.

  • 命名空间管理员 -具有" Create权限的命名空间管理员可以在该命名空间中创建或删除表,以及获取和还原快照. 具有Admin权限的名称空间管理员可以对该名称空间内的表执行诸如拆分或主要压缩之类的操作.

  • 表管理员 -表管理员只能在该表上执行管理操作. 具有" Create权限的表管理员可以从该表创建快照,也可以从快照还原该表. 具有Admin权限的表管理员可以对该表执行诸如拆分或主要压缩之类的操作.

  • 用户 -用户可以读取或写入数据,或两者都有. 如果被赋予Executable权限,用户也可以执行协处理器端点.

表9.访问级别的真实示例
职称 Scope Permissions Description

高级管理员

Global

访问,创建

管理集群并授予初级管理员访问权限.

初级管理员

Global

Create

Creates tables and gives access to Table Administrators.

表管理员

Table

Access

从操作角度维护表.

数据分析师

Table

Read

根据HBase数据创建报告.

Web应用程序

Table

读,写

将数据放入HBase并使用HBase数据执行操作.

ACL矩阵

有关ACL如何映射到特定HBase操作和任务的更多详细信息,请参见附录acl矩阵 .

Implementation Details

单元级ACL是使用标签实现的(请参见标签 ). 为了使用单元级别的ACL,必须使用HFile v3和HBase 0.98或更高版本.

  1. 由HBase创建的文件归运行HBase进程的操作系统用户所有. 要与HBase文件进行交互,应使用API​​或批量加载工具.

  2. HBase不在HBase内部对"角色"建模. 而是可以授予组名权限. 这允许通过组成员资格对角色进行外部建模. 通过Hadoop组映射服务在HBase外部创建和操作组.

Server-Side Configuration
  1. As a prerequisite, perform the steps in Procedure: Basic Server-Side Configuration.

  2. 通过在hbase-site.xml中设置以下属性来安装和配置AccessController协处理器. 这些属性采用类列表.

    如果将AccessController与VisibilityController一起使用,则AccessController必须在列表中排在第一位,因为在两个组件都处于活动状态的情况下,VisibilityController会将其系统表上的访问控制委托给AccessController. 有关将两者一起使用的示例,请参阅" 安全性配置示例" .
    <property>
      <name>hbase.security.authorization</name>
      <value>true</value>
    </property>
    <property>
      <name>hbase.coprocessor.region.classes</name>
      <value>org.apache.hadoop.hbase.security.access.AccessController, org.apache.hadoop.hbase.security.token.TokenProvider</value>
    </property>
    <property>
      <name>hbase.coprocessor.master.classes</name>
      <value>org.apache.hadoop.hbase.security.access.AccessController</value>
    </property>
    <property>
      <name>hbase.coprocessor.regionserver.classes</name>
      <value>org.apache.hadoop.hbase.security.access.AccessController</value>
    </property>
    <property>
      <name>hbase.security.exec.permission.checks</name>
      <value>true</value>
    </property>

    (可选)您可以通过将hbase.rpc.protection设置为privacy来启用传输安全性. 这需要HBase 0.98.4或更高版本.

  3. Set up the Hadoop group mapper in the Hadoop namenode’s core-site.xml. This is a Hadoop file, not an HBase file. Customize it to your site’s needs. Following is an example.

    <property>
      <name>hadoop.security.group.mapping</name>
      <value>org.apache.hadoop.security.LdapGroupsMapping</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.url</name>
      <value>ldap://server</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.bind.user</name>
      <value>Administrator@example-ad.local</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.bind.password</name>
      <value>****</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.base</name>
      <value>dc=example-ad,dc=local</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.search.filter.user</name>
      <value>(&amp;(objectClass=user)(sAMAccountName={0}))</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.search.filter.group</name>
      <value>(objectClass=group)</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.search.attr.member</name>
      <value>member</value>
    </property>
    
    <property>
      <name>hadoop.security.group.mapping.ldap.search.attr.group.name</name>
      <value>cn</value>
    </property>
  4. (可选)启用提前评估策略. 在HBase 0.98.0之前,如果未授予用户访问列族或至少一个列限定符的权限,则将引发AccessDeniedException. HBase 0.98.0删除了此异常,以便允许单元级别的特殊授予. 要恢复旧的行为在HBase的0.98.0-0.98.6,设置hbase.security.access.early_outtrueHBase的-site.xml中 . 在HBase 0.98.6中,默认值已返回true .

  5. 分发配置并重新启动集群以使更改生效.

  6. 要测试您的配置,请以给定用户身份登录到HBase Shell,并使用whoami命令报告您的用户所属的组. 在此示例中,该用户被报告为services组的成员.

    hbase> whoami
    service (auth:KERBEROS)
        groups: services
Administration

可以从HBase Shell或通过API执行管理任务.

API范例

下面的许多API示例都来自源文件hbase-server / src / test / java / org / apache / hadoop / hbase / security / access / TestAccessController.javahbase-server / src / test / java / org / apache /hadoop/hbase/security/access/SecureTestUtil.java .

示例及其来源文件均不是公共HBase API的一部分,并且仅出于说明目的而提供. 有关使用说明,请参考官方API.

  1. 用户和组管理

    用户和组在目录的HBase外部维护.

  2. 授予对命名空间,表,列族或单元格的访问权限

    授予语句有几种不同类型的语法. 第一个也是最熟悉的如下,表和列族是可选的:

    grant 'user', 'RWXCA', 'TABLE', 'CF', 'CQ'

    以相同的方式为组和用户授予访问权限,但组前面带有@符号. 以相同的方式,表和名称空间以相同的方式指定,但名称空间以@符号为前缀.

    如本示例所示,还可以在单​​个语句中授予针对同一资源的多个权限. 第一个子句将用户映射到ACL,第二个子句指定资源.

    HBase Shell在单元级别授予和撤消访问的支持仅用于测试和验证支持,不应用于生产用途,因为它不会将权限应用于尚不存在的单元. 应用单元格级别权限的正确方法是在存储值时在应用程序代码中进行操作.
    ACL粒度和评估顺序

    从最小粒度到最精细粒度对ACL进行评估,并且在达到授予许可的ACL时,评估将停止. 这意味着单元ACL不会以较小的粒度覆盖ACL.

    例子14. HBase Shell
    • Global:

      hbase> grant '@admins', 'RWXCA'
    • Namespace:

      hbase> grant 'service', 'RWXCA', '@test-NS'
    • Table:

      hbase> grant 'service', 'RWXCA', 'user'
    • 列族:

      hbase> grant '@developers', 'RW', 'user', 'i'
    • 列限定词:

      hbase> grant 'service, 'RW', 'user', 'i', 'foo'
    • Cell:

      授予单元ACL的语法使用以下语法:

      grant <table>, \
        { '<user-or-group>' => \
          '<permissions>', ... }, \
        { <scanner-specification> }
    • <user-or-group>是用户名或组名,如果是组,则以@开头.

    • <permissions>是一个包含任何或所有" RWXCA"的字符串,尽管只有R和W在单元格范围内有意义.

    • <scanner-specification>是'scan'shell命令使用的扫描仪规范语法和约定. 有关扫描仪规格的一些示例,请发出以下HBase Shell命令.

      hbase> help "scan"

      如果需要启用ACL单元格,则hbase-site.xml中的hfile.format.version选项应大于或等于3,并且hbase.security.access.early_out选项应设置为false.在" pii"列中与过滤器匹配的单元格上,对" testuser"用户具有访问权限,对"开发者"组具有读/写访问权限.

      hbase> grant 'user', \
        { '@developers' => 'RW', 'testuser' => 'R' }, \
        { COLUMNS => 'pii', FILTER => "(PrefixFilter ('test'))" }

      外壳程序将使用给定的标准运行扫描程序,用新的ACL重写找到的单元,然后将其存储回其精确坐标.

    例子15. API

    以下示例显示了如何在表级别授予访问权限.

    public static void grantOnTable(final HBaseTestingUtility util, final String user,
        final TableName table, final byte[] family, final byte[] qualifier,
        final Permission.Action... actions) throws Exception {
      SecureTestUtil.updateACLs(util, new Callable<Void>() {
        @Override
        public Void call() throws Exception {
          try (Connection connection = ConnectionFactory.createConnection(util.getConfiguration());
               Table acl = connection.getTable(AccessControlLists.ACL_TABLE_NAME)) {
            BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
            AccessControlService.BlockingInterface protocol =
              AccessControlService.newBlockingStub(service);
            AccessControlUtil.grant(null, protocol, user, table, family, qualifier, false, actions);
          }
          return null;
        }
      });
    }

    要在单元级别授予权限,可以使用Mutation.setACL方法:

    Mutation.setACL(String user, Permission perms)
    Mutation.setACL(Map<String, Permission> perms)

    具体而言,此示例为特定put操作中包含的任何单元格上的用户user1提供读取权限:

    put.setACL(user1, new Permission(Permission.Action.READ))
  3. 撤消命名空间,表,列族或单元格中的访问控制

    revoke命令和API是grant命令和API的双胞胎,语法完全相同. 唯一的例外是您不能撤消单元级别的权限. 您只能撤消先前已授予的访问权限,并且revoke语句与显式拒绝资源不同.

    HBase Shell对授予和撤消访问的支持是用于测试和验证支持,不应将其用于生产用途,因为它不会将权限应用于尚不存在的单元. 应用单元格级别权限的正确方法是在存储值时在应用程序代码中进行操作.
    例子16.撤销对表的访问
    public static void revokeFromTable(final HBaseTestingUtility util, final String user,
        final TableName table, final byte[] family, final byte[] qualifier,
        final Permission.Action... actions) throws Exception {
      SecureTestUtil.updateACLs(util, new Callable<Void>() {
        @Override
        public Void call() throws Exception {
          Configuration conf = HBaseConfiguration.create();
          Connection connection = ConnectionFactory.createConnection(conf);
          Table acl = connection.getTable(util.getConfiguration(), AccessControlLists.ACL_TABLE_NAME);
          try {
            BlockingRpcChannel service = acl.coprocessorService(HConstants.EMPTY_START_ROW);
            AccessControlService.BlockingInterface protocol =
                AccessControlService.newBlockingStub(service);
            ProtobufUtil.revoke(protocol, user, table, family, qualifier, actions);
          } finally {
            acl.close();
          }
          return null;
        }
      });
    }
  4. 显示用户的有效权限

    HBase外壳
    hbase> user_permission 'user'
    
    hbase> user_permission '.*'
    
    hbase> user_permission JAVA_REGEX
例子17. API
public static void verifyAllowed(User user, AccessTestAction action, int count) throws Exception {
  try {
    Object obj = user.runAs(action);
    if (obj != null && obj instanceof List&lt;?&gt;) {
      List&lt;?&gt; results = (List&lt;?&gt;) obj;
      if (results != null && results.isEmpty()) {
        fail("Empty non null results from action for user '" ` user.getShortName() ` "'");
      }
      assertEquals(count, results.size());
    }
  } catch (AccessDeniedException ade) {
    fail("Expected action to pass for user '" ` user.getShortName() ` "' but was denied");
  }
}

63.3. Visibility Labels

可见性标签控件只能用于允许与给定标签关联的用户或主体读取或访问带有该标签的单元格. 例如,您可以标记一个top-secret的单元格,而仅将访问该标签的权限授予managers组. 可见性标签是使用标签实现的,标签是HFile v3的一项功能,可让您按单元存储元数据. 标签是字符串,可以使用逻辑运算符(&,|或!)并使用括号将标签组合成表达式. 除了基本格式正确之外,HBase不会对表达式进行任何形式的验证. 可见性标签本身没有含义,可以用来表示敏感度级别,特权级别或任何其他任意语义.

如果用户的标签与单元格的标签或表达式不匹配,则拒绝用户访问该单元格.

在HBase 0.98.6和更高版本中,可见性标签和表达式支持UTF-8编码. 使用org.apache.hadoop.hbase.security.visibility.VisibilityClient类提供的addLabels(conf, labels)方法创建标签并通过"扫描"或"获取"在"授权"中传递标签时,标签可以包含UTF-8字符以及可见性标签中通常使用的逻辑运算符,带有普通的Java表示法,而无需任何转义方法. 但是,当您通过Mutation传递CellVisibility表达式时,如果您使用UTF-8字符或逻辑运算符,则必须使用CellVisibility.quote()方法将该表达式括起来. 见TestExpressionParser和源文件HBase的客户端/ src目录/测试/ JAVA /组织/阿帕奇/的Hadoop / HBase的/客户机/ TestScan.java.

用户在Put操作期间向单元格添加可见性表达式. 在默认配置中,用户不需要访问标签即可为其标记单元格. 此行为由配置选项hbase.security.visibility.mutations.checkauths . 如果将此选项设置为true ,则用户必须将与突变相关的用户正在修改的标签与该用户相关联,否则该突变将失败. 在"获取"或"扫描"期间确定用户是否有权读取标记的单元格,并过滤掉不允许用户读取的结果. 这将产生与返回结果相同的I / O损失,但是会减少网络上的负载.

还可以在"删除"操作期间指定可见性标签. 有关可见性标签和删除的详细信息,请参见HBASE-10885 .

当RegionServer首次接收到请求时,用户的有效标签集将建立在RPC上下文中. 用户与标签关联的方式是可插入的. 默认插件将通过添加到"获取"或"扫描"中的"授权"中指定的标签,并根据主叫用户的已认证标签列表检查这些标签. 当客户端传递未经用户验证的标签时,默认插件会将其删除. 您可以通过Get#setAuthorizations(Authorizations(String,…​))Scan#setAuthorizations(Authorizations(String,…​));传递用户身份验证标签的子集Scan#setAuthorizations(Authorizations(String,…​)); 方法.

可以向组授予与用户相同的可见性标签. 组以@符号为前缀. 当检查用户的可见性标签时,服务器将包括用户所属的组的可见性标签以及用户自己的标签. 当使用API VisibilityClient#getAuths或Shell命令get_auths为用户检索可见性标签时,我们将仅返回专门为该用户添加的标签,而不是组级别标签.

可见性标签访问检查由VisibilityController协处理器执行. 您可以使用VisibilityLabelService接口提供自定义实现和/或控制将可见性标签与单元格一起存储的方式. 有关一个示例,请参见源文件hbase-server / src / test / java / org / apache / hadoop / hbase / security / visibility / TestVisibilityLabelsWithCustomVisLabService.java .

可见性标签可以与ACL结合使用.

必须先明确定义标签,然后才能在可见性标签中使用它们. 请参阅以下示例,了解如何完成此操作.
当前无法确定已将哪些标签应用于单元格. 有关详细信息,请参见HBASE-12470 .
可见性标签当前不适用于超级用户.
表10.可见性表达的示例
Expression Interpretation
fulltime

允许访问与全职标签关联的用户.

!public

允许访问未与公共标签关联的用户.

( secret | topsecret ) & !probationary

允许访问与秘密或最高机密标签关联但与试用标签无关的用户.

63.3.1. Server-Side Configuration

  1. 作为前提条件,请执行过程:基本服务器端配置中的步骤 .

  2. 通过在hbase-site.xml中设置以下属性来安装和配置VisibilityController协处理器. 这些属性采用类名列表.

    <property>
      <name>hbase.security.authorization</name>
      <value>true</value>
    </property>
    <property>
      <name>hbase.coprocessor.region.classes</name>
      <value>org.apache.hadoop.hbase.security.visibility.VisibilityController</value>
    </property>
    <property>
      <name>hbase.coprocessor.master.classes</name>
      <value>org.apache.hadoop.hbase.security.visibility.VisibilityController</value>
    </property>
    如果同时使用AccessController和VisibilityController协处理器,则AccessController必须在列表中排在第一位,因为在两个组件都处于活动状态的情况下,VisibilityController会将其系统表上的访问控制委托给AccessController.
  3. 调整配置

    默认情况下,用户可以使用任何标签来标记单元格,包括它们不相关的标签,这意味着用户可以放置他无法读取的数据. 例如,即使用户没有与该标签相关联,用户也可以使用(假设的)"最高机密"标签对其进行标签. 如果只希望用户能够使用与其关联的标签来标记单元格,请将hbase.security.visibility.mutations.checkauths设置为true . 在这种情况下,如果突变使用了用户未关联的标签,则它将失败.

  4. 分发配置并重新启动集群以使更改生效.

63.3.2. Administration

可以使用HBase Shell或Java API执行管理任务. 为了定义可见性标签列表以及将标签与用户相关联,HBase Shell可能更简单.

API范例

本节中的许多Java API示例均来自源文件hbase-server / src / test / java / org / apache / hadoop / hbase / security / visibility / TestVisibilityLabels.java . 有关更多上下文,请参考该文件或API文档.

这些示例或它们的源文件均不是公共HBase API的一部分,并且仅出于说明目的而提供. 有关使用说明,请参考官方API.

  1. 定义可见性标签列表

    HBase外壳
    hbase> add_labels [ 'admin', 'service', 'developer', 'test' ]
    例子18. Java API
    public static void addLabels() throws Exception {
      PrivilegedExceptionAction<VisibilityLabelsResponse> action = new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
        public VisibilityLabelsResponse run() throws Exception {
          String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE, COPYRIGHT, ACCENT,
              UNICODE_VIS_TAG, UC1, UC2 };
          try {
            VisibilityClient.addLabels(conf, labels);
          } catch (Throwable t) {
            throw new IOException(t);
          }
          return null;
        }
      };
      SUPERUSER.runAs(action);
    }
  2. 将标签与用户相关联

    HBase外壳
    hbase> set_auths 'service', [ 'service' ]
    hbase> set_auths 'testuser', [ 'test' ]
    hbase> set_auths 'qa', [ 'test', 'developer' ]
    hbase> set_auths '@qagroup', [ 'test' ]
    例子19. Java API
    public void testSetAndGetUserAuths() throws Throwable {
      final String user = "user1";
      PrivilegedExceptionAction<Void> action = new PrivilegedExceptionAction<Void>() {
        public Void run() throws Exception {
          String[] auths = { SECRET, CONFIDENTIAL };
          try {
            VisibilityClient.setAuths(conf, auths, user);
          } catch (Throwable e) {
          }
          return null;
        }
        ...
  3. 清除用户标签

    HBase外壳
    hbase> clear_auths 'service', [ 'service' ]
    hbase> clear_auths 'testuser', [ 'test' ]
    hbase> clear_auths 'qa', [ 'test', 'developer' ]
    hbase> clear_auths '@qagroup', [ 'test', 'developer' ]
    例子20. Java API
    ...
    auths = new String[] { SECRET, PUBLIC, CONFIDENTIAL };
    VisibilityLabelsResponse response = null;
    try {
      response = VisibilityClient.clearAuths(conf, auths, user);
    } catch (Throwable e) {
      fail("Should not have failed");
      ...
    }
  4. 将标签或表达式应用于单元格

    仅在写入数据时才应用标签. 标签与单元的给定版本相关联.

    HBase外壳
    hbase> set_visibility 'user', 'admin|service|developer', { COLUMNS => 'i' }
    hbase> set_visibility 'user', 'admin|service', { COLUMNS => 'pii' }
    hbase> set_visibility 'user', 'test', { COLUMNS => [ 'i', 'pii' ], FILTER => "(PrefixFilter ('test'))" }
    HBase Shell支持将标签或权限应用于单元格是为了进行测试和验证支持,不应将其用于生产用途,因为它不会将标签应用于尚不存在的单元格. 正确应用单元格级别标签的方法是在存储值时在应用程序代码中进行操作.
    例子21. Java API
    static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
        throws Exception {
      Configuration conf = HBaseConfiguration.create();
      Connection connection = ConnectionFactory.createConnection(conf);
      Table table = NULL;
      try {
        table = TEST_UTIL.createTable(tableName, fam);
        int i = 1;
        List<Put> puts = new ArrayList<Put>();
        for (String labelExp : labelExps) {
          Put put = new Put(Bytes.toBytes("row" + i));
          put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
          put.setCellVisibility(new CellVisibility(labelExp));
          puts.add(put);
          i++;
        }
        table.put(puts);
      } finally {
        if (table != null) {
          table.flushCommits();
        }
      }

63.3.3. Reading Cells with Labels

发出"扫描"或"获取"时,HBase使用默认的授权集来过滤掉您无权访问的单元. 超级用户可以使用set_auths HBase Shell命令或VisibilityClient.setAuths()方法来设置给定用户的默认授权集.

您可以通过在HBase Shell中传递AUTHORIZATIONS选项或在使用API​​的Scan.setAuthorizations()方法中在"扫描"或"获取"期间指定其他授权. 该授权将与您的默认设置结合在一起作为附加过滤器. 它将进一步过滤您的结果,而不是授予您其他授权.

HBase外壳
hbase> get_auths 'myUser'
hbase> scan 'table1', AUTHORIZATIONS => ['private']
例子22. Java API
...
public Void run() throws Exception {
  String[] auths1 = { SECRET, CONFIDENTIAL };
  GetAuthsResponse authsResponse = null;
  try {
    VisibilityClient.setAuths(conf, auths1, user);
    try {
      authsResponse = VisibilityClient.getAuths(conf, user);
    } catch (Throwable e) {
      fail("Should not have failed");
    }
  } catch (Throwable e) {
  }
  List<String> authsList = new ArrayList<String>();
  for (ByteString authBS : authsResponse.getAuthList()) {
    authsList.add(Bytes.toString(authBS.toByteArray()));
  }
  assertEquals(2, authsList.size());
  assertTrue(authsList.contains(SECRET));
  assertTrue(authsList.contains(CONFIDENTIAL));
  return null;
}
...

63.3.4. Implementing Your Own Visibility Label Algorithm

解释为给定的获取/扫描请求验证的标签是可插入的算法.

您可以使用属性hbase.regionserver.scan.visibility.label.generator.class指定一个或多个自定义插件. 第一个ScanLabelGenerator的输出将是下一个ScanLabelGenerator的输入,直到列表末尾.

HBASE-12466中实现的默认实现会加载两个插件FeedUserAuthScanLabelGeneratorDefinedSetFilterScanLabelGenerator . 请参阅读取带有标签的单元格 .

63.3.5. Replicating Visibility Tags as Strings

如以上各节所述,可以使用接口VisibilityLabelService来实现将可见性表达式存储在单元格中的另一种方式. 启用复制的集群还必须将可见性表达式复制到对等集群. 如果将DefaultVisibilityLabelServiceImpl用作VisibilityLabelService的实现,则基于标签表中存储的每个可见性标签的所有序号,所有可见性表达式都将转换为相应的表达式. 在复制过程中,可见细胞也将按顺序表达完整. 对等群集可能不具有相同的labels表,并且具有相同的可见性标签顺序映射. 在这种情况下,复制普通字母毫无意义. 如果复制以字符串形式传输的可见性表达式来进行复制会更好. 要将可见性表达式作为字符串复制到对等群集,请创建一个RegionServerObserver配置,该配置基于VisibilityLabelService接口的实现来工作. 通过以下配置,可以将可见性表达式作为字符串复制到对等群集. 有关更多详细信息,请参见HBASE-11639 .

<property>
  <name>hbase.security.authorization</name>
  <value>true</value>
</property>
<property>
  <name>hbase.coprocessor.regionserver.classes</name>
  <value>org.apache.hadoop.hbase.security.visibility.VisibilityController$VisibilityReplication</value>
</property>

63.4. Transparent Encryption of Data At Rest

HBase提供了一种机制,用于保护驻留在HDFS或另一个分布式文件系统中的HFiles和WAL中的静态数据. 两层体系结构用于灵活和非侵入式密钥旋转. "透明"表示在客户端不需要更改任何实现. 写入数据时,将对其进行加密. 读取后,将按需解密.

63.4.1. How It Works

管理员为群集设置一个主密钥,该主密钥存储在密钥提供程序中,该密钥提供程序可用于每个受信任的HBase进程,包括管理工作站上的HMaster,RegionServers和客户端(例如HBase Shell). 默认密钥提供程序已与Java KeyStore API以及任何支持它的密钥管理系统集成在一起. 其他自定义密钥提供程序实现也是可能的. 密钥检索机制在hbase-site.xml配置文件中进行配置. 主密钥可以存储在群集服务器上,受安全的KeyStore文件保护,也可以存储在外部密钥服务器上,或者存储在硬件安全模块中. HBase进程会根据需要通过配置的密钥提供程序解析此主密钥.

接下来,可以通过创建或修改列描述符以包括两个附加属性,在模式中为每个列族指定加密使用:加密算法的名称(当前仅支持" AES"),以及可选的用集群主密钥包装(加密)的数据密钥. 如果未为ColumnFamily显式配置数据密钥,则HBase将为每个HFile创建一个随机数据密钥. 与替代方案相比,这提供了安全性方面的增量改进. 除非需要提供显式数据密钥,例如在生成加密的HFile以使用给定的数据密钥批量导入的情况下,否则仅在ColumnFamily模式元数据中指定加密算法,然后让HBase根据需要创建数据密钥. 每列族键可促进低冲击的增量键旋转,并减少键材料外部泄漏的范围. 包装的数据密钥存储在ColumnFamily架构元数据中,并存储在Column Family的每个HFile中,并使用集群主密钥进行加密. 配置列系列进行加密后,所有新的HFile将被写入加密状态. 为确保对所有HFile进行加密,请在启用此功能后触发重大压缩.

打开HFile时,将从HFile中提取数据密钥,并使用集群主密钥解密该数据密钥,并将其用于解密HFile的其余部分. 如果主密钥不可用,则HFile将不可读. 如果远程用户由于HDFS权限的某些失效或从不当丢弃的媒体中以某种方式获得了对HFile数据的访问权限,则将无法解密数据密钥或文件数据.

也可以对WAL进行加密. 即使WAL是瞬态的,在基础文件系统遭到破坏的情况下,也有必要对WALEdits进行加密,以避免绕过HFile对加密列族的保护. 启用WAL加密后,所有WAL都会被加密,无论相关的HFile是否已加密.

63.4.2. Server-Side Configuration

此过程假定您正在使用默认的Java密钥库实现. 如果您使用的是自定义实现,请查看其文档并进行相应调整.

  1. 使用keytool实用程序为AES加密创建适当长度的秘密密钥.

    $ keytool -keystore /path/to/hbase/conf/hbase.jks \
      -storetype jceks -storepass **** \
      -genseckey -keyalg AES -keysize 128 \
      -alias <alias>

    ****替换为密钥库文件的密码,将<alias>替换为HBase服务帐户的用户名或任意字符串. 如果使用任意字符串,则需要配置HBase以使用它,这将在下面介绍. 指定适当的密钥大小. 不要为密钥指定单独的密码,但在出现提示时按Return键.

  2. 在密钥文件上设置适当的权限,并将其分发给所有HBase服务器.

    上一条命令在HBase conf /目录中创建了一个名为hbase.jks的文件. 对此文件设置权限和所有权,以便只有HBase服务帐户用户可以读取该文件,并将密钥安全地分发给所有HBase服务器.

  3. 配置HBase守护程序.

    在区域服务器上的hbase-site.xml中设置以下属性,以配置HBase守护程序以使用由KeyStore文件支持的密钥提供者或检索集群主密钥. 在下面的示例中,将****替换为密码.

    <property>
      <name>hbase.crypto.keyprovider</name>
      <value>org.apache.hadoop.hbase.io.crypto.KeyStoreKeyProvider</value>
    </property>
    <property>
      <name>hbase.crypto.keyprovider.parameters</name>
      <value>jceks:///path/to/hbase/conf/hbase.jks?password=****</value>
    </property>

    默认情况下,HBase服务帐户名将用于解析群集主密钥. 但是,您可以使用任意别名存储它(在keytool命令中). 在这种情况下,请将以下属性设置为您使用的别名.

    <property>
      <name>hbase.crypto.master.key.name</name>
      <value>my-alias</value>
    </property>

    您还需要确保您的HFiles使用HFile v3,以便使用透明加密. 这是HBase 1.0及更高版本的默认配置. 对于以前的版本,请在hbase-site.xml文件中设置以下属性.

    <property>
      <name>hfile.format.version</name>
      <value>3</value>
    </property>

    (可选)您可以使用其他密码提供程序,即Java密码学加密(JCE)算法提供程序或自定义HBase密码实现.

    • JCE:

      • 安装签名的JCE提供程序(通过128位密钥支持AES/CTR/NoPadding模式)

      • 以最高优先级将其添加到JCE站点配置文件$ JAVA_HOME / lib / security / java.security中 .

      • 更新hbase.crypto.algorithm.aes.provider -site.xml中的 hbase.crypto.algorithm.aes.providerhbase.crypto.algorithm.rng.provider选项.

    • 自定义HBase密码:

      • Implement org.apache.hadoop.hbase.io.crypto.CipherProvider.

      • 将实现添加到服务器类路径.

      • Update hbase.crypto.cipherprovider in hbase-site.xml.

  4. 配置WAL加密.

    通过设置以下属性,在每个RegionServer的hbase-site.xml中配置WAL加密. 您也可以将它们包含在HMaster的hbase-site.xml中,但是HMaster没有WAL,因此不会使用它们.

    <property>
      <name>hbase.regionserver.hlog.reader.impl</name>
      <value>org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogReader</value>
    </property>
    <property>
      <name>hbase.regionserver.hlog.writer.impl</name>
      <value>org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogWriter</value>
    </property>
    <property>
      <name>hbase.regionserver.wal.encryption</name>
      <value>true</value>
    </property>
  5. hbase-site.xml文件上配置权限.

    由于密钥库密码存储在hbase-site.xml中,因此需要确保只有HBase用户可以使用文件所有权和权限来读取hbase-site.xml文件.

  6. 重新启动集群.

    将新的配置文件分发到所有节点,然后重新启动集群.

63.4.3. Administration

可以在HBase Shell或Java API中执行管理任务.

Java API

本节中的Java API示例摘自源文件hbase-server / src / test / java / org / apache / hadoop / hbase / util / TestHBaseFsckEncryption.java . .

这些示例或它们的源文件均不是公共HBase API的一部分,并且仅出于说明目的而提供. 有关使用说明,请参考官方API.

Enable Encryption on a Column Family

要在列系列上启用加密,可以使用HBase Shell或Java API. 启用加密后,触发一次重大压缩. 当主要压缩完成时,将对HFiles进行加密.

Rotate the Data Key

要旋转数据键,请首先更改列描述符中的ColumnFamily键,然后触发主要压缩. 压缩完成后,将使用新的数据密钥重新加密所有HFile. 在压缩完成之前,仍然可以使用旧密钥读取旧的HFile.

Switching Between Using a Random Data Key and Specifying A Key

如果您将列系列配置为使用特定键,并且想要返回使用对该列系列使用随机生成的键的默认行为,请使用Java API更改HColumnDescriptor以便不随键ENCRYPTION_KEY发送任何值.

Rotate the Master Key

要旋转主密钥,请首先生成并分发新密钥. 然后更新密钥库以包含新的主密钥,并使用其他别名将旧的主密钥保留在密钥库中. 接下来,将回退配置为hbase-site.xml文件中的旧主密钥.

63.5. Secure Bulk Load

安全模式下的批量加载比普通设置要复杂得多,因为客户端必须将MapReduce作业生成的文件的所有权转移到HBase. 安全大容量加载是通过名为SecureBulkLoadEndpoint的协处理器实现的,该协处理器使用由配置属性hbase.bulkload.staging.dir配置的暂存目录,该目录默认为/ tmp / hbase-staging / .

安全批量加载算法
  • 仅创建一个登台目录,该登台目录可在世界范围内遍历并由运行HBase的用户拥有(模式711或rwx—​x—​x ). 该目录的清单将类似于以下内容:

    $ ls -ld /tmp/hbase-staging
    drwx--x--x  2 hbase  hbase  68  3 Sep 14:54 /tmp/hbase-staging
  • 用户将数据写到该用户拥有的安全输出目录中. 例如, / user / foo / data .

  • 在内部,HBase创建一个可全局读取/写入的秘密登台目录( -rwxrwxrwx, 777 ). 例如, / tmp / hbase-staging / averylongandrandomdirectoryname . 该目录的名称和位置不向用户公开. HBase管理此目录的创建和删除.

  • 用户使数据可全球读取和写入,然后将其移动到随机暂存目录中,然后调用SecureBulkLoadClient#bulkLoadHFiles方法.

安全性的强度在于秘密目录的长度和随机性.

要启用安全的批量加载,请将以下属性添加到hbase-site.xml .

<property>
  <name>hbase.security.authorization</name>
  <value>true</value>
</property>
<property>
  <name>hbase.bulkload.staging.dir</name>
  <value>/tmp/hbase-staging</value>
</property>
<property>
  <name>hbase.coprocessor.region.classes</name>
  <value>org.apache.hadoop.hbase.security.token.TokenProvider,
  org.apache.hadoop.hbase.security.access.AccessController,org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint</value>
</property>

63.6. Secure Enable

在hbase-2.x之后,默认的" hbase.security.authorization"已更改. 在hbase-2.x之前,它默认为true,而在更高版本的HBase中,默认值为false. 因此,要启用hbase授权,必须在hbase-site.xml中配置以下属性. 参见HBASE-19483 ;

<property>
  <name>hbase.security.authorization</name>
  <value>true</value>
</property>

64. Security Configuration Example

此配置示例包括对HFile v3,ACL,可见性标签的支持,以及对静态数据和WAL的透明加密. 在以上各节中已单独讨论了所有选项.

例子23. hbase-site.xml中的例子安全设置
<!-- HFile v3 Support -->
<property>
  <name>hfile.format.version</name>
  <value>3</value>
</property>
<!-- HBase Superuser -->
<property>
  <name>hbase.superuser</name>
  <value>hbase,admin</value>
</property>
<!-- Coprocessors for ACLs and Visibility Tags -->
<property>
  <name>hbase.security.authorization</name>
  <value>true</value>
</property>
<property>
  <name>hbase.coprocessor.region.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController,
  org.apache.hadoop.hbase.security.visibility.VisibilityController,
  org.apache.hadoop.hbase.security.token.TokenProvider</value>
</property>
<property>
  <name>hbase.coprocessor.master.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController,
  org.apache.hadoop.hbase.security.visibility.VisibilityController</value>
</property>
<property>
  <name>hbase.coprocessor.regionserver.classes</name>
  <value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
<!-- Executable ACL for Coprocessor Endpoints -->
<property>
  <name>hbase.security.exec.permission.checks</name>
  <value>true</value>
</property>
<!-- Whether a user needs authorization for a visibility tag to set it on a cell -->
<property>
  <name>hbase.security.visibility.mutations.checkauth</name>
  <value>false</value>
</property>
<!-- Secure RPC Transport -->
<property>
  <name>hbase.rpc.protection</name>
  <value>privacy</value>
 </property>
 <!-- Transparent Encryption -->
<property>
  <name>hbase.crypto.keyprovider</name>
  <value>org.apache.hadoop.hbase.io.crypto.KeyStoreKeyProvider</value>
</property>
<property>
  <name>hbase.crypto.keyprovider.parameters</name>
  <value>jceks:///path/to/hbase/conf/hbase.jks?password=***</value>
</property>
<property>
  <name>hbase.crypto.master.key.name</name>
  <value>hbase</value>
</property>
<!-- WAL Encryption -->
<property>
  <name>hbase.regionserver.hlog.reader.impl</name>
  <value>org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogReader</value>
</property>
<property>
  <name>hbase.regionserver.hlog.writer.impl</name>
  <value>org.apache.hadoop.hbase.regionserver.wal.SecureProtobufLogWriter</value>
</property>
<property>
  <name>hbase.regionserver.wal.encryption</name>
  <value>true</value>
</property>
<!-- For key rotation -->
<property>
  <name>hbase.crypto.master.alternate.key.name</name>
  <value>hbase.old</value>
</property>
<!-- Secure Bulk Load -->
<property>
  <name>hbase.bulkload.staging.dir</name>
  <value>/tmp/hbase-staging</value>
</property>
<property>
  <name>hbase.coprocessor.region.classes</name>
  <value>org.apache.hadoop.hbase.security.token.TokenProvider,
  org.apache.hadoop.hbase.security.access.AccessController,org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint</value>
</property>
示例24. Hadoop core-site.xml中的示例组映射器

调整这些设置以适合您的环境.

<property>
  <name>hadoop.security.group.mapping</name>
  <value>org.apache.hadoop.security.LdapGroupsMapping</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.url</name>
  <value>ldap://server</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.bind.user</name>
  <value>Administrator@example-ad.local</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.bind.password</name>
  <value>****</value> <!-- Replace with the actual password -->
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.base</name>
  <value>dc=example-ad,dc=local</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.search.filter.user</name>
  <value>(&amp;(objectClass=user)(sAMAccountName={0}))</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.search.filter.group</name>
  <value>(objectClass=group)</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.search.attr.member</name>
  <value>member</value>
</property>
<property>
  <name>hadoop.security.group.mapping.ldap.search.attr.group.name</name>
  <value>cn</value>
</property>

Architecture

65. Overview

65.1. NoSQL?

HBase是一种" NoSQL"数据库. " NoSQL"是一个通用术语,表示该数据库不是支持SQL作为其主要访问语言的RDBMS,但是NoSQL数据库的类型很多:BerkeleyDB是本地NoSQL数据库的示例,而HBase在很大程度上分布式数据库. 从技术上讲,HBase实际上比"数据库"更像是"数据存储",因为它缺少您在RDBMS中发现的许多功能,例如类型列,二级索引,触发器和高级查询语言等.

但是,HBase具有支持线性和模块化缩放的许多功能. HBase群集通过添加在商品类服务器上托管的RegionServer来扩展. 例如,如果一个群集从10个RegionServer扩展到20个,则它在存储和处理能力方面都会翻倍. RDBMS可以很好地扩展,但是只能扩展到一个点-特别是单个数据库服务器的大小-为了获得最佳性能,需要专用的硬件和存储设备. 注意的HBase功能包括:

  • 高度一致的读/写:HBase不是"最终一致"的DataStore. 这使其非常适合诸如高速计数器聚合之类的任务.

  • 自动分片:HBase表通过区域分布在集群上,并且随着数据的增长,区域会自动拆分和重新分布.

  • 自动RegionServer故障转移

  • Hadoop / HDFS集成:HBase开箱即用地支持HDFS作为其分布式文件系统.

  • MapReduce:HBase支持通过MapReduce大规模并行化处理,以将HBase用作源和接收器.

  • Java客户端API:HBase支持易于使用的Java API进行编程访问.

  • Thrift / REST API:HBase还为非Java前端支持Thrift和REST.

  • 块缓存和Bloom过滤器:HBase支持块缓存和Bloom过滤器,以进行大量查询优化.

  • 运营管理:HBase提供了内置的网页,以提供运营见解以及JMX指标.

65.2. When Should I Use HBase?

HBase并不适合所有问题.

First, make sure you have enough data. If you have hundreds of millions or billions of rows, then HBase is a good candidate. If you only have a few thousand/million rows, then using a traditional RDBMS might be a better choice due to the fact that all of your data might wind up on a single node (or two) and the rest of the cluster may be sitting idle.

其次,确保没有RDBMS提供的所有额外功能(例如,类型化的列,二级索引,事务,高级查询语言等),您就可以生存.仅通过简单地更改,就不能将基于RDBMS构建的应用程序"移植"到HBase.例如JDBC驱动程序. 考虑从RDBMS迁移到HBase,作为与端口相对的完整重新设计.

第三,确保您有足够的硬件. 即使少于5个DataNode(由于诸如HDFS块复制(默认值为3)之类的东西)以及一个NameNode,HDFS也不能很好地处理.

HBase在笔记本电脑上可以很好地独立运行-但这仅应视为开发配置.

65.3. What Is The Difference Between HBase and Hadoop/HDFS?

HDFS是一个分布式文件系统,非常适合存储大文件. 它的文档指出,它不是通用文件系统,并且不提供文件中的快速个人记录查找. 另一方面,HBase构建在HDFS之上,并为大型表提供快速记录查找(和更新). 有时这可能是概念上的混乱点. HBase在内部将数据放入HDFS上存在的索引" StoreFiles"中,以进行高速查找. 有关HBase如何实现其目标的更多信息,请参见数据模型和本章的其余部分.

66. Catalog Tables

目录表hbase:meta作为HBase表存在,并hbase:meta HBase Shell的list命令中过滤出来,但实际上是一个表,与其他任何表一样.

66.1. hbase:meta

hbase:meta表(以前称为.META. )保留了系统中所有区域的列表,并且hbase:meta的位置存储在ZooKeeper中.

hbase:meta表结构如下:

Key
  • 格式的区域键( [table],[region start key],[region id]

Values
  • info:regioninfo regioninfo (此区域的序列化HRegionInfo实例)

  • info:server (包含该区域的RegionServer的server:port)

  • info:serverstartcode (包含该区域的RegionServer进程的开始时间)

当表正在拆分时,将创建另外两个列,分别为info:splitAinfo:splitB . 这些列代表两个子区域. 这些列的值也是序列化的HRegionInfo实例. 分割区域后,最终将删除此行.

Note on HRegionInfo

空键用于表示表的开始和结束. 起始键为空的区域是表中的第一个区域. 如果一个区域同时具有空的开始键和空的结束键,则它是表中唯一的区域

如果需要对目录元数据进行编程处理(这种情况不太可能发生),请参阅RegionInfo.parseFrom实用程序.

66.2. Startup Sequencing

首先,在ZooKeeper中查找hbase:meta的位置. 接下来,使用服务器和起始码值更新hbase:meta .

有关region-RegionServer分配的信息,请参见Region-RegionServer分配 .

67. Client

HBase客户端找到正在服务的特定行范围的RegionServer. 它通过查询hbase:meta表来做到这一点. 有关详细信息,请参见hbase:meta . 找到所需的区域后,客户端将联系为该区域提供服务的RegionServer,而不是通过主服务器,并发出读取或写入请求. 此信息被缓存在客户端中,因此后续请求无需经过查找过程. 如果由主负载平衡器重新分配了区域,或者由于RegionServer已经失效,则客户端将重新查询目录表以确定用户区域的新位置.

有关主服务器对HBase客户端通信的影响的更多信息,请参见运行时影响 .

管理功能通过Admin实例完成

67.1. Cluster Connections

API在HBase 1.0中已更改. 有关连接配置的信息,请参阅连接到HBase群集的客户端配置和依赖项 .

67.1.1. API as of HBase 1.0.0

它已被清理,并且为用户提供了针对接口而不是针对特定类型的接口. 在HBase 1.0中,从ConnectionFactory获取一个Connection对象,然后根据需要从中获取TableAdminRegionLocator实例. 完成后,关闭获得的实例. 最后,请确保在退出前清理Connection实例. Connections是重量级的对象,但是是线程安全的,因此您可以为应用程序创建一个对象并保留该实例. TableAdminRegionLocator实例是轻量级的. 随心所欲地创建,然后在关闭时立即放手. 有关新HBase 1.0 API的示例用法,请参阅客户端软件包Javadoc说明 .

67.1.2. API before HBase 1.0.0

HTable实例是与1.0.0之前的HBase群集进行交互的方式. 实例不是线程安全的 . 在任何给定时间,只有一个线程可以使用Table的实例. 创建表实例时,建议使用相同的HBaseConfiguration实例. 这将确保将ZooKeeper和套接字实例共享到RegionServer,这通常是您所需要的. 例如,这是首选:

HBaseConfiguration conf = HBaseConfiguration.create();
HTable table1 = new HTable(conf, "myTable");
HTable table2 = new HTable(conf, "myTable");

与此相反:

HBaseConfiguration conf1 = HBaseConfiguration.create();
HTable table1 = new HTable(conf1, "myTable");
HBaseConfiguration conf2 = HBaseConfiguration.create();
HTable table2 = new HTable(conf2, "myTable");

有关如何在HBase客户端中处理连接的更多信息,请参见ConnectionFactory .

Connection Pooling

对于需要高端多线程访问的应用程序(例如,可能在单个JVM中服务多个应用程序线程的Web服务器或应用程序服务器),您可以预先创建一个Connection ,如以下示例所示:

例子25.预创建一个Connection
// Create a connection to the cluster.
Configuration conf = HBaseConfiguration.create();
try (Connection connection = ConnectionFactory.createConnection(conf);
     Table table = connection.getTable(TableName.valueOf(tablename))) {
  // use table as needed, the table returned is lightweight
}
HTablePool已弃用

本指南的先前版本讨论了HTablePoolHTablePool在HBase HTablePool和0.96中已弃用,并在0.98.1中由HBASE-6580HConnection ,而HConnection在HBase 1.0中已由Connection弃用. 请改用Connection .

67.2. WriteBuffer and Batch Methods

在HBase 1.0和更高版本中,不推荐使用HTable,而推荐使用Table . Table不使用自动刷新. 要进行缓冲写入,请使用BufferedMutator类.

在HBase 2.0和更高版本中, HTable不使用BufferedMutator来执行Put操作. 有关更多信息,请参考HBASE-18500 .

有关写持久性的其他信息,请查看ACID语义页面.

要对PutDelete的批处理进行细粒度控制,请参阅表上的批处理方法.

67.3. Asynchronous Client

它是HBase 2.0中引入的新API,旨在提供异步访问HBase的功能.

您可以从ConnectionFactory获取AsyncConnection ,然后从中获取一个异步表实例以访问HBase. 完成后,关闭AsyncConnection实例(通常在程序退出时).

对于异步表,大多数方法与旧的Table接口具有相同的含义,期望返回值通常用CompletableFuture包装. 我们这里没有任何缓冲区,因此没有关闭异步表的方法,您不需要关闭它. 而且它是线程安全的.

扫描有几个区别:

  • 仍然有一个getScanner方法,该方法返回ResultScanner . 您可以按旧方式使用它,它的工作方式类似于旧的ClientAsyncPrefetchScanner .

  • 有一个scanAll方法将立即返回所有结果. 它旨在为小型扫描提供一种更简单的方法,您通常希望一次获得整个结果.

  • 观察者模式. 有一种扫描方法可以接受ScanResultConsumer作为参数. 它将结果传递给消费者.

请注意, AsyncTable接口已模板化. template参数指定扫描使用的ScanResultConsumerBase的类型,这意味着观察者样式的扫描API是不同的. 两种类型的扫描使用者是ScanResultConsumerAdvancedScanResultConsumer .

ScanResultConsumer需要一个单独的线程池,该线程池用于执行注册到返回的CompletableFuture的回调. 因为使用单独的线程池可以释放RPC线程,所以回调可以随意执行任何操作. 如果回调不快速或有疑问,请使用此选项.

AdvancedScanResultConsumer在框架线程内执行回调. 不允许在回调中执行耗时的工作,否则可能会阻塞框架线程并造成严重的性能影响. 顾名思义,它是为想要编写高性能代码的高级用户设计的. 有关如何使用它编写完全异步代码的信息,请参见org.apache.hadoop.hbase.client.example.HttpProxyExample .

67.4. Asynchronous Admin

您可以从ConnectionFactory获取一个AsyncConnection ,然后从中获取一个AsyncAdmin实例以访问HBase. 请注意,有两种getAdmin方法可获取AsyncAdmin实例. 一种方法有一个额外的线程池参数,用于执行回调. 它是为普通用户设计的. 另一个方法不需要线程池,并且所有回调都在框架线程内执行,因此不允许在回调中执行耗时的工作. 它是为高级用户设计的.

默认的getAdmin方法将返回一个使用默认配置的AsyncAdmin实例. 如果你想定制一些CONFIGS,您可以使用getAdminBuilder方法来获取AsyncAdminBuilder创建AsyncAdmin实例. 用户可以自由地设置他们关心的配置来创建一个新的AsyncAdmin实例.

对于AsyncAdmin接口,大多数方法与旧的Admin接口具有相同的含义,希望返回值通常用CompletableFuture包装.

对于大多数管理员操作,完成返回的CompletableFuture后,这意味着管理员操作也已完成. 但是对于压缩操作,这仅意味着压缩请求已发送到HBase,并且可能需要一些时间才能完成压缩操作. 对于rollWALWriter方法,这仅意味着将rollWALWriter请求发送到区域服务器,并且可能需要一些时间才能完成rollWALWriter操作.

对于区域名称,我们仅接受byte[]作为参数类型,它可以是完整的区域名称或编码的区域名称. 对于服务器名称,我们仅接受ServerName作为参数类型. 对于表名,我们仅接受TableName作为参数类型. 对于list*操作,如果要进行正则表达式匹配,我们仅接受Pattern作为参数类型.

67.5. External Clients

Apache HBase外部API涵盖了有关非Java客户端和自定义协议的信息.

68. Client Request Filters

可以选择使用在RegionServer上应用的筛选器来配置GetScan实例.

过滤器可能会造成混乱,因为类型很多,最好通过了解过滤器功能组来进行过滤.

68.1. Structural

结构过滤器包含其他过滤器.

68.1.1. FilterList

FilterList表示过滤器列表,这些过滤器之间具有FilterList.Operator.MUST_PASS_ALLFilterList.Operator.MUST_PASS_ONE关系. 以下示例显示了两个过滤器之间的"或"(检查同一属性上的"我的值"或"我的其他值").

FilterList list = new FilterList(FilterList.Operator.MUST_PASS_ONE);
SingleColumnValueFilter filter1 = new SingleColumnValueFilter(
  cf,
  column,
  CompareOperator.EQUAL,
  Bytes.toBytes("my value")
  );
list.add(filter1);
SingleColumnValueFilter filter2 = new SingleColumnValueFilter(
  cf,
  column,
  CompareOperator.EQUAL,
  Bytes.toBytes("my other value")
  );
list.add(filter2);
scan.setFilter(list);

68.2. Column Value

68.2.1. SingleColumnValueFilter

SingleColumnValueFilter(请参阅: https ://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/SingleColumnValueFilter.html)可用于测试列值是否相等( CompareOperaor.EQUAL ),不等式( CompareOperaor.NOT_EQUAL )或范围(例如CompareOperaor.GREATER ). 以下是测试列与字符串值" my value"的等效性的示例……

SingleColumnValueFilter filter = new SingleColumnValueFilter(
  cf,
  column,
  CompareOperaor.EQUAL,
  Bytes.toBytes("my value")
  );
scan.setFilter(filter);

68.2.2. ColumnValueFilter

作为对SingleColumnValueFilter的补充,在HBase-2.0.0版本中引入了ColumnValueFilter仅获取匹配的单元格,而SingleColumnValueFilter获取匹配的单元格所属的整行(具有其他列和值). ColumnValueFilter的构造函数的参数与SingleColumnValueFilter相同.

ColumnValueFilter filter = new ColumnValueFilter(
  cf,
  column,
  CompareOperaor.EQUAL,
  Bytes.toBytes("my value")
  );
scan.setFilter(filter);

注意. 对于简单的查询(例如"等于family:qualifier:value"),我们强烈建议使用以下方式,而不是使用SingleColumnValueFilter或ColumnValueFilter:

Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("family"), Bytes.toBytes("qualifier"));
ValueFilter vf = new ValueFilter(CompareOperator.EQUAL,
  new BinaryComparator(Bytes.toBytes("value")));
scan.setFilter(vf);
...

此扫描将限制为指定的列'family:qualifier',避免扫描不相关的族和列,从而获得更好的性能,并且ValueFilter是用于进行值过滤的条件.

但是如果查询超出了本书,则请视情况作好选择.

68.3. Column Value Comparators

There are several Comparator classes in the Filter package that deserve special mention. These Comparators are used in concert with other Filters, such as SingleColumnValueFilter.

68.3.1. RegexStringComparator

RegexStringComparator支持用于值比较的正则表达式.

RegexStringComparator comp = new RegexStringComparator("my.");   // any value that starts with 'my'
SingleColumnValueFilter filter = new SingleColumnValueFilter(
  cf,
  column,
  CompareOperaor.EQUAL,
  comp
  );
scan.setFilter(filter);

有关Java中受支持的RegEx模式的信息,请参见Oracle JavaDoc.

68.3.2. SubstringComparator

SubstringComparator can be used to determine if a given substring exists in a value. The comparison is case-insensitive.

SubstringComparator comp = new SubstringComparator("y val");   // looking for 'my value'
SingleColumnValueFilter filter = new SingleColumnValueFilter(
  cf,
  column,
  CompareOperaor.EQUAL,
  comp
  );
scan.setFi