阅读rocketmq技术内幕、实战与原理杂记 - 设计
最近正在研究rocketmq,简单记录下设计的不同
互联网系统中Rpc、服务治理、消息中间件基本都是标配,消息中间件能解耦,削峰,高可用并能间接提供达到最终一致性
消息中间件中,消息消费分为最多一次,至少一次和刚好一次,如果需要实现刚好一次,则系统设计难度增大,系统性能损失增加,权衡利弊,rocket实现的是最少一次,消费端可能会重复接收消息(ACK模式下,ACK消息可能丢失),由消费端幂等消费
为什么不用zk,还是从实际需求出发,Topic路由信息无需在集群之间保持强一致性,最终一致即可,从而减少对zk的依赖和性能的损失
消息存储方面,rocket引入文件组,无限循环使用,commitlog文件每个1G,以第一个偏移值为文件名,为了和consumequeue一致,log中还包含了tag,key等信息便于恢复,顺序写,引入内存映射,相同主题的消息被顺序存储在同一文件中,还提供定时清理等防止过度堆积,利用消费队列文件和索引文件及pagecache等提升读性能,ConsumeQueue是消息的逻辑队列,类似数据库的索引文件,存储的是指向物理存储的地址。每个Topic下的每个Message Queue都有一个对应的ConsumeQueue文件, 里面有一部分是存储了tag对应的hashcode,经过对比,符合要求的消息被从commitlog中读取出来,消息在消费前,会对比完整的Message Tag字符串,清除hash冲突造成的误读
消息过滤,基于tag等,在存储设计上基于hash等方式提升过滤效率,可以从Broker或者消费端过滤,broker端过滤可以减少传递到消费端的消息,减少网络损失,消费端过滤可以由消费者任意定义
定时消息,如果要支持任意精度的定时消息消费,必须在消息服务端对消息进行排序,势必带来很大的性能损耗,rocketmq设计不支持任意进度的定时消息,只支持特定延迟级别
客户端支持Push(被推送)、pull(自主控制messagequeue的遍历及消息的读取)两种模式
线程池设计,rocketmq会根据不同的任务类型创建不同的线程池,如果该类型没注册,则由other之类的线程池统一处理
Namesrv之间数据可以不一致,彼此之间互不通信
消息发送端提供容错机制,这个地方之前我就有疑问,为什么在客户端或者消费端获取消息存储meta信息之后,namesrv发现变化后不会通知他们。。。原来是由meta使用端的容错机制来保证高可用,降低namesrv的复杂性
消息的顺序性保证,如果要全局一致,必须单一topic,单一生产者及消费者,清除一切并发,可行性比较低,性能和吞吐量无法接受,结合业务,一般是部分顺序消息,发送端将同一业务ID的消息发送到同一个Message Queue,在消费过程中,不并发处理
CommitLog同步,不是经过netty命令的方式,而是直接TCP连接,效率更高,连接成功后,通过对比master和slave的offset,不断进行同步
从broker获得的消息,因为是提交到线程池里并行执行,很难监控和控制执行状态,RocketMQ定义了一个快照类ProcessQueue来解决
负载均衡或消息分配是在消费者端代码中完成,Consumer从broker处获取全局消息,然后自己做负载均衡,只处理分给自己的部分
跟kafka一样,总的消费者数量不要超过topic的队列数,否则多余的消费者收不到消息
Namesrv本身无状态,其中的Broker,topic等状态信息不会持久存储,都是由各个角色定期上报并存储到内存中
事物消息的实现:发送方向RocketMQ发送“待确认”消息,RocketMQ将收到的“待确认”消息持久化后,向发送方回复消息已经发送成功,发送方开始执行本地事件逻辑,发送方根据本地事件逻辑想RocketMQ发送二次确认,RocketMQ收到commit状态则将第一阶段消息标记为可投递,订阅方将能收到该消息,收到rollback状态则删除第一阶段的消息,如果出现异常,服务器在一段时间后未收到确认消息,则服务器将对“待确认”消息发起回查请求,发送方收到回查请求后通过检查对应消息的本地事件执行结果返回对应的状态,RocketMQ收到后继续处理
服务端接受到新请求后,如果队列没有新消息,并不急于返回,通过一个循环不断查看状态,长轮询的核心是,broker端hold住客户端过来的请求一小段时间,在这个时间内有新消息到达,就利用现有的链接立即返回给消息的consumer,长轮询主动权还是掌握在消费端手中,即使broker消息大量积压,也不会主动推送给消费者
在同步刷盘过程种,有一个设计,避免了任务提交与任务执行的锁冲突,由于避免同步刷盘消费任务与其他消费生产者提交任务直接的锁竞争,GroupCommitService提供读容器与写容器,这两个容器每执行完一次任务后,交互,继续消费任务。
private volatile List<GroupCommitRequest> requestsWrite = new ArrayList<GroupCommitRequest>();
private volatile List<GroupCommitRequest> requestsRead = new ArrayList<GroupCommitRequest>(); public synchronized void putRequest(final GroupCommitRequest request) {
synchronized (this.requestsWrite) {
this.requestsWrite.add(request);
}
if (hasNotified.compareAndSet(false, true)) {
waitPoint.countDown(); // notify
}
} private void swapRequests() {
List<GroupCommitRequest> tmp = this.requestsWrite;
this.requestsWrite = this.requestsRead;
this.requestsRead = tmp;
}
阅读rocketmq技术内幕、实战与原理杂记 - 设计的更多相关文章
- Spring技术内幕:SpringIOC原理学习总结
前一段时候我把Spring技术内幕的关于IOC原理一章看完,感觉代码太多,不好掌握,我特意又各方搜集了一些关于IOC原理的资料,特加深一下印象,以便真正掌握IOC的原理. IOC的思想是:Spring ...
- 社区布道师揭秘消息中间件技术内幕,撰写MQ架构设计与实现原理
RocketMQ是什么 RocketMQ是由阿里捐赠给Apache的一款分布式.队列模型的开源消息中间件,经历了淘宝双十一的洗礼. RocketMQ的特性 RocketMQ基本概念 Client端 P ...
- jQuery技术内幕 深入解析jQuery架构设计与实现原理
jquery的外衣 jquery是一个轻量级的JS框架 //以下截取自jquery源码片段 (function( window, undefined ) { /* 源码内容 */ })( window ...
- 【RocketMQ】事务的实现原理
事务的使用 RocketMQ事务的使用场景 单体架构下的事务 在单体系统的开发过程中,假如某个场景下需要对数据库的多张表进行操作,为了保证数据的一致性,一般会使用事务,将所有的操作全部提交或者在出错的 ...
- Struts2技术内幕 读书笔记一 框架的本质
本读书笔记系列,主要针对陆舟所著<<Struts2技术内幕 深入解析Strtus2架构设计与实现原理>>一书.笔记中所用的图片若无特殊说明,就都取自书中,特此声明. 什么是框架 ...
- 重读COM技术内幕(inside com)有感
重读COM技术内幕(inside com)有感 面向对象设计哲学在复杂领域并不能很好地解决问题.参考(http://www.richardlord.net/blog/what-is-an-entity ...
- 快读《ASP.NET Core技术内幕与项目实战》EFCore2.5:集合查询原理揭秘(IQueryable和IEnumerable)
本节内容,涉及4.6(P116-P130).主要NuGet包:如前述章节 一.LINQ和EFCore的集合查询扩展方法的区别 1.LINQ和EFCore中的集合查询扩展方法,虽然命名和使用完全一样,都 ...
- 《ASP.NET Core技术内幕与项目实战》精简集-目录
本系列是杨中科2022年最新作品<ASP.NET Core技术内幕与项目实战>及B站配套视频(强插点赞)的精简集,是一个读书笔记.总结和提炼了主要知识点,遵守代码优先原则,以利于快速复习和 ...
- 《jQuery技术内幕:深入解析jQuery架构设计与实现原理》
<jQuery技术内幕:深入解析jQuery架构设计与实现原理> 基本信息 作者: 高云 出版社:机械工业出版社 ISBN:9787111440826 上架时间:2014-1-10 出版日 ...
随机推荐
- IO文件流
定义:流是一种抽象的概念,通过流的方式组成无结构字符和字符序列,从流中取数据的操作进行输入输出.[io流的作用就是用流的方式进行输入输出] 常用语法: 1. 首先引用using.system.io ...
- DataGrip for Mac破解步骤详解 亲测好用
https://blog.csdn.net/le945926/article/details/81912085
- C++ 状态机接口
最近的状态极差,甚至代码也写不下去了.给自己手臂上的两刀没有任何的作用,看来早已经是麻痹了. 一直想弄一个勉强能用的状态机,用于在各种涉及到状态转换的时候用到,然而脑子并不是太清醒. 先放在这里一个接 ...
- MySQL Hardware--NUMA与MySQL
MUMA架构 在单实例的MySQL服务器上,通过会为MySQL的Buffer Pool分配50%至70%甚至更高的内存,让MySQL 服务会尽可能多地占用系统资源.在基于NUMA系统中,内存被分配到各 ...
- mongdb 报错“Cannot connect to the MongoDB at 192.179.1.6:27017. Error: Network is unreachable.”
1.命令行输入talnet 192.179.1.6 27017 看能拼通不 2.防火墙添加入站规则 27017 3.修改mongdb配置文件 mongodb.config dbpath=c:\Mon ...
- 前端SEO与爬虫与SSR(Server Side Render)
讲真,之前没考虑过这个问题.因为项目原因,自己用python的一些工具,爬取了淘宝.京东.百度等的一些图片和图片名称之类的信息.以为爬虫只是解析html文本,然后提取关键字,保存自己想要的信息即可,或 ...
- mysql循环插入千万级数据
mysql使用存储过程循环插入大量数据,简单的一条条循环插入,效率会很低,需要考虑批量插入. 测试准备: 1.建表: CREATE TABLE `mysql_genarate` ( `id` ) NO ...
- 知识点总结——STL相关(持续补充)
---恢复内容开始--- C++ STL 与ACM竞赛相关的应用 1.vector vector是动态数组,可以理解为是能够根据需要随时申请内存的动态数组. 常用操作如下: 容量 vec.size() ...
- dubbo 用来做什么
1.各个独立app之间的通信问题怎么解决? 2.怎么做到统一调度.协调处理. 3.如果计费模块是并发最大的模块,但是其他模块并发不是很大.则需要对计费进行负载均衡,怎么实现?
- iOS 自定义底部tabbar加号按钮实现方法
自定义UITabBar替换系统默认的,目的是为了在UITabBar中间位置添加一个“+号按钮” 1.自定义WBTabBar,让其继承自UITabBar,并定义点击事件代理方法. .h方法里面 #imp ...