分享
【日志系统平台】企业微信万亿级日志检索系统
输入“/”快速插入内容
【日志系统平台】企业微信万亿级日志检索系统
📌
在日常工作中,通常需要存储大量日志,如用户请求的出入参,系统运行时打印的info、error之类的日志,从而更好的排查问题。日志存储和检索是个常见且简单的工作,市面上有很多关于日志搜集、存储、检索的框架可供使用,
1.
只有个位数机器时,可通过登录服务器,查看log4j之类的框架打印到本地文件到日志
2.
日志多起来后,可通过elk三剑客处理日志
3.
当日志量进一步增多,可使用消息队列,如kafka之类来承接,然后消费入库。或者写入本地文件,再采用filebeat之类上报再入库
日志框架的功能可总结如下几点:暂存、传输、入库保存、快速检索等
背景
开发在定位问题时需要查找日志,但企业微信模块日志存储在本机磁盘,会产生如下问题
•
日志查找效率低下
:一次用户请求涉及近十个模块,几十台机器,查找日志需要登录机器 grep 日志文件。这一过程通常需要耗费 10 分钟以上,非常低效
•
日志保存时间短
:单机磁盘存储容量有限,为保存最新日志,清理脚本周期清理旧日志文件腾出磁盘空间,比如:现网一核心存储 7 天日志占用了 90%的磁盘空间,7 天前日志都会被清理,用户投诉因日志被清理而得不到解决
•
日志缺失
:虽然现网保留 7 天最新日志,但是由于某些模块请求量大或日志打印不合理,我们也会限制一个小时日志打印量,超过阈值后不再保存,比如:现网一核心存储前 10 分钟打了 10G 日志达到阈值,后 50 分钟日志不再保存了,用户投诉因日志缺失无法得到解决
理想的日志系统
•
存储全量日志
:由于 To B 业务的特殊性,至少需要保存 30 天的全量日志(数 PB 日志量,日志达数万亿条),方便回查日志定位问题;
•
日志快速定位
:根据模块+时间段+关键字或用户请求信息快速定位日志;
•
实时性
:日志峰值达数亿条每秒,需要做到秒级入库、秒级可查;
•
支持日志模糊匹配和统计
:单机日志查询常用到模糊匹配以及 awk/uniq/sort 等复杂统计,在新日志系统同样希望能够支持;
•
支持模块级全量日志查询
:日常运营中有些用户投诉的问题并不确定具体发生时间,需要对模块进行全量日志(日志量达 TB 级别)查询。
业界方案对比
是否对日志做全文索引分为两类:
•
全文索引的日志系统
:对日志内容切分词和建倒排,通过查询关键词的倒排取交集支持模糊匹配,这类系统一般入库资源消耗较多,也不支持日志统计,典型实现有:ELK、Hermes 以及腾讯云日志服务(Cloud Log Service, CLS)等系统
•
部分字段索引的日志系统
:只对部分字段建索引,支持特定字段的快速检索,入库资源消耗较低,但是这类系统对模糊匹配未能很好支持,也不支持日志统计,不支持模块级全量日志查询,如 wxlog、LogTrace 等系统
方案设计的考虑
保存时间短和日志缺失
:单机存储空间的限制导致日志丢失,日志也没法长时间保存
•
使用分布式文件系统替换单机文件系统,可在水平扩展的分布式文件系统支撑下,存储空间无限大,日志不再因存储空间而丢失
日志查找效率低下
:日志散落到多台机器,需要登录到机器做日志 grep。引入了分布式文件系统存储全网日志后,我们看到的仍然是一个一个不相关的日志文件,快速定位日志仍然困难
•
对日志数据建立索引,快速定位到所需日志
•
开发收到模块告警,通过告警信息结合代码找到关键字,使用关键字查找模块告警时间段内的日志
•
根据用户投诉找到用户请求信息,使用用户请求信息查找所有关联模块的日志。从以上场景看出,我们通常根据模块+时间段+关键字或者用户请求信息查找日志
入库资源消耗问题
:为了支持模糊查询,业界方案一般都会对日志内容分词建索引,这会消耗大量资源
•
日志查询系统有两个特点:每天只有数百次查询请求,日志存储模块(分布式文件系统)IO 密集、CPU 利用率低。为了支持用户模糊查询请求,入库时不对日志内容分词建索引。用户查询时,日志存储模块使用关键字对日志内容正则匹配过滤(利用本机空闲 CPU)。这样既解决了入库资源消耗高的问题,又解决了存储机 CPU 低利用率的问题
面临的挑战
•
高性能
:目前企业微信日志量月级数 PB,日志数万亿条,天级数百 TB,面对如此海量日志,如何做到入库和查询的高性能
•
可靠性
:引入了分布式文件系统以及索引带来更大的复杂性,如何保证整个日志系统可靠性
•
支持灵活多变的用户查询需求
:
◦
一次用户请求关联的所有模块日志查询
◦
模块一段时间内日志模糊查询
◦
模块全量日志模糊查询
◦
查询日志统计(如:awk/uniq/sort 指令等)
名称解释
•
callid
:唯一标识一次用户请求,每条日志中都会携带 callid 信息
•
模糊查询
:根据用户输入模块、时间段和关键字查询日志
•
全链路查询
:根据 callid 查询一次用户请求所有关联的模块日志