免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2777 | 回复: 0
打印 上一主题 下一主题

dynamo 的最终一致性和两阶段提交 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-03 19:02 |只看该作者 |倒序浏览
       --插一句, 在写这个东东的时候, 发现我发的那个 dynamo 简介中, 关于 W N R 模型的一致性说明是有错误的, 在那个文章里加了个注释. 因为没有源码可看, 很多东西只能靠自己的理解来写了, 请发现问题的同学不吝指出, 谢谢.
    最近聊天时, 有些同学提出用两阶段提交来实现分布式系统中的一致性.  下面以 Dynamo 为例子, 说说我的理解.
   
首先看两阶段提交, 它是为了在分布式的数据库保证数据的一致性而采用的一种策略. 简单举一个例子, 比如一个事务,涉及到数据库A中的一些改动,
又涉及到数据库B中的一些改动. 那么需要提交的时候如何操作呢? 假设不采用两阶段提交, 我们要先提交一个数据库,比如A,
然后再提交第二个,比如B. 但是如果A提交成功, B提交失败, 这个时候一致性没有了, 因为A是无法回滚的. 都哪些原因可以引起提交失败呢?
很多的, 比如一些约束上的冲突, 比如各种日志写失败, 网络失败, 甚至断电等等. 两阶段提交如何解决这个问题呢, 简单的说,
两阶段提交把提交过程分成两个阶段(这句是废话), 首先进行预提交, 数据库完成各种约束检查啊, 日志写入等工作. 数据库承诺, 预提交成功了,
正式提交一定成功.但是预提交毕竟不是提交, 是可以回滚的. 所以如果有某个数据库预提交失败, 我们可以对所有的库回滚掉整个事物.
如果预提交成功, 则进入第二阶段, 正式提交. 插一句,两阶段提交可能会需要一个分布锁, 用来保证在提交过程中, 相关的数据不可读写,
从而消除违反一致性的时间窗. 这个分布锁跟我们要说的关系不大, 不讨论了. 那么两阶段提交完全解决了分布式系统的一致性问题了吗? 不是的.
在正式提交阶段如果发生错误, 比如A提交成功, B网络连接断掉, 这个时候事物处于错误的状态. 很多时候, 出现这样的问题是需要dba介入的.
两阶段提交只是把导致事物失败的危险期缩小到第二个阶段, 因为第二阶段数据库要做的事情很少,时间很短,可以认为那个阶段几乎不可能出错误.
   
那么如果我们来实现 Dynamo 是否可以从两阶段提交中吸取营养呢? 我各人认为意义不大. 为了便于讨论, 让我们的 Dynamo 实例采取
N=3 W=3 R=1的配置. 这个配置, Dynamo的承诺是, 写要写三个节点都成功才算是成功, 读可以只从一个节点来读.
两阶段提交不大适用的原因, 我认为有这么几个.1 节点之间的交互太多, 效率不够. 2 写操作太过频繁, 加之网络问题是经常出现的,
所以第二阶段的失败成为一种正常事件, 这个失败又无法自动恢复. 对于第二点, 也许有人会提出,
发现某个节点提交失败则对其余节点做一个反向操作. 我们暂且认为这个反向操作不会失败(实际上这个也是可能失败的),
那么在其余节点收到反向操作以前, 从该节点的读操作会读到update后的数据, 反向操作后, 这部分数据消失了.也就是说, 会有人读到脏数据.
这个问题对大部分应用来说是比读到旧数据严重得多的问题. 注意, 这里没讨论分布式锁的解决方案, 那个效率太差了, 不可接受.
   
下面看看 Dynamo 如何处理这个问题的. 首先要明确的是, Dynamo 保证的是最终一致性, 就是说, 如果一个更新操作正确的完成了,
Dynamo 不保证所有的读操作都立刻能读到最新信息. 我们看看具体实现就明白了为什么是这个行为. 具体内容请看原论文 4.6 hadling
failures: Hinted Handoff 这里简单说一下:dynamo有一层叫做coordinator, 是可以放到任意位置的,
我们假设放到了客户端. 那么一个写操作, coordinator
会根据一致性哈希算法选择三个节点(不妨设为 A B C), 同时发三个写操作的包, 然后等候回应. 假设规定时间内,
只有两个节点返回成功(不妨设为A B),
也就是说, 第三个节点没成功, 这个时候coordinator会再选择一个不同与上面三个的第四个节点, 发出写操作,
...直到写成功为止(不妨设这个节点是X). 这样保证了备份数.
额外被选择的节点(X)存储这个数据信息到一个单独的目录中, X节点负责不断的尝试把这部分数据写回到C节点. 这个过程叫做 hinted
handoff. 在这样的策略下, 因为R=1, 读任何一个节点都是有效的, 假设客户读节点 A B, 那么读到的都是最新数据,
如果读节点C, 可能读到老的数据. 但是无论如何读不到脏数据. 因为在可期望的时间内, 所有的节点上的数据可以达到一致,
所以这种一致性叫做最终一致性.
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/103470/showart_2085644.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP