先把结论列在前面:
1.Golang的性能可以做到非常好,但是一些native包的性能很可能会拖后腿,比如regexp和encoding/json。如果在性能要求较高的场合使用,要根据实际情况做相应优化。
2.on-cpu/off-cpu火焰图的使用是程序性能分析的利器,往往一针见血。虽然生成一张火焰图比较繁琐(尤其是off-cpu图),但绝对值得拥有!
之前一直使用Logstash作为日志文件采集客户端程序。Logstash功能强大,有丰富的数据处理插件及很好的扩展能力,但由于使用JRuby实现,性能堪忧。而Filebeat是后来出现的一个用go语言实现的,更轻量级的日志文件采集客户端。性能不错、资源占用少,但几乎没有任何解析处理能力。通常的使用场景是使用Filebeat采集到Logstash解析处理,然后再上传到Kafka或Elasticsearch。值得注意的是,Logstash和Filebeat都是Elastic公司的优秀开源产品。
为了提高客户端的日志采集性能,又减少数据传输环节和部署复杂度,并更充分的将go语言的性能优势利用于日志解析,于是决定在Filebeat上通过开发插件的方式,实现针对公司日志格式规范的解析,直接作为Logstash的替代品。
背景介绍完毕,下面是实现和优化的过程。
Version 1
先做一个最简单的实现,即用go自带的正则表达式包regexp做日志解析。性能已经比Logstash(也是通过开发插件做规范日志解析)高出30%。
这里的性能测试着眼于日志采集的瓶颈——解析处理环节,指标是在限制只使用一个cpu core的条件下(在服务器上要尽量减少对业务应用的资源占用),采集并解析1百万条指定格式和长度的日志所花费的时间。测试环境是1台主频为3.2GHz的PC。为了避免disk IO及page cache的影响,将输入文件和输出文件都放在/dev/shm中。对于Filebeat的CPU限制,是通过启动时指定环境变量GOMAXPROCS=1实现。
这一版本处理1百万条日志花费的时间为122秒,即每秒8200条日志。
Version 2