Kafka数据读写过程
读取数据
- consumer请求zk,获取该topic所对应的所有分区的信息,找到分区的主副本位置
- consumer找到对应的分区请求消费指定的第几条offset对应的数据
- 通过二分法来对比segment的文件名,判断这条数据在哪个segment文件中
- 找到对应的segment编号,从内存中访问该segment的index文件,(因为index的稀疏索引,相当于二级索引)
- 通过index的稀疏索引找到log文件中数据的位置,然后直接从该位置来访问offset对应的数据
- 补充:
- 通过offset偏移量与log/index文件命名来计算这条数据在log文件中的存储偏差
- 通过存储偏差来计算对比index文件稀疏索引,索引键就是log文件存储的第几条数据,索引值是对应数据位置
- 通过索引键得到索引值,通过索引值去log文件中找到对应的offset数据
- 若消费者组是第一次启动(通过groupid来判断),第一次在zk中注册,需要设置从哪个位置(earlist从0开始,latest最新)开始消费,默认会消费latest最新的数据
- kafka保证集群中至少有一个ISR副本,若无ISR副本可用,则从AR中选择健康状态不是很好的节点提供服务
写入数据
- producer请求zk,获取topic的元数据信息(主分区信息,主副本位置,可用副本等)
- producer在本地缓存数据,达到条件(指定缓存大小)后将数据PUSH到消费主题topic中
- 根据producer指定的分区规则(hash取余,轮询,指定,自定义)将数据写到对应分区的主副本中
- 在写入主副本时,根据offset的规则生成offset,将offset和这条数据等信息写入pagecache中,
- 当pagecache内存缓存达到条件时,将数据flush写入segment文件中,将offset和生产的数据(分区级别的)写入.log文件中,将稀疏索引和offset写入到.index中
性能保证
- 概念: kafka效率之所以高的原因,除了硬件和架构设计还有其他方面
- 内容:
- Pagecache 页缓存,将数据先写入内存进行缓存,后台通过线程不断刷写到segment文件中
- Zero copy :零拷贝,硬件机制,数据只在内存中传递
- 顺序读写硬盘:避免了寻址使用随机读写来提高读写速度
ACK确认
概念: 用于返回写入请求确认,有0,1,all
-
分类:
- ack="0" 不需要确认,生产者将数据交给kafka之后,就立即返回生产下一条,不管kafka是否存储成功,性能最快,但是数据不安全,容易产生数据丢失,概率大
- ack="1" 确认写入主副本,生产者将数据交给kafka后,等待kafka将数据写入分区内主副本后返回ack确认,然后再返回生产下一条,kafka的默认设置,也可能产生数据丢失,概率小,性能中等
- ack="all"确认写入所有副本或指定个数副本,生产者将数据交给kafka后,等待kafka将数据写入分区内所有副本后返回ack确认,然后再返回生产下一条,性能最低,数据最安全
-
补充:
- 问kafka如何保证数据安全,不丢失不重复
- kafka通过Ack确认来保证写入数据不丢失,通过offset偏移量保证数据消费不重复