Kafka 是常用的消息队列,它的定位是高吞吐的场景。但如果一个公司采用了多套 MQ,势必会增加维护成本。那么 Kafka 到底能否用在业务上呢?本文通过压测,对这个问题进行了探讨。

请仔细了解这张图,尤其注意有标志的几个关注点。我们会不止一次回到这张图上

背景

Kafka 到底能够应用在高可用的业务上?官方给出的答案是肯定的,最新版,已经支持消息队列的事务,但我们对其性能是有疑问的。

Kafka 根据配置的 ACK 级别,其性能表现将特别大,为了找到其适用场景,特做此测试,以便应用 kafka 时能够灵活应对。

测试过程还探讨了许多丢消息的场景。相对于大多数仅仅针对 kafka 集群本身的测试,本测试还介绍了丢消息的业务场景。整个方案应该是一个整体,才能够达到最高级别的高可用,不因该区别对待。

测试目标

  • 集群高可用,以及需要满足高可用时需要的最小集群大小和相关配置以及限制等
  • 消息不丢失,以及为了满足消息不丢失需要的配置和约定等
  • 测试环境

broker:

3 台机器8 core 16G 1T SSD Centos 6.8kafka_2.12-0.10.2.0 broker jvm 参数配置:Xms=8G Xmx=8G

client:

8 core 16G Centos 6.8

测试场景

集群高可靠性配置:

zookeeper.connection.timeout.ms=15000zookeeper.session.timeout.ms=15000default.replication.factor=3num.partitions=6 min.insync.replicas=2 unclean.leader.election.enable=falselog.flush.interval.ms=1000

ack

acks= all retries = 3 request.timeout.ms=5000

消息大小:1024byte


failover 测试

测试方法

下线一个节点,测试故障的恢复时间和故障期间的服务水平

测试过程

将 replica.lag.time.max.ms 从 10s 调整为 60s(延长时间方便观察),然后 kill Broker 0,挑选 3 个 partition,观察 ISR 变化如下:其中,第二 / 三阶段入队成功率受损:

  • 第二阶段期间,Partition 96/97/98 均无法写入,入队成功率成功率下降至 0%。
  • 第三阶段期间,Partition 96 可继续写入,但 Partition 97/98 无法写入,因为写入要等 Broker 0 回 ack,但 Broker 0 已 kill,入队成功率下降至 33%。

而实际观察,第二 / 三阶段期间完全没吞吐,原因是压测工具不断报连接失败,停止了写入。

原因分析

Kafka Broker leader 是通过 Controller 选举出来的,ISR 列表是 leader 维护的。前者的的租约是 Controller 定义的,后者的租约是 Broker 配置 replica.lag.time.max.ms 指定的。所以,第二阶段持续时间较短,是 Controller 的租约时间决定的,第三阶段持续时间较长,是 replica.lag.time.max.ms 决定的。当 Broker 0 被 kill 时,前者影响本来 Broker 0 是 leader 的 1/3 partitions 的入队成功率,后者影响 Broker 0 作为 follower 的 2/3 partitions 的入队成功率。

HA 结论

kafka 在 failover 期间,会有大约 10 秒的不可用时间,该时间由 replica.lag.time.max.ms 决定。因此应用程序需要处理此种情况下的异常信息,设置合理的重试次数和退避算法。


压力测试

测试方法

测试脚本:

./kafka-producer-perf-test.sh --topic test003 --num-records 1000000 --record-size 1024  --throughput -1 --producer.config ../config/producer.properties

测试结果

不限制并发吞吐量

