其他
读文笔记:Kafka 官方设计文档
数据持久化
不用惧怕文件系统
对象的内存开销非常高,通常是实际数据大小的2倍(甚至更多) 随着堆上数据量增大,Java 的 GC 表现也会更糟糕
常量时间就能搞定
效率
操作系统从磁盘将数据读到内核空间的内存页缓存(pagecache) 应用程序从内核空间将数据读到用户空间缓冲区 应用程序将数据从用户空间缓冲区读到内核空间的套接字缓冲区 操作系统将数据从套接字缓冲区读到 NIC 缓冲区,网卡从 NIC 缓冲区读取数据通过网络发出去
生产者(The Producer)
负载均衡
消息交付语义
最多消费一次 - 消息可能会丢失,但不会被重复消费
最少消费一次 - 消息不会丢,但可能被重复消费
仅消费一次 - 每个消息都会被消费且仅消费一次
acks
:acks=0:表示 producer 不需要等分区 leader broker 返回任何响应,将消息存入套接字缓冲区(socket buffer)就当做消息已经发送成功。所以可靠性是没有保证的。 acks=1:表示 分区 leader broker 将消息写入自己的本地日志文件,就向 producer 响应成功,不必等待分区副本 broker 同步好消息。 acks=-1 或 acks=all:表示 分区 leader broker 需要等待所有同步副本 broker 同步好消息并响应成功,才向 producer 响应成功
节点必须维持与 Zookeeper 的 session 连接(通过 Zookeeper 的心跳机制) 如果是一个从节点(follower),则必须不断从 leader 节点同步消息数据,且同步进度没有落后太多
如果 consumer 读取消息后,先向 kafka 提交消费位置,再处理消息;如果该 consumer 挂掉或重启,会可能导致丢消息,从而只能满足“最多处理一次”交付语义。 如果 consumer 读取消息后,是先处理,再提交消费位置;如果该 consumer 挂掉或重启,则可能导致重复消费消息,从而只能满足“最少处理一次”交付语义。
复制
replica.lag.time.max.ms
配置参数判定。日志数据复制:仲裁成员集(Quorums)、同步中副本集(ISRs)和状态机
(备注:这一节我理解得还不太透彻。)
可用性和持久性保证
acks=all
并不是要求所有的副本都确认写入成功,而是在当前同步中副本(ISR)都确认写入成功时,分区 leader 就向 producer 响应成功。例如:某个 topic 被设置为 2 个副本,然后其中一个副本节点挂掉,此时要求 acks=all
的写操作也会成功。如果剩下的副本节点也挂了,那么就会丢消息啦。禁用脏 leader 选举 指定一个最小 ISR 集大小( min.insync.replicas
参数设置):只有当 ISR 集大小大于设定的最小值,分区 [leader] 才会接受消息写入。这个设置只有当 producer 使用acks=all
时才会生效。(注:在我们生产环境中,分区副本数通常申请为 3(包含 leader),那么min.insync.replicas
应该设定为 2,但默认是 1。使用 1,那么当分区只有一个副本(即 leader),producer 也能写入成功,但如果这个副本又挂了,就会丢数据。)
副本管理
消费者消费进度跟踪
end
公众号(zhisheng)里回复 面经、ClickHouse、ES、Flink、 Spring、Java、Kafka、监控 等关键字可以查看更多关键字对应的文章。