前言
一、Kafka的架构 1.kafka基本概念:
- producer 生产者 :负责将消息发送到broker;
- consumer 消费者:从broker中接收消息;
- consumer group消费者组:由多个消费者组成,每个消费者负责消费不同的分区数据。一个分区只能由一个组内消费者消费;消费者组之间互不影响。
- Broker可以看做一个独立的Kafka服务节点或者kafka服务实例;
- topic:是一个逻辑的概念,包含很多partition,同一个topic下不同partition是消息内容是不同的。
- partition:为了实现扩展性一个非常庞大的topic可以分布到多个broker上,一个topic可以分为多个partition,每个partition是一个有序的消息队列。
- Replica:副本,同一个分区的不同副本保存的是相同的消息。为了保证集群中某个节点发生故障时,该节点的消息不丢失,且kafka仍旧可用 ,kafka提供了副本机制 。一个topic的每个分区都有多个副本。一个leader和若干个follower。
- leader :每个分区的多个副本中的主,生产者和消费者只和leader交互。
- follower:每个分区的从副本,负责leader中同步数据,保持和leader数据的同步。leader发生故障,从follower中重新选举新的leader副本对外提供服务。
1.AR (all replicas) 所有的Replica 称为AR;
2.ISR(in sync replicas) 所有与leader副本保持一定程度同步的列表
3.OSR(out sync replica) 与leader副本同步滞后过多的replica组成了OSR;
Leader会负责维护和跟踪ISR集合中所有follower消息同步滞后状态,当某个follower副本落后于Leader太多时(落后的阈值可以设置)就会将其放入OSR列表中,当follower副本追上了leader进度时就会将其放回ISR集合。
默认情况下只有ISR列表中的follower才会被选为leader。
3.如何确定当前读到那条消息分区日志文件
LogsStartOffset :日志文件开始标识;
LogsEndOffset:代表即将要写入消息的偏移量offset;
HW:分区ISR集合中的每个副本都会维护自己的LEO,而ISR集合中最小的
LEO即为分区的HW。
1.发后即忘 : 只管往kafka里面发消息,不关心是否发送成功
2.同步:producer.send() 返回一个Future对象,调用get方法进行同步等待可以知道发送是否成功。
3.异步:通过producer.send()中传送一个回调函数
1.轮询:依次将消息发送给该topic下的所有分区,如果在创建消息的时候key为null kafka默认采用这种策略
2.key指定分区:在创建消息时key不为空并且使用默认分区器,kafka会将key进行hash,然后根据hash值映射到制定的partition上。这样的好处是key相同的消息会在同一个分区。虽然kafka不能保证全局有序性。但是在每个分区下的消息是有序的,按照顺序消费。但是此时partition数量发生变化就不能保证有序性。
3.自定义策略
4.指定分区发送
kafka不支持读写分离,其实读写分离设计思想的目的是实现负载均衡。但是kafka通过分区特性可以实现。而且如果设计读写分离就要考虑数据一致问题以及延时问题。
7 kafka的负载均衡会有什么问题?
1.broker端分布不均,当创建topic的时候会出现某些broker分配到的分区数多而某些broker分配的分区较少;
2.生产者写入消息不均 生产者可能只对某些broker中的leader副本进行大量写操作。
3.消费者消费不均 消费者可能只对某些broker中的leader副本进行大量消费
4.leader副本切换不均。当主从副本进行切换或者分区副本进行了重新分配后,可能会导致各个broker中的leader分配不均匀。
1.acks:当acks = 1时(默认为1)生产者发送消息只要leader写入成功。这种情况出现的问题是leader写入成功但是未同步到follower,leader出现问题,这条消息就会丢失。
2.acks=0 生产者发送消息之后不需要等待响应,这种情况只要broker处理写消息时出现问题就会造成消息丢失。
3.acks = -1 或者 acks = all 。生产者发送消息后,需要等待ISR中的所有副本都写成功后才能收到服务端的响应。
(2)消息发送过程中失败重试来保证消息的可靠性
(3)消费者端手动提交位移(offset)默认情况下当消费者收到消息后就会自动提交位移。但是如果消费者消费出错,没有进行真正的业务处理或者消息处理失败,也会造成消息丢失,所以我们可以开启手动提交位移等待正常业务处理完成后再提交位移offset;
(4)从副本机制考虑由于kafka的副本机制ISR,它可以根据多副本的LEO确定HW,当leader副本挂掉之后,选举出的新leader仍然可以保证消息offset的正确性。
9. kafka 的消费方式有哪些?点对点、发布订阅
点对点(1)如果所有消费者都属于同一个消费者组,那么每个消费者会固定消费其中一个partition;
(2)发布-订阅 如果所有消费者属于不同的消费组,那么所有的消息都会被投递给每个消费者,
分区再分配时为了解决负载均衡问题。
比如场一:当集群中的一个节点下线。如果该节点的分区是单副本的那么分区将变得不可用。如果是多副本的就会进行leader进行选举,再其它机器上选取出新的leader。
kafka并不会将失效的分区迁移到其它broker。这样可能会影响其它服务的可用性和可靠性。
场景二、当集群新增broker时,只有新的主题分区会分配在该broker上,而老的分区不会分配在该broker上。就会造成老节点和新节点的负载不均衡。
为了解决上述问题,kafka提出了一种分区再分配策略。
分区再分配的原理:就是通过控制器给分区新增新的副本,然后通过网络把旧的副本数据拷贝到新的分区副本中,再将旧的分区副本删除。当然为了保证服务可用性,在复制过程中还会有一系列保证性能的操作。比如复制限流。
其实读写分离的一个好处就是让一个节点去承担另一个节点的负载压力。也就是能做到一定程度的负载均衡,而kafka是通过partition来进行负载均衡的。
但是读写分离由于数据节点之间的数据同步,会造成数据一致性问题以及延迟问题。读写主从节点的磁盘造成的延迟问题,对一些延迟性要求较高的应用来说并不适用。
失效副本为比leader数据延迟相差很多的follower(10秒)
将失效的follower移除ISR,等速率接近leader再加入ISR。
1.顺序读写
磁盘分为顺序读写和随机读写,基于磁盘的随机读写确实很慢,但是顺序读写的性能却很高。
2.PageCahce
kafka利用了操作系统本身的pageCahe;
3.零拷贝技术
kafka使用了零拷贝技术,直接将数据从内核空间的读缓冲区拷贝到内核空间的socket缓冲区。然后再写到NIC(网络接口控制器)缓冲区,避免了内核空间和用户空间直接的切换。
4.分区分段+索引
kafka的message是按照topic分类存储的。topic中的数据又是按照一个一个的partition存储到不同的broker节点。每一个partition对应了系统上的一个文件。而partition又是按照segment分段存储的。同时kafka为分段之后的数据建立了索引。一定程度上提高了读取数据的并行度。
5.批量读写
kafka数据也是批量读写的。这样可以避免在网络上频繁传输单个消息带来的延迟和带宽开销。假设网络带宽为10M/S,一次性传输10M的消息比传输1KB的消息1万次显然要快的多。
6.批量压缩
kafka把所有消息都变成一个批量的文件,并且进行合理的压缩。写入数据的时候由于单个partition是末尾添加所以速度较快。
kafka有三次消息传递的过程。生产者发送消息给Broker,Broker同步消息和持久化消息,Broker将消息传递给消费者。
1.生产者发送数据。当acks=0时只要服务端写消息出现 任何问题都会导致消息丢失。
2.ack=1时只要leader副本成功写入消息就代表成功。这种方案在于当返回成功之后如果leader和follower还没来得及同步,leader就崩溃了,那么重新选举后的leader就没有这条消息,消息会丢失。
3.Borker 存储数据kafka通过PageCache将数据写入磁盘。PageCahce就是当往磁盘文件中写入的时候,系统会将数据流写入缓存,但是什么时候将缓存数据写入文件是由操作系统决定的。如果此时机器挂掉,也是会出现消息丢失的。
4.消费者在开启自动提交offset之后。只要消费到消息就会提交偏移量。如果业务还没来得及处理或者处理失败也会丢失消息。
kafka的事务有两种:
producer和consumer。 producer事务是为了解决kafka跨分区会话问题。kafka每次启动的producer的PID都是随机分配的。我们可以手动给producer分配一个全局唯一id,也就是transactionid。简称TID。
将PID和TID绑定。在第一次注册懂啊broker时,borker记录TID并生成一个新的组件,transcation_state 保存TID的事务状态信息。当producer重启后会带上TID和新的PID向broker发送请求。当发现TID一致时,producer就会获取之前的PID,覆盖新的PID,并获取上一次事务状态信息,从而继续上次工作。
consumer需要确保消费和提交位置一致且具有事务功能。
十六 数据传输的事务种类?数据传输的事务定义有三种级别:
最多一次:消息不会重复发送,最多传输一次,可能漏发
最少一次:消息不回漏发,最少被传输一次
精确一次:消息不会重复也不会漏发



