kafka相关问题

Kafka
1. 为什么要使用 kafka?
缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够
多的机器来保证冗余, kafka 在中间可以起到一个缓冲的作用,把消息暂存
kafka 中,下游服务就可以按照自己的节奏进行慢慢处理。
解耦和扩展性:项目开始的时候,并不能确定具体需求。消息队列可以作为
一个接口层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获
取扩展能力。
冗余:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅 topic
的服务消费到,供多个毫无关联的业务使用。
健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会
影响主要业务的正常进行。
异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异
步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列
中放入多少消息就放多少,然后在需要的时候再去处理它们。
2. Kafka 消费过的消息如何再消费?
kafka 消费消息的 offset 是定义在 zookeeper 中的, 如果想重复消费 kafka 的消
息,可以在 redis 中自己记录 offset checkpoint 点(
n 个),当想重复消费消息
时,通过读取 redis 中的 checkpoint 点进行 zookeeper offset 重设,这样就可以
达到重复消费消息的目的了
3. kafka 的数据是放在磁盘上还是内存上,为什么速度会快?
kafka 使用的是磁盘存储。
速度快是因为:
1. 顺序写入: 因为硬盘是机械结构,每次读写都会寻址 -> 写入,其中寻址是一个 机械动
,它是耗时的。所以硬盘 讨厌 随机 I/O , 喜欢顺序 I/O 。为了提高读写硬盘的速
度, Kafka 就是使用顺序 I/O
2. Memory Mapped Files (内存映射文件): 64 位操作系统中一般可以表示 20G 的数据文
件,它的工作原理是直接利用操作系统的 Page 来实现文件到物理内存的直接映射。完
成映射之后你对物理内存的操作会被同步到硬盘上。
3. Kafka 高效文件存储设计: Kafka topic 中一个 parition 大文件分成多个小文件段,通
过多个小文件段,就容易定期清除或删除已经消费完文件,减少磁盘占用。通过索引信
息可以快速定位
message 和确定 response 的 大 小。通过 index 元数据全部映射到 memory (内存映射
文件),
可以避免 segment file IO 磁盘操作。通过索引文件稀疏存储,可以大幅降低 index
件元数据占用空间大小。
注:
1. Kafka解决查询效率的手段之一是将数据文件分段,比如有100条Message,它们的offset
是从 0 到 99。假设将数据文件分成 5 段,第一段为 0-19,第二段为 20-39,以此类推,
每段放在一个单独的数据文件里面,数据文件以该段中 小的 offset 命名。这样在查找
指定 offset 的
Message 的时候,用二分查找就可以定位到该 Message 在哪个段中。
2. 为数据文件建 索引数据文件分段 使得可以在一个较小的数据文件中查找对应 offset
的 Message 了,但是这依然需要顺序扫描才能找到对应 offset 的 Message。
为了进一步提高查找的效率,Kafka 为每个分段后的数据文件建立了索引文件,文件名
与数据文件的名字是一样的,只是文件扩展名为.index。
4. Kafka 数据怎么保障不丢失?
分三个点说,一个是生产者端,一个消费者端,一个 broker 端。
生产者数据的不丢失:
kafka ack 机制:在 kafka 发送数据的时候,每次发送消息都会有一个确认反馈
机制,确保消息正常的能够被收到,其中状态有 0 1 -1
如果是同步模式:
ack 设置为 0 ,风险很大,一般不建议设置为 0 。即使设置为 1 ,也会随着 leader
宕机丢失数据。所以如果要严格保证生产端数据不丢失,可设置为 -1
如果是异步模式:
也会考虑 ack 的状态,除此之外,异步模式下的有个 buffer ,通过 buffer 来进行
控制数据的发送,有两个值来进行控制,时间阈值与消息的数量阈值,如果 buffer
满了数据还没有发送出去,有个选项是配置是否立即清空 buffer 。可以设置为 -1
永久阻塞,也就数据不再生产。异步模式下,即使设置为 -1 。也可能因为程序员
的不科学操作,操作数据丢失,比如 kill -9 ,但这是特别的例外情况。
注:
ack=0:producer 不等待 broker 同步完成的确认,继续发送下一条(批)信息。
ack=1(默认):
producer 要等待leader成功收到数据并得到确认,才发送下一条message。
ack=-1:producer 得到 follwer 确认,才发送下一条数据。
消费者数据的不丢失:
通过 offset commit 来保证数据的不丢失, kafka 自己记录了每次消费的 offset
值,下次继续消费的时候,会接着上次的 offset 进行消费。
offset 的信息在 kafka0.8 版本之前保存在 zookeeper 中,在 0.8 版本之后保存
topic 中,即使消费者在运行过程中挂掉了,再次启动的时候会找到 offset
值,找到之前消费消息的位置,接着消费,由于 offset 的信息写入的时候并不
是每条消息消费完成后都写入的,所以这种情况有可能会造成重复消费,但是不
会丢失消息。
唯一例外的情况是,我们在程序中给原本做不同功能的两个 consumer 组设置
KafkaSpoutConfig.bulider.setGroupid 的时候设置成了一样的 groupid ,这种情况会
导致这两个组共享同一份数据,就会产生组 A 消费 partition1 partition2 中的消
息,组 B 消费 partition3 的消息,这样每个组消费的消息都会丢失,都是不完整
的。 为了保证每个组都独享一份消息数据, groupid 一定不要重复才行。
kafka 集群中的 broker 的数据不丢失:
每个 broker 中的 partition 我们一般都会设置有 replication (副本)的个数,生产
者写入的时候首先根据分发策略(有 partition partition ,有 key key ,都没
有轮询)写入到 leader 中, follower (副本)再跟 leader 同步数据,这样有了备
份,也可以保证消息数据的不丢失。 
5. 采集数据为什么选择 kafka?
采集层 主要可以使用 Flume, Kafka 等技术。
Flume Flume 是管道流方式,提供了很多的默认实现,让用户通过参数部署,
及扩展 API.
Kafka Kafka 是一个可持久化的分布式的消息队列。 Kafka 是一个非常通用的系
统。你可以有许多生产者和很多的消费者共享多个主题 Topics
相比之下 ,Flume 是一个专用工具被设计为旨在往 HDFS HBase 发送数据。它对
HDFS 有特殊的优化,并且集成了 Hadoop 的安全特性。
所以, Cloudera 建议如果数据被多个系统消费的话,使用 kafka ;如果数据被设
计给 Hadoop 使用,使用 Flume
6. kafka 重启是否会导致数据丢失?
1. kafka 是将数据写到磁盘的,一般数据不会丢失。
2. 但是在重启 kafka 过程中,如果有消费者消费消息,那么 kafka 如果来不及提交 offset
可能会造成数据的不准确(丢失或者重复消费)。
7. kafka 宕机了如何解决?
先考虑业务是否受到影响
kafka 宕机了,首先我们考虑的问题应该是所提供的服务是否因为宕机的机器而
受到影响,如果服务提供没问题,如果实现做好了集群的容灾机制,那么这块就
不用担心了。
节点排错与恢复
想要恢复集群的节点,主要的步骤就是通过日志分析来查看节点宕机的原因,从
而解决,重新恢复节点。
8. 为什么 Kafka 不支持读写分离?
Kafka 中,生产者写入消息、消费者读取消息的操作都是与 leader 副本进行
交互的,从 而实现的是一种 主写主读 的生产消费模型。
Kafka 并不支持 主写从读 ,因为主写从读有 2 个很明显的缺点 :
数据一致性问题 :数据从主节点转到从节点必然会有一个延时的时间窗口,这个
时间 窗口会导致主从节点之间的数据不一致。某一时刻,在主节点和从节点中 A
数据的值都为 X , 之后将主节点中 A 的值修改为 Y ,那么在这个变更通知到从
节点之前,应用读取从节点中的 A 数据的值并不为最新的 Y ,由此便产生了数
据不一致的问题。
延时问题: 类似 Redis 这种组件,数据从写入主节点到同步至从节点中的过程
需要经历 网络 主节点内存 网络 从节点内存 这几个阶段,整个过程会耗费
一定的时间。而在 Kafka 中,主从同步会比 Redis 更加耗时,它需要经历 网络
主节点内存 主节点磁盘 网络 从节 点内存 从节点磁盘 这几个阶段。对
延时敏感的应用而言,主写从读的功能并不太适用。
kafka 主写主读 的优点就很多了:
1. 可以简化代码的实现逻辑,减少出错的可能 ;
2. 将负载粒度细化均摊,与主写从读相比,不仅负载效能更好,而且对用户可控 ;
3. 没有延时的影响 ;
4. 在副本稳定的情况下,不会出现数据不一致的情况。
9. kafka 数据分区和消费者的关系?
每个分区只能由同一个消费组内的一个消费者 (consumer) 来消费,可以由不同的
消费组的消费者来消费,同组的消费者则起到并发的效果。
10. kafka 的数据 offset 读取流程
1. 连接 ZK 集群,从 ZK 中拿到对应 topic partition 信息和 partition Leader
的相关信息
2. 连接到对应 Leader 对应的 broker
3. consumer 己保存的 offset 发送给 Leader
4. Leader 根据 offset 等信息定位到 segment (索引 文件和 日志 文件)
5. 根据索引 文件中的内容,定位到 日志 文件中该偏移量 对应的开始
位置读取相应 长度的数据并返回给 consumer
11. kafka 内部如何保证顺序,结合外部组件如何保证消费者的顺
序?
kafka 只能保证 partition 内是有序的,但是 partition 间的有序是没办法的。爱奇
艺的搜索架构,是从业务上把需要有序的打到同 partition
12. Kafka 消息数据积压,Kafka 消费能力不足怎么处理?
1. 如果是 Kafka 消费能力不足,则可以考虑增加 Topic 的分区数,并且同时
提升消费组的消费者数量,消费者数 = 分区数。(两者缺一不可)
2. 如果是下游的数据处理不及时:提高每批次拉取的数量。批次拉取数据过
少(拉取数据 / 处理时间 < 生产速度),使处理的数据小于生产的数据,也
会造成数据积压。
13. Kafka 单条日志传输大小
kafka 对于消息体的大小默认为单条最大值是 1M 但是在我们应用场景中 , 常常
会出现一条消息大于 1M ,如果不对 kafka 进行配置。则会出现生产者无法将消
息推送到 kafka 或消费者无法去消费 kafka 里面的数据 , 这时我们就要对 kafka
行以下配置: server.properties
replica .fetch.max.bytes : 1048576 broker 可复制的消息的最大字节数 , 默认为 1 M
message .max.bytes : 1000012
kafka 会接收单个消息 size 的最大限制, 默认为 1 M
左右
注意: message.max.bytes 必须小于等于 replica.fetch.max.bytes ,否则就会导致
replica 之间数据同步失败。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值