青青木屋 2019-07-01
hbase海量实时存储(百万/秒,数据库千/秒),druid(万亿/秒)。hbase常用于海量数据直接存储或分析后数据实时查询等,druid常作为流数据计算后实时查询。本文将介绍二者的架构/分布式部署,存储结构/格式,对比等。
官方:Apache HBase™ is the Hadoop database, a distributed, scalable, big data store.
Use Apache HBase™ when you need random,realtime
read/write access to your Big Data. 硬件成本不高情况下托管数十亿行*百万列。开发思路基于bigtable。文件系统基于hdfs(这部分分布式相关的一致性可用性不再说了)
CF——region(只有一个CF)s——多个stores——一个memstore+多个HFILE
region
一般的region server不可用,需要zk的发现-重新分配-恢复,期间该分区不可用,对于不能容忍的新版实现:region server多副本:https://hbase.apache.org/book...
region自动分片和region server自动故障转移(master检测后,重新分配region,更新zk的meta),WAL 保存在HDFS 的 /hbase/.logs/ 里面,每个region一个文件。
region server会在mem flush时把hfile压缩为更少,更大的文件,检测该区域的hfile文件过大会自动拆分,
region重新分配过程:
1.RegionServer在本地决定拆分区域,并准备拆分。获取共享读锁,以防止在拆分过程中修改模式。zookeeper下创建一个znode /hbase/region-in-transition/region-name,并将znode的状态设置为SPLITTING。 2.Master watcher获取 3.RegionServer创建一个在HDFS中.splits父region目录下命名的子目录。 4.RegionServer关闭父区域,并在其本地数据结构中将该区域标记为脱机。该region离线。此时,将发送到父区域的客户端请求NotServingRegionException。客户端将重试。 5.RegionServer在目录下.splits为子区域A和B创建区域目录,并创建必要的数据结构。然后分割存储文件,创建两个引用到父区域 6.RegionServer在HDFS中创建实际的区域目录,并移动每个子项的引用。 7.RegionServer向表发送Put请求.META.,将父级设置为脱机,并添加有关子区域的信息。成功之后才有单独的条目,否则清理回滚 8.RegionServer并行打开A和B. 9.RegionServer将女儿A和B .META.以及它托管区域的信息添加到其中。分裂地区(带有父母参考的孩子)现在在线。在此之后,客户可以发现新区域并向其发出请求。客户端在.META.本地缓存条目,但是当它们向RegionServer发出请求时.META.,它们的缓存将失效,并且它们将从中了解新区域.META.。 10.RegionServer将/hbase/region-in-transition/region-nameZooKeeper中的znode更新为state SPLIT,以便master可以了解它。如有必要,平衡器可以自由地将子区域重新分配给其他区域服务器。分裂交易现已完成。 11.拆分后,.META.HDFS仍将包含对父区域的引用。当子区域中的压缩重写数据文件时,将删除这些引用。主服务器中的垃圾收集任务会定期检查子区域是否仍然引用父区域的文件。如果不是,则将删除父区域。
WAL
一个region server一个WAL(串行写入HDFS瓶颈,multiwal在底层HDFS中使用多个管道并行写入,按区域划分你传入,不研究了)
打开某个区域时,需要重播属于该区域的WAL文件中的编辑。因此,WAL文件中的编辑必须按区域分组,以便可以重放特定的集合以重新生成特定区域中的数据。按区域对WAL编辑进行分组的过程称为日志分割。
旧的日志切割任务由hmaster完成并由zk协调,region server多时压力大=》改为每个region server执行
1.重命名WAL / HBase的/ WALS / <主机>,<端口>,<起始码> -splittin 2.日志分割器一次一个读取日志文件,放入region缓存中,启动多个写线程,每个读region缓存到临时文件/hbase/<table_name>/<region_id>/recovered.edits/.temp。分割后.temp文件重命名为sequennce id作为第一个。 3.日志拆分完成后,每个受影响的区域都将分配给RegionServer。 当区域被打开,recovered.edits文件夹中检查恢复的编辑文件。如果存在任何此类文件,则通过阅读编辑并将其保存到MemStore来重放它们。重放所有编辑文件后,MemStore的内容将写入磁盘(HFile)并删除编辑文件。
基于列存储
HBase 中创建表格时,就需要指定表格的 CF、Row-key 以及 Qulifier
Row-key 加上 CF 加上 Qulifier 再加上一个时间戳才可以定位到一个单元格数据(Hbase 中每个单元格默认有 3 个时间戳的版本数据)
列与行之间的转化如图:
http://cloudepr.blogspot.com/...
HFILE类似Google’s SSTable,不分层
内存占用:key不宜过大(所有index放内存key长度n),1G占用1.2M(15600 (1GB/64KB)(64+))
The trailer, file-info and total data block indexes (optionally, may add meta block indexes)
只用于数据量大的,HDFS 默认会将每一个 Block 数据备份 3 分,硬件还是比较多
Druid的重点是极低延迟查询,Druid完全索引所有数据。
高性能,亚秒响应的交互式查询(万亿行数据集上执行 query,响应时间小于1秒);可扩展性,采用分布式shared-nothing的架构,可以扩展到PB级;支持聚合函数,count和sum,近似查询的Aggregator。只支持流失插入,不支持流失更新,不支持大表join。适用于插入高更新少,有时间,列式聚合和报告等。较低的成本(比ES在聚合的成本低)
关键点:列存储,倒排索引,Roll UP,roaring 或者concise bitmap位图索引以及高效的压缩支撑了Druid的高效查询
常作用与spark之上。
官方:http://druid.io/docs/latest/d...
为每个定向类别(包括日期)创建一个单独的column family,Hbase受限于rowkey设计,都不能很好地解决多维分析。另外Hbase本身没有为column family创建bitmap indexing,查询速度应该会受到影响。
外部依赖
datasources->chunck(按时间分区)->segment
segment的数据生成过程
不支持单键更新
历史数据根据时间分层,冷/热
段可以继续分片和合并
1.broker识别数据再哪些Historicals和MiddleManagers,发送子查询。
其中为了减少查询:
1).broker的purge修剪:找段
2).每段用索引,行过滤器找行(bitmap)
3).查询所需列时,可以在行之间跳过。见特性
2.处理后broker合并
图中标识第一列的索引
以这个SQL查询为例,select sum(click) from table where time between 2016-05-24T11 and 2016-05-24T12 and广告=C2 and 地域=P1;首先根据时间段定位到Segment,然后根据广告=C2和地域=P1,得到 他们各自的字典编码,C2=1,P1=0,然后根据字典编码得到BitMap的Offet,从而得到Bitmap,C2=1 index为1的bitmap为0110,同理得到P1的bitmap为1100,0110和1100进行And与运算是0100,得到的offset是1,说明我们需要在click中读取offset=1的值是4.