1、如何获取 topic 主题的列表

  1. bin/kafka-topics.sh --list --zookeeper localhost:2181

2、生产者和消费者的命令行是什么?

生产者在主题上发布消息:

  1. bin/kafka-console-producer.sh --broker-list 192.168.43.49 :9092 --topic Hello-Kafka

注意这里的 IP是 server.properties 中的 listeners 的配置。 接下来每个新行就是输入一条新消息。
消费者接受消息:

  1. bin/kafka-console-consumer.sh --zookeeper localhost:2181 --topic Hello-Kafka --from-beginning

3、 consumer 是推还是拉?

  1. Kafka 最初考虑的问题是,customer 应该从 brokes 拉取消息还是 brokers将消息推送到 consumer,也就是 pull还是push 。在这方面,Kafka 遵循了一种大部分消息系统共同的传统的设计: producer 将消息推送到 broker,consumer 从 broker 拉取消息 。
  2. 一些 消息系统 比如 Scribe 和 Apache Flume 采用了 push 模式, 将消息推送到下游的consumer 。 这样做有好处也有坏处:由 broker 决定消息推送的速率, 对于不同消费速率的consumer 就不太好处理了。 消息系统都致力于让 consumer 以 最大 的速 率最 快速 的消 费消 息, 但不 幸的 是, push 模式 下, 当 broker 推送 的速 率远 大于 consumer 消费 的速 率时, consumer 恐怕 就要 崩溃 了。 最终 Kafka 还 是选 取了 传统 的 pull 模式 。
  3. Pull 模 式 的 另 外 一 个 好 处 是 consumer 可 以 自 主 决 定 是 否 批量 的 从 broker 拉 取 数 据 。 Push 模 式 必 须 在 不 知 道 下游 consumer 消 费 能 力 和 消 费 策 略的 情 况 下决 定 是 立 即 推 送 每 条 消 息 还是 缓 存 之后 批 量 推 送 。如 果 为 了 避 免 consumer 崩 溃 而 采 用 较 低 的 推 送 速 率, 将可 能 导 致一 次 只 推 送 较少 的 消 息 而 造 成 浪 费 。 Pull 模 式 下 , consumer 就 可 以 根 据 自 己 的 消费 能 力 去决 定 这 些 策 略。
  4. Pull 有个 缺 点 是, 如果 broker 没 有 可 供 消 费 的 消 息, 将 导 致 consumer 不 断 在 循 环 中 轮 询, 直 到 新 消 息 到 t 达 。 为 了 避 免 这 点, Kafka 有个 参 数 可 以 让 consumer 阻 塞 知 道 新 消 息 到 达 (当 然 也 可 以 阻 塞 知 道消 息 的 数量 达 到 某 个 特定 的 量 这 样 就 可 以 批 量 发 送 ) 。

4、讲讲 kafka 维护消费状态跟踪的方法

大 部 分 消 息 系 统 在 broker 端 的 维 护 消 息 被 消 费的 记 录: 一 个 消 息 被 分发 到 consumer 后 broker 就 马 上 进 行 标 记 或 者等待 customer 的 通 知 后 进 行 标 记 。这 样 也 可 以 在 消 息 在 消费 后 立 马就 删 除 以 减 少空 间 占 用 。 但 是 这 样 会 不 会 有 什么 问 题 呢? 如 果 一 条 消息 发 送 出 去 之 后 就 立 即 被 标 记 为 消 费 过 的, 一 旦 consumer 处 理 消 息 时 失 败 了 (比 如 程 序崩 溃) 消 息 就丢 失 了 。 为 了 解 决 这 个 问 题, 很 多消 息 系 统提 供 了 另 外 一个 个 功 能: 当 消 息 被 发 送 出 去 之 后 仅 仅 被 标 记 为 已 发 送 状态, 当 接到 consumer 已 经 消 费 成 功 的 通 知后 才 标 记为 已 被 消 费 的 状 态 。这 虽 然 解 决 了 消 息 丢失 的 问 题,但 产 生 了 新 问 题,首 先 如 果 consumer 处 理 消 息 成 功 了 但 是向 broker 发 送 响 应 时 失 败 了, 这 条 消 息 将 被 消 费 两次 。 第 二 个 问 题 时, broker 必 须 维 护 每 条 消 息 的状 态, 并且 每 次 都 要 先锁 住 消 息 然 后 更 改 状 态 然 后 释 放 锁 。 这样 麻 烦 又来 了, 且 不 说要 维 护 大 量 的 状 态 数 据, 比 如 如 果 消 息 发 送 出 去 但 没 有 收到 消 费 成功 的 通 知, 这条 消 息 将 一 直 处 于 被 锁 定 的 状 态 , Kafka 采 用 了 不 同 的 策 略 。 Topic 被 分 成 了 若 干 分 区, 每 个 分 区 在 同 一 时 间只 被 一 个 consumer 消 费 。 这 意 味 着 每 个分 区 被 消费 的 消 息 在 日志 中 的 位 置 仅 仅 是 一 个
简 单 的 整 数: offset 。 这 样 就 很 容 易 标 记 每个 分 区 消费 状 态 就 很 容易 了, 仅 仅 需 要 一 个 整 数 而 已 。 这 样消 费 状 态的 跟 踪 就 很 简单 了 。
这带 来了 另外 一个 好处: consumer 可以 把 offset 调成 一个 较老 的值, 去 重新 消 费老 的消 息。 这对 传统 的消 息系 统来 说看 起来 有些 不可 思议, 但 确实 是非 常有 用 的, 谁规 定了 一条 消息 只能 被消 费一 次呢?

