Architecting HBase Applications
目录
What is HBase?
HBase原则
- Table布局:null值不存储,列簇(cf)不需要预先定义
- Table存储:region > cf > 1 memstore + * hfile > blocks
- region由RegionServers管理(也就是说不存在真正聪明的分布式hash数据切分)
- 严格的水平切分(cf不宜太多,会导致很多小文件),这种情况下感觉更像是一个分布式K-V数据库?
- 感觉主要还是底层的分布式存储引擎太弱了(不过复杂性有会导致不可靠性)
- 4种block类型:
- 数据
- 索引
- Bloom filter
- Trailer
- Cells
- 块编码(基于与前一个key的diff?)
- 一系列最大长度限制
- 内部表操作
- 压缩(Compaction,有点类似于GC的概念)
- Minor(HBase的存储是基于immutable快照的,记录在逻辑删除时仅仅只是标记一下,只有当被compact操作时才真正删除)
- 与cell version count的关系
- Major
- Minor(HBase的存储是基于immutable快照的,记录在逻辑删除时仅仅只是标记一下,只有当被compact操作时才真正删除)
- 分割(Splits,Auto-sharding)
- 基本上是基于key的值区间的,=> 所以数值key最好先做一个MD5哈希?
- 所有的columns都会留在相同的region里:再次强调,HBase是‘严格的水平分片’!
- 所有的cf都会同样切分(为了保证访问单个key的所有columns时的局部性?)
- 平衡(Balancing)
- 0.96+ StochasticLoadBalancer
- 开发自己的(应用特定的?)balancer?
- 压缩(Compaction,有点类似于GC的概念)
- HBase Roles
- Master(性能要求不高,但要求可靠性) + RS(IO性能要求高)
- Thrift/REST Server
HBase生态系统
- 监控工具
- Cloudera Manager
- Apache Ambari
- Hannibal
- SQL on Hadoop/HBase
- Apache Phoenix
- Apache Trafodion
- Splice Machine
- Honorable Mentions (Kylin, Themis, Tephra, Hive, and Impala)
- Frameworks
- OpenTSDB
- Kite
- HappyBase(Python绑定)
- AsyncHBase
Sizing and Tuning Overview
- 0.96 bucket cache(SSD)
- 应当在0.98.6+上使用,due to HBASE-11678
环境Setup
实现一个底层(记录)存储引擎
- Omneo,Avro,Bulk load,Solr Cloud on Hadoop?
- create 'sensors', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}, \ (注意这里对原始的id进行了MD5哈希)
-
- {NAME => 'v',
- COMPRESSION => 'SNAPPY',\
- BLOOMFILTER => 'NONE',\
- DATA_BLOCK_ENCODING => 'FAST_DIFF'}
-
- HFile Validation
- hbase hfile -printmeta -f ch07/hfiles/v/345c5c462c6e4ff6875c3185ec84c48e
- Data Validation
- 记录数:hbase(main):003:0> count 'sensors', INTERVAL => 40000, CACHE => 40000
- 或 hbase org.apache.hadoop.hbase.mapreduce.RowCounter sensors
- File Content
- scan 'sensors', {COLUMNS => ['v'], STARTROW => '000a', LIMIT => 1 }
- Data Indexing
- solrctl?
- Data Retrieval
- CloudSolrServer solr = new CloudSolrServer("localhost:2181/solr");
- 。。。
- 记录数:hbase(main):003:0> count 'sensors', INTERVAL => 40000, CACHE => 40000
用例:近实时的事件处理
- 作者老喜欢批评Cassandra缺乏生态系统支持,tmd
- Kafka/Storm/Flume?
- ... we will use a Kafka queue as our Flume channel.
- Flume Interceptor:XmlToAvro?
- Lily Indexer?
- append the customer or insurance ID at the end of the MD5...
- DocumentID:不作为组合key的一部分(不同row可能在不同的region!),而是直接在column上存储Document内容的多个版本
- 上限估计:10000 * 10KB Avro记录 = 100MB,而HBase region可以很容易增加到10GB(还能承受?)
- Morphlines脚本?skip
- UniformSplit?
- alter 'documents', { NAME => 'c', COMPRESSION => 'GZ' }
用例:作为数据管理工具
- Spark with/over HBase?
用例:文档存储
- HBASE-11339 MOB:‘写放大’问题 => 当刷新memstore时,仅其引用被写到HFile(专门的MOB区域)
- RDBMS需要SSD,而HBase只需要SDATA,所以开销更低???
- 一致性:保证数据放在一个row里面(一次Put完成),抛弃cross-ref?
问题解决:Too many regions
- the more regions there are, the smaller the memstore flushes will be(更小的HFile)
- 原因:
- Maximum region size set too low
- Configuration settings not updated following an HBase upgrade
- Accidental configuration settings
- Over-splitting
- Improper presplitting
- 解决方案:
- 0.98-:
- CopyTable?
- Kafka and Flume可配置为暂停数据Ingest?
- Offline merges(集群必须完全下线)
- CopyTable?
- 0.98+:HBASE-7403 online merge
- 0.98-:
- 预防
- Regions Size:最大size设置为最少10GB
- Key and Table Design(降低cf)
问题解决:Too many 列簇
- 每个cf会被flush到一个HFile里,但共享同一个memstore!
- Split:基于目录的均衡?(split操作不会分布到另一个RS上去吧?还是说这里的目录是HDFS上的虚拟逻辑概念?)
- 删除cf:alter 'sensors', NAME => 'picture', METHOD => 'delete'
- 合并cf:CopyTable,源和目标可以是同一个?
- hbase org.apache.hadoop.hbase.mapreduce.CopyTable --new.name=customer --families=address:profile customer
- 合并多个cf到一个:--families=address:profile,phone:profile,status:profile
- hbase org.apache.hadoop.hbase.mapreduce.CopyTable --new.name=customer --families=address:profile customer
- 分隔cf到新表(都是通过数据复制来实现的!)
- hbase org.apache.hadoop.hbase.mapreduce.CopyTable --families=picture --new.name=map customer
问题解决:Hotspotting(热点)
- 我觉得热点问题才是HBase的核心疑难问题,应用特定的数据总是有可能导致不均匀的hash分布的
- 原因:key design?
- Small Reference Tables(例如postcode-city关联映射表):直接冗余存储到引用表中去
- 也可预先直接加载到内存常驻
- 如果有update需求,则最好一开始就想好怎么presplit!
- 如果数据是均匀分布的,=> Applications Issues?
- Meta Region Hotspotting:创建一个到ZooKeeper的单连接
- Small Reference Tables(例如postcode-city关联映射表):直接冗余存储到引用表中去
问题解决:超时与GC
- RS没有来得及向ZooKeeper作HeartBeat报告,YouAreDeadException
- 原因
- Java平台上,memory fragmentation(内存碎片)是GC和pause的主要原因(由于不一样的object size)
- Storage Failure
- Power-Saving Features
- Network Failure
- 避免
- Reduce Heap Size(靠?)
- 默认设置:<20G,CMS
- Off-Heap BlockCache(BucketCache):允许HBase自己管理碎片?
- 使用G1GC:内存根据不同size作regions分类,garbage first,允许HBase更大的memstore(从而提高性能)
- -XX:+UseG1GC
- -XX:+PrintFlagsFinal
- -XX:+PrintGCDetails
- -XX:+PrintGCDateStamps
- -XX:+PrintGCTimeStamps
- -XX:+PrintAdaptiveSizePolicy
- -XX:+PrintReferenceGC
- 附加选项(当内存超过100G)
- -XX:-ResizePLAB
- -XX:+ParallelRefProcEnabled
- -XX:+AlwaysPreTouch
- -XX:MaxGCPauseMillis=100
- 其他的有趣参数
- -XX:ParallelGCThreads=X 公式:8 + (logical processors – 8) (5/8)
- -XX:G1NewSizePercent=X
- -XX:+UnlockExperimentalVMOptions
- -XX:G1HeapWastePercent=5
- -XX:G1MixedGCLiveThresholdPercent=75
- Configure Swappiness to 0 or 1
- Disable Environment-Friendly Features(电源管理)
- 硬件冗余
- Reduce Heap Size(靠?)
问题解决:HBCK与不一致状态
- hbase(main):002:0> describe 'hbase:meta'
- -bash-4.1$ hadoop fs -ls -R /hbase/data/default/odell/3ead...
- -bash-4.1$ sudo -u hbase hbase hbck
- 下略