Kafka基本概念与术语&使用场景
使用场景
消息
消息的组成部分:
- Key:消息键,对消息做partition处理,即决定消息被保存在某topic下的哪个partition。
- Value:消息体,保存实际的消息数据。
- Timestamp:消息发送时间戳,用于流式处理以及其他依赖时间的处理语义,如果不指定则取当前时间。
topic和partition
topic只是一个逻辑概念,代表了一类消息,也可以认为是消息被发送到的地方。通常我们可以使用topic来区分实际业务,比如业务A使用了一个topic,业务B使用了另外一个topic。
kafka中的topic通常会被多个消费者订阅,因此出于性能的考虑,kafka并不是topic-message的两级结构,而是采用topic-partition-message的三级结构来分散负载。本质上来说,每个kafka topic都由多个partition组成。
我们可以从上图非常清楚的看到它们两者间的关系,topic是由多个partition组成的,而kafka的partition是不可修改的有序消息序列。每个partition有自己专属的partition号,通常是从0开始的。用户对partition唯一能做的就是在消息序列的尾部追加写入消息。partition上的每条消息都会分配一个唯一的序列号——按照kafka的术语来说,该序列号被称为位移。该位移值是从0开始顺序递增的整数,位移信息可以唯一定位到某partition下的一条消息。
值得一提的是,kafka的partition实际上并没有太多的业务含义,它的引入就是单纯的为了提升系统的吞吐量,因此在创建kafka topic的时候可以根据集群实际情况设置具体的partition数,实现性能的最大化。
Kafka可以将主题划分为多个分区(Partition),会根据分区规则选择把消息存储到哪个分区中,只要如果分区规则设置的合理,那么所有的消息将会被均匀的分布到不同的分区中,这样就实现了负载均衡和水平扩展。另外,多个订阅者可以从一个或者多个分区中同时消费数据,以支撑海量数据处理能力。
为什么要这么设计呢?举个例子:像我们的高速公路,不同的起始点和目的地需要修不同高速公路(主题),高速公路上可以提供多条车道(分区),流量大的公路多修几条车道保证畅通,流量小的公路少修几条车道避免浪费。收费站好比消费者,车多的时候多开几个一起收费避免堵在路上,车少的时候开几个让汽车并道就好了。
offset
前面我们提到,topic partition下的每条消息都被分配一个位移值。实际上,kafka的消费者端也有唯一的概念,但要注意这两个offset属于不同的概念。
显然每条消息在某个partition的位移是固定的,但消费该partition的消费者的位移会随着消费进度不断地前移,但终究不可能超过该分区最新一条消息的位移。
综合之前的内容,我们可以断言kafka中的一条消息其实就是一个<topic,partition,offset>三元组,通过该三元组我们可以在kafka集群中找到唯一对应的那条消息。
replica
既然我们知道partition是有序的消息日志,那么一定不能只保存这一份日志,否则一旦保存partition的kafka服务器挂掉了,其上保存的消息也就都丢失了。分布式系统必然要实现高可靠性,而目前实现的主要途径还是依靠冗余——简单来说,就是备份多份日志。这些备份日志在kafka中被称为副本,他们存在的唯一目的就是防止数据丢失。
副本分为两类:领导者副本和追随者副本。follwer replica是不能提供服务给客户端的,也就是说不负责响应客户端发来的消息写入和消息消费请求。他只是被动的向领导者副本获取数据,而一旦leader replica所在的broken宕机,kafka会从剩余的replica中选举新的leader继续提供服务。
leader和follower
在leader-follower系统中通常只有leader对外提供服务,follower只是被动的追随leader的状态,保持与leader的同步。follower存在唯一的价值就是充当leader的备胎:一旦leader挂掉立即就会有一个追随者选举为新的leader接替他工作。
kafka保证同一个partition的多个replica一定不会分配在同一台broker上。毕竟如果同一个broker上有同一个partition的多个replica,那么将无法实现备份冗余的效果。
ISR
ISR全称是in-sync replica,翻译过来就是与leader replica保持同步的replica集合。只是一个特别重要的概念。前面讲了很多关于kafka的副本机制,比如每个partition可以配置N个replica,那么这是否意味着该partition可以容忍N-1个replica失效而不丢失数据呢?答案是“否”!
kafka为每个partition动态维护一个replica集合。该集合下面的所有replica保存的消息日志都与leader replica保持同步状态。只有这个集合中的所有replica才能被选举为leader,也只有该集合中的replica都接受到了同一个消息,kafka才会将该消息置于“已提交”状态,即认为这条消息发送成功。回到刚才的问题,kafka承诺只要集合中存在一个replica,那些已提交状态的消息就不会丢失——记住这句话的关键点:①ISR中至少存在一个活着的replica;②已提交的消息。(kafka对于没有提交成功的消息不做任何交付保证,他只保证ISR存活的情况下已提交的消息不会丢失。)
正常情况下,partition的所有replica都应该与leader replica保持同步,即所有的replica都在ISR中。因为各种各样的原因,一小部分replica开始落后于leader replica的进度,当滞后到一定程度时,kafka会将这些replica踢出ISR。相反的,当这些replica重新追上了leader的进度时,那么kafka会将他们拉回到ISR中。这一切都是自动维护的,不需要人工干预,因而保证了消息交付语义的同时还简化了用户的操作成本。
使用场景
消息传输
kafka非常适合替代传统的消息总线或消息代理。传统的这类系统擅长于解耦生产者以及批量处理消息,而这些特点kafka基本都具备。除此之外,kafka还具有更好的吞吐量特性,其内置的分区机制和副本机制既实现了高性能的消息传输,同时还打到了高可靠性和高容错性。因此kafka特别适合于实现一个超大量级消息处理应用。
网站行为日志追踪
kafka最早就是用于重建用户行为数据追踪系统的。很多网站上的用户操作都会以消息形式发送到kafka的某个对应的topic上。这些地啊你蕴含了巨大的商业价值,事实上,目前很多创业公司实用机器学习或其他实时处理框架来帮助收集并分析用户的点击流数据。鉴于这种点击流数据量是很大的,kafka超强的吞吐量特性此时就有了用武之地。
日志收集
这个貌似被ELK替代了???
Event Sourcing
Event Sourcing实际上是领域驱动设计的名词,他使用事件序列表示状态变更,这种思想和kafka的设计特性不谋而合。kafka也是用不可变更的消息序列来抽象化表示业务消息的,因此kafka特别适合作为这种英勇的后端存储。
流式处理
等我用到了再更新,暂时不懂可以干嘛~