我通过在EC2服务器上传输1k大小的消息来对Kafka 0.8.1.1进行基准测试。
我在两台m3.xlarge服务器上安装了zookeeper,并进行了以下配置:
dataDir=/var/zookeeper/
clientPort=2181
initLimit=5
syncLimit=2
server.server1=zoo1:2888:3888
server.server2=zoo2:2888:3888
其次,我在i2.2xlarge机器上安装了单卡地卡服务器,配备32Gb RAM和额外的6个SSD驱动器,其中每个磁盘分区为/mnt/a , mnt/b, etc....
。在服务器上,我有一个代理,端口9092上的单个主题和复制因子1的8个分区:
broker.id=1
port=9092
num.network.threads=4
num.io.threads=8
socket.send.buffer.bytes=1048576
socket.receive.buffer.bytes=1048576
socket.request.max.bytes=104857600
log.dirs=/mnt/a/dfs-data/kafka-logs,/mnt/b/dfs-data/kafka-logs,/mnt/c/dfs-data/kafka-logs,/mnt/d/dfs-data/kafka-logs,/mnt/e/dfs-data/kafka-logs,/mnt/f/dfs-data/kafka-logs
num.partitions=8
log.retention.hours=168
log.segment.bytes=536870912
log.cleanup.interval.mins=1
zookeeper.connect=172.31.26.252:2181,172.31.26.253:2181
zookeeper.connection.timeout.ms=1000000
kafka.metrics.polling.interval.secs=5
kafka.metrics.reporters=kafka.metrics.KafkaCSVMetricsReporter
kafka.csv.metrics.dir=/tmp/kafka_metrics
kafka.csv.metrics.reporter.enabled=false
replica.lag.max.messages=10000000
我的所有测试都是从另一个实例完成的,实例之间的延迟小于1毫秒。 当分区键是从0到7的随机数时,我使用一个线程生成器和8个线程使用者编写了生产者/消费者Java客户端。 我通过提供自定义编码器使用Json序列化每条消息。
我的消费者生产者属性如下:
metadata.broker.list = 172.31.47.136:9092
topic = mytopic
group.id = mytestgroup
zookeeper.connect = 172.31.26.252:2181,172.31.26.253:2181
serializer.class = com.vanilla.kafka.JsonEncoder
key.serializer.class = kafka.serializer.StringEncoder
producer.type=async
queue.enqueue.timeout.ms = -1
batch.num.messages=200
compression.codec=0
zookeeper.session.timeout.ms=400
zookeeper.sync.time.ms=200
auto.commit.interval.ms=1000
number.messages = 100000
现在,当我发送100k消息时,我每秒获得10k消息的容量和大约1毫秒的延迟。
这意味着我每秒有10兆字节,相当于80Mb / s,这还不错,但我希望那些位于同一区域的实例能有更好的性能。
我在配置中遗漏了什么?
答案 0 :(得分:3)
我建议你解决这个问题。没有JSon编码有多快。一个节点有多快,没有复制与复制。建立每个组件应该有多快的图片 我还建议你测试裸机,看它们如何比较,因为它们可以明显更快(除非CPU绑定,在这种情况下它们可以大致相同)
根据此基准测试,您应该能够从一个节点http://kafka.apache.org/07/performance.html
获得50 MB / s我希望你能够接近饱和你的1 Gb链接(我假设你拥有的)
免责声明:我在编年史队列上工作的速度要快得多http://java.dzone.com/articles/kafra-benchmark-chronicle
答案 1 :(得分:1)
如果它对您的应用程序有意义,您可以通过流式传输字节数组而不是JSON对象来获得更好的性能,并在管道的最后一步将字节数组转换为JSON对象。
如果每个使用者线程始终从同一主题分区读取,您也可能获得更好的性能。我认为Kafka一次只允许一个消费者从一个分区读取,所以根据你是如何随机选择分区,如果消费者试图从同一个分区读取另一个消费者线程,可能会被短暂阻止。
使用较少的消费者线程或不同的kafka批量大小,您也可以获得更好的性能。我使用参数化的JUnit测试来帮助找到最佳设置,例如每个消费者的线程数和批量大小。以下是我写的一些例子,说明了这个概念:
http://www.bigendiandata.com/2016-10-02-Junit-Examples-for-Kafka/ https://github.com/iandow/kafka_junit_tests
我希望有所帮助。