软件开发架构师

六 消息队列复习

架构 176 2019-03-22 23:14

1 为什么使用消息队列?

  六个字: 解耦、异步、消峰。

2 使用消息队列有什么缺点?

  消息队列挂了,系统就不能用了,系统可用性降低。

3 消息队列的高可用?

  kafka使用zookeeper,master/slave,保证高可用;

  Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance

4 如何保证消息不被重复消费(幂等性)?

  kafka有offset的概念,就是每一个消息都有一个offset,kafka消费过消息后,需要提交offset,让消息队列知道自己已经消费过了;

  造成重复消费的原因:因为网络传输等等故障,确认信息没有传送到消息队列,导致消息队列不知道自己已经消费过该消息了,再次将该消息分发给其他的消费者。如何避免:

  • insert操作,主键唯一性可以保证。
  • update, 不会有问题。
  • 其他情况下,可以用第三方工具做消费记录(比如redis),给消息分配全局ID。将<id,message>以K-V形式写入redis。消费前,先去redis中查询有没有消费记录。

5 如何保证消费的可靠性传输?

  我们在使用消息队列的过程中,应该做到消息能多消费,也不能少消费。    

     其实这个可靠性传输,每种MQ都要从三个角度来分析:生产者弄丢数据消息队列弄丢数据消费者弄丢数据

  (1)生产者弄丢数据:

    Producer在发布消息到某个Partition时,先通过ZooKeeper找到该Partition的Leader,然后无论该Topic的Replication Factor为多少(也即该Partition有 多少个Replica),Producer只将该消息发送到该Partition的Leader。Leader会将该消息写入其本地Log。每个Follower都从Leader中pull数据

    在kafka生产中,基本都有一个leader和多个follwer。follwer会去同步leader的信息。

    因此,为了避免生产者丢数据,做如下两点配置:

      1. 第一个配置要在producer端设置acks=all。这个配置保证了,follwer同步完成后,才认为消息发送成功。

      2. 在producer端设置retries=MAX,一旦写入失败,这无限重试;

    (2) 消息队列丢数据:

    针对消息队列丢数据的情况,无外乎就是,数据还没同步,leader就挂了,这时zookpeer会将其他的follwer切换为leader,那数据就丢失了。针对这种情况,应          该做两个配置。

     1. replication.factor参数,这个值必须大于1,即要求每个partition必须有至少2个副本

     2. min.insync.replicas参数,这个值必须大于1,这个是要求一个leader至少感知到有至少一个follower还跟自己保持联系

          这两个配置加上上面生产者的配置联合起来用,基本可确保kafka不丢数据。

  (3)消费者弄丢数据:消费者丢数据一般是因为采用了自动确认消息模式,至于解决方案,采用手动确认消息即可。

6 如何保证消息的顺序性?

       针对这个问题,通过某种算法,将需要保持先后顺序的消息放到同一个消息队列中(kafka中就是partition,rabbitMq中就是queue)。然后只用一个消费者去消费该队列(kafka中,一个partition只能被一个consumer Group中的一个consumer消费)。

     

  

文章评论