基线

logstash 分三大块, input, filter, output. 这三快往往存在一些问题,如:

  • logstash input (IO密集,受限网卡和数据源性能等)
  • logstash filter (CPU密集,瓶颈容易出在这)
  • logstash output (IO密集,受限网卡,写入速度,数据源性能等)

在此之前先要了解现有配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ curl 'localhost:9607/_node/pipeline?pretty'
{
"host" : "hadoop-slave-3",
"version" : "5.2.0",
"http_address" : "127.0.0.1:9607",
"id" : "c6c416c7-d82c-4b71-8153-e2f9fbc0eda2",
"name" : "hadoop-master",
"pipeline" : {
"workers" : 8,
"batch_size" : 125,
"batch_delay" : 5,
"config_reload_automatic" : false,
"config_reload_interval" : 3
}

对于单一应用性能常受限于:

  • 系统资源:cpu核数,cpu单核速度,内存,网卡,磁盘
  • 应用分配到的硬件资源:分配的cpu核数,分配的系统内存等

下面的测试仅从filter处理速度来分析

生成测试数据(Generator)

实例:

1
2
3
4
5
6
7
input {
generator {
count => 10000000
message => '{"key1":"value1","key2":[1,2],"key3":{"subkey1":"subvalue1"}}'
codec => json
}
}

使用PV进行测试

PV 全命为Pipe Viewer,利用它我们可以查看到命令执行的进度。使用 pv 命令配合LogStash::Codecs::Dots

1
2
3
4
5
output {
stdout {
codec => dots
}
}

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
input {
#stdin {}
generator {
count => 100000
message => '2017-12-25/20:54:34.481|-|-|-|^_^|[Thread-5743] INFO VIEW_LOGGER 262 - view:{"id":"9af4e4df4e2eb","from":"2","uId":1,"uType":"admin","timestamp":1514206474481}'
}
}

filter {
# 方案1
grok {
match => ["message", "%{LOGLEVEL} %{DATA} - view:%{GREEDYDATA:body}"]
add_tag => ["view"]
}
json {
source => "body"
}

# 方案2
#ruby {
# code => "
# if event.get('message').to_s.include?'view'
# event.set('datas', event.get('message').split('view:')[1])
# else
# event.cancel
# end
# "
#}
json {
source => "datas"
}
date {
match => ["timestamp", "UNIX_MS"]
}
mutate {
remove_field => ["message", "datas", "timestamp"]
}
}

output {
#stdout { codec => rubydebug }
stdout {codec => dots}
}

测试命令:

1
2
$ logstash -f switch-line.conf | pv -abt > /dev/null
99.2KiB 0:00:35 [ 2.8KiB/s]

这里单位是 B/s,但是因为一个 event 就输出一个 . ,也就是 1B。所以 2.8kiB/s 就相当于是 2.8k event/s。

注释掉上面的方案1,打开方案2,测试发现:

1
2
$ logstash -f switch-line.conf | pv -abt > /dev/null
99.2KiB 0:00:27 [3.56KiB/s]

显然方案2的处理速度更好些,虽然方案1显得比较直观,但是正则是有点耗时的。

在方案1,如果我们增大 batch-size, 可能会好点

1
2
$ logstash -b 5000 -f 5.2.0/switch-line.conf | pv -abt > /dev/null                                                                                                                                
99.8KiB 0:00:30 [3.32KiB/s]

结论

增大filter worker

filter阶段是多线程的,要增大线程数 -w 12

性能测试, 查看吞吐量:

1
$ ./bin/logstash -f ping_history.conf -w 12 | pv -bt > /dev/null

增加filter worker数很占用内存和CPU,这里就拿空间换时间吧,所以这里JVM 堆内存要调大点(4倍即可)
目前机器上 logstash 默认 8, 即运行 filter 和 output 的 pipeline 线程数量。默认是 CPU 核数, 这里我们可以设置 CPU核数 * 1.5

增大batch-size

-b 1000

增大 woker 的 batch_size, 目前pipeline-batch-size默认125, 可增大点来提升吞吐量。在每个 Logstash pipeline 线程,执行具体的 filter 和 output 函数之前,最多能累积的日志条数。默认是 125 条。越大性能越好,同样也会消耗越多的 JVM 内存。

增大JVM堆内存

目前的默认配置如下:

1
2
3
4
5
6
7
8
9
$ cat jvm.options

## JVM configuration

# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space

-Xms256m
-Xmx1g

可以适当增大4倍。