- 1、本文档共13页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
微信序列号生成器架构设计精要
微信序列号生成器架构设计
使用场景
1、高(增量)数据同步要求(数据库双活等)
2、高数据排序要求(交易消息发送等)
3、海量请求
系统背景
微信服务器端为每一份需要与客户端同步的数据(例如消息)都会赋予一个唯一的、递增的序列号(后文称为sequence),作为这份数据的版本号。在客户端与服务器端同步的时候,客户端会带上已经同步下去数据的最大版本号,后台会根据客户端最大版本号与服务器端的最大版本号,计算出需要同步的增量数据,返回给客户端。这样不仅保证了客户端与服务器端的数据同步的可靠性,同时也大幅减少了同步时的冗余数据。
技术介绍
从seqsvr申请的、用作数据版本号的sequence,具有两种基本的性质:
1、递增的64位整型变量
2、每个用户都有自己独立的64位sequence空间( sequence非全局变量,数据极致分区,避免申请请求互斥)
举个例子,小明当前申请的sequence为100,那么他下一次申请的sequence,可能为101,也可能是110,总之一定大于之前申请的100。而小红呢,她的sequence与小明的sequence是独立开的,假如她当前申请到的sequence为50,然后期间不管小明申请多少次sequence怎么折腾,都不会影响到她下一次申请到的值(很可能是51)。
架构原型
不考虑seqsvr的具体架构的话,它应该是一个巨大的64位数组,而我们每一个微信用户,都在这个大数组里独占一格8bytes的空间,这个格子就放着用户已经分配出去的最后一个sequence:cur_seq。每个用户来申请sequence的时候,只需要将用户的cur_seq+=1,保存回数组,并返回给用户。
架构原型
面对海量请求的场景,seq只要求递增,并不要求连续,也就是说出现一大段跳跃是允许的(例如分配出的sequence序列:1,2,3,10,100,101)。于是有一个简单优雅的策略:
1.内存中储存最近一个分配出去的sequence:cur_seq,以及分配上限:max_seq
2.分配sequence时,将cur_seq++,同时与分配上限max_seq比较:如果cur_seq max_seq,将分配上限提升一个步长max_seq += step,并持久化max_seq至硬盘(不持久化cur_seq ,因海量写,I/O瓶颈无硬盘系统可以支持,且无必须性)
3.重启时,读出持久化的max_seq,赋值给cur_seq(避免seq冲突)
架构原型
引入号段Section的概念,uid相邻的一段用户属于一个号段,而同个号段内的用户共享一个max_seq,这样大幅减少了max_seq数据的大小,同时也降低了IO次数。
避免重启加载max_seq因数据过大无法快速恢复。
1、把存储层和缓存中间层分成两个模块StoreSvr及AllocSvr。StoreSvr为存储层,利用了多机NRW策略来保证数据持久化后不丢失;AllocSvr则是缓存中间层,部署于多台机器,每台AllocSvr负责若干号段的sequence分配,分摊海量的sequence申请请求。
2、整个系统又按uid范围进行分Set,每个Set都是一个完整的、独立的StoreSvr+AllocSvr子系统。分Set设计目的是为了做灾难隔离,一个Set出现故障只会影响该Set内的用户,而不会影响到其它用户。
分布式设计
容灾设计
seqsvr最核心的点是什么呢?每个uid的sequence申请要递增不回退。这里我们发现,如果seqsvr满足这么一个约束:任意时刻任意uid有且仅有一台AllocSvr提供服务,就可以比较容易地实现sequence递增不回退的要求。
存在单点问题的系统可参考一下容灾设计。
seqsvr所有模块使用了统一的路由表,描述了uid号段到AllocSvr的全映射。这份路由表由仲裁服务根据AllocSvr的服务状态生成,写到StoreSvr中,由AllocSvr当作租约读出,最后在业务返回包里旁路给Client端。
容灾设计
灵活的容灾策略,让所有机器都互为备机,在机器故障时,把故障机上的号段均匀地迁移到其它可用的AllocSvr上;还可以根据AllocSvr的负载情况,进行负载均衡,有效缓解AllocSvr请求不均的问题,大幅提升机器使用率
仲裁机制
为了避免失联AllocSvr提供错误的服务,返回脏数据,AllocSvr需要跟StoreSvr保持租约。这个租约机制由以下两个条件组成:
租约失效:AllocSvr N秒内无法从StoreSvr读取加载配置时,AllocSvr停止服务
租约生效:AllocSvr读取到新的加载配置后,立即卸载需要卸载的号段,需要加载的新号段等待N秒后提供服务
路由同步优化
把路由表嵌入到取sequence的请
文档评论(0)