引言:
大家在使用HBase的過程中,總是面臨性能優化的問題,本文從HBase客戶端參數設置的角度,研究HBase客戶端數據批量插入性能優化的問題。事實勝於雄辯,數據比理論更有說服力,基於此,作者設計了這么一個HBase數據插入性能優化實測實驗,希望大家用自己的服務器跑出的結果,給自己一個值得信服的結論。
一、客戶單優化參數
1.Put List Size
HBase的Put支持單條插入,也支持批量插入。
2. AutoFlush
AutoFlush指的是在每次調用HBase的Put操作,是否提交到HBase Server。 默認是true,每次會提交。如果此時是單條插入,就會有更多的IO,從而降低性能
3.Write Buffer Size
Write Buffer Size在AutoFlush為false的時候起作用,默認是2MB,也就是當插入數據超過2MB,就會自動提交到Server
4.WAL
WAL是Write Ahead Log的縮寫,指的是HBase在插入操作前是否寫Log。默認是打開,關掉會提高性能,但是如果系統出現故障(負責插入的Region Server 掛掉),數據可能會丟失。
參數 |
默認值 |
說明 |
JVM Heap Size |
|
平台不同值不同自行設置 |
AutoFlush |
True |
默認逐條提交 |
Put List Size |
1 |
支持逐條和批量 |
Write Buffer Size |
2M |
與autoflush配合使用 |
Write Ahead Log |
True |
默認開啟,需要手動關閉 |
… |
|
|
… |
|
|
二、源碼程序
1 import java.io.IOException; 2 import java.util.ArrayList; 3 import java.util.List; 4 import java.util.Random; 5 6 import org.apache.hadoop.conf.Configuration; 7 import org.apache.hadoop.hbase.HBaseConfiguration; 8 import org.apache.hadoop.hbase.HColumnDescriptor; 9 import org.apache.hadoop.hbase.HTableDescriptor; 10 import org.apache.hadoop.hbase.KeyValue; 11 import org.apache.hadoop.hbase.MasterNotRunningException; 12 import org.apache.hadoop.hbase.ZooKeeperConnectionException; 13 import org.apache.hadoop.hbase.client.Delete; 14 import org.apache.hadoop.hbase.client.Get; 15 import org.apache.hadoop.hbase.client.HBaseAdmin; 16 import org.apache.hadoop.hbase.client.HTable; 17 import org.apache.hadoop.hbase.client.Result; 18 import org.apache.hadoop.hbase.client.ResultScanner; 19 import org.apache.hadoop.hbase.client.Scan; 20 import org.apache.hadoop.hbase.client.Put; 21 import org.apache.hadoop.hbase.util.Bytes; 22 23 /* 24 * -------優化案例說明------------ 25 * 1.優化參數1:Autoflush 默認關閉,需要手動開啟 26 * 2.優化參數2:put list size 支持單條與批量 27 * 3.優化參數3:JVM heap size 默認值是平台而不同,需要手動設置 28 * 4.優化參數4:Write Buffer Size 默認值2M 29 * 5.優化參數5:Write Ahead Log 默認開啟,需要手動關閉 30 * */ 31 32 public class TestInsert { 33 static Configuration hbaseConfig = null; 34 35 public static void main(String[] args) throws Exception { 36 Configuration HBASE_CONFIG = new Configuration(); 37 HBASE_CONFIG.set("hbase.master", "192.168.230.133:60000"); 38 HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.230.133"); 39 HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", "2181"); 40 hbaseConfig = HBaseConfiguration.create(HBASE_CONFIG); 41 //關閉wal,autoflush,writebuffer = 24M 42 insert(false,false,1024*1024*24); 43 //開啟AutoFlush,writebuffer = 0 44 insert(false,true,0); 45 //默認值,全部開啟 46 insert(true,true,0); 47 } 48 49 private static void insert(boolean wal,boolean autoFlush,long writeBuffer) 50 throws IOException { 51 String tableName="etltest"; 52 HBaseAdmin hAdmin = new HBaseAdmin(hbaseConfig); 53 if (hAdmin.tableExists(tableName)) { 54 hAdmin.disableTable(tableName); 55 hAdmin.deleteTable(tableName); 56 } 57 58 HTableDescriptor t = new HTableDescriptor(tableName); 59 t.addFamily(new HColumnDescriptor("f1")); 60 t.addFamily(new HColumnDescriptor("f2")); 61 t.addFamily(new HColumnDescriptor("f3")); 62 t.addFamily(new HColumnDescriptor("f4")); 63 hAdmin.createTable(t); 64 System.out.println("table created"); 65 66 HTable table = new HTable(hbaseConfig, tableName); 67 table.setAutoFlush(autoFlush); 68 if(writeBuffer!=0){ 69 table.setWriteBufferSize(writeBuffer); 70 } 71 List<Put> lp = new ArrayList<Put>(); 72 long all = System.currentTimeMillis(); 73 74 System.out.println("start time = "+all); 75 int count = 20000; 76 byte[] buffer = new byte[128]; 77 Random r = new Random(); 78 for (int i = 1; i <= count; ++i) { 79 Put p = new Put(String.format("row d",i).getBytes()); 80 r.nextBytes(buffer); 81 p.add("f1".getBytes(), null, buffer); 82 p.add("f2".getBytes(), null, buffer); 83 p.add("f3".getBytes(), null, buffer); 84 p.add("f4".getBytes(), null, buffer); 85 p.setWriteToWAL(wal); 86 lp.add(p); 87 if(i%1000 == 0){ 88 table.put(lp); 89 lp.clear(); 90 } 91 } 92 93 System.out.println("WAL="+wal+",autoFlush="+autoFlush+",buffer="+writeBuffer+",count="+count); 94 long end = System.currentTimeMillis(); 95 System.out.println("total need time = "+ (end - all)*1.0/1000+"s"); 96 97 98 System.out.println("insert complete"+",costs:"+(System.currentTimeMillis()-all)*1.0/1000+"ms"); 99 } 100 }
三、集群配置
3.1 服務器硬件配置清單
序號 |
節點名稱 |
CUP |
內存 |
硬盤 |
帶寬 |
1 |
HMaster |
|
|
|
|
2 |
HregionServer1 |
|
|
|
|
3 |
HregionServer2 |
|
|
|
|
4 |
… |
|
|
|
|
5 |
|
|
|
|
|
6 |
|
|
|
|
|
7 |
|
|
|
|
|
3.2 客戶端硬件配置清單
設備 |
節點名稱 |
|
Cpu |
|
|
內存 |
|
|
硬盤 |
|
|
帶寬 |
|
|
四、測試報告
數據量 |
JVM |
AutoFlush |
Put List Size |
WriteBufferSize |
WAL |
耗時 |
1000 |
512m |
false |
1000 |
1024*1024*24 |
false |
|
2000 |
|
|
|
|
|
|
5000 |
|
|
|
|
|
|
10000 |
|
|
|
|
|
|
20000 |
|
|
|
|
|
|
50000 |
|
|
|
|
|
|
100000 |
|
|
|
|
|
|
200000 |
|
|
|
|
|
|
500000 |
|
|
|
|
|
|
100000 |
|
|
|
|
|
|
備注:該技術專題討論正在群Hadoop高級交流群:293503507同步直播中,敬請關注。