MyException - 我的异常网
当前位置:我的异常网» 互联网 » 互联网络一致性架构设计 - 消息时序一致性

互联网络一致性架构设计 - 消息时序一致性

www.MyException.Cn  网友分享于:2013-09-28  浏览:0次
互联网一致性架构设计 -- 消息时序一致性

互联网一致性架构设计 -- 消息时序一致性

 

 

为什么时序难以保证,消息一致性难?

 

 

    原因

 

  • 时钟不一致
  • 多客户端(发送方)
  • 服务集群(多接收方)
  • 网络传输与多线程

 

    时钟不一致

 

       分布式环境下,有多个客户端、有web集群、service集群、db集群,他们都分布在不同的机器上,机器之间都是使用的本地时钟,而没有一个所谓的“全局时钟”,所以不能用“本地时间”来完全决定消息的时序。



 

 

   

    多客户端(发送方)

 

       绝对时序上,APP1先发出msg1,APP2后发出msg2,都发往服务器web1,网络传输是不能保证msg1一定先于msg2到达的,所以即使以一台服务器web1的时间为准,也不能精准描述msg1与msg2的绝对时序。


     
 

 

 

    服务集群(多接收方)

 

       绝对时序上,web1先发出msg1,后发出msg2,由于网络传输及多接收方的存在,无法保证msg1先被接收到先被处理,故也无法保证msg1与msg2的处理时序。



 

 

 

    网络传输与多线程

 

       web1先发出msg1,后发出msg2,即使msg1先到达(网络传输其实还不能保证msg1先到达),由于多线程的存在,也不能保证msg1先被处理完。



 

 

 

    怎么保证绝对时序

 

       可以通过只有一个发送方,一个接收方,上下游连接只有一条连接池,通过阻塞的方式通讯,来保证先发出的消息先处理。但是吞吐量会非常低,而且单发送方单接收方单连接池的假设不太成立,高并发高可用的架构不会允许这样的设计出现。

 

 

 

 

 

优化方案

 

    以客户端或者服务端的时序为准

 

       要“有序”,先得有衡量“有序”的标尺,可以是客户端标尺,可以是服务端标尺。

 

       多客户端、多服务端导致“时序”的标准难以界定,需要一个标尺来衡量时序的先后顺序,可以根据业务场景,以客户端或者服务端的时间为准,例如:

 

  1. 邮件展示顺序,其实是以客户端发送时间为准的,潜台词是,发送方只要将邮件协议里的时间调整为1970年或者2970年,就可以在接收方收到邮件后一直“置顶”或者“置底”
  2. 秒杀活动时间判断,肯定得以服务器的时间为准,不可能让客户端修改本地时间,就能够提前秒杀

 

 

    服务端能够生成单调递增的id

 

       这个是毋庸置疑的,不展开讨论,例如利用单点写db的seq/auto_inc_id肯定能生成单调递增的id,只是说性能及扩展性会成为潜在瓶颈。对于严格时序的业务场景,可以利用服务器的单调递增id来保证时序。

 

 

 

    大部分业务能接受误差不大的趋势递增id

 

       消息发送、帖子发布时间、甚至秒杀时间都没有这么精准时序的要求:

 

  1. 同1s内发布的聊天消息时序乱了
  2. 同1s内发布的帖子排序不对
  3. 用1s内发起的秒杀,由于服务器多台之间时间有误差,落到A服务器的秒杀成功了,落到B服务器的秒杀还没开始,业务上也是可以接受的(用户感知不到)

       所以,大部分业务,长时间趋势递增的时序就能够满足业务需求,非常短时间的时序误差一定程度上能够接受。

 

 

 

    利用单点序列化,可以保证多机相同时序

 

  1. 先在一台机器上序列化操作
  2. 再将操作序列分发到所有的机器,以保证多机的操作序列是一致的,最终数据是一致的

    单点序列化,是一种常见的保证多机时序统一的方法,典型场景有db主从一致,gfs多文件一致。

 

 

    典型场景一:数据库主从同步

 


 

       数据库的主从架构,上游分别发起了op1,op2,op3三个操作,主库master来序列化所有的SQL写操作op3,op1,op2,然后把相同的序列发送给从库slave执行,以保证所有数据库数据的一致性,就是利用“单点序列化”这个思路。

 

 

    典型场景二:GFS中文件的一致性



 

       GFS(Google File System)为了保证文件的可用性,一份文件要存储多份,在多个上游对同一个文件进行写操作时,也是由一个主chunk-server先序列化写操作,再将序列化后的操作发送给其他chunk-server,来保证冗余文件的数据一致性的。

 

 

 

    单对单聊天,怎么保证发送顺序与接收顺序一致

 

       只需保证发出的时序与接收的时序一致,可以利用客户端seq。

 

  1. 如果利用服务器单点序列化时序,可能出现服务端收到消息的时序为msg3,msg1,msg2,与发出序列不一致
  2. 业务上不需要全局消息一致,只需要对于同一个发送方A,ta发给B的消息时序一致就行,常见优化方案,在A往B发出的消息中,加上发送方A本地的一个绝对时序,来表示接收方B的展现时序


 

       潜在问题:如果接收方B先收到msg3,msg3会先展现,后收到msg1和msg2后,会展现在msg3的前面。无论如何,是按照接收方收到时序展现,还是按照服务端收到的时序展现,还是按照发送方发送时序展现,是pm需要思考的点,技术上都能够实现(接收方按照发送时序展现是更合理的)。

 

 

 

    群聊消息,怎么保证各接收方收到顺序一致

 

       只需保证所有接收方消息时序一致,需要利用服务端seq,方法有两种,一种单点绝对时序,另一种id串行化。

 

    方法一:服务器单点

 

  1. sender1发出msg1,sender2发出msg2
  2. msg1和msg2经过接入集群,服务集群
  3. service层到底层拿一个唯一seq,来确定接收方展示时序
  4. service拿到msg2的seq是20,msg1的seq是30
  5. 通过投递服务讲消息给多个群友,群友即使接收到msg1和msg2的时间不同,但可以统一按照seq来展现

     
 

    缺点:这个生成全局递增序列号的服务很容易成为系统瓶颈。

 

 

    方法二:根据id穿行化

 

       service层不再需要去一个统一的后端拿全局seq,而是在service连接池层面做细小的改造,保证一个群的消息落在同一个service上,这个service就可以用本地seq来序列化同一个群的所有消息,保证所有群友看到消息的时序是相同的。



 

 

 

 

