因为研发rafka的需要, 进行了线上的压测, 这里记录下诊断的使用.

简介

rafka是在kafka上封装的实时流数据库概念性质产品, 通过内嵌rocksdb实现了数据的get set scan接口.

诊断使用

1.top

通过top看下服务的整体情况: 内存 cpu等情况

rafka-top/png

2.查看是哪个线程

top -Hp 5608 rafka-toph/png 转换16进制

printf "%x\n" 5816
16b8
jstack 5608 | grep 16b8
"kafka-request-handler-0" #65 daemon prio=5 os_prio=0 tid=0x00007fd9db72d000 nid=0x16b8 runnable [0x00007fd80c4f4000]

看线程信息, 可以知道, handler线程一直忙着处理

3.整体分布

这里使用过火焰图查看性能的分布 rafka-falme/png 可以发现, 主要的性能分布在 kafka日制写入 和 rafka的rocksdb写入. 符合预期

4.jni做了什么

因为rafka使用了jni调用rocksdb实现了存储, 那么, jni下面做了什么呢?我们使用perf进行诊断. rafka-perf/png

工具

上面的诊断方式中, 主要使用了三个工具: 火焰图 java-profiler 和 perf

1.火焰图可视化

无论是 perf 还是 java-profiler, 生成的数据都是缺乏可读性的, 可以使用 flamegraph 工具生成图片. 项目地址: https://github.com/brendangregg/FlameGraph, 下载下来后建议将可执行目录放到 PATH路径.

1.java

项目路径: https://github.com/dcapwell/lightweight-java-profiler

正常情况下不需要修改, 直接执行命令 make all 生成镜像包 liblagent.so.

kafka使用的时候, 修改bin/kafka-server-start.sh, 将镜像放到javaagent路径.

    export KAFKA_OPTS=" -javaagent:$base_dir/jmx_prometheus_javaagent-0.11.0.jar=9990:$base_dir/kafka-agent.yaml -agentpath:/home/tiger/tools/perf/lightweight-java-profiler/build-64/liblagent.so"

部署上线kafka之后, 经过压测一段时间后, kill 杀死进程, 会在启动路径下生成 traces.txt.

使用flame进行可视化

stackcollapse-ljp.awk < traces.txt | flamegraph.pl > traces.svg 

浏览器打开生成的trace.svg 就可以了

2. perf

机器上执行如下命令:

perf record -e cpu-clock -g -p 5608
ctrl+c
perf script -i perf.data &> perf.unfold
stackcollapse-perf.pl perf.unfold &> perf.folded

生成火焰图:

flamegraph.pl perf.folded > perf.svg

浏览器打开生成的perf.svg 就可以了

perf的原理分析可以参考: 知乎

总结

rafka最终作为概念性产品,并没有实际产出, 因为kafka本身的硬伤, 比如isr机制. 只能够探索其他的产品了.

其他

  • 机器配置信息参考 文章

  • 纯kafka的压测结果: [三次压测]

    50000000 records sent, 1175585.441550 records/sec (143.50 MB/sec), 4.12 ms avg latency, 182.00 ms max latency, 1 ms 50th, 8 ms 95th, 121 ms 99th, 178 ms 99.9th.
    50000000 records sent, 1202732.608486 records/sec (146.82 MB/sec), 3.59 ms avg latency, 292.00 ms max latency, 1 ms 50th, 8 ms 95th, 87 ms 99th, 255 ms 99.9th.
    50000000 records sent, 1141995.751776 records/sec (139.40 MB/sec), 0.96 ms avg latency, 136.00 ms max latency, 1 ms 50th, 1 ms 95th, 16 ms 99th, 35 ms 99.9th.
    
  • 添加rocksdb后的压测结果: [三次压测]

    50000000 records sent, 857206.535343 records/sec (104.64 MB/sec), 158.13 ms avg latency, 741.00 ms max latency, 37 ms 50th, 668 ms 95th, 720 ms 99th, 733 ms 99.9th.
    50000000 records sent, 941601.853072 records/sec (114.94 MB/sec), 8.63 ms avg latency, 346.00 ms max latency, 1 ms 50th, 57 ms 95th, 144 ms 99th, 270 ms 99.9th.
    50000000 records sent, 949252.937938 records/sec (115.88 MB/sec), 21.12 ms avg latency, 151.00 ms max latency, 1 ms 50th, 108 ms 95th, 126 ms 99th, 148 ms 99.9th.
    

对比压测数据, 以第二次压测结果计算, 9416011202732=78%, 损失了22%的性能. 所以,rocksdb的造成的性能还是可以接受的.

  • 压测脚本: 使用kafka本身bin目录下的脚本 bin/kafka-run-class.sh org.apache.kafka.tools.ProducerPerformance --topic test8 --num-records 50000000 --record-size 128 --throughput -1 --producer-props acks=1 bootstrap.servers=xxxx buffer.memory=67108864