@Catyee
2021-08-09T21:09:51.000000Z
字数 2311
阅读 412
大数据
kafka是一个分布式消息中间件,或者说分布式的消息队列,消息中间件可以解耦生产者和消费者,解决生产者生产速率和消费者消费速率不匹配的问题。消息中间件一般分为点对点的模式和发布订阅模式,区别就在于消息能不能被重复消费,我们一般认为kafka是发布订阅模式,但是kafka的消费者可以定义消费者组,组与组之间可以重复消费互不影响,但是对组内的消费者,一条消息只能被一个组队的消费者消费,个人认为相当于kafka通过消费者组变相实现了点对点模式。kafka使用topic来组织数据,或者说对数据进行分类,但是topic只是逻辑上的概念,topic可以分为多个区,数据是真正存储再分区中的,kafka保证同一个分区中数据有序,但是不保证分区之间有序,每个分区可以设定多个副本来进行容错。分区的能力使kafka有了能够分布式的能力。
kafka使用主题来组织数据,每个主题被分为若干个分区,每个分区有多个副本,这些副本被保存在broker上。副本有两种类型,leader和follower,所有生产者请求和消费者请求都会经过leader,follower不处理来自客户端的请求,他们唯一的任务就是从leader复制消息,保持与leader一致的状态,如果leader崩溃,其中的一个跟随者就会被提升为新的leader。
leader可以知道每个跟随者的复制进度,如果跟随者在一定时间(可以设置)内没有向leader请求数据,或者没有没请求最新的数据,leader会认为它属于不同步的状态,会进入不同步列表。而那些能跟上同步进度的副本叫做同步副本,处于同步列表。当leader崩溃之后,只有同步列表中的副本才能成为新的leader。
生产请求和获取请求都必须发送给分区的首领副本,客户端会先发送一个元数据请求给broker,broker的响应信息会指明客户端感兴趣的主题的所有分区信息,每个分区有哪些副本,以及哪个副本是首领。
在生产请求中可以配置一个acks的参数,这个参数指定了需要多少个副本确认才认为一个消息写入是成功的,如果acks=all,就是所有副本都要确认,如果acks=1就只需要首领确认,如果acks=0,那生产者把消息发出去就可以了,完全不需要等待broker的响应。
客户端发送请求,向 broker请求主题分区里具有特定偏移量的消息,客户端还可以指定broker最多可以从一个分区里返回多少数据。这个限制是非常重要的,因为客户端需要为broker返回的数据分配足够的内存。如果没有这个限制, broker返回的大量数据有可能耗尽客户端的内存。
如果请求的偏移量存在,broker将按照客户端指定的数量上限从分区里读取消息,再把消息返回给客户端。 Kafka使用零复制技术向客户端发送消息一一也就是说,Kafka直接把消息从文件(或者更确切地说是 Linux文件系统缓存)里发送到网络通道,而不需要经过任何中间缓冲区。这是Kafka与其他大部分数据库系统不一样的地方,其他数据库在将数据发送给客户端之前会先把它们保存在本地缓存里。这项技术避免了字节复制,也不需要管理内存缓冲区,从而获得更好的性能。
kafka的基础存储单元是分区,在创建topic的时候,kafka会先决定如何在broker间分配分区,
kafka在数据传递可靠性方面具备很大的灵活性,根据不同的配置可以有不同程度的可靠性。kafka的复制机制和分区的多副本架构是kafka可靠性保证的核心。
broker有3个配置参数会影响kafka消息存储的可靠性
第一个是复制系数(replicatlon.factor),默认复制系数是3,也就是分区会有三个副本,更高的复制系数会带来更高的可用性和更少的故障,但是副本变多也意味着会占用更多的磁盘空间。所以需要权衡。
第二个参数是不完全的首领选举(unclean.leader.election),这个参数默认为true。完全的首领选举指选举过程中没有丢失数据,也就是说提交的数据同时存在于所有的同步副本上。这个选举就是完全的,但是如果首领不可用的时候,其它副本都是不同步的,这种情况就是两难的选择,如果不同步的副本不能成为新的首领,那么在崩溃的首领恢复之前这个分区都是不可用的。如果允许不同步的副本成为新的首领,那么在这个副本变为不同步之后写入旧首领的消息会全部丢失,导致数据不一致。
也就是说,如果我们允许不同步的副本成为首领,那么就要承担丢失数据和出现数据不一致的风险。如果不允许它们成为首领,那么就要接受较低的可用性,因为我们必须等待原先的首领恢复到可用状态。
第三个参数是最少同步副本数(min.insync.replicas),比如三个副本,一个是首领副本,另外两个是跟随者,但是跟随者有可能都是不同步的状态,假如把最少同步副本数设为2,那么当两个跟随者副本都是不同步状态的时候,leader会停止接受生产者的请求,生产者会收到一个报错,消费者还是可以继续消费,相当于变成了只读的状态。只有等待至少一个跟随者再次变为同步状态之后才会允许继续生产。
生产者的配置也会影响可靠性。生产者有三种不同的确认模式,在生产请求中可以配置一个acks的参数,这个参数指定了需要多少个副本确认才认为一个消息写入是成功的,如果acks=all,就是所有副本都要确认,如果acks=1就只需要首领确认,如果acks=0,那生产者把消息发出去就可以了,完全不需要等待broker的响应。