[root@l-monitor-logstash2.pub.prod.aws.dm bin]# time ./kafka-producer-perf-test.sh --topic ack001 --num-records 1000000 --record-size 1024 --throughput -1 --producer.config ../config/producer.properties[2017-09-14 21:26:57,543] WARN Error while fetching metadata with correlation id 1 : {ack001=LEADER_NOT_AVAILABLE} (org.apache.kafka.clients.NetworkClient)81112 records sent, 16219.2 records/sec (15.84 MB/sec), 1416.2 ms avg latency, 1779.0 max latency.92070 records sent, 18414.0 records/sec (17.98 MB/sec), 1671.7 ms avg latency, 1821.0 max latency.91860 records sent, 18368.3 records/sec (17.94 MB/sec), 1670.3 ms avg latency, 1958.0 max latency.91470 records sent, 18294.0 records/sec (17.87 MB/sec), 1672.3 ms avg latency, 2038.0 max latency.91050 records sent, 18202.7 records/sec (17.78 MB/sec), 1678.9 ms avg latency, 2158.0 max latency.92670 records sent, 18534.0 records/sec (18.10 MB/sec), 1657.6 ms avg latency, 2223.0 max latency.89040 records sent, 17808.0 records/sec (17.39 MB/sec), 1715.0 ms avg latency, 2481.0 max latency.86370 records sent, 17274.0 records/sec (16.87 MB/sec), 1767.5 ms avg latency, 2704.0 max latency.91290 records sent, 18254.3 records/sec (17.83 MB/sec), 1670.2 ms avg latency, 2553.0 max latency.92220 records sent, 18444.0 records/sec (18.01 MB/sec), 1658.1 ms avg latency, 2626.0 max latency.90240 records sent, 18048.0 records/sec (17.63 MB/sec), 1669.9 ms avg latency, 2733.0 max latency.1000000 records sent, 17671.591150 records/sec (17.26 MB/sec), 1670.61 ms avg latency, 2764.00 ms max latency, 1544 ms 50th, 2649 ms 95th, 2722 ms 99th, 2753 ms 99.9th.real 0m57.409suser 0m14.544ssys 0m2.072s

限制吞吐量 1w

[root@l-monitor-logstash2.pub.prod.aws.dm bin]# time ./kafka-producer-perf-test.sh --topic ack003 --num-records 1000000 --record-size 1024 --throughput 10000 --producer.config ../config/producer.properties[2017-09-15 10:51:53,184] WARN Error while fetching metadata with correlation id 1 : {ack003=LEADER_NOT_AVAILABLE} (org.apache.kafka.clients.NetworkClient)[2017-09-15 10:51:53,295] WARN Error while fetching metadata with correlation id 4 : {ack003=LEADER_NOT_AVAILABLE} (org.apache.kafka.clients.NetworkClient)49766 records sent, 9953.2 records/sec (9.72 MB/sec), 34.9 ms avg latency, 358.0 max latency.50009 records sent, 10001.8 records/sec (9.77 MB/sec), 23.9 ms avg latency, 39.0 max latency.50060 records sent, 10008.0 records/sec (9.77 MB/sec), 23.9 ms avg latency, 49.0 max latency.49967 records sent, 9991.4 records/sec (9.76 MB/sec), 23.6 ms avg latency, 38.0 max latency.50014 records sent, 10000.8 records/sec (9.77 MB/sec), 24.0 ms avg latency, 51.0 max latency.50049 records sent, 10007.8 records/sec (9.77 MB/sec), 23.5 ms avg latency, 37.0 max latency.49978 records sent, 9995.6 records/sec (9.76 MB/sec), 23.5 ms avg latency, 44.0 max latency.49803 records sent, 9958.6 records/sec (9.73 MB/sec), 23.7 ms avg latency, 47.0 max latency.50229 records sent, 10045.8 records/sec (9.81 MB/sec), 23.6 ms avg latency, 46.0 max latency.49980 records sent, 9996.0 records/sec (9.76 MB/sec), 23.5 ms avg latency, 36.0 max latency.50061 records sent, 10010.2 records/sec (9.78 MB/sec), 23.6 ms avg latency, 36.0 max latency.49983 records sent, 9996.6 records/sec (9.76 MB/sec), 23.4 ms avg latency, 37.0 max latency.49978 records sent, 9995.6 records/sec (9.76 MB/sec), 23.9 ms avg latency, 55.0 max latency.50061 records sent, 10012.2 records/sec (9.78 MB/sec), 24.3 ms avg latency, 55.0 max latency.49981 records sent, 9996.2 records/sec (9.76 MB/sec), 23.5 ms avg latency, 42.0 max latency.49979 records sent, 9991.8 records/sec (9.76 MB/sec), 23.8 ms avg latency, 39.0 max latency.50077 records sent, 10013.4 records/sec (9.78 MB/sec), 23.6 ms avg latency, 41.0 max latency.49974 records sent, 9994.8 records/sec (9.76 MB/sec), 23.4 ms avg latency, 36.0 max latency.50067 records sent, 10011.4 records/sec (9.78 MB/sec), 23.8 ms avg latency, 65.0 max latency.49963 records sent, 9992.6 records/sec (9.76 MB/sec), 23.5 ms avg latency, 54.0 max latency.1000000 records sent, 9997.300729 records/sec (9.76 MB/sec), 24.24 ms avg latency, 358.00 ms max latency, 23 ms 50th, 28 ms 95th, 39 ms 99th, 154 ms 99.9th.real 1m40.808suser 0m16.620ssys 0m1.260s更多...吞吐量 5k 1000000 records sent, 4999.275105 records/sec (4.88 MB/sec), 22.94 ms avg latency, 127.00 ms max latency, 23 ms 50th, 27 ms 95th, 31 ms 99th, 41 ms 99.9th.吞吐量 2w 1000000 records sent, 18990.827430 records/sec (18.55 MB/sec), 954.74 ms avg latency, 2657.00 ms max latency, 739 ms 50th, 2492 ms 95th, 2611 ms 99th, 2650 ms 99.9th.吞吐量 3w 1000000 records sent, 19125.212768 records/sec (18.68 MB/sec), 1527.07 ms avg latency, 3020.00 ms max latency, 1582 ms 50th, 2815 ms 95th, 2979 ms 99th, 3011 ms 99.9th.

