通过kafka学习数据一致性

kafka哪些环节存在数据不一致

数据复制

数据从主节点(leader)复制到从节点(follower)的过程中,由于网络延迟、节点故障或其他原因
可能导致从节点未能及时获取或处理主节点的数据变更,从而产生数据不一致

消息提交

消息提交涉及多个阶段,包括生产者发送消息、消息被写入日志、消息被复制到从节点等。
如果在这个过程中发生错误或异常,可能导致消息丢失或重复,进而引发数据不一致。

消费者处理

消费者在处理消息时,如果因为某些原因(如网络中断、消费者进程崩溃等)未能成功处理消息
而消息又被重新投递给其他消费者处理,也可能导致数据不一致。

分区重新分配

在Kafka中,如果分区的leader节点发生故障,Kafka会触发分区重新分配,将leader切换到其他节点
在这个过程中,如果切换不及时或切换过程中发生错误,可能导致数据不一致。

kafka如何保证数据一致性

一条消息从生产到消费完成,可以划分三个阶段:
• 生产阶段:从消息在 Producer 创建出来,经过网络传输发送到 Broker 端。
• 存储阶段:消息在 Broker 端存储,如果是集群,消息会在这个阶段被复制到其他的副本上
• 消费阶段:Consumer 从 Broker 上拉取消息,经过网络传输发送到Consumer上

消息传递语义

首先当 Producer 向 Broker 发送数据后,会进行 commit,如果 commit 成功,由于 Replica 副本机制的存在,则意味着消息不会丢失,但是 Producer 发送数据给 Broker 后,遇到网络问题而造成通信中断,那么 Producer 就无法准确判断该消息是否已经被提交(commit),这就可能造成 at least once 语义。

在 Kafka 0.11.0.0 之前, 如果 Producer 没有收到消息 commit 的响应结果,它只能重新发送消息,确保消息已经被正确的传输到 Broker,重新发送的时候会将消息再次写入日志中;而在 0.11.0.0 版本之后, Producer 支持幂等传递选项,保证重新发送不会导致消息在日志出现重复。为了实现这个, Broker 为 Producer 分配了一个ID,并通过每条消息的序列号进行去重。也支持了类似事务语义来保证将消息发送到多个 Topic 分区中,保证所有消息要么都写入成功,要么都失败,这个主要用在 Topic 之间的 exactly once 语义。

启用幂等传递的方法配置:enable.idempotence = true
启用事务支持的方法配置:设置属性 transcational.id = “指定值”

从 Consumer 角度来剖析, Offset 是由 Consumer 自己来维护的, 如果 Consumer 收到消息后更新 Offset, 这时 Consumer 异常 crash 掉, 那么新的 Consumer 接管后再次重启消费,就会造成 at most once 语义(消息会丢,但不重复)。
如果 Consumer 消费消息完成后, 再更新 Offset,如果这时 Consumer crash 掉,那么新的 Consumer 接管后重新用这个 Offset 拉取消息, 这时就会造成 at least once 语义(消息不丢,但被多次重复处理)。

默认 Kafka 提供「at least once」语义的消息传递,允许用户通过在处理消息之前保存 Offset的方式提供 「at most once」 语义。如果自己实现消费幂等,理想情况下这个系统的消息传递就是「exactly once」, 也就是保证不丢失、且只会被精确的处理一次,但是这样是很难做到的。

kafka如何保证消息不丢失?

生产阶段

Kafka生产者异步发送消息并返回一个Future代表发送结果

首先需要获取返回结果判断是否发送成功。
消息队列通过最常用的请求确认机制,来保证消息的可靠传递:当代码调用发消息方法时,消息队列的客户端会把消息发送到 Broker,Broker 收到消息后,会给客户端返回一个确认响应,表明消息已经收到了。客户端收到响应后,完成了一次正常消息的发送。

