浅析超越分布式事务的方法—— 一个叛逆者的观点
Posted HIT智能数据俱乐部
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析超越分布式事务的方法—— 一个叛逆者的观点相关的知识,希望对你有一定的参考价值。
浅析超越分布式事务的方法——
一个叛逆者的观点
本文主要探索和命名一些在不能使用分布式事务的情况下,用于实现高伸缩、任务关键的应用程序的实践方法。讨论对细粒度应用程序数据块的管理,随着应用的增长它们可能需要重新分区,另外也将讨论在这些可重新分区的数据块之间发送消息的设计模式。
一、 简介
目的:讨论可伸缩应用以及无限伸缩应用的几种通用模式。
假设: a)应用程序的分层与伸缩性无关;
b)事务序列化范围;
c)大部分应用使用"至少一次"的消息方式。
二、 实体
1、分离的序列化范围:实体定义为拥有一个唯一键值的数据集合;
2、唯一标识的实体:使用唯一的键值进行标识;
3、重分区和实体:当应用增长时,实体需重分区,该过程应与应用程序上层无关;
4、原子事务和实体:在可伸缩系统中不能跨越不同实体使用更新事务,应用程序底层将确保每个实体位于单一的机器上,而不同实体则可能分布在任何地方;
5、考虑辅助索引:使用两步搜索,首先查找辅助索引得到实体键值,然后使用实体键值存取实体。
三、 跨越实体的消息通讯
1、异步发送事务
消息是跨越实体的,待发送消息位于一个实体中,消息终端是另一个实体。
应用开发者通过发送消息的方式使用事务可能是异常复杂的,将消息发送出去,然后事务可能被中断。
如果发送事务提交之后无法立即接收到目的地的回馈,我们看到相对于发送事务消息是异步的。实体在事务中会转化到新的状态,而消息是触发器,它来自于一个事物到达另一个实体并引发新的事务。
2. 确定消息终端
在开发应用程序伸缩无关的部分时,一个实体需要向另一个实体发送消息,伸缩无关的代码并不知道目标实体的位置,即实体键值。这由应用程序伸缩相关的部分来处理,它将实体键值和实体位置关联起来。
3. 重分区和消息分发
移动实体有时会中断发送方和目的地之间先进先出队列的通路,这时消息被重发,后来的消息会比先前的更早到达,会造成消息队列的混乱。
由于这些原因,我们看到伸缩无关的应用程序对应用程序可见的消息支持幂等处理,这也意味着重新订阅消息分发。
四、实体、SOA和对象
1. 实体和对象实例
对象有很多形式,有些是实体有些不是,对象成为实体有两个重要前提。
首先对象封装的数据必须严格与其它数据分离,其次分离的数据永远不能和其它数据一起自动更新。对象非常好但它们属于不同的概念。
2. 消息与方法的比较
方法调用通常与调用线程是同步的,因此也与调用对象的事务同步。然而被调用对象与调用对象并不一定能自动结合,普通的方法调用并不记录处理的消息,对被调用消息也不遵守至少一次这一信条。一些系统将消息发送封装成方法调用,我认为这是消息而不是方法了。
3. 实体和面向服务架构
这里对SOA的主要增强是每个服务本身可能需要处理无限伸缩,文章的内容指示了怎样实现,这些内容适用于SOA服务间的设计,也适用于那些设计为可独立伸缩的单个服务。
五、处理混乱的消息
1. 重试和幂等性
通常应用程序伸缩无关部分(上层)必须实现一些机制,确保接收的消息是幂等的。
2. 定义本质行为的幂等性
如果后续对消息处理的重复执行不会给实体带来本质变化,这个消息处理就是幂等的。
如果消息不会改变调用实体而只是读取信息,这个消息处理是幂等的。
3. 自然幂等性
消息不会造成本质副作用是实现幂等性的关键,有些消息任何时候都不会造成本质影响,他们就是自然幂等的。
只从实体读取数据的消息是自然幂等的。如果消息处理确实改变了实体但并不带来本质影响,那也是自然幂等的。
接下来是更麻烦的,有些消息带来了本质变化因此他们不是自然幂等的,而应用程序必须引入一些机制确保这些消息也是幂等的,这意味着采用某种方式记录已处理过的消息,以使后续重复的调用不会造成本质变化。
这就是接下来我们要讨论的非自然幂等的消息处理。
4. 将消息记录为状态
为了确保非自然幂等消息的幂等处理,实体必须记住哪些消息已经处理过了,这就是状态,状态随着消息处理不断记录下来。
除了记录消息已经处理过之外,如果消息需要回复则必须返回相同的回复内容,因为我们无法确定原发送者是否已经收到了这个回复。
5. 管理每个协作伙伴的状态
为了跟踪关系和收到的消息,伸缩无关应用中的每个实体必须采用某种方式记录协作伙伴的状态信息,并且必须针对每个协作伙伴分别记录,我们将这个状态命名为活动。如果一个实体与其它多个实体交互,它就会有多个活动。活动跟踪实体与每个协作伙伴的关系。
6. 通过活动确保最多接受一次消息
非自然幂等消息的处理必须确保最多处理一次。为了实现这个目的必须有一些唯一性机制,确保消息不会重复处理多次。
实体必须将等待处理的消息转换持久化记录到状态中,以使重复的消息处理不会造成本质影响。
通常实体基于每个协作伙伴使用活动实现这种状态管理,这一点很重要,因为有时实体会有很多不同的协作伙伴并且使用特定形式的消息跟每个协作伙伴进行交互。
针对各个协作伙伴有效的使用状态集合,程序员能够专注于协作伙伴的交互。
只需关注各个协作伙伴的信息时很容易构建可伸缩应用,例如在实现了幂等消息处理的平台上。
六、面对不确定性的解决方案
本节讲述在没有分布式事务的情况下可伸缩系统怎样管理分布式协议。另外由于是在无限伸缩这样一个环境中,必须采用以每个协作伙伴关系为中心这样一种细粒度设计来解决不确定性,这些数据在实体内部使用活动这一概念进行管理。
1. 目的地的不确定性
没有分布式事务意味着跨越不同实体的决策必须考虑不确定性,目前跨越分布式系统的决策仍无法规避不确定性这一问题。使用分布式事务时,这些不确定性发生在数据锁上,由事务管理器管理。
不能使用分布式事务的系统必须在业务逻辑中管理不确定性,使用业务语义而不是记录锁控制不确定性的影响,这就是工作流了。没什么玄乎的,只是由于不能使用分布式事务而必须采用工作流而已。
这些因素使得我们使用实体和消息,使我们明白如果伸缩无关的应用需要跨越多个实体达成协议,就必须自己使用工作流管理不确定性。
2. 活动与不确定性管理
实体在与其它实体交互时可能出现不确定性,这种不确定性必须基于每个协作伙伴进行管理,即在具体的协作伙伴活动状态中实现。
大部分时候不确定性缘于实体间的关系,但有必要按照协作伙伴进行跟踪,在每个协作伙伴进入新的状态时,活动将跟踪记录下来。
3. 处理尝试性业务操作
为了在实体间达成协议,实体必须能够让其它实体来处理不确定性,这通过发送一个确认消息请求实现,同时也需要能应对取消的情况,这就叫做尝试性操作。每个尝试性操作最终会被确认或取消。
实体允许尝试性操作时,它允许其它实体决定操作结果,这样实体遇到不确定性时为纠纷的处理带来了改善,取消或确认消息的到达意味着不确定性的减少。以前不断增加或减少的不确定性问题解决了,新的问题又会来到你身边,这在生活中很正常(译注:下面接着讨论新的问题)
4. 不确定性和无限伸缩
这种无限伸缩方案有意思的方面是围绕两方协议管理不确定性。
无限伸缩中考虑两方关系是很有意思的事情,基于两方关系构建尝试性/取消/确认操作框架,我们看到分布式协议的达成原理。就像委托公司一样,很多实体可以通过某个组织参与到一个协议中。
因为是两方关系,活动的简单意义就是"我保存的那个合作伙伴的资料",这也是管理大型系统的基础。就算数据是保存在实体中,你并不知道它具体位于哪儿而必须假定是在很远的地方,这样就能够采用伸缩无关的方式开发。
真实世界中无限伸缩应用程序偏向于两阶段提交或其他算法实现的全局序列化范围带来的便利性,不幸的是它将导致可用性上不可接受的压力,因此为伸缩无关应用的开发者提供尝试性方法管理不确定性,象预留库存、信用额度的分配以及其它应用的相关概念必须这样处理。
责任编辑:宋新彤
以上是关于浅析超越分布式事务的方法—— 一个叛逆者的观点的主要内容,如果未能解决你的问题,请参考以下文章