分布式事务性能分析

标签: 分布 性能分析 | 发表时间:2011-07-16 09:22 | 作者:风轻扬 wangdei
出处:http://wangyuanzju.blog.163.com
这两年来,随着NoSQL系统、CAP理论和Eventual Consistency的大热,关于分布式操作要保证强一致还是弱一致性的讨论络驿不绝。双方各执一词,倾向实现强一致性的一方认为弱一致性满足不了应用开发的需要,倾向实现弱一致性的一方则认为保证强一致性将导致系统性能与可伸缩性难以接受。弱一致性能否满足应用开发的需求这一点由应用特征决定,难以一概而论,但强一致性对系统性能、可伸缩性和可用性的影响则是可以作技术分析的。奇怪的是,找了很久,也没找到对这一问题的深入分析,决定自己来做一个。

对于分布式操作,一般来说有以下两种实现选择:
1、    在每个节点上使用单独的事务,只实现弱一致性。
2、    使用2PC保证强一致性。即分布式事务协调者先要求所有参与节点PREPARE,大家都说PREPARE成功后,再要求所有节点COMMIT。只要有一个节点PREPARE不成功,大家都要回滚。这样参与者要强制写两次日志,协调者在决定要COMMIT时也要强制写一次日志。

首先,假设用户发起分布式操作的速率为TpS(Transactions per Second),每个分布式操作平均会操作K个节点。在每个节点上,平均要操作RpT(Rows per Transaction)条记录,而操作每条记录平均要用时TpR(Time per Row),这样在每个节点上事务操作的执行时间为:
    TExec=RpT×TpR
另外,设定以下参数:
- N:数据库中所有节点上的总记录数
- TCommit:在每个节点上PREPARE或COMMIT的时间,PREPARE和COMMIT的主要工作都是写相应的日志,执行时间接近

对分布式操作性能方面一种常见的认识是若使用2PC,将导致事务执行时间大为延长,从而导致过高的事务并发冲突和死锁。当然,从趋势上使用2PC自然会导致并发冲突和死锁增长,但是否能满足应用需求,需要定量的来分析。由于死锁的概率完全取决于冲突概率,以下只分析冲突概率。

对选择1,即每个节点用独立事务时,用户发起的每个事务都会被分成K个小事务,这时系统中的并发事务数是事务速率与事务持续时间之积,即:
    CT_1=TpS×K×(RpT×TpR+TCommit)
当某事务要锁定并操作某条记录时,系统中被其它事务所锁定的记录数是(CT_1-1)×RpT≈CT_1×RpT。假设事务操作的记录是纯随机的,则该事务要锁定的记录与其它事务冲突的概率是(CT_1×RpT)/N。而这个事务总共要锁定RpT条记录,则该事务与其它事务冲突的概率是:
    TWait_1=1-(1-(CT_1×RpT)?N )^RpT≈CT_1×RpT^2/N

对选择2,即使用2PC保证强一致性时,每个节点上需要强制写两次日志,在事务协调者上还要强制写一次PREPARE日志(事务协调者上的COMMIT日志不需要强制写,这一时间可以忽略)。系统中的并发事务数是:
    CT_2=TpS×((RpT×TpR+2×TCommit)×K+TCommit)
但此时系统中被其它事务所锁定的记录数是选择1的K倍,且事务要锁定的记录数也是选择1的K倍,这时事务的冲突概率是:
    TWait_2≈CT_2×RpT^2×K^2/N
这个公式比较复杂,我们先简化一下,假设TCommit和TPrepare时间相对于TExec来说可以忽略,则可以得到有:
    TWait_2=TWait_1×K^2
也就是说事务冲突的概率将会随着分布式操作涉及的节点数K的平方数增长。平方数增长听起来比较厉害,但实际上在真实应用中K通常是很小的,绝大多数情况下等于2。如经典的转账问题,就只涉及两个节点,还有比如建立好友关系时也只涉及两个节点。在使用我们分布式数据库的大量应用中(总共包含约500张表,上千个索引,几千种SQL模式),绝大多数情况下K为2,很少有3,超过3的更是绝无仅有。因此,如果我们忽略2PC PREPARE和提交的时间,则使用2PC时会导致事务冲突概率4~9倍的增长。

