hbase

hbase
HBase是建立在Hadoop文件系统之上的分布式可扩展的 列式数据库。属于Nosql
HBase是一个数据模型,类似于谷歌的bigTable设计,可以提供快速随机访问海量结构化数据。它利用了Hadoop文件系统(HDFS)提供的容错能力
LSM树原理把一棵大树拆分成N棵小树,它首先写入内存中,随着小树越来越大,内存中的小树会flush到磁盘中,磁盘中的树定期可以做merge操作,合并成一棵大树,以优化读性能。
HBase架构及组件
hbase架构图
以上这些大概就是HBase存储的设计主要思想,这里分别对应说明下:
因为小树先写到内存中,为了防止内存数据丢失,写内存的同时需要暂时持久化到磁盘,对应了HBase的MemStore和HLog
MemStore上的树达到一定大小之后,需要flush到HRegion磁盘中(一般是Hadoop DataNode),这样MemStore就变成了DataNode上的磁盘文件StoreFile,定期HRegionServer对DataNode的数据做merge操作,彻底删除无效空间,多棵小树在这个时机合并成大树,来增强读性能。
Client:包含HBase的接口,并维护cache来加快对HBase的访问,比如region的位置信息
Master:
1、为Region Server分配Region
2、负责Region Server的负载均衡
3、发现失效的Region Server并重新分配其上的region
4、管理用户对table的增删改查操作
Region Server:
1、Region Serever 维护region,处理对这些region的IO请求
2、Region Server负责切分在运行过程中变得过大的region
Region:是HBase中对表进行切割的单元
Zookeeper:
1、通过选举,保证任何时候、集群中只有一个master,Master与RegionServers启动时会向Zookeeper注册
2、存储所有Region的寻址入口
3、实时监控Region Server的上线和下线信息。并实时通知给Master
4、存储HBase的schema和table元数据
5、默认情况下,HBase管理Zookeeper实例,比如,启动或者停止Zookeeper
6、Zookeeper的引入使得Master不再是单点故障
HBase物理存储
1、Table中的所有行都按照row key的字典序排列
2、Table在行的方向上分割为多个Hregion
3、region按大小分割(默认10g),每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,Hregion就会分成两个新的Hregion。当Table中的行不断增多,就会有越来越多的Hregion。
4、Hregion是HBase中分布式存储和负载均衡的最小单元。最小单元就表示不同的Hregion可以分布到不同的Hregion Server上。但一个Hregion是不会拆分到多个server上的。
5、Hregion虽然是负载均衡的最小单元,但并不是物理存储的最小单元。Hregion由一个或多个Store组成,每个store保存一个column family。每个Store又由一个位于内存的memStore和0至多个位于硬盘的StoreFile组成
写操作先写入memstore,当memstore中的数据量达到某个阈值,HregioniServer启动flashcache进行写入storeFile,每次写入形成单独一个storefile。
当storefile大小超过一定阈值后,会把当前的region分割成两个,并有Hmaster分配给相应的region服务器,实现负载均衡。
客户端检索数据时,先在memstore找,找不到再找storefile
HBase基本概念
HBase表由多行组成,一行在HBase由行键和一个或多个列的值组成
存储结构
行序时按照行键的字典序进行排序的
列是表中的最基本的元素,HBase的列包含一个列族和一个列限定符,列属于一个列族,列族属于一个行。
Hbase含有版本的概念,一个列的数据可以有多个历史版本,体现的形式就是时间戳。
每一列的值或单元格的值都具有时间戳,默认由系统指定,也可以由用户显示设置。一个单元格的不同版本的值按照降序排列在一起,访问的时候优先读取最新的值。这种优化的目的在于让新值比老值更容易被读取。
HBase中,列族是一行中一个或多个列的集合,就是一行数据的一部分。列族需要在表创建时就定义好。
列族中可以包含多个列,一个表中的某个列的定位方式就成了meta:size 这种方式。称之为列限定符
一个单元格是行、列族、和列限定符的结合,也就是说,通过这三个值(也称之为坐标)来唯一确定一个单元格。单元格中的值与关系型数据库不同的是,其如果没有值的话,就为空,也不占用底层物理存储。
时间戳就是写入某个单元格中的数据的具体时间,用来表示一个单元格中的数据的新旧
HBase 写流程
默认情况下,执行写入时回写到两个地方:预写日志(write-ahead log 也称HLog)和MemStore。HBase的默认方式时把写入动作记录在这两个地方,以保证数据持久化。只有当这两个地方的变化信息都写入并确认后,才认为写动作完成。
MemStore时内存的写入缓冲区,当MemStore填满后,数据会刷写到硬盘,生成一个HFile。HFile是HBase使用的底层存储格式。HFile对应于列族,一个列族可以有多个HFile,但一个Hfile不能存储多个列族的数据。在集群的每个节点上,每个列族有一个MemStore
HBase在写动作完成之前先写入WAL。HBase集群中每台服务器维护一个WAL来记录发生的变化。WAL是底层文件系统上的一个文件。直到WAL新纪录成功写入后,写动作才被认为成功完成。这样可以保证HBase和支撑它的文件系统满足持久性。
如果HBase服务器宕机,没有从MemStore里刷写到HFile的数据可以通过回放WAL来恢复,自动执行
a) Client发起了一个HTable.put(Put)请求给HRegionServer
b) HRegionServer会将请求匹配到某个具体的HRegion上面
c) 决定是否写WAL log。WAL log文件是一个标准的Hadoop SequenceFile,文件中存储了HLogKey,这些Keys包含了和实际数据对应的序列号,主要用于崩溃恢复。
d) Put数据保存到MemStore中,同时检查MemStore状态,如果满了,则触发Flush to Disk请求。
e) HRegionServer处理Flush to Disk的请求,将数据写成HFile文件并存到HDFS上,并且存储最后写入的数据序列号,这样就可以知道哪些数据已经存入了永久存储的HDFS中。
由于不同的列族会共享region,所以有可能出现,一个列族已经有1000万行,而另外一个才100行。当一个要求region分割的时候,会导致100行的列会同样分布到多个region中。所以,一般建议不要设置多个列族。
HBase读流程
如果想快速访问数据,通用的原则是数据保持有序并尽可能的保存在内存里。
HBas在读操作上使用了LRU(最近最少使用算法)缓存技术。这种缓存也叫做BlockCache,和MemStore在一个JVM堆里。BlockCache设计用来保存从HFile里读入内存的频繁访问的数据,避免硬盘读。每个列族都有自己的BlockCache
Block是HBase从硬盘完成一次读取的数据单位。HFile物理存放形式是一个Block的序列外加这些Block索引。从HBase里读取一个Block需要先在索引上查找一次该Block然后从硬盘读出。Block大小按照列族设定,默认值是64KB。根据使用场景可能会调大或者调小该值。
如果主要用于随机查询,可能需要细粒度的Block索引,小一点的Block更好一些。Block变小会导致索引变大,进而消耗更多内存。如果经常执行顺序扫描,一次读取多个Block,大一点的Block更好一些。Block变大意味着索引项变少,索引变小,因此节省内存。
从HBase中读出一行,首先会检查MemStore等修改的队列,然后检查BlockCache看包含该行的Block是否被访问过,最后访问硬盘上的对应HFile
注意:HFile存放某个时刻MemStore刷写时的快照。一个完整行的数据可能存放在多个HFile里。为了读出完整行,HBase可能需要读取包含该行信息的所有HFile
HBase删流程
Delete命令并不立即删除内容。实际上,它只是给记录打上删除的标记。针对那个内容的一条“墓碑”(tombstone)记录写入进来,作为删除的标记。”墓碑“记录用来标志删除的内容不能在Get和Scan命令中返回结果。因为HFile文件是不能改变的,直到执行一次大合并(major compaction),这些墓碑记录才会被处理,被删除,占用的空间才会被释放。
合并分为两种:大合并(major compaction)和小合并(minorco mpaction)。两者将会重整存储在HFile里的数据。小合并把多个小HFile合并生成一个大HFile。因为读出一条完整的行可能引用很多文件,限制HFile的数量对于读性能很重要。执行合并时,HBase读出已有的多个HFile的内容,把记录写入一个新文件。然后,把新文件设置为激活状态,删除构成这个新文件的所有老文件。HBase根据文件的号码和大小决定合并哪些文件。小合并的设计出发点时轻微影响HBase的性能,所以涉及的HFile的数量有上限。
大合并将处理给定region的一个列族的所有HFile。大合并完成后,这个列族的所有HFile合并成一个文件。可以从Shell中手工触发整张表的大合并。这个动作相当耗费资源,不要经常使用。小合并时轻量级的,可以频繁发生。大合并是HBase清理被删除记录的唯一机会。因为我们不能保证被删除的记录和墓碑标记记录在一个HFile里面。HBase可以确保同时访问到两种记录。
HBase和Hive的区别
hive和hbase是两种基于Hadoop的不同技术。
Hive的定位是数据仓库,虽然也有增删改查,但其删改对应的是整张表,而不是单行数据,查询的延迟较高。其本质是更加方便的使用MR来进行离线分析的一个数据分析工具。
HBase的定位是Hadoop的数据库,是一个典型的Nosql,所以Hbase是用来在大量数据中进行低延迟的随机查询。
HBase 数据查找路由
参考:http://blog.csdn.net/wangzhen199009/article/details/41593289
HBase的rowKey的设计原则
RowKey长度原则
RowKey是一个二进制码流,RowKey的长度被很多开发者建议说设计在10~100个字节,不过建议是越短越好,不要超过16个字节。
原因:
1、数据的持久化文件HFile中是按照KeyValue存储的,如果rowKey过长,1000万列数据光RowKey就要占用100*1000万=10亿个字节,将近1g数据,这会极大影响HFile的存储效率
2、MemStore讲缓存部分数据到内存,如果RowKey字段过长内存的有效利用率降低,系统将无法缓存更多的数据,这会降低检索效率。因此RowKey的字节长度越短越好。
3、目前操作系统都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。
RowKey散列原则
提高数据均衡分布在每个RegionServer实现负载均衡的几率。如果没有散列值,首字段直接是时间信息,将产生所有新数据都在一个RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率
RowKey唯一原则
必须在设计上保证其唯一性,rowkey是按照字典顺序排序存储的,因此,设计rowkey的时候,要充分利用这个排序的特点,将经常读取的数据存储到一起,将最近可能会被访问的数据放到一起
什么是热点
HBase中的行是按照rowkey的字段顺序排序的,这种设计优化了scan操作,可以将相关的行以及会被一起读取的行存取在临近位置,便于scan,然而糟糕的rowkey设计是热点的源头。热点发生在大量client直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。大量的访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region的请求。
避免热点方法
加盐
这里所说的加盐不是密码学中的加盐,而是rowkey的前面增加随机数,具体就是给rowkey分配一个随机前缀以使得它和之前的rowkey的开头不同。分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致。加盐之后的rowkey就会根据随机生成的前缀分散到各个region上,以避免热点。
哈希
哈希会使同一行永远用一个前缀加盐。哈希也可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的rowkey,可以使用get操作准确获取某一行数据
反转
反转固定长度或者数字格式的rowkey。这样使得rowkey中经常改变的部分(最没有意义的部分)放在前面。这样可以有效的随机rowkey,但是牺牲了rowkey的有序性。
反转rowkey的例子 以手机号为rowkey,将手机反转后的字符串作为rowkey,这样就避免了以手机号比较固定开头导致的热点问题。
时间戳反转一个常见的数据处理问题使快速获取数据的最近版本,使用反转的时间作为rowkey的一部分堆这个问题十分有用,可以用 Long.Max_Value - timestamp追加到key的末尾,例
[key][reverse_timestamp]
其他建议
尽量减少行和列的大小,value永远和它的key一起传输的。当具体的值在系统间传输时,它的rowkey、列名、时间戳也会一起传输。如果你的rowkey和列明很大,甚至可以和具体的值相比较,那么你将会遇到一些有趣的问题。
HBase storefiles中的索引(有助于随机访问)最终占据了HBase分配的大量内存,因为具体的值和它的key很大。可以增加block大小使得storefiles索引再更大的时间间隔增加,或者修改表的模式以减小rowkey和列名的大小。压缩有助于更大的索引。
列族尽可能越短越好,最好是一个字符
冗长的属性名虽然可读性好,但是更短的属性名存储再HBase中会更好





posted @ 2019-04-02 12:54  火丶日月明  阅读(219)  评论(0编辑  收藏  举报