2020.12.03课堂笔记(kafka数据可靠性深度解读)

参考博客:https://blog.csdn.net/u013256816/article/details/71091774
建议跳转阅读,这里只做知识点整理:

Kafka架构图:

在这里插入图片描述
1.Kafka的角色:Broker、Producer、Consumer

名称解释
Broker消息中间件处理节点,一个Kafka节点就是一个broker,一个或者多个Broker可以组成一个Kafka集群
Producer消息生产者,向Broker发送消息的客户端
Consumer消息消费者,从Broker读取消息的客户端

2.Kafka是磁盘读写为什么比内存快?
两个名词:Topic & Partition
一个topic可以认为一个一类消息,(可以看作是一张表)。
每个topic将被分成多个partition(分区),每个partition在存储层面是append log文件。
任何发布到此partition的消息都会被追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset为一个long型的数字,它唯一标记一条消息。
每条消息都被append到partition中,是顺序写磁盘,因此效率非常高(经验证,顺序写磁盘效率比随机写内存还要高,这是Kafka高吞吐率的一个很重要的保证)。

每一个log的文件名都代表了它的偏移量,文件夹下有两个同名文件,log类型和index类型。通过二分查找可以快速定位偏移量。
在这里插入图片描述所以在生产环境中最好的是选择3台干净的机器,只装Kafka,有利于Kafka顺序写磁盘,否则会影响Kafka的读写速度。
3.为什么需要分区?
partition体现了Kafka的水平扩展性能。
每一条消息被发送到broker中,会根据partition规则选择被存储到哪一个partition。
如果一个topic对应一个文件,那这个文件所在的机器I/O将会成为这个topic的性能瓶颈,而partition解决了这个问题,会为每个partition分别生成一个文件
参数设置:

$KAFKA_HOME/config/server.properties中:
# The default number of log partitions per topic. More partitions allow greater
# parallelism for consumption, but this will also result in more files across
# the brokers.
num.partitions=1

partition机制可以通过指定producer的partition.class这一参数来指定,该class必须实现kafka.producer.Partitioner接口。(编写Java类实现接口,指定分区规则)
4.Kafka保证高可靠性
Kafka高可靠性的保证:健壮的副本(replication)策略
通过调节其副本相关参数,可以使得Kafka在性能和可靠性之间运转的游刃有余。Kafka从0.8.x版本开始提供partition级别的复制,replication的数量可以在$KAFKA_HOME/config/server.properties中配置(default.replication.factor)自动创建topic时的默认副本个数,默认值为1。
Kafka为保证高可靠性做出的努力:
1.文件存储机制(底层存储细节)
2.Kafka复制原理和同步方式(宏观层面的概念)
3.ISR,HW,leader选举以及数据可靠性和持久性保证

Kafka文件存储机制:
Kafka中消息是以topic进行分类的。
生产者通过topic向Kafka broker发送消息,消费者通过topic读取数据
一个topic可以分成若干个partition,partition还可以细分为segment,什么是segment?

一个Kafka节点就是一个broker。
broker的核心配置:
broker.id:用于服务的broker id。如果没设置,将生存一个唯一broker id。为了避免ZooKeeper生成的id和用户配置的broker id相冲突,生成的id将在reserved.broker.max.id的值基础上加1。
log.dirs:保存日志数据的目录,如果未设置将使用log.dir的配置。
zookeeper.connect:Zookeeper主机地址
这时候创建一个topic:

[root@hadoop100 config]# kafka-topics.sh 
--create 
--zookeeper hadoop100:2181  //zookeeper地址
--partitions 4              //分区数设置为4
--topic topic_test01        //topicName
--replication-factor 1      //副本数为1

这个时候在log.dirs设置的日志数据目录下,可以看到以下4个文件夹,每个partition为一个目录,命名规则:topic名称+有序序号:

drwxr-xr-x. 2 root root  141 Dec  4 15:05 topic_test01-0
drwxr-xr-x. 2 root root  141 Dec  4 15:05 topic_test01-1
drwxr-xr-x. 2 root root  141 Dec  4 15:05 topic_test01-2
drwxr-xr-x. 2 root root  141 Dec  4 15:05 topic_test01-3

进入topic_test01-0又有4个文件:

-rw-r--r--. 1 root root 10485760 Dec  4 15:05 00000000000000000000.index
-rw-r--r--. 1 root root        0 Dec  4 15:05 00000000000000000000.log
-rw-r--r--. 1 root root 10485756 Dec  4 15:05 00000000000000000000.timeindex
-rw-r--r--. 1 root root        0 Dec  4 15:05 leader-epoch-checkpoint

细节展开:
segment文件由两部分组成,分别为“.index”文件和“.log”文件,分别表示为segment索引文件和数据文件。命名规则:partition全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值,数值大小为64位,20位数字字符长度,没有数字用0填充
在这里插入图片描述
“.index”索引文件存储大量的元数据
“.log”数据文件存储大量的消息
索引文件中的元数据指向对应数据文件中message的物理偏移地址。
其中以“.index”索引文件中的元数据[3, 348]为例,在“.log”数据文件表示第3个消息,即在全局partition中表示170410+3=170413个消息,该消息的物理偏移地址为348。

00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log

假设partition中的文件是这个样子的,现在要读取第170413个消息的内容,首先每个index和log文件以其实际偏移量命名并排列这些文件,可以使用二分查找快速定位到是在00000000000000170410.index文件中的[3,348]定位到00000000000000170410.log文件中的348的位置进行读取。

为什么要将partition细分为segment?
1.如果就以partition为最小存储单位,生产者(Kafka producer)不断发送消息,partition文件大小不断增大,不利于消息文件的维护,以及已经被消费的消息的清理。
2.每个partition(目录)被平均分配到多个大小相等的segment(段)数据文件中(每个segment 文件中消息数量不一定相等)这种特性也方便old segment的删除,即方便已被消费的消息的清理,提高磁盘的利用率。

Kafka复制原理和同步方式
Kafka的副本(replication)策略:
名词解释:
HW:HW是HighWatermark的缩写,俗称高水位。是指consumer能够看到的此partition的位置,取一个partition对应的ISR中最小的LEO作为HW,consumer最多只能消费到HW所在的位置。另外每个replica都有HW,leader和follower各自负责更新自己的HW的状态。(从后面的学习来看,每个replication维护的HW有可能不同,当他没有和leader取数据同步HW的时候,leader挂掉了,不能把自己回到HW的状态等待生产者重新发送消息,这样有可能会造成数据丢失)
LEO:LogEndOffset的缩写,表示每个partition的log最后一条Message的位置,最低的partition的LEO就是HW
ISR:In-Sync Replicas的缩写,表示副本同步队列,由leader维护ISR列表,follower从leader同步数据有一些延迟,包括延迟时间replica.lag.time.max.ms,(延迟条数replica.lag.max.messages在0.10.x版本中删除),超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表(说人话:ISR中存放了leader和同步比较快的follower,如果follower跟不上了延迟较高就踢出去,OSR中的follower重新跟上了延迟较低再加入回来,ISR+OSR=AR。所有的副本(replicas)统称为Assigned Replicas,即AR。)

在这里插入图片描述

数据可靠性和持久性保证:
当producer向leader发送数据时,可以通过acks参数来设置数据可靠性的级别:
此配置是 Producer 在确认一个请求发送完成之前需要收到的反馈信息的数量。 这个参数是为了保证发送请求的可靠性。以下配置方式是允许的:
acks=0 如果设置为0,则 producer 不会等待服务器的反馈。该消息会被立刻添加到 socket buffer 中并认为已经发送完成。在这种情况下,服务器是否收到请求是没法保证的,并且参数retries也不会生效(因为客户端无法获得失败信息)。每个记录返回的 offset 总是被设置为-1。
acks=1 如果设置为1,leader节点会将记录写入本地日志,并且在所有 follower 节点反馈之前就先确认成功。在这种情况下,如果 leader 节点在接收记录之后,并且在 follower 节点复制数据完成之前产生错误,则这条记录会丢失。
acks=all 如果设置为all,这就意味着 leader 节点会等待所有同步中的副本确认之后再确认这条记录是否发送完成。只要至少有一个同步副本存在,记录就不会丢失。这种方式是对请求传递的最有效保证。acks=-1与acks=all是等效的。
HW高水位的作用
HighWatermark相关的参数配置:

replica.high.watermark.checkpoint.interval.ms=5000

每个replica将最高水位进行flush的时间间隔,用来标记日后恢复点
HW的作用:如果失败的follower恢复过来,它首先将自己的log文件截断到上次checkpointed时刻的HW的位置,之后再从leader中同步消息。leader挂掉会重新选举,新的leader会发送“指令”让其余的follower截断至自身的HW的位置然后再拉取新的消息。当ISR中的个副本的LEO不一致时,如果此时leader挂掉,选举新的leader时并不是按照LEO的高低进行选举,而是按照ISR中的顺序选举
Leader选举机制
Kafka的提交机制:一条消息只有被ISR中的所有follower都从leader复制过去才会被认为已提交。
(避免了部分数据被写进了leader,还没来得及被任何follower复制就宕机了,而造成数据丢失)
在生产者设置了acks=-1时,生产者会等待消息commit
(这种机制确保了只要ISR中有一个或者以上的follower,一条被commit的消息就不会丢失)
如何选举出新的leader?
一个基本的原则:如果leader不在了,新的leader必须拥有原来的leader commit的所有消息
master/slave主从架构常用的选举方式是"少数服从多数(过半通过)原则",Kafka使用的并不是这种选举方式。这种方式的缺点:在生产环境下为了保证较高的容错率,必须要有大量的副本,而大量的副本又会在大数据量下导致性能的急剧下降。
Kafka使用的选举方式:Kafka所使用的leader选举算法更像是微软的PacificA算法
正常情况:
Kafka在Zookeeper中为每一个partition动态的维护了一个ISR,这个ISR里的所有replica都跟上了leader,只有ISR里的成员才能有被选为leader的可能(unclean.leader.election.enable=false)在ISR中至少有一个follower时,Kafka可以确保已经commit的数据不丢失
特殊情况:
如果某一个partition的所有replica都挂了,就无法保证数据不丢失了。这种情况下有两种可行的方案:
1.等待ISR中任意一个replica“活”过来,并且选它作为leader -> 不可用的时间就可能会相对较长
2.选择第一个“活”过来的replica(并不一定是在ISR中)作为leader -> 不保障已经包含了所有已commit的消息(unclean.leader.election.enable=true 也是Kafka的默认参数设置)
Kafka的发送模式:
由producer端的配置参数producer.type来设置,这个参数指定了在后台线程中消息的发送方式是同步的还是异步的。
默认是同步的方式,即producer.type=sync
异步的模式,即producer.type=async,可以是producer以batch的形式push数据,这样会极大的提高broker的性能,但是这样会增加丢失数据的风险。
如果需要确保消息的可靠性,必须要将producer.type设置为sync。

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值