适用于面试回答

Redis

MQ

消息队列优缺点

优点

​ 解耦、削峰和异步

缺点

​ 提升了系统的复杂度、系统可用性降低以及存在一致性的问题。

为什么用RocketMQ

  • 吞吐量:ActiveMQ和RabbitMQ是万级,而RocketMQ和Kafka是十万级。
  • Topic: RocketMQ可以支持成百上千,而Kafka几十几百吞吐量大幅下降
  • 时效性: 除了Rabbit都是ms级别
  • 可用性:RocketMQ和Kafka都非常高
  • 可靠性:RockMQ和Kafka可以做到不丢

RocketMQ如何保证高可用性

一个最基本的架构认识:由多个 broker 组成,每个 broker 是一个节点;你创建一个 topic,这个 topic 可以划分为多个 partition,每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据。

副本机制,每个 partition 的数据都会同步到其它机器上,形成自己的多个 replica 副本。所有副本会选取一个leader用来读写数据。如果leader down了,就重新选择leader。

写数据的时候,生产者就写 leader,然后 leader 将数据落地写本地磁盘,接着其他 follower 自己主动从 leader 来 pull 数据。一旦所有 follower 同步好数据了,就会发送 ack 给 leader,leader 收到所有 follower 的 ack 之后,就会返回写成功的消息给生产者。

RocketMQ如何保证消息不被重复消费

每个消息写进去,都有一个 offset,代表消息的序号,然后 消费者消费了数据之后,每隔一段时间就会提交 offset 。

如果重启怎么办?

  • 比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
  • 比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
  • 比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
  • 比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

如何保证消息可靠性