1. Rocketmq消费模型(实时性)
常见的数据同步方式有这几种:
  push:producer发送消息后,broker马上把消息投递给consumer。这种方式好在实时性比较高,但是会增加broker的负载;而且消费端能力不同,如果push推送过快,消费端会出现很多问题。
  pull:producer发送消息后,broker什么也不做,等着consumer自己来读取。它的优点在于主动权在消费者端,可控性好;但是间隔时间不好设置,间隔太短浪费资源,间隔太长又会消费不及时。
  长轮询:当consumer过来请求时,broker会保持当前连接一段时间 默认15s,如果这段时间内有消息到达,则立刻返回给consumer;15s没消息的话则返回空然后重新请求。这种方式的缺点就是服务端要保存consumer状态,客户端过多会一直占用资源。

RocketMQ默认是采用pushConsumer方式消费的,从概念上来说是推送给消费者,它的本质是pull+长轮询。这样既通过长轮询达到了push的实时性,又有了pull的可控性。系统收到消息后会自动处理消息和offset(消息偏移量),如果期间有新的consumer加入会自动做负载均衡(集群模式下offset存在broker中; 广播模式下offset存在consumer里)。当然我们也可以设置为pullConsumer模式,这样灵活性会提高,但是代码却会很复杂,需要手动维护offset,消息存储和状态。

  * offset:简单粗暴的理解就是数组下标。message queue是无限长的数组,每次消息进来就会涨1,下标就是offset。consumer可以通过指定offse位置开始读取数据。queue的maxOffset是消息的最大offset,不是最新消息的offset 而是最新消息的offset+1,minOffset则是现存的最小offset。

2. Rocketmq消息存储(顺序写,随机读)   

  消息存储是由ConsumeQueue和CommitLog配合完成的。一个Topic里面有多个MessageQueue,每个MessageQueue对应一个ConsumeQueue.
  默认地址:store/consumequeue/{topicName}/{queueid}/fileName
ConsumeQueue里记录着消息物理存储地址。(读:consumer根据消息的consumeQueue找到消息存储具体路径,从而读取里面信息)
CommitLog就存储文件具体的字节信息。(写:文件大小默认1g,文件名称20位数 左边补0右边为偏移量。消息顺序写入文件,文件满了则写入下一个文件)

3. ZeroCopy高性能零拷贝

linux有两个上下文(内核态、用户态), 传统的将一个file读取并发送出去会经历4个过程。
 read时:
  1. 将文件从磁盘copy到kernel(内核)态
  2. cpu将kernrl态的数据copy到user(用户)态
 write时:
  3. user态的内容会copy到kernel态的socket的buffer中
  4. 将kernel中buffer的数据copy到网卡中传送
 我们可以发现2、3完全是多余的步骤,而且上下文之间的切换是很耗性能的。

   

  ZeroCopy:内核直接把磁盘的数据传输到socket,而不是通过应用程序去传输。减少了不必要的内核缓冲区和用户缓冲区间的拷贝,从而提升了性能。
  零拷贝技术有mmap及sendfile;sendfile大文件传输快,mmap小文件传输快。MMQ发送的消息通常都很小,rocketmq就是以mmap+write方式实现的。像kafka、netty都采用了零拷贝技术。

