HBase流量限制和表負載均衡剖析

哥不是小蘿莉發表於2017-11-11

1.概述

  在HBase-1.1.0之前,HBase叢集中資源都是全量的。使用者、表這些都是沒有限制的,看似完美實則隱患較大。今天,筆者就給大家剖析一下HBase的流量限制和表的負載均衡。

2.內容

  也許有同學有疑問,為啥要做流量限制,無限制全量跑不是更好嗎?舉個例子,比如今天的雙十一日,資料流量是非常大的。如果不限制使用者和表的流量,某些重要的核心業務,需要在資源有限的情況下優先保證正常執行。如果非核心業務在此期間其QPS一直降不下來,嚴重消耗系統資源,影響核心業務的正常運作。

  針對上述問題,可以採取以下方案來解決:

  • 資源限制:針對使用者、名稱空間及表的請求大小和QPS進行限制。
  • 資源隔離:將不同表中的資料通過物理隔離,均衡到不同的RegionServer上。

3.資源限制

  開啟HBase資源限制是有條件,其中包含以下兩個條件:

  • 版本必須在1.1.0以上,或者在低版本中打上了HBase對應的Patch(HBASE-11598
  • HBase的資源限制開關預設是關閉的,需要在HBase的配置檔案中進行開啟。新增內容如下所示:
# 編輯HBase配置檔案
vi $HBASE_HONE/conf/hbase-site.xml

# 新增如下內容
 <property>
   <name>hbase.quota.enabled</name>
   <value>true</value>
 </property>

# 退出編輯並儲存

  如果不是在首次啟動時配置的,需要額外重啟HMaster服務程式才能使之生效。

3.1 Quota語句

  HBase中限流是通過Quota語句來操作的,限流的方式有兩種,一種是針對使用者進行限流;另一種是針對表來進行限流。操作命令如下所示:

# 限制使用者u1每秒請求10次
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10req/sec'

# 限制使用者u1每秒的讀請求為10次
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', LIMIT => '10req/sec'

# 限制使用者u1每天的請求量為10M
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => '10M/day'

# 限制使用者u1的寫請求量每秒為10M
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => WRITE, USER => 'u1', LIMIT => '10M/sec'

# 限制使用者u1在操作表t2時,每分鐘的請求量為5K
hbase> set_quota TYPE => THROTTLE, USER => 'u1', TABLE => 't2', LIMIT => '5K/min'

# 限制使用者u1在操作表t2時,每秒的讀請求為10次
hbase> set_quota TYPE => THROTTLE, THROTTLE_TYPE => READ, USER => 'u1', TABLE => 't2', LIMIT => '10req/sec'

# 刪除使用者u1在命令空間ns2的請求限制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', NAMESPACE => 'ns2', LIMIT => NONE

# 限制在名稱空間ns1中每小時的請求為10次
hbase> set_quota TYPE => THROTTLE, NAMESPACE => 'ns1', LIMIT => '10req/hour'

# 限制表t1每小時的請求為10T
hbase> set_quota TYPE => THROTTLE, TABLE => 't1', LIMIT => '10T/hour'

# 刪除使用者u1的所有請求限制
hbase> set_quota TYPE => THROTTLE, USER => 'u1', LIMIT => NONE

# 顯示使用者u1在名稱空間ns2中的所有限制詳情
hbase> list_quotas USER => 'u1, NAMESPACE => 'ns2'

# 顯示命令空間ns2的所有限制詳情
hbase> list_quotas NAMESPACE => 'ns2'

# 顯示錶t1的所有限制詳情
hbase> list_quotas TABLE => 't1'

# 顯示所有限制詳情
hbase> list_quotas

  從操作的命令中可以看出,HBase限制流量支援表和使用者。可以通過THROTTLE_TYPE來控制READ(讀)、WRITE(寫)操作,這類操作在HBase中是隨機進行限制的。而LIMIT關鍵字,可以從兩個維度進行資源限制,分別是req/time和size/time。

  • req/time:這種表示限制單位時間內的請求次數,time可以是秒、分、時、天,req表示次數。
  • size/time:這種表示單位時間內請求資料的量,time可以是秒、分、時、天,size可以時B (bytes), K (kilobytes), M (megabytes), G (gigabytes), T (terabytes), P (petabytes)。

  LIMIT限制預設大小是:10req/day 或 100P/hour。對於命令set_quota來說,執行這條命令僅僅是限制單個RegionServer上的流量,並不是整個叢集的限制總量(叢集限制總量=每個RegionServer的限制量*RegionNum)。另外,執行set_quota命令後,預設是需要等待300000秒(5分鐘)才會生效。如果覺得時間太長,可以將生效時間縮短,通過hbase-site.xml檔案中的引數hbase.quota.refresh.period來設定時間,比如:

# 一分鐘後生效
hbase.quota.refresh.period=60000

3.2 限制名稱空間中的表個數

  在建立名稱空間中的表個數,可以在建立名稱空間時指定,也可以在建立之後在此修改表個數,同樣也可以刪除表限制。通過設定hbase.namespace.quota.maxtables屬性值來改變。操作內容如下所示:

# 建立一個命令空間最大包含5個表
hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxtables'=>'5'}

# 修改一個已存在的命令空間所允許的表數量大小為8個
hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxtables'=>'8'}

# 顯示命令空間下的所有詳情
hbase> describe_namespace 'ns2'

# 刪除命令空間中表個數的限制
hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=>'hbase.namespace.quota.maxtables'}

