分享

请教关于hbase的强一致模型的理解

pengsuyun 发表于 2015-1-12 17:38:36 [显示全部楼层] 只看大图 回帖奖励 阅读模式 关闭右栏 20 66553
找了很多资料都说,HBase用的是强一致模型,一个客户端对数据的变更, 其他客户端马上就可以看到。

我想问的是,HBase是怎么做到强一致性的?

已有(20)人评论

跳转到指定楼层
pengsuyun 发表于 2015-1-14 11:29:48
折腾很久HBase的强一致模型,今天终于可以对自己有个交待了。

说道HBase的强一致性模型,其实应该去理解事务。传统关系型数据库做到了跨行、跨表的事务,但是原生的HBase仅支持单行的事务,仅这一点,其实是可以得到HBase强一致性的结论。所以这篇帖中,有同学提到了这点,只是那时候我不太理解HBase怎么实现行的事务的,所以我直接飘过了。事务的ACID特征中的C其实讲的就是一致性,所以只要承认了HBase的行事务,也就说明了HBase的强一致性了。

下面我谈谈HBase中怎么实现行事务的。

要明白这点,建议大家看看http://www.rigongyizu.com/hbase-row-lock-and-multiversion-concurrency-control/ 这篇文章,HBase官网的翻译贴,其中讲了MVCC(多版本并发控制)机制,顺着他的思路,应该可以部分理解HBase中的事务。下面就结合MVCC谈谈我对HBase的行事务的理解:
(1)MVCC中用到了行锁,通过串行化的操作,保证了行操作的原子性;
(2)在读操作的时候,读取点使用完成的最大的写序号(没有完成的写序号不可用)保证了事务的隔离型;
(3)在Region刷写MemStore的时候,MemStore通过加写锁,阻塞了region的更新操作,直到HFile写完成,释放锁,使得更新的行数据,顺利的写到HDFS中,保证了持久性;
(4)再来看行数据的一致性,最新的数据不是在MemStore中就是在HFile中,这样,其他客户端在读取行数据的时候,结合MemStore和HFile,取到的数据就总是最新的数据。

HBase行事务的实现,也就保证了HBase的强一致性。

关于第三点,我想补充下我的认识,之前,我担心在memstore刷写的过程中出现datanode没有及时更新的情况,这点是我想多了,再查看了《Hadoop权威指南》中“文件写入剖析”和“一致模型”后,我发现我的担心显得多余,因为,hadoop会等到最小份数datanode的写确认,只有这样,才说明文件写入成功,而且,在hdfs的文件cllose的时候,写入的数据在各个datanode都是可见的,再结合MemStore的写入锁,整个MemSotre的刷写过程是可以当作一个原子操作的。

到此,就是我对HBase的强一致性的理解了,有问题,也请各位同学指正。
回复

使用道具 举报

阿飞 发表于 2015-1-12 18:17:17
hbaseq强一致个人认为主要做了以下的工作:

1. 每个值只出现在一个region,且同一时间每个region只被分配给一台region服务器。
2. 所有行内的mutation操作都是原子操作。所有put操作要么完全成功,要么完全失败。
3. 通过任何API返回的行的内容都是一个完整的行。

回复

使用道具 举报

langke93 发表于 2015-1-12 18:31:01
楼主说这个还真是第一次听说:强一致性,可能和hbase wal有关系。这样能够保证数据不会丢失

如果每个客户端都知道,如果集群能上千台,而且彼此通知,每台都有可能收到上千条信息,这个集群恐怕要挂了。
回复

使用道具 举报

pengsuyun 发表于 2015-1-13 11:26:30
阿飞 发表于 2015-1-12 18:17
hbaseq强一致个人认为主要做了以下的工作:

1. 每个值只出现在一个region,且同一时间每个region只被分 ...

我理解的HBase的写数据模型。
结合这个写数据模型,我用一些假设,是会出现读不一致的情况,你看这种情况会不会有问题?
假设 client A 修改 列的数据,这时候store 中memsotre全部被flush到datanode中,然后hadoop只将修改数据写到datanode1,还来不及写到datanode2和datanode3。
clientB现在要读该列的数据,由于memsotre中没有缓存,需要从hdfs中取数据,这时候,hdfs从datanode2或者datanode3取数据,如果这种情况出现的化,clientB取的数据就不是刚刚修改的数据了。

总结下,clientA修改数据还没完全写到hadoop的datanode节点中,但是clientB从hadoop的未同步节点中取数据,这样就出现了数据不一致的情况。

我想问这种情况在HBase中存在吗?


HBase写数据模型.gif
回复

使用道具 举报

w123aw 发表于 2015-1-13 12:47:49
本帖最后由 w123aw 于 2015-1-13 12:55 编辑
pengsuyun 发表于 2015-1-13 11:26
我理解的HBase的写数据模型。
结合这个写数据模型,我用一些假设,是会出现读不一致的情况,你看这种情 ...

hbase不会出现楼主说的情况。

说先说写入数据:

HBase写入数据会写到HMemcache和Hlog中,HMemcache建立缓存,Hlog同步Hmemcache和Hstore的事务日志,发起Flush Cache时,数据持久化到Hstore中,并清空HMemecache。

