我想了解kafka经纪人的log.flush.interval.messages
设置。
强制执行之前写入日志分区的消息数 日志上的fsync
是否意味着当它达到指定数量的消息时它会写入磁盘中的另一个文件?如果是,那么:
同时
消息仅在从段文件(http://notes.stephenholiday.com/Kafka.pdf)刷新到磁盘后才会向消费者公开
然后,消费者总是从磁盘读取,因为它无法从段文件读取?
存储在段文件和磁盘上有什么区别?
答案 0 :(得分:14)
我想要警告你的第一件事就是that Kafka paper有点过时关于所有这些是如何工作的,因为当时Kafka没有复制。我建议你在Kafka文档的Replication Section中阅读(如果还没有这样做)。
正如本文所述,每个到达的消息都被写入段文件。但您必须记住,当您写入文件时,数据不会立即传输到磁盘设备,而是首先进行缓冲。强制执行此写操作的方法是调用fsync系统调用(请参阅man fsync),这就是" log.flush.interval.messages"和" log.flush.interval.ms"参加进来。通过这些设置,您可以准确地告诉Kafka何时进行此刷新(在一定数量的消息或一段时间之后)。但请注意,Kafka一般建议您不要设置这些并使用复制来提高持久性并允许操作系统的后台刷新功能,因为它更有效(请参阅Kafka文档中的Broker configs)。 / p>
对于问题的第二部分,正如Kafka文档的Replication Section中所提到的那样,只有已提交的消息(一条消息被认为是#34;已提交"当该分区的所有同步副本时已经将它应用到他们的日志中)被发给消费者。这是为了避免消费者在领导失败时可能会看到可能丢失的消息(因为它还没有被提升到磁盘)。
答案 1 :(得分:2)
@ user1870400
log.flush.interval.ms
和log.flush.interval.messages
均设置为“最大”。它使Kafka刷新日志到磁盘(例如Linux中的fsync
)仅取决于文件系统。
因此,即使您将ack设置为“ all”,跟随者relica(和leader本身)也无法确保从leader读取的日志已刷新到磁盘。并且如果所有副本在刷新前崩溃,日志将丢失。
卡夫卡之所以选择这样一个“不安全的”选择,是因为,正如该论文所说的那样:
Kafka avoid explicitly caching messages in memory at the Kafka layer.
Kafka rely on the underlying file system page cache.
This has the main benefit of avoiding double buffering---messages are only cached in the page cache.
This has the additional benefit of retaining warm cache even when a broker process is restarted.
为了更好地利用文件系统缓存,kafka默认将两个刷新间隔都设置为max。如果即使N个代理崩溃也要摆脱丢失的消息,请将主题级别的配置flush.messages
或代理级别的配置log.flush.interval.messages
设置为1。