文章目录
前言:
十年生死两茫茫,千行代码,Bug何处藏。
纵使产品经理祭苍天,又怎样?
朝令改,夕断肠。
相顾无言,惟有泪千行。
每晚灯火阑珊处,夜难寐,加班狂
KafKa
kafka传统定义:Kafka是一个分布式基于发布/订阅模式的消息队列,主要应用于实时处理领域。
发布/订阅:消息的发布者不会将消息直接发送给特定的订阅者,而是将发布的消息分为不同的类别,订阅者只接收感兴趣的消息。
提供了类似于JMS的特性,作用是日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer
(1)Producer:消息生产者,就是向 Kafka broker 发消息的客户端。
(2)Consumer:消息消费者,向Kafka broker 取消息的客户端。
(3)Consumer Group(CG):消费者组,由多个 consumer组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
(4)Broker:一台 Kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个topic。
(5)Topic:可以理解为一个队列,生产者和消费者面向的都是一个 topic。
(6)Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上,一个 topic 可以分为多个partition,每个 partition 是一个有序的队列。
(7) Replica:副本。一个 topic的每个分区都有若干个副本,一个 Leader 和若干个Follower。
(8)Leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 Leader。
(9)Follower:每个分区多个副本中的“从”,实时从 Leader 中同步数据,保持和Leader 数据的同步。Leader发生故障时,某个 Follower 会成为新的 Leader。
确定kafka机器的数量(2n+1)
Kafka机器数量=2*(峰值生产速度20M*副本数/100)+1
kafka分区有多少个3-10个分区(分区影响消费的并发度,分区个数不建议超过集群的个数)
峰值生产速度不到50m/s 3台节点就够
(ps:假设每条数据大小为1kb 1mb=1024条数据 也就是说峰值生产速度不高于51200条)
副本数设定
一般我们设置成2个或3个,很多企业设置为2个。
副本的优势:提高可靠性
副本劣势:增加了网络IO传输
Kafka压测
Kafka官方自带压力测试脚本(kafka-consumer-perf-test.sh、kafka-producer-perf-test.sh)。Kafka压测时,可以查看到哪个地方出现了瓶颈(CPU,内存,网络IO)。一般都是网络IO达到瓶颈。
Kafka日志保存时间
默认保存7天;生产环境建议3天
(ps:因为flume会消费kafka中的数据并上传到hdfs,正常情况下当天数据当天消费完成,顶多到凌晨30分,多出来的一天是预留量)
Kafka中数据量计算
每天总数据量100g
每天产生1亿条日志, 10000万/24/60/60=1150条/每秒钟
平均每秒钟:1150条
低谷每秒钟:50条
高峰每秒钟:1150条*(2-20倍)=2300条-23000条
每条日志大小:0.5k-2k(取1k)
每秒多少数据量:2.0M - 20MB
Kafka的硬盘大小
每天的数据量100g * 2个副本 * 3天 / 70%约等于1T数据量
Kafka监控
公司自己开发的监控器;
开源的监控器:KafkaManager、KafkaMonitor、KafkaEagle,我所采用的时kafkaEagle
Kakfa分区数
1)创建一个只有1个分区的topic
2)测试这个topic的producer吞吐量和consumer吞吐量。
3)假设他们的值分别是Tp和Tc,单位可以是MB/s。
4)然后假设总的目标吞吐量是Tt,那么分区数=Tt / min(Tp,Tc)
(ps:取生产huo消费速率最小的值进行计算)
例如:producer吞吐量=20m/s;consumer吞吐量=50m/s,期望吞吐量100m/s;
分区数=100 / 20 = 5分区
https://blog.csdn.net/weixin_42641909/article/details/89294698
分区数一般设置为:3-10个
多少个Topic
通常情况:多少个日志类型就多少个Topic。也有对日志类型进行合并的,我这里分为业务数据和用户行为数据,大概10个topic(点赞,评论,商品的增删改查等等),每个topic5个分区。
Kafka的高效读写的原因
1.Kafka本身是分布式集群,同时采用分区技术,并发度高。
2.顺序写入磁盘
Kafka的producer生产数据,要写到log文件中,写的过程是一直追加到文件的末尾,顺序写入磁盘的速度600M/s,这个和硬盘是机械还是固态有一些关联,随机写入默认100K/s , 根据是否需要进行磁盘寻址
3.零复制技术
Linux中提供的一种文件处理技术,Linux总会将系统中还没有使用到的内存挪给 Page cache 当写操作发生的时候, 他会将写入page Cache中,并在该写入位置加入dirty标志,当读操作发生的时候,它会首先查找Page cache中是否存在,如果存下就直接返回,如果没有就从磁盘中读取再写入到Page Cache中
Zookeeper在kafka中的作用
0.8版本以后的Zookeeper就不在维护偏移量offset,Zookeeper在后续的Kafka中起到的是一个选举作用
Kafka集群中有一个broker被选举为Controller,负责管理集群中broker的上下线,所有topic的分区和副本分配和leader的选举工作Controller的管理工作都是依赖于Zookeeper的
Kafka如何保证数据一致性
数据可靠性保证(ack机制)
为了保证producer发送数据,能够可靠的发送到指定topic,topic的每个partition收到producer发送数据就会向producer发送"ack"(acknowledgement 确认收到) 如果producer收到ack,就会进行下一轮的发送,否则就重新发送数据。
为了保证Topic的partition可以正常提供服务,会提供副本机制,所以会有多个partition存在
例如:一个topic存在三个partition,topic中有一个leader两个follower当leader接收到Producer发送的消息后,是等待所有follower全部完成后再发送ack还是只要有过半机制就发送ack
Kafka选择了全部完成方案,原因如下:
Kafka的每个分区都有大量的数据,过半机制的副本保存会造成大量数据冗余
全部完成方案的网络延迟会比较高,网络延迟对Kafka的影响较小
(针对所有follower都开始同步数据,有一个follower,迟迟不能与leader进行同步的情况。采用ISR(一个存储着follower集合),如果follower长时间未向leader同步数据则该follower将被踢出ISR,如果是Leader发生故障,会从ISR中选举新的leader。)
ACK应答机制(丢不丢数据)
所以Kafka为了用户提供了三种可靠级别设置,可以根据不同雪球来修改选择acks参数配置:参数是0 ,1 和 -1
Kafka的ISR副本同步队列
幂等机制
幂等简单来说1的几次幂都等于1,也就是说一天消息无论发送几次都只算一次,无论多少条消息,我们只实例化一次
Kafka完成幂等性其实就是给消息添加一个唯一ID,这个ID组成PID(ProducerID),这样就可以保证每一个Producer发送的时候都是唯一,还会为Producer中每条消息添加一个消息ID,当消息发送到kafka后会暂时缓存ID,写入数据后没有收到ACK会重新发送,消息收到后会与缓存中ID进行比较,如果已存在,不再接收
水位线机制
kafka副本同步机制
ISR副本同步队列
ISR(In-Sync Replicas),副本同步队列。ISR中包括Leader和Follower。如果Leader进程挂掉,会在ISR队列中选择一个服务作为新的Leader。有replica.lag.max.messages(延迟条数)和replica.lag.time.max.ms(延迟时间)两个参数决定一台服务是否可以加入ISR副本队列,在0.10版本移除了replica.lag.max.messages参数,防止服务频繁的进去队列。
任意一个维度超过阈值都会把Follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的Follower也会先存放在OSR中。
offset的维护
Kafka0.9版本之前,consumer默认将offet保存在Zookeeper,从0.9版本开始后,consumer默认将offset保存在kafka这一个内置的topic中,该topic为 __consumer_offsets
手动维护(可以维护到redis中),自动维护(将偏移量维护到kafka记录偏移量的topic中)
Kafka中topic数量
(一般情况下一张表对应一个topic,也可以相同主题的表进行轻度聚合放在一个topic中
例如:
将商品列表,商品详情,商品点击放到一个topic中。
将广告放在一个tpoic中。
通知、前台活跃、后台活跃放到一个topic中。
评论、点击、收藏、点赞放到一个topic中。
故障日志放一个topic中)
Kafka消息数据积压,Kafka消费能力不足怎么处理?
1)如果是Kafka消费能力不足,则可以考虑增加Topic的分区数,并且同时提升消费组的消费者数量,消费者数 = 分区数。(两者缺一不可)
2)如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过少(拉取数据/处理时间 < 生产速度),使处理的数据小于生产的数据,也会造成数据积压。
Kafka参数优化
1、日志保留策略配置
保留三天,也可以更短 (log.cleaner.delete.retention.ms)
log.retention.hours=72
2、Replica相关配置
default.replication.factor:1 默认副本1个
3、网络通信延时
1)Broker参数配置(server.properties)
replica.socket.timeout.ms:30000 #当集群之间网络不稳定时,调大该参数
replica.lag.time.max.ms= 600000# 如果网络不好,或者kafka集群压力较大,会出现副本丢失,然后会频繁复制副本,导致集群压力更大,此时可以调大该参数
2)Producer优化(producer.properties)
compression.type:none gzip snappy lz4
#默认发送不进行压缩,推荐配置一种适合的压缩算法,可以大幅度的减缓网络压力和Broker的存储压力。
3)Kafka内存调整(kafka-server-start.sh)
默认内存1个G,生产环境尽量不要超过6个G。
export KAFKA_HEAP_OPTS=“-Xms4g -Xmx4g”
Kafka单条日志传输大小
Kafka对于消息体的大小默认为单条最大值是1M但是在我们应用场景中,常常会出现一条消息大于1M,如果不对Kafka进行配置。则会出现生产者无法将消息推送到Kafka或消费者无法去消费Kafka里面的数据,这时我们就要对Kafka进行以下配置:server.properties
replica.fetch.max.bytes: 1048576 broker可复制的消息的最大字节数, 默认为1M
message.max.bytes: 1000012 kafka 会接收单个消息size的最大限制, 默认为1M左右
注意:message.max.bytes必须小于等于replica.fetch.max.bytes,否则就会导致replica之间数据同步失败。
Ps:这样设置的缺点是,如果大日志只有1-2条这样日志,设置单条2M的话加载每条日志(即使单条日志不大)都会预留2M的内存,可以建议业务端改掉
Kafka中的数据是有序的吗
单分区内有序;多分区,分区与分区间无序;
扩展:kafka producer发送消息的时候,可以指定key:
这个key的作用是为消息选择存储分区,key可以为空,当指定key且不为空的时候,Kafka是根据key的hash值与分区数取模来决定数据存储到那个分区。
有序解决方案:同一张表的数据 放到 同一个 分区
=> ProducerRecord里传入key,会根据key取hash算出分区号
=> key使用表名,如果有库名,拼接上库名
Kafka如何进行分区的
Consumer消费数据的方式(分区分配策略)
- RoundRobin(轮询)将每一个分区一次发送给一个消费者组
- Range(范围)是默认策略。是对每个Topic而言的(即一个Topic一个Topic分),首先对同一个Topic里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。然后用Partitions分区的个数除以消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。
常用命令示例
查看topic列表:
bin/kafka-topics.sh --zookeeper localhost:2181 –list
查看指定topic明细:
bin/kafka-topics.sh --zookeeper localhost:2181 --desc --topic demo
常用的kafka工具:kafkaTools
有收获?希望烙铁们来个三连击,让更多的同学看到这篇文章
1、烙铁们,关注我看完保证有所收获,不信你打我。
2、点个赞呗,可以让更多的人看到这篇文章,后续还会有很哇塞的产出。
本文章仅供学习及个人复习使用,如需转载请标明转载出处,如有错漏欢迎指出
务必注明来源(注明: 来源:csdn , 作者:-马什么梅-)