1. Kafka 写入
1. Kafka 是基于磁盘的吗?Kafka 机器不需要消耗内存?
- JVM 对象存储松散,通常使数据所占内存加倍,通过 OS 缓存二进制数据更紧凑。
- 用 JVM 内存 cache 数据,容易导致 GC,使用 page cache 缓存,不存在 GC 问题。
- 若 JVM 维护了进程内 cache,若要写磁盘,page cache 会再缓存一份,导致内存折半。
- 使用 JVM 进程内 cache,重启 broker 时需要重新加载数据(加载 10G 的数据,可能需要 10min),page cache 不需要重新加载。
2. Kafka 接收
push、pull 方式比较
方式 | 优点 | 缺点 |
---|---|---|
push | 实时性 | 客户端的压力是被动的(不能自己控制可以承受的压力大小),服务端有性能瓶颈(元信息数据保存在服务端) |
pull | 客户端自己控制进度 | 实时性不好 |
3. kafka 分段存储
- .index 为索引文件,.log 为数据文件
- .index 文件中,第一个值表示 partition offset,第二个值表示 file offset。
- 根据客户端传入的 offset,从 .index 文件中查找到对应的 file offset 范围,在 .log 文件中查询对应的数据。
4. Kafka 查询速度快的原因
1. 通过 page cache 实现
- 当读取文件 1,此时 page cache 会将数据加载到 3 个 page 中去(哪怕此时可能只用到其中一个 page 的数据)。
- 假如 100ms 之后又来读取文件 1,此时数据在 page 中已经存在,我们称为命中,此时会直接返回 page 中的数据。
- 返回数据之后,会加载更多的数据到 page 中去。
假如第三次又读取文件 1,我们从 page 中返回数据,并且加载更多的数据到 page 中,此操作称为预读。
2. Kafka zero copy
图 1:数据会在 page cache、JVM 进程、socket 缓冲区进行三次数据拷贝。
- 图 2:只会在 page cache 进行一次拷贝。
- Kafka 通过 netty 实现 zero copy。
5. Kafka 在 PROD 的方案之:网卡流量激增方案
- 如果将 Kafka 机器放到了业务区,当大批量从 Kafka 集群抽取数据时,可能会把交换机的网卡带宽直接打满,此时业务区的其他系统将处于不可用状态。
- 解决方案:使用多个网卡,业务系统和 Kafka 所使用网卡分离。
- Kafka 的 server.properties 文件中不对 host.name、advertised.host.name 做配置,Kafka server 实例就会监听所有网卡。
6. Kafka 优化
producer
- 写入数据:从以下几条考虑:
- ack(0、1、All)
- buffer(压测)
- 数据类型(binary)
-
broker
从
topic partition 个数 / replication 个数
考虑。写非常多的情况:
consumer group:
producer
- ack=all
- broker
- replication:>=2
- IRS: >=2 (Kafka 允许 follower 跟不上 leader 节奏,IRS 表示至少有多少个 follower 跟上了 leader 的节奏,假如设置为2,表示至少有一个 follower 跟上了 leader 的节奏。)
- consumer
- 使用 offset info 记录 partition、offset 的信息,保证了数据落地和 offset commit 的原子性。
- 为了预防 producer 重复发送数据,导致数据重复消费,业务层添加唯一标识 message_id 进行重复过滤。