hbase數據模型以及編碼壓縮(轉)


原文鏈接:hbase源碼系列(四)數據模型-表定義和列族定義的具體含義

hbase是一個KeyValue型的數據庫,在《hbase實戰》描述它的邏輯模型【行鍵,列族,列限定符,時間版本】,物理模型是基於列族的。但實際情況是啥?還是上點代碼吧。

復制代碼
     HTableDescriptor tableDesc = new HTableDescriptor("test"); //日志flush的時候是同步寫,還是異步寫  tableDesc.setDurability(Durability.SYNC_WAL); //MemStore大小 tableDesc.setMemStoreFlushSize(256*1024*1024); HColumnDescriptor colDesc = new HColumnDescriptor("f"); //塊緩存,保存着每個HFile數據塊的startKey colDesc.setBlockCacheEnabled(true); //塊的大小,默認值是65536 //加載到內存當中的數據塊越小,隨機查找性能更好,越大,連續讀性能更好 colDesc.setBlocksize(64*1024); //bloom過濾器,有ROW和ROWCOL,ROWCOL除了過濾ROW還要過濾列族  colDesc.setBloomFilterType(BloomType.ROW); //寫的時候緩存bloom colDesc.setCacheBloomsOnWrite(true); //寫的時候緩存索引 colDesc.setCacheIndexesOnWrite(true);
     //存儲的時候使用壓縮算法
      colDesc.setCompressionType(Algorithm.SNAPPY); //進行compaction的時候使用壓縮算法 colDesc.setCompactionCompressionType(Algorithm.SNAPPY); //壓縮內存和存儲的數據,區別於Snappy colDesc.setDataBlockEncoding(DataBlockEncoding.PREFIX); //寫入硬盤的時候是否進行編碼 colDesc.setEncodeOnDisk(true); //關閉的時候,是否剔除緩存的塊 colDesc.setEvictBlocksOnClose(true); //是否保存那些已經刪除掉的kv colDesc.setKeepDeletedCells(false); //讓數據塊緩存在LRU緩存里面有更高的優先級 colDesc.setInMemory(true); //最大最小版本 colDesc.setMaxVersions(3); colDesc.setMinVersions(1); //集群間復制的時候,如果被設置成REPLICATION_SCOPE_LOCAL就不能被復制了 colDesc.setScope(HConstants.REPLICATION_SCOPE_GLOBAL); //生存時間 colDesc.setTimeToLive(18000); tableDesc.addFamily(colDesc);
復制代碼

   在上面列出來表定義和列族定義的所有參數,含義也標上去了,我們經常需要設置的可能就是下面的這些。

復制代碼
     //bloom過濾器,過濾加速
colDesc.setBloomFilterType(BloomType.ROW); //壓縮內存和存儲中的數據,內存緊張的時候設置 colDesc.setDataBlockEncoding(DataBlockEncoding.PREFIX);
     //讓數據塊緩存在LRU緩存里面有更高的優先級 colDesc.setInMemory(true); //最大版本,沒必要的話,就設置成1個 colDesc.setMaxVersions(1); //集群間復制的時候,如果被設置成REPLICATION_SCOPE_LOCAL就不能被復制了 colDesc.setScope(HConstants.REPLICATION_SCOPE_GLOBAL);
     //存儲的時候使用壓縮算法,這個基本是必備的,hbase的存儲大得驚人
      colDesc.setCompressionType(Algorithm.SNAPPY);
//進行compaction的時候使用壓縮算法
        colDesc.setCompactionCompressionType(Algorithm.SNAPPY);
復制代碼

  

  hbase的表在hdfs上面的是這么存儲的,/hbase-root/tableName/regionName/familyName /HFile, 在tableName這一級目錄會有一個名.tabledesc的文件,在region這一級目錄有一個名為.regioninfo的文件,都是明文的。

  了解完表和列族的定義之后,我們看看KeyValue是怎么存儲的吧,引用一下代碼,可能大家一看就都懂了。

復制代碼
  @Override
    public void write(Cell cell) throws IOException { checkFlushed(); // Row rowkey,起始位置,長度  write(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()); // Column family 列族,起始位置,長度  write(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()); // Qualifier 列名,起始位置,長度  write(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()); // Version 時間戳 this.out.write(Bytes.toBytes(cell.getTimestamp())); // Type Put或者Delete this.out.write(cell.getTypeByte()); // Value 值,起始位置,長度  write(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()); }
復制代碼

  好吧,列存儲的話存儲的時候每個列都會重復前面的rowkey、列族這些信息,在列很多的情況下,rowkey和列族越長,消耗的內存和列族都會很大,所以它們都要盡量的短。

  可以考慮用colDesc.setDataBlockEncoding(DataBlockEncoding.PREFIX_TREE)來壓縮一下內存中的大小,這個后面后面會講到。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM