前兩天在觀察kafka消費資料的時候,發現hbase偶爾會報乙個org.apache.hadoop.hbase.regiontoobusyexception: org.apache.hadoop.hbase.regiontoobusyexception
這種錯誤出來,從描述上看,是hbase寫入太過頻繁導致的。
首先來看我的寫入操作**:
/**
* 單條更新hbase資料
* *@param tablename
* 表名
*@param put
* put物件
*@return 成功與否
*@throws ioexception
*/public
synchronized
boolean
insert(string tablename, put put) throws ioexception
這種方式寫入單條資料,寫入情況就是,沒過來一條資料,就向hbase的region裡面寫入一條,操作太頻繁。
解決方式:批量寫入
首先,在hbase-site.xml配置檔案中加入(也可以使用其他配置方式,如**方式,但是不建議使用**方式,發布時候還要重新編譯,太麻煩):
hbase.client.write.buffername>
5242880value>
property>
設定達到多少時候就行寫入。
接著,修改單條寫入時候的**:
public
synchronized
boolean
insert(string tablename, put put) throws ioexception
這樣,如果呼叫這個insert方法,插入資料,雖然成功返回也不報錯,但是只是在客戶端做乙個資料累計,等達到了我設定的5m之後,才進行一次性寫入。雖然這樣做減少了io次數和網路傳輸次數,但是,一旦客戶端出錯或者hbase有問題,那麼這些資料就丟失掉了,對於保證資料絕對不能丟失的這種情況,建議謹慎使用。
public
void
put(put put) throws ioexception
}
觀察hbase client的api,會發現,這裡,如果是autoflash,會立馬執行乙個操作,叫做flushcommits,在這個操作裡面,會立即將資料寫入資料庫。
另外,在table進行關閉的時候,也會隱性的將資料寫入資料庫:
public
void
close() throws ioexception while(!e);
} catch (interruptedexception var2)
}if(this.cleanupconnectiononclose && this.connection != null)
this.closed = true;
}}
真正的寫入操作,其實是發生在:
public
void
mutate(list<? extends mutation> ms) throws interruptedioexception, retrie***haustedwithdetail***ception else
}if(this.ap.haserror()) else
while(this.currentwritebuffersize.get() > this.writebuffersize)
}}
當當前的資料達到我們設定的buff size的時候,才會進行乙個真正的寫入操作。
ps:如果想讓資料立即寫入,可以顯示呼叫flushcommits
或者呼叫close
方法。
Hbase的資料寫入
建立多個htable 客戶端用於寫操作,提高寫資料的吞吐量,乙個例子 static final configuration conf hbaseconfiguration.create static final string table log name user log wtablelog new...
hbase資料讀取優化 HBase效能優化 總結篇
1 hbase.hregion.max.filesize應該設定多少合適 預設值 256m 說明 maximum hstorefile size.if any one of a column families hstorefiles has?grown to exceed this value,th...
HBase查詢優化
1.概述 hbase是乙個實時的非關係型資料庫,用來儲存海量資料。但是,在實際使用場景中,在使用hbase api查詢hbase中的資料時,有時會發現資料查詢會很慢。本篇部落格將從客戶端優化和服務端優化兩個方面來介紹,如何提高查詢hbase的效率。2.內容 這裡,我們先給大家介紹如何從客戶端優化查詢...