HBase之 HTable執行緒不安全

2021-08-31 22:58:06 字數 1463 閱讀 4871

在單執行緒環境下使用hbase的htable是沒有問題,但是突然高併發多執行緒情況下就可能出現問題原因是什麼呢?

我們來看看htable的api說明

this class is not thread safe for updates; the underlying write buffer can be corrupted  if multiple threads contend over a single htable instance.
當有多個執行緒競爭時可能把當前正在寫的執行緒corrupted這是為什麼呢

還是從htbale的原始碼來看

public htable(final byte  tablename)

throws ioexception

public static configuration create()

從上面我們可以看到每乙個htable的例項化過程都要建立乙個新的conf,我們甚至可以認為乙個conf對應的是乙個htable的connection,因此如果客戶端對於同乙個表,每次新new 乙個configuration物件的話,那麼意味著這兩個htable雖然操作的是同乙個table,但是建立的是兩條鏈結connection,它們的socket不是共用的,在多執行緒的情況下,經常會有new htable的情況發生,而每一次的new都可能是乙個新的connection,而我們知道zk上的鏈結是有限制的如果鏈結達到一定閾值的話,那麼新建立的鏈結很有可能擠掉原先的connection,而導致執行緒不安全。

因此hbase官方文件建議我們:

htable不是執行緒安全的。建議使用同乙個

hbaseconfiguration例項來建立htable例項。這樣可以共享zookeeper和socket例項。例如,最好這樣做:

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");

當然最方便的方法就是使用htablepool了,維持乙個執行緒安全的map裡面存放的是tablename和其引用的對映,可以認為是乙個簡單的計數器,當需要new 乙個htable例項時直接從該pool中取,用完放回,很簡單~~~

hbase不睡覺書重點

儲存架構 部署架構 訪問流程 部分api 擴容方便。新增節點後執行rebalance即可。缺點 對比關係型資料庫 master負責跨region server的操作,如建表 移動region 合併region等。zk管理所有的region server,包括meta節點的位址。hfile memst...

HBase學習之HBase的RowKey設計原則

hbase是三維有序儲存的,通過rowkey 行鍵 column key column family和qualifier 和timestamp 時間戳 這個三個維度可以對hbase中的資料進行快速定位。hbase中rowkey可以唯一標識一行記錄,在hbase查詢的時候,有以下幾種方式 通過get方...

hbase不建議有過多列簇

hbase本身對支援的列簇沒有數量限制,當我們建議列簇一般設在1 3之間。在hbase中呼叫api往對應的表中插入資料,會寫到menstore的,而menstore是一種記憶體結構,每個列簇對應乙個menstore。儲存在menstore中的資料在一定條件下會進行flush操作,每次flush的時候...