换一种情况,如果执行很快但提交写日志很慢,即TExec相对于TCommit来说可以忽略,则可以得到:
    TWait_2=TWait_1×(2×K+1)/K×K^2
这时的情况比只考虑执行时间时差一些,但还是随着分布式操作涉及的节点数K的平方数增长,只不过从4~9倍变成10~21倍。

真实的情况一般在这两者之间,作为估算,可以大致认为采用2PC保证强一致性时将导致事务冲突概率增加8倍左右。

性能方面还涉及到吞吐率和响应时间。类似的进行分析,可以发现如果TCommit相对于TExec可以忽略,则响应时间不受2PC影响,反之,则2PC会导致响应时间增加为原来的3倍,平均的估计可以取增加1倍。对大多数应用,日志提交的吞吐率完全足够,则事务吞吐率不受2PC影响,反之,事务吞吐率会下降一半。

对大多数WEB应用冲突概率非常低,分布式操作只涉及2~3个节点,日志提交的吞吐率完全足够,则使用2PC可能带来的影响是事务冲突与死锁增加8倍左右,响应时间延长1倍,吞吐率不受影响。这些性能影响应该说是完全可以接受的,此时2PC带来的强一致性优点可以说远远超过其对性能的影响。

当然,以上分析中忽略了很多因素,比如网络延时,比如客户端在发起事务的多个操作之间还可能休息一会。加入这些因素后的性能分析会更复杂,但这些因素,本质上是使事务的持续时间增加,跟是否使用2PC无关。使用2PC与不使用2PC之间的性能差异比例,与这些因素关系不大。

但有一个问题需要注意。如果让客户端直接充当分布式事务的协调者,由于客户端上通常不像数据库服务器那样配置带电池的写缓存,fsync的性能很差,2PC将导致简单分布式事务的响应时间增加一个数量级,冲突概率更是可能增加两个数量级,事务提交的吞吐率也可能受到影响。解决方法是部署专职的高性能分布式事务协调者集群,配置高性能的日志存储设备如SSD。

基于这一基本的性能分析,还有一些变种:
1、如果分布式操作在各节点上并行执行,可以计算出冲突概率将是不并行的1/K。这仍比不用2PC串行高K倍,但不再是K的平方倍。比如BigTable中对二级索引和主记录的修改,就可以并行。
2、如果分布式操作是否冲突只取决于其中一个节点,可以计算出2PC并不会导致冲突概率显著增加。符合这一特征的应用模式还是BigTable中对主记录及其所有二级索引的修改,冲不冲突,完全取决于是否更新同一条记录,跟索引无关。
根据这两点也可以看出,如果用并行的2PC来保证主记录及其二级索引之间的一致性,其所带来的性能影响弱于2PC对一般分布式事务的影响,是完全可以实用的方案。

对使用2PC分布式事务的另外一个比较大的担心是如果2PC在PREPARE之后事务协调者崩溃,则参与分布式事务的各个节点只能长时间的锁定资源,等待协调者复活后告诉它事务应该提交还是回滚。如果直接让客户端直接充当分布式事务的协调者,这一问题可能很严重,因为客户端多而杂,崩溃概率高。但如果部署了专职的高性能分布式事务协调者集群,则这一问题基本可以避免。

相关 [分布 性能分析] 推荐:

分布式事务性能分析

- wangdei - 风轻扬
这两年来,随着NoSQL系统、CAP理论和Eventual Consistency的大热,关于分布式操作要保证强一致还是弱一致性的讨论络驿不绝. 双方各执一词,倾向实现强一致性的一方认为弱一致性满足不了应用开发的需要,倾向实现弱一致性的一方则认为保证强一致性将导致系统性能与可伸缩性难以接受. 弱一致性能否满足应用开发的需求这一点由应用特征决定,难以一概而论,但强一致性对系统性能、可伸缩性和可用性的影响则是可以作技术分析的.

