点击右侧关注,暴走大数据!
生产消费者模式,指的是由生产者将数据源源不断推送到消息中心,由不同的消费者从消息中心取出数据做自己的处理,在同一类别下,所有消费者拿到的都是同样的数据;订阅发布模式,本质上也是一种生产消费者模式,不同的是,由订阅者首先向消息中心指定自己对哪些数据感兴趣,发布者推送的数据经过消息中心后,每个订阅者拿到的仅仅是自己感兴趣的一组数据。这两种模式是使用消息中间件时最常用的,用于功能解耦和分布式系统间的消息通信。
本文将继续以“数据接入”和“事件分发”这两个场景为例,来探讨Kafka作为消息系统的应用方法(High Level)。搞清楚Kafka的基本概念和应用方法是进行系统方案设计的前提,编写代码只是具体落地实施,而解决bug和性能调优是系统跑起来之后的事情了。需要指出的是,本文重点是探讨应用方法,具体应用时需要根据自身需求来做调整,没有任何技术方案是万能的。
数据接入 假设有一个用户行为采集系统,负责从App端采集用户点击行为数据。通常会将数据上报和数据处理分离开,即App端通过REST API上报数据,后端拿到数据后放入队列中就立刻返回,而数据处理则另外使用Worker从队列中取出数据来做,如下图所示。
这样做的好处有:第一,功能分离,上报的API接口不关心数据处理功能,只负责接入数据;第二,数据缓冲,数据上报的速率是不可控的,取决于用户使用频率,采用该模式可以一定程度地缓冲数据;第三,易于扩展,在数据量大时,通过增加数据处理Worker来扩展,提高处理速率。这便是典型的生产消费者模式,数据上报为生产者,数据处理为消费者。
事件分发
假设有一个电商系统,那么,用户“收藏”、“下单”、“付款”等行为都是非常重要的事件,通常后端服务在完成相应的功能处理外,还需要在这些事件点上做很多其他处理动作,比如发送短信通知、记录用户积分等等。我们可以将这些额外的处理动作放到每个模块中,但这并不是优雅的实现,不利于功能解耦和代码维护。
我们需要的是一个事件分发系统,在各个功能模块中将对应的事件发布出来,由对其感兴趣的处理者进行处理。这里涉及两个角色:A对B感兴趣,A是处理者,B是事件,由事件处理器完成二者的绑定,并向消息中心订阅事件。服务模块是后端的业务逻辑服务,在不同的事件点发布事件,事件经过消息中心分发给事件处理器对应的处理者。整个流程如下图所示。这边是典型的订阅发布模式。
Kafka基本概念
Kafka是一个分布式流数据系统,使用Zookeeper进行集群的管理。与其他消息系统类似,整个系统由生产者、Broker Server和消费者三部分组成,生产者和消费者由开发人员编写,通过API连接到Broker Server进行数据操作。我们重点关注三个概念:
生产消费者模式
搞清楚了Kafka的基本概念后,我们来看如何设计生产消费者模式来实现上述的“数据接入”场景。在下图中,由Producer负责接收前端上报的数据,投递到对应的topic中(这里忽略了Broker Server的细节),在Consumer端,所有对该数据感兴趣的业务都可以建立自己的group来消费数据,至于group内部开多少个worke来消费完全取决于数据量和业务的实时性要求了。
订阅发布模式
再来看“事件分发”的场景,假如我们有“收藏”、“下单”、“付款”三个事件,业务一对“收藏”和“下单”事件感兴趣,而业务二对“下单”和“付款”事件感兴趣,那么我们如何进行事件订阅?不同于RabbitMQ中有数据路由机制(routing key),可以将感兴趣的事件绑定到自己的Queue上,Kafka只提供了单播和广播的消息模型,无法直接进行消费对象的绑定,所以理论上Kafka是不适合做此种场景下的订阅发布模式的,如果一定要做,有这么几个方案: