kafka - 数据同步 - 高水位和日志末端偏移量

kafka 0.11 之前的版本中使用high watermark实现每个分区多副本之间的数据同步,保证多副本之间数据一致性,不过不能保证数据丢失以及数据重复

名词解析
  • leader:Kafka的topic每个分区包含一个leader副本和若干个followers副本,Kafka producer和Kafka consumer的请求由leader来响应处理
  • follower:通过fetch的方式从leader处获取数据进行同步
  • isr:leader以及符合replica.lag.time.max.ms参数要求的follower列表
  • logEndOffset:保存当前副本的可写入数据的偏移量,logEndOffset从0开始计数,如当前副本有2个数据,则logEndOffset = 2
  • highWatermark:1. leader通过其自身的highWatermark记录数据同步到所有isr的最慢进度,所有isr的highWatermark等于最慢的isr的highWatermark 2. 所有leader和followers在故障恢复后会把其自身的logEndOffset设为其自身的high watermark,进行数据截断
  • remoteLogEndOffset:leader副本中保存的关于followers的logEndOffset
相关计算方式
leader.logEndOffset = leader.logEndOffset + n (leader收到producer的n条数据后写入到本地)
leader.highWatermark = min(leader.logEndOffset, leader.remoteLogEndOffset)  
follower.logEndOffset = follower.logEndOffset + n (follower fetch到leader的n条数据后写入到本地)  
follower.highWatermark = min(leader.highWatermark, follower.logEndOffset)  
leader.remoteLogEndOffset = follower.logEndOffset
同步流程之一:正常同步
  1. 初始状态,leader.logEndOffset、leader.highWatermark、follower.logEndOffset、follower.highWatermark、leader.remoteLogEndOffset均相同,处于数据完全同步的状态,假设均为0
  2. leader收到n条数据,假设n > 0(若n == 0则不发生任何变化), leader将其按顺序写入本地,并进行以下计算:
leader.logEndOffset = 0 + n = n
leader.highWatermark = min(leader.logEndOffset(n), leader.remoteLogEndOffset(0)) = 0
  1. 第一轮同步:follower向leader fetch数据,fetch参数中包含fetch.offset(该值等于follower.logEndOffset),leader收到fetch请求后进行以下计算:
leader.remoteLogEndOffset = follower.fetchOffset = follower.logEndOffset = 0
leader.highWatermark= min(leader.logEndOffset(n), leader.remoteLogEndOffset(0)) = 0
  1. follower获取到从leader处同步到的从fetchOffset开始的n条数据(包含数据以及leader.highWatermark),然后把数据按顺序写入到本地,并且进行以下计算:
follower.logEndOffset = 0 + n = n
follower.highWatermark = min(leader.highWatermark(0), follower.logEndOffset(n)) = 0
此时:
leader.logEndOffset == follower.logEndOffset == n
leader.highWatermark == follower.highWatermark == 0
  1. leader收到m条数据,m >= 0(在这期间leader可能没有接收到数据也可能有接收到数据,并且事实上leader接收数据与follower同步数据之间是异步的),并进行以下计算:
leader.logEndOffset = n + m
leader.highWatermark = min(leader.logEndOffset(n + m), leader.remoteLogEndOffset(0)) = 0
  1. 第二轮同步:follower又向leader fetch数据,并进行以下计算:
leader.remoteLogEndOffset = follower.fetchOffset = follower.logEndOffset = n
leader.highWatermark = min(leader.logEndOffset(n + m), leader.remoteLogEndOffset(n)) = n
  1. follower获取到从leader处同步到的从fetchOffset开始的m条数据并写入本地,并且进行以下计算:
follower.logEndOffset = n + m
follower.highWatermark = min(leader.highWatermark(n), follower.logEndOffset(n + m)) = n
此时:
leader.logEndOffset == follower.logEndOffset == n + m
leader.highWatermark == follower.highWatermark == n

==此时在第二轮同步中leader.highWatermark和follower.highWatermark更新到了第一轮leader收到的数据偏移量,因此说highWatermark的更新是延后一轮的==
如果m == 0,则此时又回到完全同步的状态; 如果m > 0,则watermark又开始下一轮的向logEndOffset追赶~

同步流程之二:无producer数据更新

如果leader收到follower的fetch请求后发现没有符合fetch offset的数据,则会放置该请求(不马上返回响应给follower),然后默认等待500ms后才会返回空数据给follower,或者在这期间收到了producer的新数据也会马上返回,其余流程跟流程一一致。

同步流程之三:leader掉线

leader掉线后,会在isr中选举出新的leader,其先前的follower.highWatermark变成leader.highWatermark,follower.logEndOffset变成leader.logEndOffset。等原来掉线的leader恢复后,会变成follower,并且其原来的leader.highWatermark变成follower.highWatermark,==leader.logEndOffset变成folloer.logEndOffset并且重置为其highWatermark的值,并且其他follower的logEndOffset比新leader多出的部分会被截取掉,使其跟新leader保持logEndOffset一致,防止数据不一致==。在这个时候,处于掉线状态的isr(如旧leader)无法被截取掉多出的数据,所以在副本掉线恢复时,引入了使其logEndOffset恢复至其highWatermark的机制,防止此副本数据不一致。

同步流程之四:follower掉线

follower掉线恢复后仍然是follower,并且其follower.logEndOffset重置为其follower.highWatermark,会导致其logEndOffset比其highWatermark多出的那一部分数据丢失,不过可以重新从leader同步

同步流程之五:partition数据丢失

在kafka中有两个参数声明同步的副本数,producer端的ack和broker端的min.insync.replicas
ack有三个选项,ack=0表示producer不需要接收到broker的响应,只需要发出数据给leader就认为已经成功。ack=1表示当数据写入leader时(leader的logEndOffset更新后)就给producer返回成功。ack=all表示需要所有isr都写入成功后(以leader.highWatermark为依据)才给producer返回成功。ack默认值为1
min.insync.replicas默认为1,表示当producer.ack=all时,至少需要同步多少个副本才算写入成功(以leader.highWatermark为依据),如果失败则数据最终不会写入到kafka并返回失败给producer org.apache.kafka.common.errors.NotEnoughReplicasExceptoin。

丢失原因1

ack=0,且leader没有成功写入数据

丢失原因2

ack=1,leader掉线了,某个follower还没有fetch到最新的数据然后就被选举成了新的leader,其他follower从该新leader的logEndOffset处开始同步,并移除他们有的而新leader中没有的数据。
ack=0时也有这个问题。

丢失原因3

ack=all,leader掉线了,某个follower已写入最新的logEndOffset但highWatermark没有更新到最新,然后该follower也掉线了,并且在该follower掉线恢复后成了新的leader(在恢复期间没有其他产生新的leader),这时候由于logEndOffset恢复至其highWatermark值导致数据丢失。
ack=0或1时也有这个问题。

同步流程之六:数据重复

ack=all, 在没有完成所有isr同步时,leader掉线了,此时producer认为写入失败,producer会重新往leader发送数据,而在旧leader掉线前已经写入了数据的follower成为新的leader,导致producer第二次发送的数据和第一次的数据重复写入该新leader并把重复数据同步到其他followers。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容