Skip to content

Commit 271cc8d

Browse files
luky116liuyuecai
authored andcommitted
test: add pika benchmark tools (OpenAtomFoundation#2663)
* add pika benchmark --------- Co-authored-by: liuyuecai <liuyuecai@360.cn>
1 parent b3118c1 commit 271cc8d

12 files changed

Lines changed: 654 additions & 0 deletions

File tree

tools/pika_benchmark/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
This tool provides stress testing commands for commonly used indicators, and supports one-click generation of visual statistical charts in SVG format from stress testing results to improve stress testing efficiency. The usage steps are as follows:
2+
3+
1、First of all, the stress testing tool uses Redis’ official memtier_benchmark, so you must choose to install this tool. For the installation process, please refer to the official documentation: [https://github.com/RedisLabs/memtier_benchmark](https://github.com /RedisLabs/memtier_benchmark).
4+
5+
2、Next, start a Pika process, and then execute the stress test script to perform the stress test:
6+
7+
```shell
8+
sh pika_benchmark.sh -host 127.0.0.1 -port 9221
9+
```
10+
Currently the following test parameters are supported:
11+
```shell
12+
-host <host> Server hostname, default: 127.0.0.1
13+
-port <port> Server port, default: 9221
14+
-requests <requests> Number of requests, default: 10000
15+
-clients <clients> Number of concurrent clients, default: 50
16+
-threads <threads> Number of threads, default: 4
17+
-dataSize <dataSize> Data size, default: 32
18+
```
19+
20+
3、After the stress test is completed, parse and format the stress test data. First execute go build to compile and convert the program:
21+
```shell
22+
go build parser.go
23+
```
24+
25+
Next, execute the program to format the stress test data. If the output folder does not exist, it needs to be created manually in advance:
26+
```shell
27+
mkdir -p parsed_data
28+
29+
./parser -in_dir=$(pwd)/bench_data -out_dir=$(pwd)/parsed_data
30+
```
31+
32+
4、Use a python script to generate a statistical chart image from the data:
33+
```shell
34+
sh gen_chart.sh
35+
```
36+
37+
After the execution is completed, four svg files will be produced in the ./charts directory. You can directly open them with a browser to see the effect.
38+
39+
5、Currently, the following four pressure measurement charts can be automatically generated:
40+
41+
5.1 Percentile delay statistics chart of commonly used commands:
42+
43+
![img.png](img/cmd_latency.png)
44+
45+
5.2 OPS statistics chart of commonly used commands:
46+
47+
![img.png](img/cmd_ops.png)
48+
49+
5.3 Percentile delay statistics chart under different reading and writing scenarios:
50+
51+
![img.png](img/rw_latency.png)
52+
53+
5.4 OPS statistics chart under different reading and writing scenarios:
54+
55+
![img_1.png](img/rw_ops.png)

tools/pika_benchmark/README_ZH.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
本工具提供了常用指标的压测命令,并支持将压测结果一键生成可视化的 svg 格式的统计图,提升压测效率。使用步骤如下:
2+
3+
1、首先,压测工具使用了 Redis 官方的 memtier_benchmark,所以要选把这个工具安装好,安装流程参考官方文档:[https://github.com/RedisLabs/memtier_benchmark](https://github.com/RedisLabs/memtier_benchmark)
4+
5+
2、接下来启动一个 Pika 进程,然后执行压测脚本进行压测:
6+
```shell
7+
sh pika_benchmark.sh -host 127.0.0.1 -port 9221
8+
```
9+
目前可支持以下测试参数:
10+
```shell
11+
-host <host> Server hostname, default: 127.0.0.1
12+
-port <port> Server port, default: 9221
13+
-requests <requests> Number of requests, default: 10000
14+
-clients <clients> Number of concurrent clients, default: 50
15+
-threads <threads> Number of threads, default: 4
16+
-dataSize <dataSize> Data size, default: 32
17+
```
18+
19+
3、压测完成后,对压测数据进行解析和格式化。首先执行 go build 编译转换程序:
20+
```shell
21+
go build parser.go
22+
```
23+
接下来执行程序对压测数据进行格式化,如果输出文件夹不存在需要提前手动创建:
24+
```shell
25+
mkdir -p parsed_data
26+
27+
./parser -in_dir=$(pwd)/bench_data -out_dir=$(pwd)/parsed_data
28+
```
29+
30+
4、使用 python 脚本将数据生成统计图图片:
31+
```shell
32+
sh gen_chart.sh
33+
```
34+
执行完成后,会在 ./charts 目录生产四个 svg 文件,直接使用浏览器打开即可看到效果。
35+
36+
5、目前可以自动生成以下四种压测图表:
37+
38+
5.1 常用命令的百分位延时统计图:
39+
40+
![img.png](img/cmd_latency.png)
41+
42+
5.2 常用命令的 OPS 统计图:
43+
44+
![img.png](img/cmd_ops.png)
45+
46+
5.3 不同读写场景下的百分位延时统计图:
47+
48+
![img.png](img/rw_latency.png)
49+
50+
5.4 不同读写场景下的 OPS 统计图:
51+
52+
![img_1.png](img/rw_ops.png)

tools/pika_benchmark/gen_chart.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
import json
5+
import pygal
6+
from os import path
7+
from os import walk
8+
from pygal.style import Style
9+
10+
chartStyle = Style(
11+
background='transparent',
12+
plot_background='transparent',
13+
font_family='googlefont:Montserrat',
14+
# colors=('#D8365D', '#78365D')
15+
colors=('#66CC69', '#173361', '#D8365D'),
16+
# colors=('#66CC69', '#667C69', '#173361', '#D8365D', '#78365D'),
17+
)
18+
19+
# theme = pygal.style.CleanStyle
20+
theme = chartStyle
21+
fill = False
22+
23+
24+
def create_quantile_chart(workload, title, y_label, time_series):
25+
import math
26+
chart = pygal.XY(style=theme, dots_size=0.5,
27+
legend_at_bottom=True,
28+
truncate_legend=37,
29+
x_value_formatter=lambda x: '{:,.2f} %'.format(
30+
100.0 - (100.0 / (10 ** x))),
31+
show_dots=False, fill=fill,
32+
stroke_style={'width': 2},
33+
print_values=True, print_values_position='top',
34+
show_y_guides=True, show_x_guides=False)
35+
chart.title = title
36+
# chart.stroke = False
37+
38+
chart.human_readable = True
39+
chart.y_title = y_label
40+
chart.x_labels = [0.30103, 1, 2, 3]
41+
42+
for label, values, opts in time_series:
43+
values = sorted((float(x), y) for x, y in values.items())
44+
xy_values = [(math.log10(100 / (100 - x)), y)
45+
for x, y in values if x <= 99.9]
46+
chart.add(label, xy_values, stroke_style=opts)
47+
48+
chart.render_to_file('%s/%s.svg' % (args.outPath, workload))
49+
50+
51+
def create_bar_chart(workload, title, y_label, x_label, data):
52+
chart = pygal.Bar(
53+
style=theme, dots_size=1, show_dots=False, stroke_style={'width': 2}, fill=fill,
54+
show_legend=False, show_x_guides=False, show_y_guides=False, print_values_position='top',
55+
print_values=True, show_y_labels=True, show_x_labels=True,
56+
)
57+
chart.title = title
58+
chart.x_labels = x_label
59+
chart.y_title = y_label
60+
chart.value_formatter = lambda y: "{:,.0f}".format(y)
61+
62+
for label, points in data.items():
63+
chart.add(label, points)
64+
print("workload", workload)
65+
chart.render_to_file('%s/%s.svg' % (args.outPath, workload))
66+
67+
68+
# chart.render_to_file('%s.svg' % workload)
69+
70+
if __name__ == "__main__":
71+
parser = argparse.ArgumentParser(
72+
description='Plot Kafka OpenMessaging Benchmark results')
73+
parser.add_argument('--filePath', dest='filePath', required=True, type=str,
74+
help='Explicitly specify result files to plot')
75+
parser.add_argument('--prefix', dest='prefix', help='prefix of filename')
76+
parser.add_argument('--outPath', dest='outPath', help='out path to save the plot')
77+
args = parser.parse_args()
78+
79+
aggregate = []
80+
81+
for (dirpath, dirnames, filenames) in walk(args.filePath):
82+
for file in filenames:
83+
file_path = path.join(dirpath, file)
84+
data = json.load(open(file_path))
85+
data['file'] = file
86+
aggregate.append(data)
87+
88+
opsPerSes = []
89+
latencyMap = []
90+
91+
drivers = []
92+
93+
pub_rate_avg = {}
94+
pub_rate_avg["Throughput (MB/s)"] = []
95+
96+
colors = ['#2a6e3f', '#ee7959', '#ffee6f', '#e94829', '#667C69', '#173361', '#D8365D', '#33A1C9', '#e47690',
97+
'#FF5733', '#fac03d', "#f091a0"]
98+
99+
# Aggregate across all runs
100+
count = 0
101+
for data in aggregate:
102+
103+
if ('opsPerSes' in data and data['opsPerSes'] is not None):
104+
opsPerSes.append(data['opsPerSes'])
105+
106+
if ('latencyMap' in data and data['latencyMap'] is not None):
107+
latencyMap.append(data['latencyMap'])
108+
109+
drivers.append(data['file'])
110+
111+
if ('opsPerSes' in data and data['opsPerSes'] is not None):
112+
pub_rate_avg["Throughput (MB/s)"].append(
113+
{
114+
'value': data['opsPerSes'],
115+
'color': colors[count]
116+
})
117+
count = count + 1
118+
119+
# Parse plot options
120+
opts = []
121+
for driver in drivers:
122+
opts.append({})
123+
124+
# Generate publish rate bar-chart
125+
svg = f'pika-{args.prefix}-ops'
126+
print(pub_rate_avg)
127+
if ("Throughput (MB/s)" in pub_rate_avg and len(pub_rate_avg["Throughput (MB/s)"]) > 0):
128+
create_bar_chart(svg, 'Cmd Ops', 'Ops/second',
129+
drivers, pub_rate_avg)
130+
131+
if (len(latencyMap) > 0):
132+
time_series = zip(drivers, latencyMap, opts)
133+
svg = f'pika-{args.prefix}-latency-quantile'
134+
create_quantile_chart(svg, 'Latency Quantiles',
135+
y_label='Latency (ms)',
136+
time_series=time_series)

tools/pika_benchmark/gen_chart.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
3+
mkdir -p $(pwd)/charts
4+
5+
python3 gen_chart.py --filePath $(pwd)/parsed_data/cmd_ops --prefix=cmd --outPath=$(pwd)/charts
6+
python3 gen_chart.py --filePath $(pwd)/parsed_data/cmd_latency --prefix=cmd --outPath=$(pwd)/charts
7+
python3 gen_chart.py --filePath $(pwd)/parsed_data/rw_ops --prefix=rw --outPath=$(pwd)/charts
8+
python3 gen_chart.py --filePath $(pwd)/parsed_data/rw_latency --prefix=rw --outPath=$(pwd)/charts

tools/pika_benchmark/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module pika-benchmark
2+
3+
go 1.19

tools/pika_benchmark/go.sum

Whitespace-only changes.
127 KB
Loading
70.6 KB
Loading
118 KB
Loading
34 KB
Loading

0 commit comments

Comments
 (0)