热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

分布式消息_58分布式消息队列WMB设计与实践

篇首语:本文由编程笔记#小编为大家整理,主要介绍了58分布式消息队列WMB设计与实践相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了58分布式消息队列WMB设计与实践相关的知识,希望对你有一定的参考价值。






背景


为了能够承载58业务的快速扩展及海量的用户访问,分布式系统已经成为公司一种主流架构设计。而消息队列是大型分布式系统中不可或缺的通信桥梁,在分布式系统解耦、异步通信、事件通知、流量削峰等业务场景中起着重要作用。


现常见的开源消息队列有Kafka、RocketMQ、RabbitMQ等,都有着不同的使用场景和特点。RabbitMQ采用erlang 语言开发,具有较高的可靠性,但是性能较差;kafka突出的特点是高吞吐量,但不能保证消息投递的低延迟,多用于日志数据的上报;当前比较流行的RocketMQ,在可靠性和高吞吐特性上做了平衡,但开源版本不支持一主多从数据的强一致性及主从自动切换。在58业务发展之初,开源的MQ 尚不成熟,根据当时公司技术栈特点,参考了ActiveMQ设计,自主研发了一套功能单一的消息队列ESB,但不支持所有消息的持久化,可靠性较低,静态配置不易扩展、客户端故障消息丢失、buffer堆积等问题层出不穷。


WMB是在兼容ESB基础上进行了两阶段大的重构开发,第一阶段重在提升服务可用性,完善服务端存储结构、添加了注册中心、Collector收集器、可视化管理平台等模块,在此基础上丰富了消息发送/订阅方式、配置动态扩展、可视化细粒度立体监控、消息查询等功能,并对多语言客户端(Java、php、C/C++、Go)提供了支持;第二阶段重在提升服务可靠性,引入一致性算法Paxos,实现了主从强一致性、主从秒级自动切换等能力,该版本能够同时满足高数据可靠性,且不失高可用和高吞吐的场景。




整体架构


58分布式消息队列WMB设计与实践

图1 整体架构



  • 消息发送方:提供了高并发的异步发送,以及多种不同可靠级别的同步发送方式;


  • 消息订阅方:提供了推送、拉取订阅方式,分别保证“至多一次”与“至少一次”消息投递。另外还支持回溯消费、延迟消费、定时消费、重试消费、广播消费等灵活可靠的消费方式;


  • 服务端:对接收到的消息多副本持久化存储,并提供消费队列动态负载均衡、毫秒级延迟推送、主从消息强一致、主从秒级自动切换等能力;


  • 注册中心:负责客户端与服务端配置管理,从而支持集群动态扩/缩容、快速增删主题、发送方秒级限速控制等功能;


  • Collector收集器:负责收集服务端定时上报的主题收发量、消费进度、在线状态等信息,并提供实时告警功能;


  • 可视化管理平台:为管理员和业务提供了资源管理、权限控制、流量实时展示、消费进度查询等完备的运维平台,同时支持消息模糊查询、全链路消息轨迹跟踪等功能方便排查问题。





集群架构


58分布式消息队列WMB设计与实践

图2 集群架构


58分布式消息队列WMB设计与实践

表1 主题分布




  • 每个服务集群有多个store单元,非顺序消息通过轮询方式均匀发送到每个store;


  • 每个store部署多个数据强一致的server节点,每个server节点包含多个相同的Paxos group;


  • 每个Paxosgroup的master节点可能为store内的任何server节点,同store的server节点互为主备,每个group有独立的一套存储单元;


  • 集群下每个主题隶属于其中某一个Paxos group,由Paxos group的master节点发起消息的批量有序commit;


  • WMB采用的Paxos算法组件为WPaxos,参考了微信开源生产级Paxos类库PhxPaxos,并做了调整和优化,采用Java开发实现。



下面介绍下,在以上架构基础上WMB如何保证服务的高可靠、高可用与高性能。



高可靠性

 

发送可靠性


WMB客户端提供了高并发的异步发送,以及多种不同ack级别的同步发送方式,消息发送过程如下图所示。


58分布式消息队列WMB设计与实践

图3 消息发送


业务调用客户端发送接口投递消息,客户端根据主题消息顺序性要求,选择主题所在集群某一个server节点发送消息。对于客户端发送的每条消息,正常情况下服务端都会返回ack,ack可选级别有send_ok,master_receive_ok,master_flush_ok,可靠性依次增强,异步发送方式可以在sendcallback回调中获取到发送结果,业务自定义发送失败处理逻辑,同步发送方式可以直接获取到发送结果,在同步发送请求超时之前,若存在消息发送失败,默认会重试3次发送,从而保证了消息的可靠发送。

 

存储可靠性


WMB的存储设计参考了开源消息队列RocketMQ与PhxQueue,存储过程如下图所示:

58分布式消息队列WMB设计与实践

图4 消息存储


WMB存储结构主要包括physic log、物理索引、消费队列consume queue三个部分,数据存储都采用mmap内存映射的方式,数据先写入pagecache再异步刷盘到物理文件。通过一致性算法Paxos做主从多副本数据同步


