仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 708|回复: 8
打印 上一主题 下一主题

[学习教程] 利用动静使用形态和动静行列表来取代散布式事件

[复制链接]
再现理想 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 14:07:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
为多种编程语言提供了API。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。因为数据量的伟大,年夜部分Web使用都必要部署良多个数据库实例。如许,有些用户操纵便可能必要往修正多个数据库实例中的数据。传统的办理办法是利用散布式事件包管数据的全局分歧性,典范的办法是利用两阶段提交协定。

临时以来,散布式事件供应的文雅的全局ACID包管麻醉了使用开辟者的心灵,良多人都不敢越雷池一步,想像没有散布式事件的天下会是如何。现在就如MySQL和PostgreSQL这类面向低端用户的开源数据库都撑持散布式事件了,开辟者更是沉浸个中,不往思索散布式事件是不是给体系带来了危险。

现实上,有所得必有所掉,散布式事件供应的ACID包管是以伤害体系的可用性、功能与可伸缩性为价值的。只要在介入散布式事件的各个数据库实例都可以一般事情的条件下,散布式事件才干够顺遂完成,只需有一个事情不一般,全部事件就不克不及完成。如许,体系的可用性就相称于列入散布式事件的各实例的可用性之积,实例越多,可用性下落越分明。从功能和可伸缩性角度看,起首是事件的总延续工夫一般是各实例操纵工夫之和,由于一个事件中的各个操纵一般是按次实行的,如许事件的呼应工夫就会增添良多;其次是一样平常Web使用的事件都不年夜,单机操纵工夫也就几毫秒乃至不到1毫秒,一但触及到散布式事件,提交时节点间的收集通讯往复历程也为毫秒级别,对事件呼应工夫的影响也不成无视。因为事件延续工夫延伸,事件对相干资本的锁准时间也响应增添,从而大概严峻增添了并发抵触,影响到体系吞吐率和可伸缩性。

恰是因为散布式事件有以上成绩,eBay在计划上就不接纳散布式事件,而是经由过程别的路子来办理数据分歧性成绩。个中利用的最主要的手艺就是动静行列和动静使用形态表。

举个例子。假定体系中有以下两个表
user(id,name,amt_sold,amt_bought)
transaction(xid,seller_id,buyer_id,amount)
个中user表纪录用户买卖汇总信息,transaction表纪录每一个买卖的具体信息。

如许,在举行一笔买卖时,若利用事件,就必要对数据库举行以下操纵:
begin;
INSERTINTOtransactionVALUES(xid,$seller_id,$buyer_id,$amount);
UPDATEuserSETamt_sold=amt_sold+$amountWHEREid=$seller_id;
UPDATEuserSETamt_bought=amt_bought+$amountWHEREid=$buyer_id;
commit;

即在transaction表中纪录买卖信息,然后更新卖家和买家的形态。

假定transaction表和user表存储在分歧的节点上,那末上述事件就是一个散布式事件。要打消这一散布式事件,将它拆分红两个子事件,一个更新transaction表,一个更新user表是不可的,由于有大概transaction表更新乐成后,更新user失利,体系将不克不及恢复到分歧形态。

办理计划是利用动静行列。以下所示,先启动一个事件,更新transaction表后,其实不间接往更新user表,而是将要对user表举行的更新拔出到动静行列中。别的有一个异步义务轮询行列内容举行处置。
begin;
INSERTINTOtransactionVALUES(xid,$seller_id,$buyer_id,$amount);
put_to_queue"updateuser("seller",$seller_id,amount);
put_to_queue"updateuser("buyer",$buyer_id,amount);
commit;
foreachmessageinqueue
begin;
dequeuemessage;
ifmessage.type="seller"then
UPDATEuserSETamt_sold=amt_sold+message.amountWHEREid=message.user_id;
else
UPDATEuserSETamt_bought=amt_bought+message.amountWHEREid=message.user_id;
end
commit;
end

上述办理计划看似完善,实践上还没有办理散布式成绩。为了使第一个事件不触及散布式操纵,动静行列必需与transaction表利用统一套存储资本,但为了使第二个事件是当地的,动静行列存储又必需与user表在一同。这二者是不成能同时满意的。

假如动静具有操纵幂等性,也就是一个动静被使用屡次与使用一次发生的效果是一样的话,上述成绩是很好办理的,只需将动静行列放到transaction表一同,然后在第二个事件中,先使用动静,再从动静行列中删除。因为动静行列存储与user表不在一同,使用动静后,大概还没来得及将使用过的动静从行列中删除时体系就出妨碍了。这时候体系恢复后会从头使用一次这一动静,因为幂等性,使用屡次也能发生准确的了局。

但实践情形下,动静很难具有幂等性,好比上述的UPDATE操纵,实行一次和实行屡次的停止明显是纷歧样的。办理这一成绩的办法是利用另外一个表纪录已被乐成使用的动静,而且这个表利用与user表不异的存储。假定增添以下表message_applied(msg_id)纪录被乐成使用的动静,则发生终极的办理计划以下:
begin;
INSERTINTOtransactionVALUES(xid,$seller_id,$buyer_id,$amount);
put_to_queue"updateuser("seller",$seller_id,amount);
put_to_queue"updateuser("buyer",$buyer_id,amount);
commit;
foreachmessageinqueue
begin;
SELECTcount(*)ascntFROMmessage_appliedWHEREmsg_id=message.id;
ifcnt=0then
ifmessage.type="seller"then
UPDATEuserSETamt_sold=amt_sold+message.amountWHEREid=message.user_id;
else
UPDATEuserSETamt_bought=amt_bought+message.amountWHEREid=message.user_id;
end
INSERTINTOmessage_appliedVALUES(message.id);
end
commit;
if上述事件乐成
dequeuemessage
DELETEFROMmessage_appliedWHEREmsg_id=message.id;
end
end

我们来细心剖析一下:
1、动静行列与transaction利用统一实例,因而第一个事件不触及散布式操纵;
2、message_applied与user表在统一个实例中,也能包管分歧性;
3、第二个事件停止后,dequeuemessage之前体系大概出妨碍,出妨碍后体系会从头从动静行列中掏出这一动静,但经由过程message_applied表能够反省出来这一动静已被使用过,跳过这一动静完成准确的举动;
4、最初将已乐成使用,且已从动静行列中删除的动静从message_applied表中删除,能够将message_applied表包管在很小的形态(不扫除也是能够的,不影响体系准确性)。因为动静行列与message_applied在分歧实例上,dequeuemessage以后,将对应message_applied纪录删除之前大概出妨碍。一但这时候呈现妨碍,message_applied表中会留下一些渣滓内容,但不影响体系准确性,别的这些渣滓内容也是能够准确清算的。

固然因为没有散布式事件的强分歧性包管,利用上述计划在体系产生妨碍时,体系将短工夫内处于纷歧致形态。但基于动静行列和动静使用形态表,终极能够将体系恢复到分歧。利用动静行列计划,排除了两个数据库实例之间的严密耦合,其功能和可伸缩性是散布式事件不成对比的。

固然,利用散布式事件有助于简化使用开辟,利用动静行列分明必要更多的事情量,二者各有优弱点。团体概念是,关于工夫紧急大概对功能请求不高的体系,应接纳散布式事件加速开辟效力,关于工夫需求不是很紧,对功能请求很高的体系,招考虑利用动静行列计划。关于原利用散布式事件,且体系已趋于不乱,功能请求高的体系,则可使用动静行列计划举行重构来优化功能

注:本文次要取材于eBay的工程师DanPritchet写的这篇文章。先说DDL的分类。有一类DDL,是不需要重建表的,比如加非聚簇索引。这类操作其实不会丢数据,也是在原表上直接操作,对于我们“以恢复数据为目的”的闪回,是可以先忽略的。另外一类,则是会影响到表数据的操作。
灵魂腐蚀 该用户已被删除
沙发
发表于 2015-1-18 12:00:08 | 只看该作者
光写几个SQL实在叫无知。
不帅 该用户已被删除
板凳
发表于 2015-1-25 20:35:37 | 只看该作者
一个百万级别的基本信息表A,一个百万级别的详细记录表B,A中有个身份证id,B中也有身份id;先要找出A中在B的详细记录。
乐观 该用户已被删除
地板
发表于 2015-2-4 02:53:36 | 只看该作者
一直以来个人感觉SQLServer的优化器要比Oracle的聪明。SQL2005的更是比2k聪明了不少。(有次作试验发现有的语句在200万级时还比50万级的相同语句要快show_text的一些提示没有找到解释。一直在奇怪。)
精灵巫婆 该用户已被删除
5#
发表于 2015-2-9 12:33:12 | 只看该作者
在select语句中可以使用groupby子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。
admin 该用户已被删除
6#
发表于 2015-2-27 07:43:25 | 只看该作者
如果是将来做数据库的开发设计,就应该详细学习T-SQL的各种细节,包括T-SQL的程序设计、存储过程、触发器以及具体使用某个开发语言来访问数据库。
谁可相欹 该用户已被删除
7#
发表于 2015-3-9 01:09:18 | 只看该作者
语句级快照和事务级快照终于为SQLServer的并发性能带来了突破。个人感觉语句级快照大家应该应用。事务级快照,如果是高并发系统还要慎用。如果一个用户总是被提示修改不成功要求重试时,会杀人的!
再见西城 该用户已被删除
8#
发表于 2015-3-16 21:25:07 | 只看该作者
然后最好有实践机会,能够把实践到的和实践结合起来,其实理论思考是个非常困扰和痛苦的事情
兰色精灵 该用户已被删除
9#
发表于 2015-3-23 05:21:34 | 只看该作者
以前的DTS轻盈简单。但是现在的SSIS虽然功能强大了很多,但是总是让人感觉太麻烦。看看论坛中询问SSIS的贴子就知道。做的功能太强大了,往往会有很多用户不会用了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-22 23:35

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表