先不用修改worker数量
pipeline.workers(-w)
,而是先一次修改一个参数,从而确定问题参数
检查列表:
1. 检查输入源和输出点
消费的速度受限于input源服务的速度;生产的速度受限于output端的速度;
2. 检查系统性能
- CPU
关注CPU是否占用很高;top -H
如果CPU占用高,检查JVM堆进行调优 - 内存
Logstash运行在Java VM上,Logstash内存最多使用到分配的JVM内存;(不像kafka和es使用很多堆外内存)
查看是否有其他应用使用大量内存导致Logstash被交换到磁盘,只有当应用使用总内存超过物理内存时发生; - I/O
- 监控磁盘I/O,检查磁盘I/O饱和度
当使用类似于文件输出这样的插件时,可能会导致磁盘I/O饱和;
当Logstash发生大量错误从而产生大量错误日志时,可能导致磁盘饱和;
Linux可以使用iostat
,dstat
或其他类似命令来监控
# cpu相关参数
# 展示1分钟、5分钟和15分钟内的平均负载
dstat -l, --load
# 展示cpu状态,usr用户占比,sys系统占比,idl空闲占比,wai等待次数,这四个加和是100,hiq硬中断次数,siq软中断次数
dstat -c, --cpu
# 进程相关
# 展示当前时刻的进程状态:可运行态(就绪态),无法中断的睡眠态(等待态),新进程,文档原文为:runnable, uninterruptible, new。就绪态进程多代表负载较高,配合-l参数确认,比如run为80,即当前有80个进程等待CPU处理,等待态进程多代表当前IO可能有问题,等待态进程是内存中等待非CPU资源的进程,一般是等待IO,可以根据-c的wai列确认,进一步根据-g的in列确认是否是内存瓶颈后的恢复期, 配合-s参数查看换页使用情况,-d查看当前bio情况,如果-d的bio的read和-g的in差不多,表名当前IO主要是换页到内存加载造成的,即内存不足后的恢复期,如果-g和-s表名换页未使用,但是-d居高,则说明当前有大量进程等待磁盘IO,使用--top-bio-adv确定bio最高的进程,如果-d也不高,但是-n较高,说明进程等待网络IO,使用--top-io-adv确定IO最高的进程。
dstat -p, --proc
#展示进程数量,侧面反映系统负载
dstat --proc-count
# 展示系统中断次数int和上限文切换次数csw,上下文切换:CPU运行任务1,切换运行就绪态任务2,任务1可能变成就绪态(CPU时间片耗光),也可能变成等待态(等待IO等非CPU资源),CPU的处理时间片教短,中断和上下文切换次数数字会很大,也能从侧面反映负载,如果中断和上下文切换暴涨,表明负载过大,或者程序设计不合理,或者kernel级别的BUG。
dstat -y, --sys
# 进程最耗资源统计
# 展示最耗CPU的进程名和CPU占比
dstat --top-cpu
# 展示最耗CPU的进程名、PID和CPU占比以及读写信息,这个读写信息是一个差值,推测是内存的读写。
dstat --top-cpu-adv
# 展示耗费CPU时间最多的进程名和耗费时间(ms)
dstat --top-cputime
# 展示平均最耗CPU时间片的进程名和时间耗费(ms)
dstat --top-cputime-avg
# 展示当前最耗block I/O的进程名和读写的容量
dstat --top-bio
# 展示最耗IO的进程名和IO读写信息,被统计的IO信息包括blockIO和内存还有网络等全部,因此如果要判定最耗磁盘读写的进程,应该使用--top-bio,某一时刻,最耗IO和最耗blockIO的进程不一定是同一个。
dstat --top-io
# 内存相关
# 展示内存状态,包括used, buffers, cache, free
dstat -m, --mem
# 展示内存到换页空间(swap)的使用情况,从内存到换页是out,从换页到内存是in,只有频繁的in和out才表明内存不足。
dstat -g, --page
# 展示换页空间使用状态,换页空间有空间使用不代表内存不足,通过-g参数查看是否有频繁的换入换出来判断内存是否不足。
dstat -s, --swap
# 网络相关参数
# 展示总体网络收发状态,折算后附带单位友好展示
dstat -n, --net
# 展示收发的包数量
dstat --net-packets
# 展示套接字状态,包括tot总数量,tcp套接字数量,udp套接字数量,raw原始套接字数量,frg(ip-fragments IP碎片)套接字数量。
dstat --socket
# 展示tcp网络连接状态,lis监听的数量,act(established)活动的确立的数量,synTCP/IP的握手数量,tim(time_wait)发起关闭后的等待关闭态数量,clo关闭态数量,即命令netstat -tpln对应记录的搂取合并。
dstat --tcp (listen, established, syn, time_wait, close)
# 硬盘相关参数
# 展示磁盘设备读写总计,折算后附带单位友好展示
dstat -d, --disk
# 展示I/O请求状态,包括读请求次数和写请求次数
dstat -r, --io
# 展示异步io状态速度
dstat --aio
# 展示每个磁盘每秒事物读写数量
dstat --disk-tps
# 展示每个磁盘使用百分比
dstat --disk-util
# 文件系统参数
# 展示每个文件系统的使用情况
dstat --freespace
# 展示文件系统状态,包括打开的文件数量和正在使用的inode数量
dstat --fs
# 展示文件锁状态(posix, flock, read, write):pos锁数量,lck锁数量,rea读锁数量,wri写锁数量
dstat --lock
- 监控网络I/O是否饱和
如果输入或输出占用很多网络时会发生;
Linux下可以使用dstat
,iftop
来监控网络I/O;
iftop -i eth1 -n -P
# 其中中间的<= =>这两个左右箭头,表示的是流量的方向。
# TX:发送流量
# RX:接收流量
# TOTAL:总流量
# Cumm:运行iftop到目前时间的总流量
# peak:流量峰值
# rates:分别表示过去 2s 10s 40s 的平均流量
3. 检查JVM堆
- 如果堆太小,会导致CPU使用很高,因为会频繁发生GC;
- 简单的方法是double堆内存,看性能是否提升; JVM内存不要超过物理内存,留至少1G给OS和其他应用
- 也可以使用其他更准确的方法来测量JVM,比如
jmap
,或者VisualVM - 总是设置
Xms
和Xmx
大小一样,防止运行时堆的扩张和收缩影响应用运行
jmap 139961 # pid = 139961
# 查看进程的内存映像信息,类似 Solaris pmap 命令。
jmap -heap pid
# 查看进程的详细内存占用,包括每个区域大小和使用大小
jmap -histo:live 33320
# 查看存活对象大小, 单位是字节
4. 调整worker设置
- 使用
-w
参数来调整pipeline workers的数量,这会改变filters和outputs的可用线程数。可以设置为CPU核数,因为在I/O时,线程是空闲的 - 也可以调整output的batch size。例如ES output时,对应了I/O的操作。
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
5. 修改默认设置
pipeline.workers
设置,决定了有多少线程来执行filter和output操作。如果发生事件堆积或者CPU不饱和,可以考虑来增加这个参数来提高性能。另一种情况是,如果输出会耗费大量时间在I/O上时,增加这个参数也会提升性能;只能设置为正整数pipeline.batch.size
设置,决定了每个独立的worker线程,在收到多少个事件后执行过滤和输出操作。越大的参数通常效率更高,但是会增加内存消耗。太大的话可能会导致性能退化,比如频繁的GC或者JVM的OOM异常pipeline.batch.delay
设置,决定了Logstash pipeline的延迟,这个参数极少需要调优。对接收到事件进行过滤或输出等待的最大毫秒数,
建议:
- 运行中的事件的数量由
pipeline.batch.size
和pipeline.batch.delay
的乘积决定。 - 测试每个修改,保证它们都提升了性能而不是降低了性能
- 确保留有足够的内存来处理事件的突然增加,比如大量的异常文本;
- worker数量可以设置为高于CPU核数的数值,因为输出线程会花费大量时间在I/O上
- Java中的线程有名字,可以使用
jstack
,top
和VisualVM图工具来确定给定线程使用了那些资源 - Linux平台上,Logstash对所有线程增加了自己的描述,类似于
[base]<inputname
,[base]>workerN
等