HBase 提供以下机制来管理处理多个工作负载的集群的性能:。 配额。 请求队列。 多种类型的队列
HBASE-11598 引入了 RPC 配额,允许您根据以下限制限制请求:
可以对指定的用户,表或命名空间强制实施这些限制。
启用配额
默认情况下禁用配额。要启用该功能,请在 hbase-site.xml 文件中为所有群集节点将hbase.quota.enabled
属性设置为true
。
一般配额语法
THROTTLE_TYPE 可以表示为 READ,WRITE 或默认类型(读取+写入)。
时间范围可以用以下单位表示:sec
,min
,hour
,day
请求大小可以用以下单位表示:B
(字节),K
(千字节),M
(兆字节),G
(千兆字节),T
(兆兆字节),P
(千兆字节) )
请求数表示为整数,后跟字符串req
与时间相关的限制表示为 req / time 或 size / time。例如10req/day
或100P/hour
。
表或区域的数量表示为整数。
设置请求配额
您可以提前设置配额规则,也可以在运行时更改限制。配额刷新期到期后,更改将传播。此有效期默认为 5 分钟。要更改它,请修改hbase-site.xml
中的hbase.quota.refresh.period
属性。此属性以毫秒表示,默认为300000
。
# Limit user u1 to 10 requests per second
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10req/sec'
# Limit user u1 to 10 read requests per second
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', LIMIT => '10req/sec'
# Limit user u1 to 10 M per day everywhere
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10M/day'
# Limit user u1 to 10 M write size per sec
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => WRITE, USER => 'u1', LIMIT => '10M/sec'
# Limit user u1 to 5k per minute on table t2
hbase> set_quota TYPE => THROTTLE, USER => 'u1', TABLE => 't2', LIMIT => '5K/min'
# Limit user u1 to 10 read requests per sec on table t2
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', TABLE => 't2', LIMIT => '10req/sec'
# Remove an existing limit from user u1 on namespace ns2
hbase> set_quota TYPE => THROTTLE, USER => 'u1', NAMESPACE => 'ns2', LIMIT => NONE
# Limit all users to 10 requests per hour on namespace ns1
hbase> set_quota TYPE => THROTTLE, NAMESPACE => 'ns1', LIMIT => '10req/hour'
# Limit all users to 10 T per hour on table t1
hbase> set_quota TYPE => THROTTLE, TABLE => 't1', LIMIT => '10T/hour'
# Remove all existing limits from user u1
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => NONE
# List all quotas for user u1 in namespace ns2
hbase> list_quotas USER => 'u1, NAMESPACE => 'ns2'
# List all quotas for namespace ns2
hbase> list_quotas NAMESPACE => 'ns2'
# List all quotas for table t1
hbase> list_quotas TABLE => 't1'
# list all quotas
hbase> list_quotas
您还可以通过应用GLOBAL_BYPASS
属性来设置全局限制并从限制中排除用户或表。
hbase> set_quota NAMESPACE => 'ns1', LIMIT => '100req/min' # a per-namespace request limit
hbase> set_quota USER => 'u1', GLOBAL_BYPASS => true # user u1 is not affected by the limit
设置命名空间配额
通过在命名空间上设置hbase.namespace.quota.maxtables property
,可以在创建命名空间时或通过更改现有命名空间来指定给定命名空间中允许的最大表或区域数。
每个命名空间限制表
# Create a namespace with a max of 5 tables
hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxtables'=>'5'}
# Alter an existing namespace to have a max of 8 tables
hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxtables'=>'8'}
# Show quota information for a namespace
hbase> describe_namespace 'ns2'
# Alter an existing namespace to remove a quota
hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=>'hbase.namespace.quota.maxtables'}
每个命名空间限制区域
# Create a namespace with a max of 10 regions
hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxregions'=>'10'
# Show quota information for a namespace
hbase> describe_namespace 'ns1'
# Alter an existing namespace to have a max of 20 tables
hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxregions'=>'20'}
# Alter an existing namespace to remove a quota
hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=> 'hbase.namespace.quota.maxregions'}
如果未配置限制策略,则当 RegionServer 收到多个请求时,它们现在将被放入等待空闲执行槽的队列(HBASE-6721)。最简单的队列是 FIFO 队列,其中每个请求在运行之前等待队列中的所有先前请求完成。快速或交互式查询可能会滞后于大量请求。
如果您能够猜测请求需要多长时间,您可以通过将长请求推送到队列末尾并允许短请求抢占它们来重新排序请求。最终,您仍然必须执行大型请求并确定其后面的新请求的优先级。短请求将更新,因此结果并不可怕,但与允许将大量请求拆分为多个较小请求的机制相比仍然不是最理想的。
HBASE-10993 引入了这样一种系统,用于对长时间运行的扫描仪进行优先级排序。有两种类型的队列,fifo
和deadline
。要配置使用的队列类型,请在hbase-site.xml
中配置hbase.ipc.server.callqueue.type
属性。无法估计每个请求可能需要多长时间,因此取消优先级只会影响扫描,并且基于扫描请求所做的“下一次”调用的次数。假设当您进行全表扫描时,您的作业可能不是交互式的,因此如果存在并发请求,则可以通过设置hbase.ipc.server.queue.max.call.delay
属性将长时间运行的扫描延迟到可调整的限制。延迟的斜率由(numNextCall * weight)
的简单平方根计算,其中权重可通过设置hbase.ipc.server.scan.vtime.weight
属性进行配置。
您还可以通过配置指定数量的专用处理程序和队列来确定不同类型请求的优先级或优先级。您可以使用单个处理程序在单个队列中隔离扫描请求,并且所有其他可用队列可以为短Get
请求提供服务。
您可以使用静态调整选项根据工作负载类型调整 IPC 队列和处理程序。此方法是临时的第一步,最终将允许您在运行时更改设置,并根据负载动态调整值。
多个队列
为了避免争用并分离不同类型的请求,请配置hbase.ipc.server.callqueue.handler.factor
属性,该属性允许您增加队列数量并控制可以共享同一队列的处理程序数量。允许管理员增加队列数量并确定多少处理程序共享同一队列。
使用更多队列可以在将任务添加到队列或从队列中选择任务时减少争用。您甚至可以为每个处理程序配置一个队列权衡是,如果某些队列包含长时间运行的任务,则处理程序可能需要等待从该队列执行而不是从具有等待任务的另一个队列中窃取。
读写队列
使用多个队列,您现在可以划分读取和写入请求,为一种或另一种类型提供更多优先级(更多队列)。使用hbase.ipc.server.callqueue.read.ratio
属性选择提供更多读取或更多写入。
获取和扫描队列
与读/写拆分类似,您可以通过调整hbase.ipc.server.callqueue.scan.ratio
属性来拆分获取和扫描,以便为获取或扫描提供更多优先级。 0.1
的扫描比率将为传入的获取提供更多的队列/处理程序,这意味着可以同时处理更多的获取,并且可以同时执行更少的扫描。值0.9
将为扫描提供更多队列/处理程序,因此执行的扫描次数将增加,并且获取次数将减少。
HBASE-16961 为 HBase 引入了一种新的配额来利用:文件系统配额。这些“空间”配额限制了 HBase 名称空间和表可以使用的文件系统上的空间量。如果恶意或无知的用户有足够的时间将数据写入 HBase,则该用户可以通过消耗所有可用空间来有效地崩溃 HBase(或更糟糕的 HDFS)。当没有可用的文件系统空间时,HBase 崩溃,因为它无法再为预写日志创建/同步数据。
此功能允许在表或命名空间的大小上设置限制。在命名空间上设置空间配额时,配额的限制适用于该命名空间中所有表的使用总和。在具有配额的命名空间中存在具有配额的表时,表配额优先于命名空间配额。这允许可以对表集合施加大限制的情况,但该集合中的单个表可以具有细粒度限制集。
现有的set_quota
和list_quota
HBase shell 命令可用于与空间配额交互。空间配额是TYPE
SPACE
的配额,具有LIMIT
和POLICY
属性。 LIMIT
是一个字符串,它指的是配额主题(例如表或命名空间)可能消耗的文件系统上的空间量。例如,LIMIT
的有效值为'10G'
,'2T'
或'256M'
。 POLICY
是指当配额主体的使用量超过LIMIT
时 HBase 将采取的行动。以下是有效的POLICY
值。
NO_INSERTS
- 无法写入新数据(例如Put
,Increment
,Append
)。
NO_WRITES
- 与NO_INSERTS
相同,但Deletes
也不允许。
NO_WRITES_COMPACTIONS
- 与NO_WRITES
相同,但也不允许压缩。
DISABLE
- 禁用表,阻止所有读/写访问。
设置简单的空间配额
# Sets a quota on the table 't1' with a limit of 1GB, disallowing Puts/Increments/Appends when the table exceeds 1GB
hbase> set_quota TYPE => SPACE, TABLE => 't1', LIMIT => '1G', POLICY => NO_INSERTS
# Sets a quota on the namespace 'ns1' with a limit of 50TB, disallowing Puts/Increments/Appends/Deletes
hbase> set_quota TYPE => SPACE, NAMESPACE => 'ns1', LIMIT => '50T', POLICY => NO_WRITES
# Sets a quota on the table 't3' with a limit of 2TB, disallowing any writes and compactions when the table exceeds 2TB.
hbase> set_quota TYPE => SPACE, TABLE => 't3', LIMIT => '2T', POLICY => NO_WRITES_COMPACTIONS
# Sets a quota on the table 't2' with a limit of 50GB, disabling the table when it exceeds 50GB
hbase> set_quota TYPE => SPACE, TABLE => 't2', LIMIT => '50G', POLICY => DISABLE
请考虑以下方案在命名空间上设置配额,覆盖该命名空间中表的配额
表和命名空间空间配额
hbase> create_namespace 'ns1'
hbase> create 'ns1:t1'
hbase> create 'ns1:t2'
hbase> create 'ns1:t3'
hbase> set_quota TYPE => SPACE, NAMESPACE => 'ns1', LIMIT => '100T', POLICY => NO_INSERTS
hbase> set_quota TYPE => SPACE, TABLE => 'ns1:t2', LIMIT => '200G', POLICY => NO_WRITES
hbase> set_quota TYPE => SPACE, TABLE => 'ns1:t3', LIMIT => '20T', POLICY => NO_WRITES
在上面的场景中,名称空间ns1
中的表将不允许在文件系统之间消耗超过 100TB 的空间。表'ns1:t2'的大小仅允许为 200GB,并且当使用率超过此限制时将禁止所有写入。表'ns1:t3'的大小允许增长到 20TB,并且还将禁止所有写入,然后使用超出此限制。由于'ns1:t1'上没有表配额,因此该表可以增长到 100TB,但仅当'ns1:t2'和'ns1:t3'使用零字节时才会增长。实际上,它的限制是'ns1:t2'和'ns1:t3'的当前使用量减去 100TB。
默认情况下,如果删除具有空间配额的表或命名空间,则也会删除配额本身。在某些情况下,可能需要不自动删除空间配额。在这些情况下,用户可以将系统配置为不通过 hbase-site.xml 自动删除任何空间配额。
<property>
<name>hbase.quota.remove.on.table.delete</name>
<value>false</value>
</property>
默认情况下,该值设置为true
。
与 HBase 一起使用的非预期文件系统的一个常见区域是通过 HBase 快照。由于快照存在于 HBase 表管理之外,因此管理员突然意识到 HBase 快照正在使用数百 GB 或 TB 的空间并且这些空间被遗忘并且从未被删除的情况并不少见。
HBASE-17748 是一个伞形 JIRA 问题,它扩展了原始空间配额功能,还包括 HBase 快照。虽然这是一个令人困惑的主题,但实现尝试以尽可能合理和简单的方式为管理员提供此支持。此功能不会对管理员与空间配额的交互进行任何更改,仅在表/命名空间使用的内部计算中进行。表和命名空间使用将根据下面定义的规则自动合并快照占用的大小。
作为回顾,我们将介绍快照的生命周期:快照是指向文件系统上的 HFile 列表的元数据。这就是为什么创建快照是一个非常便宜的操作;实际上没有复制 HBase 表数据来执行快照。出于同样的原因,将快照克隆到新表或恢复表是一种廉价的操作;新表引用文件系统中已存在但没有副本的文件。要在空间配额中包含快照,我们需要在快照引用文件时定义哪个表“拥有”文件(“拥有”是指包含该文件的文件系统用法)。
考虑针对表格创建的快照。当快照引用文件并且表不再引用该文件时,“originating”表“拥有”该文件。当多个快照引用同一文件且没有表引用该文件时,将选择具有最低排序名称(按字典顺序排列)的快照,并且从“拥有”该文件创建该快照的表。 HFile 不是“重复计算”的表,而一个或多个快照指的是 HFile。
当表格“重新物化”时(通过clone_snapshot
或restore_snapshot
),会出现类似的文件所有权问题。在这种情况下,虽然重新表示的表引用了快照也引用的文件,但该表并不“拥有”该文件。创建快照的表仍然“拥有”该文件。当压缩重新实现的表或删除快照时,重新实现的表将唯一地引用新文件并“拥有”该文件的使用。类似地,当通过快照和restore_snapshot
复制表时,新表将不会消耗任何配额大小,直到原始表停止引用文件,原因是由于原始表上的压缩,新表上的压缩,或原始表被删除。
添加了一个新的 HBase shell 命令来检查 HBase 实例中每个快照的计算大小。
hbase> list_snapshot_sizes
SNAPSHOT SIZE
t1.s1 1159108