其中,每个paxos group共享physic log、物理索引存储单元,服务端将每个group的消息依次批量合并为BatchMsg,封装为一个新的数据实例instance,由paxos group的master节点发起instance数据同步申请,将instance数据封装在accept请求发向slave节点,等待slave节点返回accept结果,若在超时之前,收到过半节点(包括自己)接受了数据同步申请,再向所有节点发起commit请求,确认instance有效数据存储。若没有接收到过半节点accept返回成功,将延迟一段时间重新发起prepare请求进行二阶段数据提交,防止数据冲突。


Commit阶段主要是指状态机的回调执行,将封装在instance实例中的BatchMsg解析,获取单条消息的主题号以及在physic log中的offset、size、存储时间戳等元信息,分发到对应主题的某一个consume queue。只有当元信息被分发到consume queue存储成功后,消息才可能会被订阅方消费到,从而保证了多副本有效数据的一致性。


WMB通过引入Paxos算法,保证了主从数据的强一致性,当server节点故障,master可随机切换,主从节点数据能够快速对齐,大幅度降低了消息丢失率。

 

订阅可靠性


WMB提供了推送(push)、拉取(pull)订阅方式,分别保证“至多一次”与“至少一次”消息投递。

Push VS Pull

58分布式消息队列WMB设计与实践


订阅交互过程如下图所示:


58分布式消息队列WMB设计与实践

图5 消息订阅


每个主题在服务端默认有8个consume queue,可动态调整,相同clientID的不同client向服务端发起订阅,服务端会通过动态负载均衡机制,将consume queue尽量平均分配给每个client,每个queue最多只能分配给一个client消费,不同queue的消息可并行消费。


无论是推送模式还是拉取模式,当消息推送到客户端后,首先都放入本地接收队列message queue,同一个queue的消息会顺序执行messageReceiveHandler消费回调。


消息消费过程可靠性主要由以下几个机制保证:




  • 推送/拉取堆积控制



客户端实时统计本地接收队列消息量,超过阈值则停止拉取或者向Server发送停止推送命令,恢复时再继续拉或发送继续推送命令,防止出现大量消息堆积导致客户端内存溢出。




  • 消费ack



对于Pull消费方式,会定时向服务端提交消费offset,已经推送到客户端,没有提交消费ack的消息,重新初始化拉取时,会被再次推送到客户端,另外,消费失败的消息也可选择重试消费。




  • 重试消费



重试消费的消息会被订阅方重新发送到服务端,分配到对应clientID的重试消费队列,如图5中的队列10001(10000+ClientID),延迟一定时间后重新推送给客户端,一条消息最多可被重复消费6次。




  • 回溯消费



如果业务某段时间内存在大面积消息处理故障,可选择回溯消费,调整消费offset到故障前的时间点,重推消息。


小结


综上所述, 发送、存储、订阅的可靠性共同支撑了WMB服务的可靠性,采用同步发送或者异步发送+回调的方式、服务端高可靠消息持久化机制、订阅方拉取消费+ack确认方式,可以为业务提供一个完全不丢的消息通信链路。但可靠性带来的另外一个问题是消息重复,当发送或者消费过程因网络问题ack丢失,都可能会导致消息重发,目前WMB还不支持消息去重,去重逻辑交给业务去做幂等性实现。



高可用性


容灾能力


线上环境总会存在一些不可预知的故障,如服务器宕机、网络抖动、服务节点因未知bug挂掉等,WMB在异常情况下的容灾能力直接关系到服务的可用性。




  • 服务端容灾能力



如WMB集群架构所示,每个服务节点都可能会分布着一些paxos group的master节点与另外一些group的slave节点。若节点故障或者与store内其它节点网络隔离,master租约周期结束之前续约失败,master可能会漂到其它节点,发生主从自动切换。如果服务节点仅与store内部分节点网络出现抖动,通过过半节点的投票以及多个续约周期的判定,可以防止master随着网络抖动而发生多次不必要的切换。


58分布式消息队列WMB设计与实践

图6 容灾1


58分布式消息队列WMB设计与实践

图7 容灾2


如果master发生变更,会通过注册中心下发配置给客户端,客户端立即重连到新的master,降低了服务不可用时间。




  • 客户端容灾能力



WMB服务端采用集群部署结构,一个集群至少包括4个store单元,正常情况每个主题可用的master节点都会有多个。


如果客户端与服务节点之间出现网络中断,客户端能够立即感知到连接状态变化,会直接摘除该服务节点,再定期探测节点状态直至恢复。


如果客户端与服务节点出现网络抖动,连接状态正常,Master配置不会发生变化,客户端继续将请求发送到原有节点,这个时候请求有可能失败,客户端会将请求连续失败5次以上服务节点,自动踢除,再定期探测节点状态直至恢复。


横向扩展能力


WMB支持集群动态扩/缩容,当某集群负载较高时,可动态扩展store数量,增大集群容量,并对业务透明无感知。

 

