kafka(一):前瞻

212 阅读3分钟

1. 引入 MQ

参考:引入MQ消息队列的作用及其优缺点

优点:

  • 解藕:降低系统耦合性
  • 异步:加快系统响应
  • 削峰:降低系统瞬时压力

1.1 引入MQ需要考虑的点

  • MQ 需要解决的问题: (见第2节kafka如何设计保证下面的点)
    • MQ的高性能
    • MQ的高可用
    • MQ消息可靠性
  • 生产和消费系统需要解决的问题: (见第3节)
    • 消息丢失
    • 重复消费
    • 消息顺序性

2. kafka 如何设计解决上述MQ的点

2.1 AKF 理论

参考:分布式AKF拆分原则 基本原理为从三个维度来提升系统的可用性和性能,解决系统的单点故障和性能瓶颈:

  • x轴:解决单点问题,保证高可用
    • mysql主从机制
    • 无状态微服务集群横向扩展
  • y轴:按照业务拆分,降低模块的复杂性
    • 系统服务业务拆分为 用户系统,订单系统,消息系统;
    • mysql 不同业务的数据存储在不同的mysql,如:用户库存储用户信息,订单库存储用户订单信息,消息库存储用户消息...)
  • z轴:分片
    • 系统根据地域划分,如游戏的各个区
    • mysql 根据用户id拆分,不同的用户存储在不同的用户库 (如果按照业务拆分还是无法存储,那么就需要对数据进行拆分,比如用户量太多,导致用户库性能和容量不足,那么就要对用户分片)

2.2 kafka 设计

kafka 2.png

kafka topic高可用.png

kafka AKF.png

2.2.1 kafka 高性能设计

  • kafka 支持集群部署
  • kafka 支持 topic, (Y轴拆分) 不同的业务数据可以写入不同的topic,即按照业务对数据拆分,不同的业务数据放入不同的topic
  • kafka 每个 topic 支持多个 partition, (Z轴拆分) 数据可以分片后,分散到不同的partition中。

2.2.2 kafka 高可用设计

  • kafka 支持集群部署
  • kafka 节点支持 leader 和 follower 角色。(X轴拆分) 当leader故障后,所有的follower会收到通知,选举新的leader(leader 选举以来 zookeeper 分布式协调)。
  • kafka 的 topic 的 partition 支持副本 (x轴拆分)。另外主从就存在数据一致性的问题,kafka 如何保证 partition 的主从一致性: partition 的读写只能在 主 partition, 副本不参与读写。

2.2.3 kafka 消息可靠性设计

  • kafka partiton 数据会写入磁盘保存
  • kafka partition 支持副本, 每个 partition 可以有多个副本。

3. 生产和消费系统需要解决的问题

  • 消息丢失
  • 重复消费
  • 消息顺序性

3.1 生产端

3.2 消费端

  • 消费端处理的顺序性保证的前提是: 生产端写入MQ是有序的,且相同类型的数据(如同一个用户)写入相同的 partition 中。否则顺序是无法保证的,因为消息的顺序在消费端消费之前已经乱序了。

假设从MQ读区到消息后,服务要做执行3步:

  • 查询 Redis, 耗时 20ms
  • 写 DB, 耗时 20ms
  • commit offset,耗时 20ms

3.2.1 单线程同步提交

  • 单线程由于都是同步的,所以耗时为60ms
  • 先提交 offset, 但是后续操作失败,会造成消息的丢失
  • 最后提交 offset, 前面的操作完成了, offset失败,会造成消息的重复消费
  • 可以保证partition内的消息顺序消费
  • 单线程,按顺序,单条处理,offset就是递增的,无论对db,offset频率,成本有点高,CPU,网卡,资源浪费

kafka consumer 单线程同步提交 (4).png

3.2.2 多线程同步提交

多线程同步提交.png

3.2.3 异步提交

  • 异步提交为 commit 线程和 message 处理线程相互独立, commit 线程固定时间间隔提交 offset. 可能造成数据重复消费, 也可能造成数据丢失. 不推荐此方式,故不做详细分析
    • 重读消费: 消息处理成功还没有commit时,程序崩溃导致没有 offset 没有 commit
    • 消息丢失: offset 已经 commit, 但是消息还没有处理完, 程序崩溃.