登 录
注 册
< 大 数 据
Flink
Hadoop
Spark
Hive
HBase
Kafka
其他框架
分布式消息队列
Kafka命令行操作
生产者与幂等性
ExactlyOnce与事务
分区消费策略
手动提交offset
Kafka对接Flume
热门推荐>>>
中台架构
中台建设与架构
Hadoop
源码分析-NN启动(三)
HBase
HBased对接Hive
Linux
Nginx高可用
Python
数据导出工具
Flink
3分钟搭建Flink SQL测试环境
深度学习
卷积神经网络
数据结构与算法
选择合适的算法
MySQL
数据备份恢复
计算机系统
信号量同步线程
Hive
Hive调优参数大全
其他框架
Azkaban Flow1.0与2.0
ClickHouse
表引擎-其他类型
技术成长
最好的职业建议
精选书单
技术成长书单—机器学习
技术资讯
数据在线:计算将成为公共服务
开发工具
IntelliJ IDEA 20年发展回顾(二)
系统工具
Mac命令行工具
虚拟化
内存虚拟化概述
云原生
云原生构建现代化应用
云服务
一文搞懂公有云、私有云...
Java
Spring Boot依赖注入与Runners
Go
Go函数与方法
SQL
SQL模板
安全常识
一文读懂SSO
当前位置:
首页
>>
Kafka
>>
生产者与幂等性
生产者与幂等性
2020-07-04 14:43:01 星期六 阅读:2246
####分区原则 一个topic如果有多个分区,那么生产者在发送的时候到底往哪个分区里写?一般来说有以下几种情况: - 指明partition号的情况下,直接将指明的值作为partition值 如果没有指定partition,只传入key和value,那么默认会将k做hash,再将hash值与这个topic的分区数进行取模 如果既没有指定分区,也没有传入key,只传入value,Kafka会通过轮询的方式将数据平均分到不同的分区 ####生产者数据可靠性保证 为保证producer发送的数据能可靠的发送到指定的topic,topic的每个partition收到producer发送的数据后,都需要向producer发送`ack`(acknowledge,确认收到),如果producer收到ack,就会进行下一轮的发送,否则重新发送数据。 **`1、副本数据同步方案`** - 半数以上分区副本完成同步就发送ack - - 优点:延迟低 缺点:选举新的leader时,容忍n台节点的故障,需要2n+1副本 - 全部完成同步,才发送ack - 优点:选举新的leader是,容忍n台节点的故障,需要n+1个副本 缺点:延迟高 **`2、ISR方案`** 对于上面的同步副本数,Kafka默认是第二种方案,这样会导致一个问题,比如如果有一个分区有9个副本,其中8个都完成了 。有一个挂了,那么producer永远都不会收到ack,导致生产者暂停拥堵。所以Kafka推出了ISR策略进行优化 leader维护了一个动态的in-sync replica set(ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据的同步之后,leader就会给producer发送ack。如果follower长时间未向leader同步数据,则该follower将被剔出ISR,该时间阈值由`replica.lag.time.max.ms`参数设定。leader发生故障之后,就会从ISR中选举新的leader。 **`3、ack应答机制`** 上面两种类型的可靠性保证都会影响生产者的发送速度。在生产中,对于一些不太重要的数据,没必要等ISR中的follower全部接收成功。所以Kafka提供了三种可靠性级别(可通过对生产者acks配置文件进行配置),设置acks的值为以下几种 - 0:producer不等待任何broker的ack 1:producer等待leader分区返回ack后再发送下一条数据。这种情况下:当ack已经被leader返回,但是follower在同步时leader挂掉,会导致数据丢失。 all或者-1:producer等待leader和ISR中的所有follower(注意是ISR中的follower,而不是全部follower)全部落盘后再发送下一条数据。 上面的acks=-1时(或者=all)是会导致重复数据。 解释一下: 1、2、3是某个分区的三个副本,最开始2是leader,1、3是follower。当2收到生产者的消息后,会等待ISR中的follower同步(假设1、3现在都在ISR里面),当1、3都同步完后,2作为leader要向producer发送ack信息。但是在发送这个ack之前,2挂掉了。导致生产者没有收到ack信息,所以生产者会重新发送数据。因为2挂掉了,kafka会自动选主,假设选择1为leader,则1就会收到producer重新发送的消息,从而导致消息重复。 有一个极端情况,acks=-1(或者=all)也会导致数据丢失。即ISR里面只有leader一个分区副本的时候,acks=-1就会退化为acks=1的情况。 ####保证消费者消费数据的一致性 如果leader的offset已经存储到20,但是follower中最大的offse只到15,此时leader挂掉,其中一个follower被选为leader,但是新leader的offset才到15,而消费者刚才已经消费到20,就会导致15-20之间的数据被消费者重复消费。所以Kafka提出了LEO和HW的概念(类似于木桶效应),`只有最慢的那个follower的offset之前的数据才对消费者可见`。 如果follower被提升为leader后,此前的leader又活了。而老leader的offset已经到20,新的leader才到15,这样就导致leader和follower之间的数据乱套了。为 了保证数据存储的一致性,kafka采用了如下方案: `follower故障` follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该partition的HW,即follower追上leader后,就可以重新加入ISR了。 `leader故障` leader发生故障后,会从ISR中选出一个新的leader,之后为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截取掉,然后从新的leader同步数据。 注意:这`只能保证副本之间的数据一致性问题`,并不能保证数据丢失和数据重复问题,因为数据丢失和重复问题是通过ack方案来控制的。高水位是它的下游。