# 內存壓縮
## 77\. 概況
內存壓縮(A.K.A Accordion)是hbase-2.0.0中的一項新功能。它首先在[Accordion:HBase Breathes with In-Memory Compaction]的Apache HBase博客上引入(https://blogs.apache.org/hbase/entry/accordion-hbase-breathes-with-in)。引用博客:
> Accordion將LSM原理[_Log-Structured-Merge Tree_,HBase所基于的設計模式]重新應用于MemStore,以便在數據仍在RAM中時消除冗余和其他開銷。這樣做可以降低flush到HDFS的頻率,從而減少寫入放大和整個磁盤占用空間。由于刷新次數較少,因此MemStore溢出時寫入操作停頓的頻率降低,因此寫入性能得到改善。磁盤上的數據越少,對塊緩存的壓力越小,命中率越高,最終讀取響應時間越短。最后,具有較少的磁盤寫入也意味著在后臺發生較少的compaction,即,從生產(讀取和寫入)工作中分割的資源較少。總而言之,內存壓縮的效果可以被看作是一個催化劑,使系統整體上運行速度更快。
可在以下鏈接中了解開發者視圖[Accordion: Developer View of In-Memory Compaction](https://blogs.apache.org/hbase/entry/accordion-developer-view-of-in).
內存壓縮在高數據流應用中效果最佳;當數據仍在內存中時,可以消除重寫或過期版本。如果寫入都是唯一的,則可能會拖慢寫入吞吐量(內存壓縮有CPU成本)。我們建議您在部署到生產之前進行測試和比較。
在本節中,我們將介紹如何啟用Accordion和可用的配置。
## 78\. 啟用
要啟用內存壓縮,則對每個你想要啟用內存壓縮的列簇設置 _IN_MEMORY_COMPACTION_配置項。_IN\_MEMORY\_COMPACTION_ 配置項的值可以為下面四個中任意一個。
* _NONE_: 不啟用內存壓縮.
* _BASIC_: 基本策略開啟后,會在內存中一直保持一個flush管道,直到我們超過管道最大閾值,然后我們就會flush到磁盤。雖然沒有內存壓縮操作,但仍然可以幫助提高吞吐,因為數據從空間效率不高的原生ConcurrentSkipListMap數據類型轉移到更緊湊(和高效)的數據類型。
* _EAGER_: 這是 _BASIC_策略加上對flush操作的內存壓縮組合(非常像磁盤上hfile的compaction);當執行內存壓縮時,使用的與磁盤上釋放過期版本,冗余數據,超時數據等規則一樣。
* _ADAPTIVE_: 對負載進行自適應壓縮操作。它會根據數據中重復單元格的比例來判斷是否需要執行索引壓縮或者數據壓縮。
想要在表格 _radish_的 _info_列簇中應用 _BASIC_策略,需要先禁用表,然后給 _info_列簇增加屬性,操作如下:
```
hbase(main):002:0> disable 'radish'
Took 0.5570 seconds
hbase(main):003:0> alter 'radish', {NAME => 'info', IN_MEMORY_COMPACTION => 'BASIC'}
Updating all regions with the new schema...
All regions updated.
Done.
Took 1.2413 seconds
hbase(main):004:0> describe 'radish'
Table radish is DISABLED
radish
COLUMN FAMILIES DESCRIPTION
{NAME => 'info', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR => 'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER => 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE => 'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true', BLOCKSIZE => '65536', METADATA => {
'IN_MEMORY_COMPACTION' => 'BASIC'}}
1 row(s)
Took 0.0239 seconds
hbase(main):005:0> enable 'radish'
Took 0.7537 seconds
```
注意 _IN_MEMORY_COMPACTION屬性是作為 _METADATA_映射里的一部分。
還有一個全局配置 _hbase.hregion.compacting.memstore.type_,可以在 _hbase-site.xml_文件里設置。可以用這個來設置新創建表的默認策略(在創建列簇存儲時,我們首先看列簇配置中 _IN_MEMORY_COMPACTION_配置,如果沒有,我們將查詢 _hbase.hregion.compacting.memstore.type_的值作為配置值,其默認是 _BASIC_策略)。
默認情況下,新的hbase系統表將會被設置為 _BASIC_內存壓縮策略。要另外指定,則在新表創建時,將 _hbase.hregion.compacting.memstore.type_設置為 _NONE_(注意,設置此值后之前創建的系統表不會改變;您將必須更改表以設置內存中屬性為 _NONE_。)
內存flush發生的條件是通過將配置的Region flush大小(在表描述符中設置或從 _hbase.hregion.memstore.flush.size_ 中讀取)除以列簇數,然后乘以 _hbase.memstore.inmemoryflush.threshold.factor_ 來計算,其默認值為0.014。
管道承載的flush次數會被控制在memstore的大小范圍內,當然你也可以設置 _hbase.hregion.compacting.pipeline.segments.limit_ 參數指定一個最大flush次數值,默認值是2。
創建列簇存儲時,需要指定哪種memstore類型。在撰寫本文時,有兩種memstore類型,分別是舊式的使用 _ConcurrentSkipListMap_ 來存放數據,然后flush到磁盤上的 _DefaultMemStore_ ,新式的提供上述內存壓縮機制的 _CompactingMemStore_。下面是一個配置 _family_ 屬性為 _CompactingMemStore_ 類型的列簇存儲日志行:
```
Note how the IN_MEMORY_COMPACTION attribute shows as part of the _METADATA_ map.
2018-03-30 11:02:24,466 INFO [Time-limited test] regionserver.HStore(325): Store=family, memstore type=CompactingMemStore, storagePolicy=HOT, verifyBulkLoads=false, parallelPutCountPrintThreshold=10
```
可以為CompactingMemStore類(_org.apache.hadoop.hbase.regionserver.CompactingMemStore_)打開TRACE級別日志來查看運行細節。
- HBase? 中文參考指南 3.0
- Preface
- Getting Started
- Apache HBase Configuration
- Upgrading
- The Apache HBase Shell
- Data Model
- HBase and Schema Design
- RegionServer Sizing Rules of Thumb
- HBase and MapReduce
- Securing Apache HBase
- Architecture
- In-memory Compaction
- Backup and Restore
- Synchronous Replication
- Apache HBase APIs
- Apache HBase External APIs
- Thrift API and Filter Language
- HBase and Spark
- Apache HBase Coprocessors
- Apache HBase Performance Tuning
- Troubleshooting and Debugging Apache HBase
- Apache HBase Case Studies
- Apache HBase Operational Management
- Building and Developing Apache HBase
- Unit Testing HBase Applications
- Protobuf in HBase
- Procedure Framework (Pv2): HBASE-12439
- AMv2 Description for Devs
- ZooKeeper
- Community
- Appendix