本节将会对前面给出的算法和系统做一个总结,并为乐观复制系统的设计者和用户给出一些建议。
表4总结了Section1.4中所介绍的乐观复制系统在最高比较层面上的不同。该表说明了这里并没有唯一的赢家;每种策略都有自己的优点和缺点。单master传输对于请求负载主要为读取的应用并仅有一个写入节点的应用是一个好的选择,因为它的实现简单同时没有冲突。多master的状态传输相对简单,较低的空间开销(为每一个对象保存一个时间戳,或者版本向量)。它的不足在于,进行冲突解决时无法利用操作的语义信息,同时也会随之对象数目的增多而增加它的开销。因此,对于同步对象少,冲突概率低,同时冲突可以被简单的“last writer wins”规则解决的应用,多master的state传输策略是一个很好的选择。多master的操作传输,解决了state传输的不足,但需要付出算法复杂性以及空间开销增加的代价。
表5总结了用于解决乐观复制所面临挑战的算法,这些挑战在section1.3中进行了说明。灰色的单元表示该方法与本文不是密切相关,或者不是一个问题。比如,对于单master中的调度和冲突管理可以通过本地并发控制解决,在状态传输系统中tombstones的空间开销则远小于操作传输系统日志所需的空间开销。
10.3乐观复制系统的总结
表6总结了综述中提到的乐观复制系统,以及它们所采用的算法。
10.4 对设计乐观复制系统的建议
通过对我们自己经验的总结以及对前面提到论文的总结,我们这里为设计乐观复制系统的朋友给出一些建议。
乐观,异步的数据处理确实可以提高网络灵活性和扩展性。因此,在低速和不可靠网络上贡献数据,或者在广域网上协同工作,同时存在计算节点连接会断开的情况下,我们不可避免地会采用乐观,异步的数据处理。然后,使用乐观复制确实需要付出一定的代价。为了保证一致性,它包含了最复杂的算法。冲突通常需要应用相关的语义信息来解决,丢失更新的问题无可避免。为此我们给出了一些建议。
1)尽量保持简单。悲观符合,采用大量现成解决方案,对于工作在完全连接并且网络可靠环境中的应用是最好的解决方案。另外,尝试单master复制,它简单,无冲突,并在实际中能扩展良好。Thomas`s写规则对于很多应用有良好的表现。对于版本向量,操作传输等高级技术,只有当你确实需要灵活性以及利用语义信息来解决冲突时再采用。
2)保持对象独立避免负面效应。绝大多数乐观复制算法能够保证一个对象在不同副本的一致性,但很难保证多个对象的一致性。
(思考:这一点也是我认为最大的问题,因为复制的数据对象间并不总是独立的。Order data与unorder data。对于这一点普遍采用state-transfer与operation-transfer相结合的方法解决。对象间关系的维护采用operation-transfer,而具体对象的同步则采用state-transfer。)
3)快速传播更新是避免冲突最好的方法。当节点相互连接时,经常的传播更新,保持节点尽量在一个接近的同步状态。这将最小化节点断开发生后的不一致。
4)尽可能地将对象设计为无冲突的。下面给出了关于这一点的一些建议:
--将大对象划分为小对象避免false positives.
--将操作设计为可交换的。例如,利用单调的数据结构,如只允许追加的日志,或者一个线性增加的计数器,或者一个全局唯一集合。
5)使用简单,结构化的拓扑,比如采用星型或者两层拓扑。相比P2P网络,它们较容易控制和扩展。
对于存在全局时间的系统,请求的先后顺序可以根据请求发生的绝对时间很容易获得。然而对于分布式系统获取系统的全局时间是困难的,为系统中每一个操作确定先后顺序也是异常困难的。分布式系统分为同步系统和异步系统。Lamport在他的论文[72]中已经阐明,尽管时钟同步是可能的,但它不是绝对必要的。如果两个进程不进行交互,那么它们的时钟也无需同步,这是因为即使没有同步也觉察不出来,并且也不会产生问题。Lamport进一步指出,通常,重要的不是所有的进程在时间上完全一致,而是它们在事件的发生顺序上要达成一致。在异步系统中我们将发送消息和接收消息也视为事件。Lamport定义了一个“先发生”(Happens-before)关系来表达事件间的先后顺序[50,72]。
表达式a->b读作“a在b之前发生”,意思是所有进程一致认为事件a先发送,然后事件b才发生。这种先发生关系有两种情况:
(1)如果a和b是同一进程中的两个事件,且a在b之前发生,则a->b为真。
(2)如果a是一个进程发送消息的事件,而b为另一个进程接收这个消息的事件,则a->b也为真。消息不可能在发送之前就被接收,也不能在发送的同时被接收,这是因为消息需要一定时间才能到达接收端。
先发生关系是一个传递关系,所以若a->b且 b->c,则a->c。如果事件x和y发生在两个互不交换消息的进程中(也不通过第三方间接交换消息),那么x->y不真,y->x也同样不真。这两个事件称为并发,这意味着无法描述这两个事件什么时候发生,哪一个先发生。