12 分区,2.6w 吞吐量

[root@l-monitor-logstash2.pub.prod.aws.dm bin]# time ./kafka-producer-perf-test.sh --topic ack001 --num-records 1000000 --record-size 1024 --throughput 26000 --producer.config ../config/producer.properties129256 records sent, 25840.9 records/sec (25.24 MB/sec), 31.9 ms avg latency, 123.0 max latency.129794 records sent, 25953.6 records/sec (25.35 MB/sec), 28.6 ms avg latency, 73.0 max latency.130152 records sent, 26025.2 records/sec (25.42 MB/sec), 28.3 ms avg latency, 64.0 max latency.130278 records sent, 26045.2 records/sec (25.43 MB/sec), 28.1 ms avg latency, 55.0 max latency.130106 records sent, 26010.8 records/sec (25.40 MB/sec), 27.9 ms avg latency, 45.0 max latency.130080 records sent, 26005.6 records/sec (25.40 MB/sec), 27.7 ms avg latency, 41.0 max latency.130093 records sent, 26013.4 records/sec (25.40 MB/sec), 74.5 ms avg latency, 343.0 max latency.1000000 records sent, 25904.051394 records/sec (25.30 MB/sec), 38.33 ms avg latency, 343.00 ms max latency, 28 ms 50th, 122 ms 95th, 242 ms 99th, 321 ms 99.9th.real 0m39.395suser 0m12.204ssys 0m1.616s

cpu 与内存无任何变化。网络 rx/tx :170Mbps/120Mbps,磁盘 IoUtil: 6%。1 百万数据能在 2 分钟内完成。

压测结论

影响提交效率的原因主要有:partition 数量 + 超时时长 + 消息大小 + 吞吐量

  • 不做限制:ack=all 的模式,不限制吞吐量,TPS 能够保持在 2w 左右,平均耗时在 1600ms 左右,99.9%的记录能够两秒左右正常提交反馈,最大耗时有记录超过 5 秒。

  • 超时时长:当将超时时常设置为 5 秒以上时,提交全部成功(ack)。将超时逐步降低到 3 秒左右,陆续会有大量超时出现。官方的默认值为 30 秒,考虑到网络环境的复杂性,建议将此参数设置成 10 秒,如还有超时,需要客户端捕获异常进行特殊处理。

  • 消息大小:当将消息大小设置为 512byte,提交的 TPS 能够打到 3w/秒;当增加到 2k 左右,TPS 降低到 9k/s,消息大小与 TPS 成线性关系。

  • 流量:当限制吞吐量为 1.3w 左右,减少竞争,效果最佳。平均耗时降低到 24 毫秒,最大延迟仅 300 多毫秒,服务水平相当高。

  • 分区数量:增加分区数能显著提高处理能力,但分区数会影响故障恢复时间。本测试用例仅针对 6 分区的情况,测试证明,当分区数增加到 12,处理能力几乎增加一倍,但继续增加,性能不会再有显著提升。

最终结论:假定网络状态良好,在 ack=all 模式、超时 10 秒、重试 3 次、分区为 6 的情况下,能够承受 1.3w/s 的消息请求,其写入平均耗时不超过 30ms,最大耗时不超过 500ms。想要增加 TPS,可以增加 partition 到 12,能够达到 2.6w/s 的高效写入。

堆积测试

kafka 生产和消费理论上不受消息堆积影响,消息堆积只是占用磁盘空间,这里的消息堆积是指 topic 中的消息数,和消息是否消费无关


结论

kafka 采用基于时间的 SLA(服务水平保证),重要消息保存 3 天。

性能

基本配置:消息 1k 大小,ack=all,即所有副本都同步的情况。为确保消息可靠,全部采用 3 个副本。

  • 3 副本,1 个 partition 的情况:6k-8k
  • 3 副本,6 个 partition 的情况:1.3w-1.6w
  • 3 副本,12 个 partion 的情况:2.6w-2.8w

注意:生产端,考虑一种场景,单条发送,然后调用 future.get()确认,TPS 会急剧降低到 2k 以下,请确认确实需要这么做,否则,使用异步提交,callback 调用的方式。相对于 ACK 模式 1.6w 的 TPS,普通模式提交,能够达到 13w(主要是网络和 IO 瓶颈,带宽占满)。当吞吐量限制在 1w 左右并且开启 ACK(非常符合我们的业务特征),kafka 是高效且高可用的,平均耗时仅 24 毫秒,生产者的最佳实践是将超时设置成 10 秒,重试 3 次。消费者同样是高效的,6 个 partition、ack 模式,平均耗时在 20 毫秒左右,具体处理耗时取决于消费端的处理能力。

kafka 消息可靠性

  • 写 3 个副本,开启 ack=all 模式,每 1 秒刷一次磁盘。一条消息要经历 Client --> Leader →Replica 这个过程。leader 等待所有的 replica 的 ack 应答,然后 ack 给 Client 端,整个过程多次确认;ack 失败的消息,会再次重试,此模式能保证数据不丢失。要想达到此种消息级别,请务必按照架构组提供的最佳实践进行配置(kafka 不同版本间参数相差很多)。
  • 消息传递有三种模式,kafka 同步发送是 At least one 模式(0.10 版)。消费端,要做幂等处理。可能产生重复消息的场景为:生产端发送了消息到 leader 节点,leader 节点同步到所有 follower 节点并得到确认,此时 leader 节点当机,未将 ack 返回给生产端,生产端此时会尝试重发消息。然后 follower 节点中某台机器提升为 leader,重复的数据由此产生。

扩容,故障的影响

  • 单节点当机,短暂影响生产消费,故障恢复时间与 leader 选举时间与 partition 数量有关(约 10 秒 isr 探测时间)。使用 ACK 模式,配合重试,能够保证故障期间数据不丢失。上图的 2 位置。
  • 扩容,等同于节点上线,不影响使用方。但节点到达可用状态,与整体落后数据量相关(简单的网络拷贝过程)。根据经验,部分消息拉取时间会变长,但影响不大。压测过程无明显抖动。建议消费端设置较长的超时来进行处理(包括异步处理情况)。上图的 3 位置。
  • >=2 节点当机(机房断电等),服务不可用。故障恢复需要两个节点达到同步状态,与整体数据量相关。磁盘每秒 fsync,极端情况(全部当机),最多会丢失 1 秒数据。

什么时候会丢数据

  • 使用 batch 模式发送,缓冲区有数据时没有优雅关闭,此时缓冲区中数据会丢失。上图 1 位置。
  • 使用 batch 模式消费,拉取消息后,异步使用线程池处理,如果线程池没有优雅关闭,此时消费数据会丢失。上图 4 位置。

风险

  • 压测 TPS 仅作参考,实际运行中受网络延迟,坏盘、高低峰流量等影响,服务会有抖动。生产和消费端务必将所有处理失败的消息进行记录,以便极端情况下进行数据回放。
  • 消息中请勿传递大块不必要数据,消息大小对服务质量有直接线性影响。(请保持消息<2kb)
  • 消费端消费,除考虑幂等,不正确的异步线程池使用(比如使用了无界队列),经常造成消费端故障,请谨慎消费。
  • 如分配了 6 个 partition,如果你有 7 台消费机器,其中有一台会是空闲的。设计时请考虑 kafka 的限制。
  • 默认 kafka 生产端开启了 batch 提交模式,也就是说,如果此时你的生产者当了,buffer 中的消息会丢。请确保:生产者使用"kill -15"杀进程以给服务 flush 的机会;同时,如果你的消息很重要,请同时写入到日志文件中。 请权衡利弊再确认使用。

阅读全文: http://gitbook.cn/gitchat/activity/5e9fa8b98d6f9619b1fc5f58

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App , GitChat 专享技术内容哦。