Producer(生产者)保证消息不丢失的方法:
1. 发送确认机制:
Producer可以使用Kafka的acks参数来配置发送确认机制。
通过设置合适的acks参数值,Producer可以在消息发送后等待Broker的确认。
确认机制提供了不同级别的可靠性保证,包括:
• acks=0:Producer在发送消息后不会等待Broker的确认,这可能导致消息丢失风险。
• acks=1:Producer在发送消息后等待Broker的确认,确保至少将消息写入到Leader副本中。
• acks=all或acks=-1:Producer在发送消息后等待Broker的确认,确保将消息写入到所有ISR(In-Sync Replicas)副本中。这提供了最高的可靠性保证。

2. 消息重试机制:
Producer可以实现消息的重试机制来应对发送失败或异常情况。
如果发送失败,Producer可以重新发送消息,直到成功或达到最大重试次数。
重试机制可以保证消息不会因为临时的网络问题或Broker故障而丢失。

Broker存储阶段

正常情况下,只要 Broker 在正常运行,就不会出现丢失消息的问题
但是如果 Broker 出现了故障,比如进程死掉了或者服务器宕机了,还是可能会丢失消息的。

在kafka高性能设计原理中了解到kafka为了提高性能用到了 Page Cache 技术
在读写磁盘日志文件时,其实操作的都是内存,然后由操作系统决定什么时候将 Page Cache 里的数据真正刷入磁盘
如果内存中数据还未刷入磁盘服务宕机了,这个时候还是会丢消息的。

为了最大程度地降低数据丢失的可能性,可以考虑以下方法:
持久化配置优化:可以通过调整 Kafka 的持久化配置参数来控制数据刷盘的频率,从而减少数据丢失的可能性。例如,可以降低 flush.messages 和 flush.ms 参数的值,以更频繁地刷写数据到磁盘。
副本因子增加:在 Kafka 中,可以为每个分区设置多个副本,以提高数据的可靠性。当某个 broker 发生故障时,其他副本仍然可用,可以避免数据丢失。
使用acks=all:在生产者配置中,设置 acks=all 可以确保消息在所有ISR(In-Sync Replicas)中都得到确认后才被视为发送成功。这样可以确保消息被复制到多个副本中,降低数据丢失的风险。
备份数据:定期备份 Kafka 的数据,以便在发生灾难性故障时可以进行数据恢复。

消费阶段

消费阶段采用和生产阶段类似的确认机制来保证消息的可靠传递,客户端从 Broker 拉取消息后,执行用户的消费业务逻辑,成功后,才会给 Broker 发送消费确认响应。如果 Broker 没有收到消费确认响应,下次拉消息的时候还会返回同一条消息,确保消息不会在网络传输过程中丢失,也不会因为客户端在执行消费逻辑中出错导致丢失。

自动提交位移:Consumer可以选择启用自动提交位移的功能。当Consumer成功处理一批消息后,它会自动提交当前位移,标记为已消费。这样即使Consumer发生故障,它可以使用已提交的位移来恢复并继续消费之前未处理的消息。
手动提交位移:Consumer还可以选择手动提交位移的方式。在消费一批消息后,Consumer可以显式地提交位移,以确保处理的消息被正确记录。这样可以避免重复消费和位移丢失的问题。

数据一致系统设计特点

保证数据一致性,需要通过成功后commit的操作,消费过程中记录消费标记。成功与失败的情况都打上标志
Kafka作为一个分布式发布-订阅消息系统,其数据一致性的系统设计特点主要包括以下几个方面:

分区与副本机制

Kafka将数据分成多个分区(Partition),每个分区在集群中有多个副本(Replica)。
这些副本分布在不同的Broker上,以实现数据的冗余备份和高可用性。
当某个Broker发生故障时,其他Broker上的副本可以接管服务,保证数据的持续可用。

ISR(In-Sync Replicas)机制:
ISR是Kafka中用于维护数据一致性的重要机制。它包含所有与Leader保持同步的副本。
当ISR中的副本数量不足时,Kafka会暂停写入操作,以防止数据不一致。
只有当ISR中的副本数量恢复到一定数量时,才会恢复写入操作。

消息提交确认

生产者发送消息到Kafka时,需要等待消息被写入ISR中的副本并得到确认,以确保消息被成功存储
消费者在处理消息时也需要定期提交偏移量(Offset),以便在发生故障时能够从正确的位置继续消费。

