kafka压力测试(官方自带)

一:Kafka压测

用Kafka官方自带的脚本,对Kafka进行压测。Kafka压测时,可以查看到哪个地方出现了瓶颈(CPU,内存,网络IO)。

一般都是网络IO达到瓶颈

kafka-consumer-perf-test.sh
kafka-producer-perf-test.sh

1、Kafka Producer压力测试

在…/kafka/bin目录下

[duoduo@hadoop100 kafka_2.11-2.4.0]$ bin/kafka-producer-perf-test.sh --topic test --record-size 100 --num-records 100000 --throughput -1 --producer-props bootstrap.servers=hadoop100:9092,hadoop102:9092,hadoop101:9092

说明:
  • record-size:一条信息有多大,单位字节
  • num-records:总共发送多少条信息
  • throughput:每秒多少条信息,设置成-1,表示不限流,可测生产者最大吞吐量
结果:

100000 records sent, 27495.188342 records/sec (2.62 MB/sec), 1461.75 ms avg latency, 2183.00 ms max latency, 1696 ms 50th, 2103 ms 95th, 2177 ms 99th, 2181 ms 99.9th.

解析:
  • 一共写入10万条消息
  • 吞吐量为2.62 MB/sec
  • 每次写入的平均延迟为1461.75ms
  • 最大延迟2183.00 ms

2、Kafka Consumer 压力测试

consumer测试,如果这四个指标(IO,CPU,内存,网络)都不能改变,考虑增加分区数来提升性能

[duoduo@hadoop100 kafka_2.11-2.4.0]$ bin/kafka-consumer-perf-test.sh --broker-list hadoop100:9092 --topic test --fetch-size 10000 -messages 10000000 --threads 1

参数说明:
  • broker-list:节点地址
  • topic:指定topic名称
  • fetch-size:指定每个fetch的数据大小
  • messages:总共要消费的消息个数
结果:

start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec, rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec
2020-06-27 13:17:57:490, 2020-06-27 13:18:11:751, 20.0272, 1.4043, 210000, 14725.4751, 1593235077858, -1593235063597, -0.0000, -0.0001

解释:
  • 开始时间
  • 结束时间
  • 共消费数据:20.0272M
  • 吞吐量:1.4043MB/s
  • 共消费数据:210000条
  • 平均每秒消费:14725.4751条

二:项目经验之Kafka机器数量计算

*Kafka机器数=2 (峰值生产速度 * 副本数 / 100)+1
先拿到峰值生产速度,再根据设定的副本数,就能预估出需要部署Kafka的数量。
比如:峰值生产速度为50M/s,副本为2

Kafka机器数=2*(50*2/100)+1=3(台)

三:项目经验值Kafak分区数计算

说到kafka就一定会想到创建几个分区,几个副本。副本数一般情况下都是连个或三个,但是分区数如何计算呢?
1)创建一个只有1个分区的topic
2)测试这个topic的producer吞吐量和consumer吞吐量。
3)假设他们的值分别是Tp和Tc,单位可以是MB/s。
4)然后假设总的目标吞吐量是Tt,那么分区数=Tt / min(Tp,Tc)
例如:producer吞吐量=20m/s;consumer吞吐量=50m/s,期望吞吐量100m/s;
分区数=100 / 20 =5分区
分区数一般设置为:3-10个

