Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

模拟场景

假如现在我需要维护两个服务A和B,B服务每秒能处理100个消息,但A服务每秒能发两百个消息

结果我们也能想到,B服务非常容器就爆炸了,聪明的我一定能想到,我在B里面加一个队列来存放A发来的消息,用offset偏移量来记录消息的位置,B服务看能力来处理消息,不断更新offset值

但这又产生了一个新问题,来不及处理的消息放在内存里,如果在服务B里面的消息没有处理完的情况下B服务关机或者重启了,里面的消息就全部丢失了,但聪明的我肯定还会想到,那我们把队列拉出来单独开一个进程不就行了嘛

这就是消息队列的来源,像A服务一样发数据到队列里就是生产者,B服务这样处理数据的就是消费者

优化

  • 高性能
    简单来说就是软件不行加硬件,消费者太慢了就加消费者,生产者慢就加生产者,但这听着感觉还是不对,如果多个生产者和消费者同时争抢同一个消息队列,抢不到就等怎么办

    解决方法:
    对消息进行分类,每一类是一个topic,按照topic数量,生产者将消息分发给不同的消息队列里面,一个消费者需要订阅不同的队列来获取消息,但这样还是会出现一个topic里消息还是很多,我们还可以把单个topic拆成多个partition分区,每个消费者负责一个partition分区

  • 高扩展

    随着partition变多,如果partition都在同一台机器上可能会导致单机CPU内存负载过高,影响系统整体效率

    解决方法:
    将partition分散部署到多台机器上,每一台机器就是一个broker,我们可以通过增加broker来缓解机器CPU负载过高带来的性能问题

  • 高可用

    如果其中一个broker挂了,那里面所有partition的消息也会跟着消失

    解决方法:
    给partition多加几个副本,统称为replicas,将他们分为leader和follower,leader负责应对生产者和消费者的读写请求,follower负责同步leader的消息,将leader和follower分散到不同的broker里,这样就算leader所在的broker挂了也不会影响到follower所在的broker,并且还能重新选举一个leader partition顶上

  • 持久化和过期策略

    假设全部broker都挂了,那所以的partition的消息不都丢失了吗

    解决方法:
    所以我们不能光将数据放在内存里,还需要持久化到磁盘上,但问题又来了,磁盘是有限的,一直往里面写数据迟早得炸,所以还需要给数据加上保留策略retention policy,比如磁盘数据超过一定大小或者数据放置超过一定时间就会被清理掉

  • 消费者组consumer group

    按现在的消费方式,每次新增的消费者只能跟着最新的offset接着消费,如何让新增的消费者从指定的offset开始消费呢

    解决方法:
    引入消费者组概念,不同消费者组维护自己的消费进度,互不打扰

  • ZooKeeper

    就目前来看,组件太多了,而且每个组件都有自己的数据和状态,因此需要有一个组件去统一维护这些组件的状态,于是引入了ZooKeeper组件

    ZooKeeper会定期和broker通信,获取整个Kafka集群的状态,以此判断某些broker是不是挂了,某些消费者消费到哪了

应用场景

  • 流量削峰填谷
  • 异构同步(不同类型、不同厂商的数据库系统之间进行数据同步)
  • 日志处理与分析
  • 系统监控与报警等

评论