30分钟带你了解「消息中间件」Kafka、RocketMQ( 二 )


30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
Kafka 文件存储机制https://www.open-open.com/lib/view/open1421150566328.html
  • 每个 partition 相当于一个巨型文件→多个大小相等 segment 数据文件中
  • 每个 partition 只需要顺序读写就行了 , segment 文件生命周期由配置决定
  • segment file 组成:index file:索引文件data file:数据文件
  • segment file 文件命名规则:全局第一个 segment 是 0后序每个加上全局 partition 的最大 offset

30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 

30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
一对 segment file
30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
message 物理结构
30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
【30分钟带你了解「消息中间件」Kafka、RocketMQ】 
分区为什么分区?
  • Kafka的消息组织方式:主题-分区-消息
  • 一条消息 , 仅存在某一个分区中
  • 提高伸缩性 , 不同分区可以放到不同机器 , 读写操作也是以分区粒度
分区策略?
  • 轮询
  • 随机
  • 按 key 保序 , 单分区有序

30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
Kafka 是否会消息丢失?
  • 只对“已提交”的消息做有限度的持久化保证已提交的消息:消息写入日志文件有限度的持久化保证:N个 broker 至少一个存活
  • 生产者丢失数据producer.send(msg) 异步发送消息 , 不保证数据到达Kafkaproducer.send(msg, callback) 判断回调
  • 消费者程序丢失数据应该「先消费消息 , 后更新位移的顺序」新问题:消息的重复处理多线程异步处理消息 , Consumer不要开启自动提交位移 , 应用程序手动提交位移
控制器
  • 在 ZooKeeper帮助下管理和协调整个 Kafka 集群
  • 运行过程中 , 只能有一个 Broker 成为控制器
控制器如何选购?在 ZooKeeper 创建 /controller 节点 , 第一个创建成功的 Broker 被指定为控制器 。
控制器有什么用?
  • 主题管理(创建、删除、增加分区)
  • 分区重分配
  • 领导者选举
  • 集群成员管理(新增 Broker、Broker 主动关闭、Broker 宕机)(ZooKeeper 临时节点)
  • 数据服务:最全的集群元数据信息
控制器故障转移
  • 只有一个 Broker 当控制器 , 单点失效 , 立即启用备用控制器

30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
Kafka 的 ZooKeeper 存储结构
30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
分布式事务的应用场景
  • 团队内部 , 某些操作要同时更新多个数据源
  • 业务团队 A 完成某个操作后 , B 业务的某个操作也必须完成 , A 业务并不能直接访问 B 的数据库
  • 公司之间 , 用户付款后 , 支付系统(支付宝/微信)必须通知商家的系统更新订单状态
两阶段最终一致
  • 先完成数据源 A 的事务(一阶段)
  • 成功后通过某种机制 , 保证数据源 B 的事务(二阶段)也一定最终完成不成功 , 会不断重试直到成功为止或达到一定重试次数后停止(配合对账、人工处理)
如何保证最终一致?为了保证最终一致 , 消息系统和业务程序需要保证:
  • 消息发送的一致性:消息发送时 , 一阶段事务和消息发送必须同时成功或失败
  • 消息存储不丢失:消息发送成功后 , 到消息被成功消费前 , 消息服务器(broker)必须存储好消息 , 保证发生故障时 , 消息不丢失
  • 消费者不丢失消息:处理失败不丢弃 , 重试直到成功为止
消息发送的一致性如何保证?
30分钟带你了解「消息中间件」Kafka、RocketMQ

文章插图
 
目标 :本地事务、消息发送必须同时成功/失败
问题