momo's Blog.

logstash发送速率太低检查

字数统计: 1.4k阅读时长: 5 min
2020/09/11 Share

前言

线上环境的logstash发送速率一直太低,而且性能使用也异常的低。上次测试,每天日志量500G+,延迟有2小时左右。此次正好抽空去测试一下什么原因导致的此问题。

环境说明

服务 配置 数量
logstash 8c8g 1
elasticsearch 8c 16g 1
filebeat 4c4g 1

logstash配置

1
2
3
4
5
6
7
8
9
10
11
12
http.host: "0.0.0.0"
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.hosts: [ "http://10.10.140.221:9200" ]
pipeline.workers: 8
pipeline.batch.size: 1000
config.reload.automatic: true
queue.type: persisted
path.queue: /data/logs/queuedata/
queue.page_capacity: 64mb
queue.max_events: 0
指定队列的最大大小
queue.max_bytes: 20000mb

filebeat 配置

1
2
3
4
5
6
7
output.logstash:
hosts: 10.10.85.177:5044"
worker: 3
bulk_max_size: 4048
compression_level: 7
loadbalance: true
ttl: 600

es保留默认配置,只调整了jvm参数

测试开始

使用基础配置测试

测试结果如下图

可以明显的看到,logstash接收速率和发送速率非常稳定,并且CPU使用率也只有40%。明显没有到达自身的瓶颈状态

那么只能从两个方向下手

  1. 检查logstash input 输入端
  2. 检查logstash output 输出端

检查ES

通过再次执行压测, 发现ES的CPU资源使用率也并是不很高,所以暂时先排除ES瓶颈

检查Filebeat

针对于Filebeat使用的资源进行监控,发现filebeat的资源使用率也并不是很高。

那么问题来了,作为input输入端,应该是不存在输入瓶颈的,那为什么发送速率这么慢呢?

  1. Filebeat 本身发送的就慢
  2. logstash本身接收速率慢,导致filebeat发送也跟着变慢

针对已发现的问题进行测试

目前猜测的两种情况:

  1. Filebeat 本身发送的就慢
  2. logstash本身接收速率慢,导致filebeat发送也跟着变慢

针对第一种情况进行测试

针对第一种情况进行测试,尝试调整filebeat的worker数量,已增加发送速率,我们从3个,调整为30个。

更改以后,我们发现发送速率还是1万? 那说明调整worker数量并没有用,难道真的是logstash接收的速度慢了?

针对第二种情况测试

此时我换了一种方式进行验证,首先我们把input端换成redis,以排除filebeat的影响。

再次进行测试,filebeat 在几十秒内将日志全部发送至Redis。但是我们可以看到下图,logstash还是每秒1万的进行处理.

那也就说明,目前瓶颈卡在logstash

  • 那我们继续验证?把logstash的,worker 数量从 8个改为16个呢?
    • 结论: 不行!还是一万
  • 那把Input 的consumer数量也改成16个呢?
    • 结论: 不行!还是一万

然后…我陷入了沉思..
目前logstash使用的是硬盘持久化队列,会不会是因为硬盘读写原因导致性能无法提升呢?

Ok,那我们换成RSSD硬盘测试一下!

每秒写入600MB,这个可以了吧。

然而。。。。

那会不会是因为这个持久化队列导致的性能下降呢?

然后,我在官方的论坛上找到了一个帖子 Correct way of Logstash persisted queue performance testing

这个基于内存队列和持久化队列做了对比测试, 可以明显的看到,使用持久化队列以后logstash的性能下降了至少一倍。

内存队列和持久化队列如何抉择?

logstash默认使用的队列类型是 基于内存的, 这样的好处就是快,但是随之而来的问题就是如果遇到服务器断电等类似情况,异常宕机时,内存中的数据将会造成丢失。

而持久化好处则刚好可以弥补这个短板。

真的可以为了这点数据的安全去牺牲性能吗?

当然是不的。

基于内存队列的压测测试

环境说明

服务名 配置 数量
elasticsearch 8c16g 1
logstash 8c8g 2
filebeat 4c4g 2

logstash 配置

logstash.yml

1
2
3
4
5
6
7
http.host: "0.0.0.0"
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.hosts: [ "http://10.10.140.221:9200" ]
pipeline.workers: 16
pipeline.batch.size: 1000
config.reload.automatic: true
queue.type: memory

Filebeat 配置

filebeat.yml

1
2
3
4
5
6
7
output.logstash:
hosts: ["10.10.85.177:5044", "10.10.142.80:5044"]
worker: 30
bulk_max_size: 4048
compression_level: 7 # 压缩等级0-9,默认为3
loadbalance: true
ttl: 600 # 每个连接的生命时间

第一次压测

结论

这次测试忘记截图了, 直接说结论。

两台logstash发送ES,ES已经是瓶颈状态了。 速率是每秒2W

第二次压测

前置条件

第一次压测中,发现ES出现了瓶颈,那么我们把ES升级到16C16G再次进行测试

结论

如下图:

升级到了 16c16G,性能稍微提升,最高达到2.8万!但是还没到ES的瓶颈

第三次压测

前置条件

第二次压测中,似乎也发现了logstash的瓶颈,2台logstash发送速率为2.8万
也就是说, 8c8g每台发送速率在1.4万

此次压测,我们升级其中一台logstash看看呢?我们将其中一台logstash也升级到 16c16g

结论

如下图:

通过filebeat发送,logstash一台8c8g,一台16c16g, es 16c16g 最大到3.6W每秒

第四次压测

前置条件

升级一台logstash效果还是很明显的, 如果我们把ES的内存升级到32G呢?内存提升对于ES写入速度影响大吗?

结论

结果跟第三次测试无太大差异

结尾

经过测试,发现单台ES 8核CPU最高写入速度为2万左右,而logstash 单台8c发送速率在1.4万左右

但是测试的时候也发现了问题, 如果单靠filebeat的负载均衡, logstash收到的流量实际上并不均衡。

解决这一个问题, 感觉可以在filebeat后面加一个redis,或者kafka队列。

CATALOG
  1. 1. 前言
  2. 2. 环境说明
  3. 3. 测试开始
    1. 3.1. 使用基础配置测试
      1. 3.1.1. 检查ES
      2. 3.1.2. 检查Filebeat
  4. 4. 针对已发现的问题进行测试
    1. 4.1. 针对第一种情况进行测试
    2. 4.2. 针对第二种情况测试
  5. 5. 内存队列和持久化队列如何抉择?
  6. 6. 基于内存队列的压测测试
    1. 6.1. 环境说明
      1. 6.1.1. logstash 配置
      2. 6.1.2. Filebeat 配置
    2. 6.2. 第一次压测
      1. 6.2.1. 结论
    3. 6.3. 第二次压测
      1. 6.3.1. 前置条件
      2. 6.3.2. 结论
    4. 6.4. 第三次压测
      1. 6.4.1. 前置条件
      2. 6.4.2. 结论
    5. 6.5. 第四次压测
      1. 6.5.1. 前置条件
      2. 6.5.2. 结论
  7. 7. 结尾