1. 保证分区消息的顺序。同一个生产者给同一个分区写消息一定是有序的
2. 所有的同步副本写入了消息时,才会被认为已经提交 3. 只要有一个副本是活跃的消息就不会丢失 4. 消费者只能提取已经提交的消息broker对消息可靠性的处理
1. 复制系数。即一个消息应该有多少个副本(一般3个),这些副本在机架上如何分布,保证不会应为1个broker挂掉或者一个机架路由有问题而导致不可用。 2. 不完全首领选举。允许不同步的副本作为首领。坏处是对于同一个偏移量,不同步的副本作为首领之后,获取的是新数据,而原来的副本存储的是旧数据。出现场景可能是
1. 假设3个副本,2个副本挂了,首领副本正常运行,这时候首领副本也挂了,随后启动了新的副本,数据不同步;
2. 3个副本中,首领副本正常,但是由于网络延迟跟随副本复制存在一定的延迟,如果首领副本挂了,其它副本都是不同步的3. 最少同步副本。当分区同步副本数少于最少同步副本的时候,就停止接受生产者的消息,抛出异常。以避免不完全选举所产生的数据写入与读出预期不一致的情况
生产者对消息可靠性的处理
生产者对消息可靠性可以从两个方面引入。- 首先是假设acks=1,但是一共有3个副本,假如首领副本这时候恰巧崩溃,而其他的副本会被认为是同步的,对生产者而言,这里丢失了一个消息;
- 其次是假设acks=all,即3个副本都是同步的才确认,如果恰好首领副本崩溃,在选举期间来的消息,生产者只会收到首领不可用的响应,需要生产者自己去处理消息。
因而需要考虑两个方面:
1. 是acks的设置,不过需要处理吞吐量和消息丢失的关系
ack越多丢失概率越小,但是吞吐量少,得等待收到所有的
2. 是生产者的重试机制,对于可重试的采用kafka内部的重试机制,不可重试的错误考虑保存到其它地方,后续进入.
重试带来的风险是消息重复
消费者对消息可靠性的处理
消费者的最大毛病在于万一提交了消息偏移量,但是却没有处理完,导致这段消息将永远不会被处理。所以最关键的地方在于如何处理消息偏移量。- 自动偏移提交:保证只提交已经处理过的偏移量
- 手动偏移提交的策略:确保总是在处理往后再提交,确保提交不过于频繁不过与少,做适当的重试,确保需要一次性语义的场景能够满足
kafka的零拷贝是什么意思?
零拷贝依赖于操作系统。kafka中存在大量数据持久化道磁盘和磁盘文件通过网络发送。传统的方式来说,经历4次拷贝。首先系统将调用文件数据读到内存态Buffer,然后应用程序将内核态读入到用户态buffer,接着用户通过socket发送数据将用户态拷贝到内核态buffer,最后通过DMA拷贝将数据拷贝到NIC 【4次上下文切换】,在linux2.4+操作系统,sendfile系统调用通过零拷贝,数据从DMA拷贝到NIC Buffer,无需CPU拷贝
零拷贝来源,只有两次上下文切换
数据保留时长是多少?
每个主题可以配置保留时长或者大小。每个分区会有若干个片段,当前写入数据的片段(活跃片段),永远不会被删除,假如配置了保留5天的数据,那么会保留5天
默认1G或者一周,以小的为准,一个片段数据满了则关闭当前文件,打开新的,方便查找和删除
数据存储的文件格式?
储存格式与生产者发送,发送给消费者的格式一致。消息里不仅包含建和值,同时有大小,检验和,版本,压缩算法,时间戳
如何直接删除某个键?
应用程序发送一个相同的键,但是值为null的消息【称为墓碑消息】,进行常规清理时,只保留null消息,一段时间后,消费者消费时发现null的记录,知晓应该从数据库中删除,这段时间后,清理线程便清理掉墓碑消息
消费者如果离线了就干不掉了
kafka的compact策略?
适用场景:消息中存在一样的key,但是只需要保留最新的key的value。执行compact的时候,会早内存中构建一个map,key是消息键的hash,值是消息键的偏移量,读取一定量的污浊消息每个片段后,如果当前的消息key存在且偏移量小,值过期,或者是null,就抛弃,否则保存