原子性操作

Kafka保证消息在分区内的顺序性和原子性。
在同一分区内的消息会按照发送的顺序被消费,且不会被其他消息插入打断。
这有助于保证数据的一致性和正确性。

容错处理

当Kafka集群中的节点发生故障时,Kafka会自动进行故障转移和恢复操作。
这包括从ISR中选择新的Leader、重新同步数据等,以确保数据的持续可用和一致性。

总结

Kafka通过分区与副本机制、ISR机制、消息提交确认、原子性操作和容错处理等手段,确保数据一致性。
这些设计使得Kafka能够在分布式环境中实现高吞吐量、持久化存储、可扩展性和高可靠性等特性
从而满足各种复杂场景下的数据一致性需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/689367.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF控件Spire.PDF for .NET【安全】演示:如何在 PDF 中添加签名字段

Spire.PDF for .NET 是一款独立 PDF 控件,用于 .NET 程序中创建、编辑和操作 PDF 文档。使用 Spire.PDF 类库,开发人员可以新建一个 PDF 文档或者对现有的 PDF 文档进行处理,且无需安装 Adobe Acrobat。 E-iceblue 功能类库Spire 系列文档处…

js之es新特性

ES6 (ECMAScript 2015) 1. let 和 const let 允许声明一个块作用域的变量。const 允许声明一个块作用域的常量。 let x 10; if (x 10) {let x 20; // 这里的 x 和外面的 x 不是同一个变量console.log(x); // 20 } console.log(x); // 10const y 5; // y 10; // 会抛出错…

PyCharm 新建目录 (directory or folder)

PyCharm 新建目录 [directory or folder] 1. 新建目录2. Enter new directory name -> OKReferences 1. 新建目录 right mouse click on the project -> New -> Directory 2. Enter new directory name -> OK ​​​ References [1] Yongqiang Cheng, https:/…

go redis

go redis 快速入门 安装: go get github.com/redis/go-redis/v9然后创建客户端: package mainimport "github.com/redis/go-redis/v9"func main() {rdb : redis.NewClient(&redis.Options{Addr: "47.109.87.142:6379",Pa…

C++_design_model_observer

/* 观察者模式是一种常用的设计模式&#xff0c;用于在对象之间建立一种一对多的依赖关系&#xff0c;当被观察的对象发生变化时&#xff0c; 所有依赖于它的对象都能够得到通知并自动更新。下面是一个使用C实现观察者模式的例子&#xff1a; */#include <iostream> #inc…

Redis篇----第六篇

系列文章目录 文章目录 系列文章目录前言一、Redis 的持久化机制是什么?各自的优缺点?二、Redis 常见性能问题和解决方案:三、redis 过期键的删除策略?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…

已经打包好了的vue dist文件夹,如何用electron打包成exe桌面应用

先在项目根目录下&#xff08;非dist根目录&#xff09;安装electron electron-packager npm install electron再在项目根目录下&#xff08;非dist根目录&#xff09;安装electron-packager npm install electron-packager 然后在dist文件夹下创建main.js文件,内容为 cons…

如何查看springboot依赖的JDK版本

通过maven构建Java项目或者使用源代码进行Java编译时&#xff0c;常常遇到JDK版本和Springboot版本不匹配的问题&#xff0c;导致编译失败&#xff0c;比如出现如下错误&#xff1a; org/springframework/beans/factory/InitializingBean.class [ERROR] 类文件具有错误的…

Unix I/O 模型及Java I/O 模型详解

在Unix Socket的输入操作中&#xff0c;可以将其分为以下几个阶段&#xff1a; 等待数据就绪(内核空间)&#xff1a; 在这个阶段&#xff0c;应用程序通过调用阻塞式的读取函数&#xff08;如recv&#xff09;或非阻塞式的读取函数&#xff08;如recv、recvfrom&#xff09;等待…

可扩展性和性能:数字化成功的支柱

在动态的数字技术世界中,用户的期望和对数字系统的需求不断增加,可扩展性和性能已成为孪生要素。在本文中,我们将全面探讨软件和系统设计的两个基本方面:水平扩展、垂直扩展和性能优化。 简介:关键当务之急 考虑一个场景:您正在管理一个电子商务平台,限时抢购导致网站…

入门级10寸加固行业平板—EM-I10J

亿道信息以其坚固耐用的智能终端设备而闻名&#xff0c;近日发布了一款理想入门级 10 英寸加固平板电脑—I10J。 EM-I10J​​ 这是一款 10 英寸的平板电脑&#xff0c;主要运行 Windows 10操作系统&#xff0c;带有硬化塑料外壳&#xff0c;具有 IP65 防水防尘功能和 MIL-STD 8…

线性dp之石子合并

设有 N堆石子排成一排&#xff0c;其编号为 1,2,3,…,N。 每堆石子有一定的质量&#xff0c;可以用一个整数来描述&#xff0c;现在要将这 N 堆石子合并成为一堆。 每次只能合并相邻的两堆&#xff0c;合并的代价为这两堆石子的质量之和&#xff0c;合并后与这两堆石子相邻的…

注册及搭建小程序开发环境

一、注册小程序账号 打开微信公众平台&#xff0c;通过邮箱注册小程序账号&#xff08;每个邮箱账号&#xff0c;只能注册一个小程序&#xff09;。 注册完成后&#xff0c;登录邮箱&#xff0c;打开激活地址&#xff0c;按照邮件提示&#xff0c;填写信息&#xff0c;激活账号…

MongoDB语言命令

文章目录 MongoDB shellMongoDB数据类型数据插入数据查询数据删除数据更新MongoDb数组更新和时间序列MongoDB特殊索引mongoDB权限设置 MongoDB shell 1、MongoDB用文档的形式存储数据&#xff0c;BSON的数据格式。 2、MongoDB与传统数据库相比&#xff0c;集合相当于表&#x…

springboot 任务执行和调度详细介绍

Spring Boot支持任务执行和调度&#xff0c;这可以通过Spring框架的TaskExecutor和TaskScheduler接口来实现。这些功能允许你异步执行任务和定时执行任务&#xff0c;这在处理批量作业、定时任务和异步服务时非常有用。 任务执行 Spring的TaskExecutor接口提供…

redis的hash数据结构底层简记

hash&#xff1a;k和v都是string的hash表。 HSET&#xff08;设置集合数据&#xff0c;4.0之前只能设置1个&#xff0c;之后可以设置多个&#xff09;&#xff0c;HSETNX(若k不存在则设置对应v)&#xff0c;HDEL&#xff08;删除指定kv&#xff0c;可以一次删除多个&#xff09…

Eclipse - 查看工程或者文件的磁盘路径

Eclipse - 查看工程或者文件的磁盘路径 1. Help -> Eclipse Marketplace -> Find: Explorer -> Eclipse Explorer 4.1.0 -> Install2. right-click -> Open in ExplorerReferences 1. Help -> Eclipse Marketplace -> Find: Explorer -> Eclipse Explo…

Java 中使用Collections类来反转集合的顺序

如何使用Collections类来反转集合的顺序 在Java中&#xff0c;Collections类提供了一些有用的静态方法&#xff0c;用于操作集合。然而&#xff0c;Collections类并没有直接提供反转集合顺序的方法。但是&#xff0c;你可以使用List接口中的Collections.reverse(List<?>…

门店数字化之旅:如何跨越那些难以逾越的鸿沟?

在数字化浪潮席卷全球的背景下&#xff0c;连锁门店运营正面临着一场深刻的变革。这场变革不仅关乎技术的升级&#xff0c;更涉及到商业模式、管理理念以及消费者体验的根本性转变。然而&#xff0c;在这场转型之路上&#xff0c;许多门店却常常遭遇各种痛点&#xff0c;让数字…

2023年总结与2024展望

今天是春节后上班第一天&#xff0c;你懂的&#xff0c;今天基本上是摸鱼状态&#xff0c;早上把我们负责的项目的ppt介绍完善了一下&#xff0c;然后写了一篇技术文章&#xff0c;《分布式系统一致性与共识算法》。接着就看了我近几年写的的年度总结&#xff0c;我一般不会在元…