HBase資料寫入測試

來源:互聯網
上載者:User
測試環境

測試硬體:4核i5處理器,8G記憶體,1T硬碟,千兆網路

測試軟體:ubuntu12.10 64位,hadoop版本:0.20.205,hbase版本:0.90.5

測試設定:一個master(namenode)和三台resigonServer(datanode),向HBase叢集寫入1千萬個資料(一個資料15K左右)

測試結果

  • 第一列和最後一列分別是插入相同資料再HBase中和HDFS中,可以看見差距很大,HBase上資料的插入時間是HDFS的10倍左右
  • 向HBase中插入資料比HDFS效能差這麼多,筆者就研究一下是什麼原因讓HBase寫效能這麼不好。向HBase中插入資料的過程大致是這樣:client插入資料時先向master請求,master回複哪個resigionserver的哪個region可以給插入資料,然後client直接和resigionserver通訊插入資料,resigionserver判斷該資料插入到哪個datablock裡(resigion是由datablock組成的),然後以HFile的形式儲存在HDFS中(資料不一定在resigionserver本地)。具體過程如下可以參考部落格http://jiajun.iteye.com/blog/899632
  • 影響HBase寫入效能的一個因素就是用put類插入資料的緩衝區問題。用put類插入資料時,預設的情況是寫入一次資料由clinet和resigionserver進行一次RPC來插入資料。由於是1千萬個資料,多次進行處理序間通訊勢必會影響時間。HBase給用戶端提供了寫緩衝區,當緩衝區填滿之後才執行寫入操作,這樣就減少了寫入的測次數。
    • 首先取消自動寫入,setAutoFlush(false)
    • 然後設定寫緩衝區大小(預設是2MB)setWriteBufferSize()或者更改hbase-site.xml的hbase.client.write.buffer的屬性
    • 上面列表可以看出把緩衝區設為20M還是對寫入時間有改進,但是改成200M寫入時間更長(為什嗎?)
  • 另一個因素就是WAL(write ahead log),因為每一個resigion都有一個memstore用記憶體來暫時存放資料,進行排序,最後再吸入HFile裡面去,這樣做為了減少磁碟尋道而節省時間,但是為了災難恢複,所以會把記憶體中的資料進行記錄。所以筆者把WAL關閉之後,又測了下效能,還是有一點協助的,但是協助不是太大,可見WAL不是寫入的瓶頸。(setWriteToWal(false))
  • 因為HBase對查詢方便,能夠快速的讀取資料,寫入時必然會採取一些措施進行排序,這就是HBase的合并和分裂機制。HBase官方為了提升寫入效能,給出一種方案就是預分配resigion,也就是池的概念,你先分配一些resigion,用的時候直接用就行了。本來這1千萬個資料要儲存900個resigion,所以筆者預先分配了150個resigion(分配900個resigion,建表時間太長,出現異常,還沒有解決),結果寫入時間提升了很多,基本是原來的一半,如果能預先分配900個resigion,應該更能節省時間。

ps: 寫入時,設定緩衝區越大,寫資料(比如8位元組)的時間越短

pps:寫入buffer不宜設成過大 M級就可以。最近寫入測試又做了一些實驗,除了預先分配region之外,用多線程寫效率還是很高的,筆者測試40個線程比單線程快了8倍左右

測試程式
package GIS.Update;import java.io.IOException;import java.math.BigInteger;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FSDataOutputStream;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.hbase.HBaseConfiguration;import org.apache.hadoop.hbase.HColumnDescriptor;import org.apache.hadoop.hbase.HTableDescriptor;import org.apache.hadoop.hbase.MasterNotRunningException;import org.apache.hadoop.hbase.ZooKeeperConnectionException;import org.apache.hadoop.hbase.client.HBaseAdmin;import org.apache.hadoop.hbase.client.HTable;import org.apache.hadoop.hbase.client.Put;import org.apache.hadoop.hbase.util.Bytes;public class TestUpdate {public static void testHDFS() throws IOException{String str="hdfs://cloudgis4:9000/usr/tmp/";Path path=new Path(str);Configuration conf=new Configuration();conf.addResource(new Path("/usr/local/hadoop/conf/hdfs-site.xml"));FileSystem hdfs=path.getFileSystem(conf);hdfs.setReplication(path, (short)4);FSDataOutputStream fsDataOut=hdfs.create(new Path(str+"zzz"));long begin=System.currentTimeMillis();for(int i=0;i<10000000;i++){//byte [] kkk=new byte[10000+i/1000];byte [] kkk=new byte[12]; fsDataOut.write(kkk);//fsDataOut.close();//hdfs.close();}fsDataOut.close();long end=System.currentTimeMillis();System.out.println("hdfs:"+(end-begin));}public static void testHBase() throws IOException{Configuration conf=HBaseConfiguration.create();conf.addResource(new Path("/usr/local/hbase/conf/hbase-site.xml"));//conf.addResource("/usr/local/hbase/conf/hdfs-site.xml");HBaseAdmin admin=new HBaseAdmin(conf);String tableName="qq";String familyName="imageFamily";String columnName="imageColumn";HTableDescriptor htd=new HTableDescriptor (tableName);HColumnDescriptor hdc=new HColumnDescriptor(familyName);htd.addFamily(hdc);long before=System.currentTimeMillis();//admin.createTable(htd,splits);admin.createTable(htd,Bytes.toBytes("0000000"),Bytes.toBytes("9999999"),150);long after=System.currentTimeMillis();System.out.println(after-before);HTable table=new HTable(conf,htd.getName());table.setAutoFlush(false);//table.setWriteBufferSize(209715200); System.out.println(table.getWriteBufferSize());long begin=System.currentTimeMillis();     for(int i=0;i<10000000;i++){byte [] kkk=new byte[10000+i/1000];   //byte [] kkk=new byte[12]; Put p1=new Put(Bytes.toBytes(intToString(i)));p1.setWriteToWAL(false);p1.add(Bytes.toBytes(familyName),Bytes.toBytes(columnName),kkk); table.put(p1);}long end=System.currentTimeMillis();table.flushCommits();System.out.println("HBase:"+(end-begin));}static public String intToString(int x){String result=String.valueOf(x);int size=result.length();while(size<7){size++;result="0"+result;}return result;} public static void main(String []args) throws IOException{testHBase();}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.