RocketMQ高性能原理(pushConsumer,CommitLog,ZeroCopy)的更多相关文章

  1. RocketMQ架构原理解析(四):消息生产端(Producer)

    RocketMQ架构原理解析(一):整体架构 RocketMQ架构原理解析(二):消息存储(CommitLog) RocketMQ架构原理解析(三):消息索引(ConsumeQueue & I ...

  2. RocketMQ架构原理解析(一):整体架构

    RocketMQ架构原理解析(一):整体架构 RocketMQ架构原理解析(二):消息存储(CommitLog) RocketMQ架构原理解析(三):消息索引(ConsumeQueue & I ...

  3. 分布式开放消息系统(RocketMQ)的原理与实践

    分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回避不了两个问题: 消息的顺序问题 消息的重复问题 RocketMQ作为阿里开源的一 ...

  4. 分布式开放消息系统(RocketMQ)的原理与实践(转)

    转自:http://www.jianshu.com/p/453c6e7ff81c 分布式消息系统作为实现分布式系统可扩展.可伸缩性的关键组件,需要具有高吞吐量.高可用等特点.而谈到消息系统的设计,就回 ...

  5. 分布式消息中间件rocketmq的原理与实践

    RocketMQ作为阿里开源的一款高性能.高吞吐量的消息中间件,它是怎样来解决这两个问题的?RocketMQ 有哪些关键特性?其实现原理是怎样的? 关键特性以及其实现原理 一.顺序消息 消息有序指的是 ...

  6. 万字长文深度剖析 RocketMQ 设计原理

    幸福的烦恼 张大胖最近是又喜又忧,喜的是业务量发展猛增,忧的是由于业务量猛增,一些原来不是问题的问题变成了大问题,比如说新会员注册吧,原来注册成功只要发个短信就行了,但随着业务的发展,现在注册成功也需 ...

  7. 分布式开放消息系统RocketMQ的原理与实践(消息的顺序问题、重复问题、可靠消息/事务消息)

    备注:1.如果您此前未接触过RocketMQ,请先阅读附录部分,以便了解RocketMQ的整体架构和相关术语2.文中的MQServer与Broker表示同一概念 分布式消息系统作为实现分布式系统可扩展 ...

  8. RocketMQ架构原理解析(三):消息索引

    一.概述 "索引"一种数据结构,帮助我们快速定位.查询数据 前文我们梳理了消息在Commit Log文件的存储过程,讨论了消息的落盘策略,然而仅仅通过Commit Log存储消息是 ...

  9. 新手入门:目前为止最透彻的的Netty高性能原理和框架架构解析

    1.引言 Netty 是一个广受欢迎的异步事件驱动的Java开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 本文基于 Netty 4.1 展开介绍相关理论模型,使用场景,基本组件 ...

随机推荐

  1. CF1213G Path Queries

    题目链接 问题分析 直接按边从小到大加入,求所有的连通点对数量即可.最后离线询问.使用并查集维护Size. 参考程序 #include <bits/stdc++.h> using name ...

  2. ship(动态规划)

    (ships.pas/c/cpp) 来源:<奥赛经典>(提高篇)[问题描述]PALMIA国家被一条河流分成南北两岸, 南北两岸上各有N个村庄. 北岸的每一个村庄有一个唯一的朋友在南岸,且他 ...

  3. JavaWeb_(SSH论坛)_七、辅助模块

    基于SSH框架的小型论坛项目 一.项目入门 传送门 二.框架整合 传送门 三.用户模块 传送门 四.页面显示 传送门 五.帖子模块 传送门 六.点赞模块 传送门 七.辅助模块 传送门 为避免代码冗余, ...

  4. kafka监控指标项

    监控配置 ​ kafka基本分为broker.producer.consumer三个子项,每一项的启动都需要用到 $KAFKA_HOME/bin/kafka-run-class.sh 脚本,在该脚本中 ...

  5. 半径R覆盖最多点

    struct point { double x, y; }; point p[N]; struct alpha { double v; bool flag; bool friend operator ...

  6. postgres 使用psql连接

    输入:sudo su - postgres 在bash下输入:psql,下文出现postgres字样 在postgres后:输入:\c 数据库名称,连接数据库 在数据库名#:输入查询语句或者其他sql ...

  7. lyf基础作业

    include <stdio.h> include <stdlib.h> int main (void) { FILE * fp; int a[10]; int max=0; ...

  8. 黑马lavarel教程---3、数据库和视图注意点

    黑马lavarel教程---3.数据库和视图注意点 一.总结 一句话总结: 使用其实都很简单,MVC的框架都很像,用的时候直接可以去看手册,这样才能记得住 1.数据库删除操作注意? 删非删:很多网站的 ...

  9. 网络安全监控实战(一):Snort,Wazuh&VT

    https://cloud.tencent.com/developer/news/222711

  10. Python之输入输出

    python中变量的输出 # 打印提示 print('hello world') print('你好!') # 输出变量 url = 'loaderman' print('我是:',url) prin ...