大数据框架复习-kafka
kafka架构
- Producer :消息生产者,就是向 kafka broker 发消息的客户端;
- Consumer :消息消费者,向 kafka broker 取消息的客户端;
- Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
- Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker 可以容纳多个 topic。
- Topic :可以理解为一个队列,生产者和消费者面向的都是一个 topic;
- Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上, 一个 topic 可以分为多个 partition,每个 partition 是一个有序的队列;
- leader是每个分区,多个副本的主,生产者发送数据的对象,以及消费者消费数据的对象都是 leader;
为什么使用kafka(项目中)
- 缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够多的机器来保证冗余,kafka 在中间可以起到一个缓冲的作用,把消息 暂存在 kafka 中,下游服务就可以按照自己的节奏进行慢慢处理。
- 解耦和扩展性:项目开始的时候,并不能确定具体需求。kafka消息队列可以作为一个接口层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能力。
- 冗余:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅 topic 的服务消费到,供多个毫无关联的业务使用。
- 健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常进行。
- 异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
- why不使用flume?
- flume类似于管道,转为hdfs和hbase发送数据设计,对这两个有优化;
- kafka是持久化的分布式消息队列,适合数据被多个系统消费的场景。
kafka 消费过的消息如何再消费
- kafka 消费消息的 offset 是定义在 zookeeper 中的, 如果想重复消费 kafka 的消息,可以在 redis 中自己记录 offset 的 checkpoint 点(n 个),当想重复消费消息时,通过读取 redis 中的 checkpoint 点进行 zookeeper 的 offset 重设, 这样就可以达到重复消费消息的目的了
kafka的数据是在磁盘还是在内存,为什么快
- kafka 使用的是磁盘存储
- 为什么快因为 3点
- 顺序写入,因为硬盘是机械结构,硬盘 “讨厌”随机 I/O, 喜欢顺序 I/O。为了提高读写硬盘的速度,Kafka 就是使用顺序I/O;
- Memory Mapped Files(内存映射文件):64 位操作系统中一般可以表示 20G 的数据文件,它的工作原理是直接利用操作系统的 Page 来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上;
- Kafka 高效文件存储设计: Kafka 把 topic 中一个 parition 大文件分成 多个小文件段,通过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。通过索引信息可以快速定位 message 和确定 response 的大小。通过 index 元数据全部映射到 memory(内存映射文件), 可 以避免 segment file 的 IO 磁盘操作。通过索引文件稀疏存储,可以大幅降低 index 文件元数据占用空间大小。
kafka的机器数量
- Kafka机器数量=2 * (峰值生产速度*副本数/100)+1;
- 例如:峰值生产速度50/s,副本数2,总共是 2*1+1=3台kafka;
kafka压测
- 官方自带压力测试脚本,可以查看那个地方出现了瓶颈(一般是CPU、内存、网络IO);
- 一般都是网络IO达到瓶颈;
kafka的日志保存时间及硬盘大小
- 7天
- 数据量:每天的数据量*7天
kafka分区数、副本数、topic数
- 分区数并不是越多越好,一般分区数不要超过集群机器数量。分区数越多占用内存越大(ISR等),一个节点集中的分区也就越多,当它宕机的时候,对系统的影响也就越大。
- 分区数一般设置为:3-10个
- 副本数:一般设置成2个或3个,很多企业设置为2个;
- 多少个topic:通常情况:多少个日志类型就多少个Topic。也有对日志类型进行合并的。
kafka丢不丢数据
- 分三个点,生产者端,消费者端,broker端;
- 生产者的数据不丢失
- 如果是同步模式: ack 设置为 0,风险很大,一般不建议设置为 0。即使设置为 1,也会随着 leader 宕机丢失数据。所以如果要严格保证生产端数据不丢失,可设置为-1。
- 如果是异步模式: 也会考虑 ack 的状态,除此之外,异步模式下的有个 buffer,通过 buffer 来进行控制数据的发送,有两个值来进行控制,时间阈值与消息的数量阈值,如果 buffer 满了数据还没有发送出去,有个选项是配置是否立即清空 buffer。可以设置为-1,永久阻塞,也就数据不再生产。异步模式下,即使设置为-1。也可能 因为程序员的不科学操作,操作数据丢失,比如 kill -9,但这是特别的例外情况
- 消费者数据的不丢失
- 通过 offset commit 来保证数据的不丢失,kafka 自己记录了每次消费的 offset 数值,下次继续消费的时候,会接着上次的 offset 进行消费;
- 即使消费者在运行过程中挂掉了,再次启动的时候会找到 offset 的值,找到之前消费消息的位置,接着消费,由于 offset 的信息写入的时候并不是每条消息消费完成后都写入的,所以这种情况有可能会造成重复消费,但是不会丢失消息
- 当消费者组的groupid相同时,在消费不同partition分区的数据,可能会丢数据
- 集群中broker的数据不丢失
- 每个 broker 中的 partition 我们一般都会设置有 replication(副本)的个数,这样有了备份,也可以保证消息数据的不丢失。
- Ack=0,相当于异步发送,消息发送完毕即offset增加,继续生产
- Ack=1(默认),leader收到leader replica 对一个消息的接受ack才增加offset,然后继续生产
- Ack=-1,leader收到所有replica对一个消息的接受ack才增加offset,然后继续生产。
- kafka重启一般数据也不会丢失,因为数据写到磁盘;但是在重启 kafka 过程中,如果有消费者消费消息,那么 kafka 如果来不及提交 offset,可能会造成数据的不准确(丢失或者重复消费)。
kafka的ISR副本同步队列
- ISR(In-Sync Replicas),副本同步队列。ISR中包括Leader和Follower。如果Leader进程挂掉,会在ISR队列中选择一个服务作为新的Leader。
- 任意一个维度超过阈值都会把Follower剔除出ISR,存入OSR(Outof-Sync Replicas)列表,新加入的Follower也会先存放在OSR中。
kafka分区分配策略
- 在 Kafka内部存在两种默认的分区分配策略:Range和 RoundRobin。
- Range是默认策略。Range是对每个Topic而言的(即一个Topic一个Topic分区),首先对同一个Topic里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。然后用Partitions分区的个数除以消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。
- 例如:我们有10个分区,两个消费者(C1,C2),3个消费者线程,10 / 3 = 3而且除不尽。
C1-0 将消费 0, 1, 2, 3 分区
C2-0 将消费 4, 5, 6 分区
C2-1 将消费 7, 8, 9 分区 - RoundRobin:前提:同一个Consumer Group里面的所有消费者的num.streams(消费者消费线程数)必须相等;每个消费者订阅的主题必须相同。
第一步:将所有主题分区组成TopicAndPartition列表,然后对TopicAndPartition列表按照hashCode进行排序,最后按照轮询的方式发给每一个消费线程。
kafka的数据量计算场景
- 每天产生1亿条日志,每天总数据量100g, 10000万/24/60/60约为1200条/每秒钟
- 平均每秒钟:1200条,低谷每秒钟:400条,高峰每秒钟:1200条*(2-20倍)=2400条-24000条
- 每条日志大小约为1k,每秒多少数据量:(高峰期)2.4M-24MB
kafka挂掉
- (如果前面是flume)Flume记录
- kafka日志有记录
- 短期没事,多台kafka
kafka消息数据积压,kafka消费能力不足怎么处理?
- 如果是Kafka消费能力不足,则可以考虑增加Topic的分区数,并且同时提升消费组的消费者数量,消费者数=分区数。(两者缺一不可) 一个分区只能由同一个消费者组的消费者消费
- 如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过少(拉取数据/处理时间<生产速度),使处理的数据小于生产的数据,也会造成数据积压。
kafka为什么不支持读写分离
- 在 Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行交互的,从而实现的是一种主写主读的生产消费模型。 Kafka 并不支持主写从读
- 主写从读的两个缺点:
- 数据一致性问题:数据从主节点转到从节点必然会有一个延时的时间窗口, 这个时间窗口会导致主从节点的数据不一致;
- 延时问题:延时大,kafka就要快;
- 主写主读的优点
- 数据一致;2.无延时影响;3.简化代码;4.负载效果好
kafka的数据offset读取流程
- 连接zk,从zk拿到对应topic的partition信息和对应的leader
- 连接到leader对应的broker,consumer将保存的offset发给leader
- leader根据offset等信息定位到segment(索引文件和日志文件)
- 根据segment,定位到日志文件的偏移量对应位置,读取相应长度返回给consumer
kafka只能分区内有序
- 只能保证partition 内是有序的,但是 partition 间的有序是没办法的;
- 要全局有序只能设置topic只是用一个分区,降低性能,不适用高并发;