5、讲一下主从同步

参考:https://blog.csdn.net/honglei915/article/details/37565289

6、为什么需要消息系统, mysql 不能满足需求吗?

  1. 解耦:

允许 你独 立的 扩展 或修 改两 边的 处理 过程, 只 要确 保它 们遵 守同 样的 接口 约束 。

  1. 冗余:

消息 队列 把数 据进 行持 久化 直到 它们 已经 被完 全处 理, 通过 这一 方式 规避 了数 据 丢失 风险 。 许多 消息 队列 所采 用的 ”插入 -获取 -删除 ”范式 中, 在把 一个 消息 从队 列中 删除 之前, 需 要你 的处 理系 统明 确的 指出 该消 息已 经被 处理 完毕, 从 而确 保 你的 数据 被安 全的 保存 直到 你使 用完 毕。

  1. 扩展性:

因为 消息 队列 解耦 了你 的处 理过 程, 所以 增大 消息 入队 和处 理的 频率 是很 容易 的, 只要 另外 增加 处理 过程 即可 。

  1. 灵活性 & 峰值处理能力:

在访 问量 剧增 的情 况下, 应 用仍 然需 要继 续发 挥作 用, 但是 这样 的突 发流 量并 不 常见 。如 果为 以能 处理 这类 峰值 访问 为标 准来 投入 资源 随时 待命 无疑 是巨 大的 浪 费。 使用 消息 队列 能够 使关 键组 件顶 住突 发的 访问 压力, 而 不会 因为 突发 的超 负 荷的 请求 而完 全崩 溃。

  1. 可恢复性:

系统 的一 部分 组件 失效 时, 不会 影响 到整 个系 统。 消息 队列 降低 了进 程间 的耦 合 度, 所以 即使 一个 处理 消息 的进 程挂掉, 加入 队列 中的 消息 仍然 可以 在系 统恢 复 后被 处理 。

  1. 顺序保证:

在大 多使 用场 景下, 数据 处理 的顺 序都 很重 要 。 大部 分消 息队 列本 来就 是排 序的, 并且 能保 证数 据会 按照 特定 的顺 序来 处理 。( Kafka 保证 一个 Partition 内的 消 息的 有序 性)

  1. 缓冲:

有助于控 制和 优化 数据 流经 过系 统的 速度, 解 决生 产消 息和 消费 消息 的处 理速 度 不一 致的 情况 。

  1. 异步通信:

很多 时候, 用户不 想也 不需 要立 即处 理消 息。 消息 队列 提供 了异 步处 理机 制, 允 许用 户把 一个 消息 放入 队列, 但 并不 立即 处理 它。 想向 队列 中放 入多 少消 息就 放 多少, 然 后在 需要 的时 候再 去处 理它 们。

7、 Zookeeper 对于 Kafka 的作用是什么?

  • Zookeeper 是一 个开 放源 码的 、高性 能的 协调 服务, 它用 于 Kafka 的分 布式 应用 。
  • Zookeeper 主要 用于 在集 群中 不同 节点 之间 进行 通信
  • 在 Kafka 中, 它被 用于 提交 偏移 量, 因此 如果 节点 在任 何情 况下 都失 败了, 它 都 可以 从之 前提 交的 偏移 量中 获取
  • 除此 之外, 它还 执行 其他 活动, 如 : leader 检测 、 分布 式同 步 、 配置 管理 、 识别 新 节点 何时 离开 或连 接、 集群 、节 点实 时状 态等 等。

8、数据传输的事务定义有哪三种?

和 MQTT 的事 务定 义一 样都 是 3 种。
(1) 最 多一 次: 消息 不会 被重 复发 送, 最多 被传 输一 次, 但也 有可 能一 次不 传输
(2) 最 少一 次: 消息 不会 被漏 发送, 最 少被 传输 一次, 但 也有 可能 被重 复传 输 .
(3) 精确 的一 次 (Exactly once) : 不会 漏传 输也 不会 重复 传输 ,每个 消息 都传 输 被一 次而 且仅 仅被 传输 一次, 这 是大家所期望的

9、 Kafka 判断一个节点是否还活着有那两个条件?

(1) 节点 必须 可以 维护 和 ZooKeeper 的连 接, Zookeeper 通过 心跳 机制 检查 每 个节 点的 连接
(2) 如果 节点 是个 follower,他必 须能 及时 的同 步 leader 的写 操作, 延时 不能 太 久

10、 Kafka 与传统 MQ 消息系统之间有三个关键区别

(1).Kafka 持久 化日 志, 这些 日志 可以 被重 复读 取和 无限 期保 留
(2).Kafka 是一 个分 布式 系统: 它以 集群 的方 式运 行, 可以 灵活 伸缩, 在内 部通 过 复制 数据 提升 容错 能力 和高 可用 性
(3).Kafka 支持 实时 的流 式处 理

11、讲一讲 kafka 的 ack 的三种机制

request.required.acks 有三 个值 0 1 -1(all)

0:生产 者不 会等 待 broker 的 ack, 这个 延迟 最低 但是 存储 的保 证最 弱当 server 挂 掉的 时候 就会 丢数 据。

1:服务 端会 等待 ack 值 leader 副本 确认 接收 到消 息后 发送 ack 但是 如果 leader 挂掉 后他 不确 保是 否复 制完 成新 leader 也会 导致 数据 丢失 。

-1(all): 服 务端 会等 所有 的 follower 的副 本受 到数 据后 才会 受到 leader 发出 的 ack, 这 样数 据不 会丢 失

12、消 费者 如何 不自 动提 交偏 移量, 由 应用 提交?

将 auto.commit.offset 设为 false, 然 后在 处理 一批 消息 后 commitSync() 或者 异步 提交 commitAsync()
即:

ConsumerRecords<> records = consumer.poll();
for (ConsumerRecord<> record : records){
。。。
tyr{
consumer.commitSync()
}
。。。
}

13、消费者故障,出现活锁问题如何解决?

出 现 “ 活 锁 ”的 情 况, 是 它 持 续 的 发 送 心 跳, 但 是 没 有 处 理 。 为 了 预 防 消 费 者 在 这 种 情 况 下 一 直 持 有 分 区, 我 们 使 用 max.poll.interval.ms 活 跃 检 测 机 制 。 在 此 基 础 上, 如 果 你 调 用 的 poll 的 频 率 大 于 最 大 间 隔, 则 客 户 端 将 主 动 地 离 开 组, 以 便 其 他 消 费 者 接 管 该 分 区 。 发 生 这 种 情 况 时, 你 会 看 到 offset 提 交 失 败 (调 用 commitSync () 引 发 的 CommitFailedException) 。 这 是 一 种 安 全 机 制, 保 障 只 有 活 动 成 员 能 够 提 交 offset。 所 以 要 留 在 组 中, 你 必 须 持 续 调 用 poll。

消费 者提 供两 个配 置设 置来 控制 poll 循环:

max.poll.interval.ms: 增 大 poll 的 间 隔, 可 以 为 消 费 者 提 供 更 多 的 时 间 去 处 理 返 回 的 消 息 (调 用 poll(long)返 回 的 消 息, 通 常 返 回 的 消 息 都 是 一 批) 。 缺 点 是 此 值 越 大 将 会 延 迟 组 重 新 平 衡 。

max.poll.records: 此 设 置 限 制 每 次 调 用 poll 返 回 的 消 息 数, 这 样 可 以 更 容 易 的 预 测 每 次 poll 间 隔 要 处 理 的 最 大 值 。 通 过 调 整 此 值, 可 以 减 少 poll 间 隔, 减 少 重 新 平 衡 分 组 的