360 度测试:Kafka 会丢数据么?其高可用是否满足需求?相关推荐

  1. 数据中心网络高可用架构

    文章不错,转来了 http://www.h3c.com.cn/Solution/Operational/DataCenter/Solutions/201003/802841_30004_0.htm 相 ...

  2. nacos 本地测试_一文详解 Nacos 高可用特性

    简介:我今天介绍的 Nacos 高可用,是 Nacos 为了提升系统稳定性而采取的一系列手段.Nacos 的高可用不仅仅存在于服务端,同时也存在于客户端,以及一些与可用性相关的功能特性中,这些点组装起 ...

  3. GBase 8s的高可用1-HAC(双机高性能实时数据复制)高可用方案

    HAC( 双机高性能实时数据复制) 是基于数据库逻辑日志复制技术, 实现主.备机数据复制, 复制方式支持同步和异步两种模式. 根据灾备距离支持同城和异地灾备技术, 异地灾备支持多节点. HAC 集群通 ...

  4. Kafka丢数据、重复消费、顺序消费的问题

    面试官:今天我想问下,你觉得Kafka会丢数据吗? 候选者:嗯,使用Kafka时,有可能会有以下场景会丢消息 候选者:比如说,我们用Producer发消息至Broker的时候,就有可能会丢消息 候选者 ...

  5. 昨晚,我们的消费者居然停止消费kafka集群数据了

    以下文章来源方志朋的博客,回复"666"获面试宝典 图片来源:伪装者 来源 | https://juejin.im/post/6874957625998606344 笔者所在的是一 ...

  6. 2021年大数据HBase(六):HBase的高可用!【建议收藏】

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 HBase的高可用 一.HBASE高可用的简介 二.搭 ...

  7. 因为一次 Kafka 宕机,终于搞透了 Kafka 高可用原理!

    -     Kafka 宕机引发的高可用思考     - 问题要从一次Kafka的宕机开始说起. 笔者所在的是一家金融科技公司,但公司内部并没有采用在金融支付领域更为流行的 RabbitMQ ,而是采 ...

  8. 因为一次宕机,终于搞透了 Kafka 高可用原理!

    1 Kafka 宕机引发的高可用思考 问题要从一次Kafka的宕机开始说起. 笔者所在的是一家金融科技公司,但公司内部并没有采用在金融支付领域更为流行的 RabbitMQ ,而是采用了设计之初就为日志 ...

  9. 慌得一逼,Kafka宕机后不再高可用?吓死宝宝了

    你知道的越多,不知道的就越多,业余的像一棵小草! 你来,我们一起精进!你不来,我和你的竞争对手一起精进! 编辑:业余草 来源:juejin.im/post/6874957625998606344 推荐 ...

  10. 数据架构:从主备,主主到集群的高可用方案

    本文转载自公众号:不止思考 在互联网项目中,当业务规模越来越大,数据越来越多,随之而来的就是数据库压力会越来越大.慢慢就会发现,数据库层可能已经成为了整个系统的关键点和性能瓶颈了,因此实现数据层的高可 ...

最新文章

  1. 007_Maven依赖管理
  2. fatal error:can't open and lock privilege tables:table 'mysql.host' doesn't exist
  3. 在VS中MFC、ATL与WIN32有什么联系或区别?
  4. 【php7扩展开发五】函数调用
  5. leetcode 137. 只出现一次的数字 II(位运算)
  6. python循环定义变量_Python变量和循环
  7. php助理工作内容,生产助理的工作职责
  8. VS2015 C#6.0 中的那些新特性(转)
  9. yii操作数据库(AR)
  10. CC2530的硬件功能及实例讲解
  11. c语言i2c读到8位数据,AT24C08 I2C的读写操作实验
  12. Vue中使用Bscroll @click无法执行的问题
  13. 新宝市场分析近期大涨的抱团板块个股大多高位收阴或者黄昏星的感觉
  14. springboot获取到的MySQL数据少了8小时
  15. angular2完整视频教程收藏(大漠穷秋)
  16. Ant Design Vue全局对话确认框(confirm)的回调不触发
  17. 论文阅读笔记《Adaptive Image-Based Visual Servoing Using Reinforcement Learning With Fuzzy State Coding》
  18. MYSQL JDBC图书管理系统
  19. 初学算法——第二天:斐波那契数列
  20. 2022-2023寒假

热门文章

  1. 微信逆向分析(一)——逆向分析的原理
  2. 【测试开发】Pytest—Html测试报告定制及封装
  3. arduino蓝牙通讯代码_arduino蓝牙通讯
  4. InfluxDB中Line Protocol理解
  5. Altium Designer之泪点和常规铺铜操作笔记
  6. 电器行业ERP案例总结
  7. 英语自然拼读:字母A的常见几种发音
  8. 计算机社团闯关游戏,计算机协会社团文化节小游戏
  9. Java人工弱智算法_人工智障也刷题!Kaggle 入门之实战泰坦尼克号
  10. ZT华尔街日报:中国楼市泡沫的破灭预言 暴跌70%