过载保护能力


对于任何高并发的系统,在服务器资源有限的情况下,单位时间服务能力也是有限的,如果超过服务承受能力,可能会发生雪崩效应,造成整个服务crash。WMB提供了主题分布式限速机制,以及基于单点访问量与内存使用的过载保护能力,可对线上服务进行合理的容量规划。



高性能


高吞吐、低延迟是衡量分布式消息队列是否具有高性能的两个重要标准。下面介绍下WMB在提高性能方面做的一些优化。

 

批量化


批量化处理是提升WMB吞吐量的重要优化点,客户端将发向相同server的消息进行批量合并后发送,减少了网络开销,服务端将相同group的消息合并后,通过Paxos批量commit,同时减少了网络交互与写磁盘次数。

 

多分组存储


服务端将所有主题进行分组合并存储,不同分组可并行commit数据,提升了系统并发处理能力,但分组数过多又容易造成严重的写磁盘放大,通过性能压测对比,WMB最终将服务端分组数固定在9。

 

长轮询


WMB推送、拉取都采用长轮询机制,若没有消息到来,服务端会挂起推送任务或拉取请求,当有消息到来或者主题消费分配有变化时,立即异步通知,唤醒阻塞的拉取请求,继续推送消息,从而保证了消息投递的低延迟。

图8 长轮询拉取

 

Master负载均衡


在master随机切换的模式下,有可能会出现同一个store内master分布不均匀,对整个store的稳定性造成影响,为了解决这个问题,WMB添加了master平滑夺取机制,每次主从切换后,可在一定周期内实现master均衡分布,具体实现细节将在下篇文章中介绍。


在master均衡分布情况下,同一个store内的server节点对等部署,存储及消费压力均匀分配在每个节点,有效的降低了服务端消息处理延迟。

 

无论是推送还是拉取方式,在订阅方消费能力足够快时,WMB服务端从接收到一条消息到成功发送给订阅方,整个服务端消息处理延迟平均为4ms。在普通机械硬盘服务器上,512字节消息,WMB单个store的QPS可达23W。



总结


WMB为58自研的高可靠、高可用分布式消息队列,目前支撑了公司4000多个核心业务项目,每天流转300多亿数据,是58分布式架构中的重要组件。本文主要介绍了WMB的系统架构以及在高可靠、高可用、高性能方面的设计实践。由于篇幅限制,部分实现如动态扩/缩容机制、Master负载均衡机制、限流机制等没有详细展开介绍,还有消息顺序性、延时消息、消息广播等一些功能实现也没有提到,将在后面其它文章中详细介绍。




推荐阅读
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 熟练掌握Spring Cloud,终于成为Java工程师的面试门槛 ... [详细]
  • Java工程师书单(初级,中级,高级)
    简介怎样学习才能从一名Java初级程序员成长为一名合格的架构师,或者说一名合格的架构师应该有怎样的技术知识体系,这是不仅一个刚刚踏入职场的初级程序员也是工作一两年之后开始迷茫的程序 ... [详细]
  • php网站设计实验报告,php网站开发实训报告
    本文目录一览:1、php动态网站设计的关键技术有哪些软件,及搭建步骤需要哪些页面,分别完成 ... [详细]
  • 软件测试工程师,需要达到什么水平才能顺利拿到 20k+ 无压力?
    前言最近看到很多应届生晒offer,稍有名气点的公司给出的价格都是一年30多W或者月薪20几k,相比之下工作几年的自己薪资确实很寒酸.根据我自己找工作经历,二线城市一般小公司招聘 ... [详细]
  • 2019我的金三银四
    先讲一下自己的情况吧,二本学生,17年毕业,目前在一家跨境电商从事Java技术开发工作(不是阿里,没那么厉害),技术栈目前偏向于容器云、持续集成持续交付这一块,也就是SpringBoot、Kuber ... [详细]
  • 第四单元和课程总结:简单的架构设计意识
    一、第四单元架构设计总结第一次作业由于需要按名查找类图模型,于是建立"Class"类进行管理由于方法具有参数导致类中存在二级结构 ... [详细]
  • Unit4博客&课程总结Unit4作业的架构设计本单元作业的设计我分为了三个模块处理:模型构建+预处理+任务函数,前两部分即为整个图的完整构建,第三部分即为实现题目要求的查询方法。 ... [详细]
  • Spring MVC 浅谈
    大学时写的的文章,当时文章水平略差,大家见谅。MVC这个词儿,最早的定义应该是作为一种软件架构设计模式出现在软工里面的,即使用model、view、controller来设计及定 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 博客_2018年博客总结
    本文由编程笔记#小编为大家整理,主要介绍了2018年博客总结相关的知识,希望对你有一定的参考价值。前言     ... [详细]
  • 分布式大型互联网企业架构!
    2019独角兽企业重金招聘Python工程师标准摘要:开发工具1.EclipseIDE:采用Maven项目管理,模块化。2.代码生成: ... [详细]
author-avatar
直拍之横打
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有