对 于 消 息 处 理 时 间 不 可 预 测 地 的 情 况, 这 些 选 项 是 不 够 的 。 处 理 这 种 情 况 的 推 荐 方 法 是 将 消 息 处 理 移 到 另 一 个 线 程 中, 让 消 费 者 继 续 调 用 poll 。 但 是 必 须 注 意 确 保 已 提 交 的 offset 不 超 过 实 际 位 置 。 另 外, 你 必 须 禁 用 自 动 提 交, 并 只 有 在 线 程 完 成 处 理 后 才 为 记 录 手 动 提 交 偏 移 量 (取 决 于 你) 。 还 要 注 意, 你 需 要 pause 暂 停 分 区, 不 会 从 poll 接 收 到 新 消 息, 让 线 程 处 理 完 之 前 返 回 的 消 息 (如 果 你 的 处 理 能 力 比 拉 取 消 息 的 慢, 那 创 建 新 线 程 将 导 致 你 机 器 内 存 溢 出) 。

14、如何控制消费的位置

kafka 使 用 seek(TopicPartition, long)指 定 新 的 消 费 位 置 。 用 于 查 找 服 务 器 保 留 的 最 早 和 最 新 的 offset 的 特 殊 的 方 法 也 可 用 (seekToBeginning(Collection) 和 seekToEnd(Collection))

15、 kafka 分布式(不是单机)的情况下,如何保证消息的顺序消费?

Kafka 分 布 式 的 单 位 是 partition,同 一 个 partition 用 一 个 write ahead log 组 织, 所 以 可 以 保 证 FIFO 的 顺 序 。 不 同 partition 之 间 不 能 保 证 顺 序 。 但 是 绝 大 多 数 用 户 都 可 以 通 过 message key 来 定 义, 因 为 同 一 个 key 的 message 可 以 保 证 只 发 送 到 同 一 个 partition。

Kafka 中 发 送 1 条 消 息 的 时 候, 可 以 指 定 (topic, partition, key) 3 个 参 数 。 partiton 和 key 是 可 选 的 。 如 果 你 指 定 了 partition, 那 就 是 所 有 消 息 发 往 同 1 个 partition, 就 是 有 序 的 。 并 且 在 消 费 端, Kafka 保 证, 1 个 partition 只 能 被 1 个 consumer 消 费 。 或 者 你 指 定 key (比 如 order id) , 具 有 同 1 个 key 的 所 有 消 息, 会 发 往 同 1 个 partition。

16、 kafka 的高可用机制是什么?

这 个 问 题 比 较 系 统, 回 答 出 kafka 的 系 统 特 点, leader 和 follower 的 关 系, 消 息 读 写 的 顺 序 即 可 。

https://www.cnblogs.com/qingyunzong/p/9004703.html

https://www.tuicool.com/articles/BNRza2E

https://yq.aliyun.com/articles/64703

17、 kafka 如何减少数据丢失

https://www.cnblogs.com/huxi2b/p/6056364.html

18、 kafka 如何不消费重复数据?比如扣款,我们不能重复的扣。

其实 还是 得结 合业 务来 思考, 我 这里 给几 个思 路:

比如 你拿 个数 据要 写库, 你 先根 据主 键查 一下, 如 果这 数据 都有 了, 你就 别插 入
了, update 一下 好吧 。
比如 你是 写 Redis, 那 没问 题了, 反 正每 次都 是 set, 天 然幂 等性 。
比如 你不 是上 面两 个场 景, 那做 的稍 微复 杂一 点, 你需 要让 生产 者发 送每 条数 据 的时 候, 里面 加一 个全 局唯 一的 id, 类似 订单 id 之类 的东 西, 然后 你这 里消 费 到了 之后, 先根 据这 个 id 去比 如 Redis 里查 一下, 之前 消费 过吗? 如 果没 有消 费过, 你 就处 理, 然后 这个 id 写 Redis。如 果消 费过 了, 那你 就别 处理 了, 保 证别 重复 处理 相同 的消 息即 可。
比如 基于 数据 库的 唯一 键来 保证 重复 数据 不会 重复 插入 多条 。因 为有 唯一 键约 束 了, 重复 数据 插入 只会 报错, 不 会导 致数 据库 中出 现脏 数据 。