也就是说hbase写数据,会首先保存到HMemcache及Hlog中,这时候就代表数据已经写入成功了,并且返回给hbase客户端,达到阀值后写到hdfs中.
这时候也不会丢失数据,因为一旦宕机,Hlog可以用来恢复数据

然后在说读取数据

base会检查数据是否在memstore里面,否则就去storefile读取,这时候storefile肯定是三份,而不是两份或则一份。
所以从写的原理和读的原理,不会出现只有一个备份有数据

所以不会出现楼主说的情况。

回复

使用道具 举报

pengsuyun 发表于 2015-1-13 14:25:49
w123aw 发表于 2015-1-13 12:47
本帖最后由 w123aw 于 2015-1-13 12:55 编辑

hbase不会出现楼主说的情况。

看了你说的写的情况,个人觉得不能很好的回答我的问题。
并发读写的情况是很多的,虽然我给出的图只是我的猜想,但是我觉的也有可能出现,另外探讨几个问题。

1、你说的Hmemcache 应该是 hbase存储架构中 位于store级别的MemStore吧,有没有可能,在刷写这部分内存后,原来存在memStore中的数据就被清空了?  在清空的情况下,渠道hadoop未被及时更新的数据,出现不一致性的可能就比较大了哦。除非他有其他的保障措施。当然这个是目前我不清楚的。

2、而且,你要注意一点,hadoop他是弱一致性的,又可能在多个datanode间同步数据的时候,被取到没及时更新的数据。
回复

使用道具 举报

w123aw 发表于 2015-1-13 14:52:59
pengsuyun 发表于 2015-1-13 14:25
看了你说的写的情况,个人觉得不能很好的回答我的问题。
并发读写的情况是很多的,虽然我给出的图只是我 ...
不一定能说服楼主,可能是论据不够。
不过尽量表达个人观点吧。

1、你说的Hmemcache 应该是 hbase存储架构中 位于store级别的MemStore吧,有没有可能,在刷写这部分内存后,原来存在memStore中的数据就被清空了?  在清空的情况下,渠道hadoop未被及时更新的数据,出现不一致性的可能就比较大了哦。除非他有其他的保障措施。当然这个是目前我不清楚的。

HMemCache(内存缓存)是hbase Region Server的内存缓存,如果被清空,hbase肯定有自己的判断机制,这个数据是完整的,如果不完整,肯定不允许读的,况且hbase及hadoop有自动平衡功能。所以这种在数据没有准备好,而memStore被清空,这种情况作者不会允许发生。
即使宕机HMemCache被清空,也有Hlog 来恢复。



2、而且,你要注意一点,hadoop他是弱一致性的,又可能在多个datanode间同步数据的时候,被取到没及时更新的数据。
这个数据如果没有同步完成,hadoop肯定也不会去读,即使读的话,发现数据块损坏,也会终止,当然这只是我的推测。楼主可以试验一下。
损坏其中一个备份,看是否会发生读取数据错误。虽然这话有些绝对,但是相信也会读取正确。

回复

使用道具 举报

pengsuyun 发表于 2015-1-13 15:07:45
w123aw 发表于 2015-1-13 14:52
不一定能说服楼主,可能是论据不够。
不过尽量表达个人观点吧。
HMemCache(内存缓存)是hbase Region Server的内存缓存,如果被清空,hbase肯定有自己的判断机制,这个数据是完整的,如果不完整,肯定不允许读的,况且hbase及hadoop有自动平衡功能。所以这种在数据没有准备好,而memStore被清空,这种情况作者不会允许发生。
即使宕机HMemCache被清空,也有Hlog 来恢复。

能说下HMemCache这个东西是出自哪里吗? 《Hbase权威指南》上有hbase的存储结构图,我没有看到过这个东西,所以有这个疑问。

另外同样出自《Hbase权威指南》,HBase的读写内存都是用的store的MemStore,可以去看下。


关于数据的完整性,看你怎么看了,hbase的数据修改没有及时同步到hadoop集群中的多个datanode节点上,可以看作数据的不完整。 但是对于datanode(处于未及时更新数据状态)本生来讲,他的数据是完整的,只不过他不是最新数据。所以他就存在了被读取的可能。


当然我的知识也比较有限,关于这块也只能是一种探讨,不一定说得对了。
回复

使用道具 举报

stark_summer 发表于 2015-1-13 16:01:22
回复

使用道具 举报

desehawk 发表于 2015-1-13 16:11:43
pengsuyun 发表于 2015-1-13 15:07
能说下HMemCache这个东西是出自哪里吗? 《Hbase权威指南》上有hbase的存储结构图,我没有看到过这个东 ...
store是没有内存的

Store
每一个region有一个或多个store组成,至少是一个store,hbase会把一起访问的数据放在一个store里面,即为每个ColumnFamily建一个store,如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。
HBase以store的大小来判断是否需要切分region。


MemStore
memStore 是放在内存里的。保存修改的数据即keyValues。当memStore的大小达到一个阀值(默认64MB)时,memStore会被flush到文件,即生成一个快照。目前hbase 会有一个线程来负责memStore的flush操作。


详细参考
回复

使用道具 举报

123下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条