3.3 限制名稱空間的Region

  在建立名稱空間時 ,可以限制Region的個數。在建立之後也可以通過命令來修改個數的上限值。具體操作如下所示:

# 建立一個名稱空間最大包含10個Region
hbase> create_namespace 'ns1', {'hbase.namespace.quota.maxregions'=>'10'

# 顯示命令空間中詳情
hbase> describe_namespace 'ns1'

# 修改名稱空間中最大Region個數為20個
hbase> alter_namespace 'ns2', {METHOD => 'set', 'hbase.namespace.quota.maxregions'=>'20'}

# 刪除名稱空間中Region個數的限制
hbase> alter_namespace 'ns2', {METHOD => 'unset', NAME=> 'hbase.namespace.quota.maxregions'}

  這裡也許有些同學在操作的過程當中遇到過,在請求操作限制閥值時,日誌沒有列印出錯誤資訊,這是由於預設日誌輸出時INFO級別,不會列印這類異常,如果要檢視,可以通過修改log4j的日誌級別為DEBUG,這樣就可以檢視到對應的異常資訊了。

 4.資源隔離

  在HBase中可以通過資源隔離的方式來間接的限流。將請求均衡到多個RegionServer中去。通過balance_switch命令來實現自動均衡操作。命令如下:

# 停止自動均衡
balance_switch false

# 開啟自動均衡
balance_switch true

  在實際業務中,如果HBase某個表的RegionServer全部集中在一個上,這時候可以考慮使用move命令手動均衡操作,具體操作語法如下:

# move手動操作語法
move [region id] [ServerName]

  如下圖所示:

  從圖中一個Table Region來說,”t2,,1510401809742.bd015fc10e75b70a52adc0c32a2321c2.“其中region id為”bd015fc10e75b70a52adc0c32a2321c2“。我們可以在HBase叢集客戶端執行以下命令來手動指定region。命令如下所示:

# 將該Region(dn3)移動到Region(dn1)
echo "move 'bd015fc10e75b70a52adc0c32a2321c2','dn1,16020,1510401268652'"|hbase shell

  在往HBase表中寫資料的時候,預設是往一個Region中寫資料,當資料量很大時,才會自動拆分成多個Region,拆分的規則和RowKey設計有關。為了防止出現這種情況,我們可以在建立表的時候進行預分割槽操作。命令如下所示:

# 建立表的預分割槽(6個Region),RegionTotals = SPLITS.length + 1
create 't2', 'cf', SPLITS => ['0001','0002','0003','0004','0005']

  這樣我們可以拆分成6個Region,這裡也許有同學要問,為什麼是6個Region。其實,從上圖中就可以看出,表分割槽中第一個Region是沒有StartKey,最後一個Region是沒有EndKey的。為什麼會出現這種情況,下面就給大家來剖析這個原因。如下圖所示:

  從圖中可知,在第一個Region中只有EndKey,沒有StartKey。第一個Region中的EndKey(0001),就是第二個Region的StartKey,以此類推,到最後一個Region就只有StartKey(0005)了。這就是為什麼第一個Region沒有StartKey,最後一個Region沒有EndKey的原因。

  其實,我們在使用HBase的Java API獲取Region的StartKey和EndKey的時候,有時會出現Null,也就是這個原因。

5.總結

  在使用Quota命令進行限流時,需要確保hbase-site.xml檔案中的限流屬性開啟。另外,在對錶做手動均衡操作時,使用move命令即可。HBase是有自動均衡的策略的,均衡的Region取決於設計分割的Key,Key的產生又和HBase中中Rowkey的設計息息相關。所以,HBase中表的RowKey設計的是否優秀,決定了Region均衡時,分割Key的選取。

6.結束語

  這篇部落格就和大家分享到這裡,如果大家在研究學習的過程當中有什麼問題,可以加群進行討論或傳送郵件給我,我會盡我所能為您解答,與君共勉。

相關文章