Kafka能解决什么问题?
以银行的金融系统为例,
银行金融系统每天有大量的交易发生,这些交易很多需要进行实时的检查与处理,比如一笔交易发生,这笔交易是否是欺诈交易,这笔交易是否已经达到限额了,相关用户是否在黑名单中,交易结果联动短信、Email等渠道通知用户……等等,也许一笔简单的交易,就要与反欺诈系统、黑名单系统、限额或授信管控系统、短信邮件系统进行通讯。
这些还不是全部,银行金融系统在进行运行时,如果出现了问题,需要日志及时定位问题;为了及时发现问题,要将处理结果实施发送监控平台;为了预防突发事件发生,还需要备份系统做高可用处理。这就仍然需要与日志系统、监控系统、备份系统进行通讯。
最重要的是,上面这些处理必须在极短时间内完成,否则用户就会感到有卡顿,影响体验。
怎么解决这些问题呢?将交易处理相关的系统全部直连起来,似乎是个办法:
但明显不是一个好办法,你将面临极高的后续维护成本:
于是,消息分发处理的概念出现了,我们在各个系统之间搭建一个消息分发的总控系统,连接这个总控系统的主要有两方:
1、消息供应方(Producer):他们会产生消息,并将消息送给消息分发系统。
2、消息消费方(Comsumer):他们需要最新的消息以进行自身功能的处理,他们会从消息分发系统拿消息。
上方的Producers会产生很多的消息和信息送给kafka。
kafka会把这些消息存储下来。
下方的Consumers会从kafka获取它所需要的数据,然后自行处理,比如Consumers可能会降消息存储到hadoop、cassandra、HBase。
什么是 Kafka?
众所周知,Kafka 是 LinkedIn 公司内部孵化的项目。
根据查阅到的公开信息显示,LinkedIn 最开始有强烈的数据强实时处理方面的需求,其内部的诸多子系统要执行多种类型的数据处理与分析,主要包括业务系统和应用程序性能监控,以及用户行为数据处理等。
当时他们碰到的主要问题包括:数据正确性不足。因为数据的收集主要采用轮询(Polling)的方式,如何确定轮询的间隔时间就变成了一个高度经验化的事情。虽然可以采用一些类似于启发式算法(Heuristic)来帮助评估间隔时间值,但一旦指定不当,必然会造成较大的数据偏差。系统高度定制化,维护成本高。各个业务子系统都需要对接数据收集模块,引入了大量的定制开销和人工成本。为了解决这些问题,LinkedIn 工程师尝试过使用 ActiveMQ 来解决这些问题,但效果并不理想。显然需要有一个“大一统”的系统来取代现有的工作方式,而这个系统就是 Kafka。
关于Kafka 的命名,作者之一 Jay Kreps 曾经谈原因:
因为 Kafka 系统的写性能很强,所以找了个作家的名字来命名似乎是一个好主意。大学期间我上了很多文学课,非常喜欢 Franz Kafka 这个作家,另外为开源软件起这个名字听上去很酷。
Kafka的基本原理
通过这张图我们来捋一捋相关的概念及之间的关系:
如果看到这张图你很懵逼,木有关系!
我们先来分析相关概念
Producer:Producer即生产者,消息的产生者,是消息的入口。
kafka cluster:Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例,我们姑且认为每个broker对应一台服务器。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等……
Topic:消息的主题,可以理解为消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。
Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是一个一个的文件夹!
Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候会选择一个备胎(Follower)上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader绝对是在不同的机器,同一机器对同一个分区也只可能存放一个副本(包括自己)。
Message:每一条发送的消息主体。
Consumer:消费者,即消息的消费方,是消息的出口。
Consumer Group:我们可以将多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!
Zookeeper:kafka集群依赖zookeeper来保存集群的的元信息,来保证系统的可用性。
发送数据
我们看上面的架构图中,producer就是生产者,是数据的入口。注意看图中的红色箭头,Producer在写入数据的时候永远的找leader,不会直接将数据写入follower!那leader怎么找呢?
写入的流程又是什么样的呢?我们看下图:
发送的流程就在图中已经说明了,就不单独在文字列出来了!需要注意的一点是,消息写入leader后,follower是主动的去leader进行同步的!producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的!写入示意图如下:
搭建使用
首先下载 kafka和zookeeper的安装包
kafka集群的数据同步是依赖 zookeeper的,先启动 zookeeper。
解压
tar -xvf apache-zookeeper-3.5.7-bin.tar.gz
配置文件,安装包 里面 有一个默认的配置文件 zoo_sample.cfg,直接使用里面的配置项即可
cp conf/zoo_sample.cfg conf/zoo.cfg
启动 zookeeper
./bin/zkServer.sh start
通过ps查看 zookeeper已经启动
Kafka
解压
tar -xvf kafka_2.11-2.4.0.tgz
这里需要修改 config/server.properties 里面的几个配置项
listeners=PLAINTEXT://192.168.157.133:9092
advertised.listeners=PLAINTEXT://192.168.157.133:9092
zookeeper.connect=localhost:2181
auto.create.topics.enable=false
unclean.leader.election.enable=false
auto.leader.rebalance.enable=false
这里解释一下这几个配置项的参数
门牌号
listeners:学名叫监听器,格式一般为”listener_name://host_name:port“,其实就是告诉外部连接者要通过什么协议访问指定主机名和端口开放的 Kafka 服务。
挂上招牌
advertised.listeners:和 listeners 相比多了个 advertised。Advertised 的含义表示宣称的、公布的,就是说这组监听器是 Broker 用于对外发布的。
不能自立为王
auto.create.topics.enable: 是否允许自动创建 Topic
一般正式环境,还是最好不要允许自动创建比较好,想象使用kafka一个topic名字拼错了,没有报错,而是去自动新建了一个topic,久而久之,出现了很多莫名其妙的topic。
宁缺毋滥
unclean.leader.election.enable:是否允许 Unclean Leader 选举
kafka有很多的副本用来备份信息,所有的副本中只有一个Leader 副本对外提供服务,Follower同步一份数据。
那么问题来了,这些副本都有资格竞争 Leader 吗?显然不是,只有保存数据比较多的那些副本才有资格竞选,那些落后进度太多的副本没资格做这件事。
好了,现在出现这种情况了:假设那些保存数据比较多的副本都挂了怎么办?我们还要不要进行 Leader 选举了?
此时这个参数就派上用场了。如果设置成 false,那么就坚持之前的原则,坚决不能让那些落后太多的副本竞选 Leader。
江山不易改
auto.leader.rebalance.enable:表示关闭定期进行 Leader 选举
换一次 Leader 代价很高的,原本向 A 发送请求的所有客户端都要切换成向 B 发送请求,而且这种换 Leader 本质上没有任何性能收益,因此我建议你在生产环境中把这个参数设置成 false。
Python demo