总结

 

    1. 分布式环境下,消息的有序性是很难的,原因多种多样:时钟不一致,多发送方,多接收方,多线程,网络传输不确定性等

 

    2. 要“有序”,先得有衡量“有序”的标尺,可以是客户端标尺,可以是服务端标尺

 

    3. 大部分业务能够接受大范围趋势有序,小范围误差;绝对有序的业务,可以借助服务器绝对时序的能力

 

    4. 单点序列化,是一种常见的保证多机时序统一的方法,典型场景有db主从一致,gfs多文件一致

 

    5. 单对单聊天,只需保证发出的时序与接收的时序一致,可以利用客户端seq

 

    6. 群聊,只需保证所有接收方消息时序一致,需要利用服务端seq,方法有两种,一种单点绝对时序,另一种id串行化

文章评论

程序员应该关注的一些事儿
程序员应该关注的一些事儿
 程序员的样子
程序员的样子
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
我是如何打败拖延症的
我是如何打败拖延症的
总结2014中国互联网十大段子
总结2014中国互联网十大段子
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
如何成为一名黑客
如何成为一名黑客
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
Java程序员必看电影
Java程序员必看电影
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员都该阅读的书
程序员都该阅读的书
漫画:程序员的工作
漫画:程序员的工作
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
一个程序员的时间管理
一个程序员的时间管理
每天工作4小时的程序员
每天工作4小时的程序员
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
程序员必看的十大电影
程序员必看的十大电影
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
10个调试和排错的小建议
10个调试和排错的小建议
鲜为人知的编程真相
鲜为人知的编程真相
代码女神横空出世
代码女神横空出世
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
旅行,写作,编程
旅行,写作,编程
程序员和编码员之间的区别
程序员和编码员之间的区别
中美印日四国程序员比较
中美印日四国程序员比较
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员的鄙视链
程序员的鄙视链
编程语言是女人
编程语言是女人
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
老程序员的下场
老程序员的下场
那些争议最大的编程观点
那些争议最大的编程观点
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有