<think>嗯,用户想了解如何使用Java代码进行Kafka压力测试。首先,我需要明确压力测试的目的,通常是评估Kafka在高负载下的性能,比如吞吐量、延迟和资源使用情况。然后,我得考虑使用哪些工具或框架。Kafka自带kafka-producer-perf-testkafka-consumer-perf-test脚本,但用户可能更希望用Java代码来实现,这样更灵活。 接下来,我得回忆一下用Java进行压力测试的常见方法。通常,可以编写生产者和消费者客户端,模拟大量消息的发送和接收。需要用到Kafka的Producer和Consumer API。对于生产者,需要配置参数如bootstrap.servers、acks、linger.ms、batch.size等,以优化性能。同样,消费者端需要配置合适的参数,比如fetch.min.bytes、max.poll.records等。 然后,考虑如何设计测试用例。可能需要多线程来模拟并发用户,或者使用线程池来同时启动多个生产者和消费者。同时,需要记录发送和接收的消息数量、时间,以便计算吞吐量和延迟。此外,可能需要统计成功发送的消息数、失败数,以及消费者的处理速度。 用户可能还需要了解如何监控测试过程中的指标,比如使用Kafka的内置指标或者集成监控工具如JMX、Prometheus。不过,这部分可能超出了代码示例的范围,但可以简要提及。 另外,需要注意在压力测试时,Kafka集群的配置,比如分区数量、副本因子等,这些都会影响性能。用户可能需要根据测试结果调整这些参数。不过,用户的问题主要集中在Java代码实现,所以这部分可能作为后续建议。 可能还需要提到第三方工具,比如Apache JMeter,或者使用Kafka自带的性能测试脚本,但用户明确要求用Java代码的方式,所以需要集中在代码示例上。 现在,我需要组织这些思路,提供一个结构化的回答。首先介绍压力测试的目的,然后分步骤说明如何实现生产者和消费者的测试,给出代码示例,并解释关键配置参数。最后,可以给出运行建议和注意事项,比如逐步增加负载、监控系统指标等。 需要确保代码示例的正确性,比如正确创建ProducerRecord,处理回调,正确关闭生产者。同时,消费者部分可能需要使用多线程来并发消费,或者使用Consumer的poll方法持续拉取消息。 还要注意资源管理,比如在测试结束后关闭所有线程和客户端,避免资源泄漏。另外,可能需要使用计数器来统计发送和接收的消息数量,使用原子变量来保证线程安全。 最后,提醒用户根据测试结果调整配置,比如调整批处理大小、压缩方式、确认机制等,以达到最佳性能。</think>以下是使用 Java 代码进行 Kafka 压力测试的常见方法和示例: --- ### **1. 压力测试目标** - **生产者**:测试最大消息发送吞吐量(如 messages/sec 或 MB/sec) - **消费者**:测试消息拉取和处理速度 - **综合场景**:模拟高并发下的端到端延迟和稳定性 --- ### **2. 核心依赖** 在 `pom.xml` 中添加 Kafka 客户端依赖: ```xml <dependency> <groupId>org.apache.kafka</groupId> <artifactId>kafka-clients</artifactId> <version>3.6.0</version> </dependency> ``` --- ### **3. 生产者压力测试示例** ```java import org.apache.kafka.clients.producer.*; public class KafkaProducerStressTest { private static final String TOPIC = "stress-test-topic"; private static final String BOOTSTRAP_SERVERS = "localhost:9092"; private static final int MESSAGE_COUNT = 1000000; // 目标发送消息数 public static void main(String[] args) { // 配置生产者参数(关键优化参数) Properties props = new Properties(); props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS); props.put(ProducerConfig.ACKS_CONFIG, "1"); // 平衡速度与可靠性 props.put(ProducerConfig.LINGER_MS_CONFIG, 10); // 批量发送延迟 props.put(ProducerConfig.BATCH_SIZE_CONFIG, 16384); // 批次大小 props.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "snappy"); // 压缩提升吞吐 props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer"); KafkaProducer<String, String> producer = new KafkaProducer<>(props); long startTime = System.currentTimeMillis(); try { for (int i = 0; i < MESSAGE_COUNT; i++) { String key = "key-" + i; String value = "value-" + System.currentTimeMillis(); ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, key, value); // 异步发送(同步会大幅降低吞吐) producer.send(record, (metadata, exception) -> { if (exception != null) { System.err.println("发送失败: " + exception.getMessage()); } }); // 进度跟踪 if (i % 10000 == 0) { System.out.println("已发送: " + i + " 条消息"); } } } finally { producer.close(); long duration = System.currentTimeMillis() - startTime; System.out.printf("总耗时: %d ms, 吞吐量: %.2f msg/s%n", duration, (MESSAGE_COUNT * 1000.0) / duration); } } } ``` --- ### **4. 消费者压力测试示例** ```java import org.apache.kafka.clients.consumer.*; public class KafkaConsumerStressTest { private static final String TOPIC = "stress-test-topic"; private static final String BOOTSTRAP_SERVERS = "localhost:9092"; private static final int POLL_TIMEOUT = 100; // ms public static void main(String[] args) { Properties props = new Properties(); props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS); props.put(ConsumerConfig.GROUP_ID_CONFIG, "stress-test-group"); props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest"); props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer"); props.put(ConsumerConfig.FETCH_MIN_BYTES_CONFIG, 1024); // 减少拉取频率 props.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 500); // 单次拉取最大记录数 KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); consumer.subscribe(Collections.singletonList(TOPIC)); long startTime = System.currentTimeMillis(); int messageCount = 0; try { while (true) { ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(POLL_TIMEOUT)); if (records.isEmpty()) break; for (ConsumerRecord<String, String> record : records) { messageCount++; // 模拟消息处理(可在此添加处理逻辑) } // 手动提交偏移量(按需选择同步/异步) consumer.commitAsync(); } } finally { consumer.close(); long duration = System.currentTimeMillis() - startTime; System.out.printf("消费 %d 条消息, 耗时: %d ms, 吞吐量: %.2f msg/s%n", messageCount, duration, (messageCount * 1000.0) / duration); } } } ``` --- ### **5. 关键优化参数** | **生产者参数** | **说明** | |------------------------------|-----------------------------------| | `acks` | 0(最快)、1(默认)、all(最可靠)| | `compression.type` | snappy/lz4/zstd 压缩减少网络开销 | | `batch.size` / `linger.ms` | 控制批量发送行为 | | **消费者参数** | **说明** | |------------------------------|-----------------------------------| | `fetch.min.bytes` | 单次拉取最小数据量 | | `max.poll.records` | 单次拉取最大消息数 | | `max.partition.fetch.bytes` | 单分区最大拉取量 | --- ### **6. 执行建议** 1. **逐步增压**:从低并发开始,逐步增加线程/消息量 2. **监控指标**:使用 `kafka-producer-perf-test.sh` / `kafka-consumer-perf-test.sh` 对比测试 3. **资源监控**:观察 CPU、网络、磁盘 IO 是否成为瓶颈 4. **集群配置**:根据测试结果调整分区数、副本因子等 --- ### **7. 高级技巧** - **多线程生产/消费**:使用线程池模拟并发客户端 - **消息去重校验**:在消息体中加入序列号,验证数据完整性 - **端到端延迟测量**:在消息中记录发送时间戳,消费时计算延迟 通过调整参数和代码逻辑,可灵活模拟各种压力场景。建议结合 JMX 监控(如 `kafka.producer:type=producer-metrics`)深入分析性能瓶颈。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值