在單執行緒環境下使用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();當然最方便的方法就是使用htablepool了,維持乙個執行緒安全的map裡面存放的是tablename和其引用的對映,可以認為是乙個簡單的計數器,當需要new 乙個htable例項時直接從該pool中取,用完放回,很簡單~~~htable table1 = new htable(conf1, "mytable");
hbaseconfiguration conf2 = hbaseconfiguration.create();
htable table2 = new htable(conf2, "mytable");
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的時候...