1. 程式人生 > >【轉載】HBase效能優化方法總結(3):寫表操作

【轉載】HBase效能優化方法總結(3):寫表操作

本文主要是從HBase應用程式設計與開發的角度,總結幾種常用的效能優化方法。有關HBase系統配置級別的優化,可參考:淘寶Ken Wu同學的部落格

下面是本文總結的第二部分內容:寫表操作相關的優化方法。

2. 寫表操作

2.1 多HTable併發寫

建立多個HTable客戶端用於寫操作,提高寫資料的吞吐量,一個例子:

static final Configuration conf = HBaseConfiguration.create();
static final String table_log_name = “user_log”;
wTableLog = new HTable[tableN];
for (int i = 0; i < tableN; i++) {
    wTableLog[i] = new HTable(conf, table_log_name);
    wTableLog[i].setWriteBufferSize(5 * 1024 * 1024); //5MB
    wTableLog[i].setAutoFlush(false);
}

2.2 HTable引數設定

2.2.1 Auto Flush

通過呼叫HTable.setAutoFlush(false)方法可以將HTable寫客戶端的自動flush關閉,這樣可以批量寫入資料到HBase,而不是有一條put就執行一次更新,只有當put填滿客戶端寫快取時,才實際向HBase服務端發起寫請求。預設情況下auto flush是開啟的。

2.2.2 Write Buffer

通過呼叫HTable.setWriteBufferSize(writeBufferSize)方法可以設定HTable客戶端的寫buffer大小,如果新設定的buffer小於當前寫buffer中的資料時,buffer將會被flush到服務端。其中,writeBufferSize的單位是byte位元組數,可以根據實際寫入資料量的多少來設定該值。

2.2.3 WAL Flag

在HBae中,客戶端向叢集中的RegionServer提交資料時(Put/Delete操作),首先會先寫WAL(Write Ahead Log)日誌(即HLog,一個RegionServer上的所有Region共享一個HLog),只有當WAL日誌寫成功後,再接著寫MemStore,然後客戶端被通知提交資料成功;如果寫WAL日誌失敗,客戶端則被通知提交失敗。這樣做的好處是可以做到RegionServer宕機後的資料恢復。

因此,對於相對不太重要的資料,可以在Put/Delete操作時,通過呼叫Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函式,放棄寫WAL日誌,從而提高資料寫入的效能。

值得注意的是:謹慎選擇關閉WAL日誌,因為這樣的話,一旦RegionServer宕機,Put/Delete的資料將會無法根據WAL日誌進行恢復。

2.3 批量寫

通過呼叫HTable.put(Put)方法可以將一個指定的row key記錄寫入HBase,同樣HBase提供了另一個方法:通過呼叫HTable.put(List<Put>)方法可以將指定的row key列表,批量寫入多行記錄,這樣做的好處是批量執行,只需要一次網路I/O開銷,這對於對資料實時性要求高,網路傳輸RTT高的情景下可能帶來明顯的效能提升。

2.4 多執行緒併發寫

在客戶端開啟多個HTable寫執行緒,每個寫執行緒負責一個HTable物件的flush操作,這樣結合定時flush和寫buffer(writeBufferSize),可以既保證在資料量小的時候,資料可以在較短時間內被flush(如1秒內),同時又保證在資料量大的時候,寫buffer一滿就及時進行flush。下面給個具體的例子:

for (int i = 0; i < threadN; i++) {
    Thread th = new Thread() {
        public void run() {
            while (true) {
                try {
                    sleep(1000); //1 second
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
synchronized (wTableLog[i]) {
                    try {
                        wTableLog[i].flushCommits();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
}
    };
    th.setDaemon(true);
    th.start();
}

轉載自:http://www.cnblogs.com/panfeng412/archive/2012/03/08/hbase-performance-tuning-section2.html