Android应用性能 分析

- - CSDN博客推荐文章
  其实主要是内存方面,内存管理是个永恒的话题. 1.从工具DDMS中,在Sysinfo的tab栏里面有一个Memory usage的选项,通过USB连接Android设备以后很容易抓到图. 在图中可以看到系统随时可以用的内存是Free和Buffers两项,因为我抓图的系统只有128M的内存,所以看上去这部分可用内存已经很少了.

lucene MoreLikeThis性能分析

- - 七磅-d0evi1
最近使用lucene的MoreLikeThis实现一个小型的推荐系统. 语料由短文本构成,本身也还算比较中小等规模:7000w左右(亿级别)的数据量,3G大小的文件. 对需要的Field建完索引后的索引文件大小在4G左右. 本文只是结合自己的实践列出一些注意事项,以做为参考. 一、MoreLikeThis实现原理.

Akka简单性能分析

- - 并发编程网 - ifeve.com
因为最近工作的关系,要把异步任务从应用服务器中拆分到专门的异步处理服务器中. 是采用MQ的方式将任务消息发出,在服务端进行处理,如下图所示:. 这种方案是采用MQ作为中间的媒介,在服务端采用线程池异步处理任务,处理完成之后将结果发送到MQ中,客户端采用侦听的方式得到结果继续进行处理. 这种方案的不足是,可能在某些需求的情况下,需要将结果存放到共享的HashMap或者Threadlocal中进行存放结果,客户端会一直阻塞,直到得到结果,从多线程的角度来说,还是用了共享变量,虽然共享变量可能是线程安全的,但是从并发模型的角度来讲,并不是一个最好的方式.

leveldb性能分析和表现

- Adam - Erlang非业余研究
原创文章,转载请注明: 转载自Erlang非业余研究. 本文链接地址: leveldb性能分析和表现. Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了. 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计. 那么数据库最怕的的随机IO他是如何解决的呢.

Rails3中的性能分析方法

- - Taobao QA Team
(转帖请注明出处: http://qa.taobao.com/?p=15025). 性能分析是Web应用开发中非常重要的一个环节,相比访问缓慢的站点,访问快速的站点拥有更好的用户体验,帮助用户节省更多时间,带来更多的用户访问. 作为当前十分流行的Web框架, rubyonrails当然也提供很多方式进行性能分析.

【转载】HTML5性能分析面面观

- - HTML5研究小组
从性能角度来说,HTML5首先是缩减了HTML文档,使这件事情变得更简单. 第一,从用户可读性上说,原先一大堆东西,像初学者第一次看到这些东西是看不懂的,而HTML5的声明方式对用户来说显然更友好一些. 第二,文档编码的声明,用HTML5方式的话,就很简单. 我们说可以先用HTML5的方式就是把DOCTYPE先改了,因为目前很多页面都还是用传统的方式.

[转][转]LevelDB性能分析和表现

- - heiyeluren的Blog
LevelDB是一个Google开发的速度飞快的数据库键值存储引擎,可按照字符串键值顺序映射. 2011年7月30日 Google宣布按照BSD许可 开源LevelDB. LevelDB是一个C++库,可用于很多情况. 比如用于一个网页浏览器存储最近存取网页的缓存,或用于操作系统存储安装包列表,或用于应用存储用户的设置参数.

Java可变参数的性能分析

- - Java译站
可变长参数列表是Java 5中的一个新特性. 如果方法需要传入多个同类型参数的话,这个功能就非常有用. 比如说,Java 5之前如果要写一个方法来将所有入参打印到控制台上的话,它的代码会是这样的:. Java 5增加了对可变参数的支持. 这个方法现在看起来就简单多了(译注:这里看起来简单难道不是因为新的for循环.