作者 | 陈夏华
一、背景
在2023年初,日志系统的日均增长量为9TB,如今已达到20TB,增幅超过了100%。尽管日志系统在多轮存储端优化后,基本维持了一年前的资源配比,但资源已被压榨至极限。为此,必须从治理层面着手,推动业务方合理输出日志。要推进整改,配套的治理工具至关重要,其中日志聚类是最关键的一环。
日志聚类在治理过程中起到双重作用:一方面,它提供了相关的指标支持,帮助业务方推进日志标准化,确保日志输出的合理性和价值。另一方面,通过智能聚类能够帮助业务方更快发现问题,减少人工分析的工作量,并提高问题解决的速度。基于此,未来还可以实现智能告警和归因分析,这也将成为AIOPS智能运维的关键一环。
二、日志系统简介
日志系统在计算机系统中具有重要意义。它记录了系统的运行情况,可用于排查故障和问题分析,帮助开发人员快速定位并解决问题。此外,日志还记录了系统的各种操作和事件,支持系统安全状态监控、潜在安全威胁检测,以及安全审计和合规性检查。同时,日志记录了系统的性能指标和运行状态,便于性能分析与优化,帮助系统管理员和开发人员发现性能瓶颈并进行系统调优。
日志还可记录用户行为和系统交互,助力企业开展业务分析、用户行为分析和运营监控,并支持数据驱动的决策。总而言之,日志系统通过记录和跟踪系统运行情况和用户操作,为故障排查、安全监控、性能优化及业务分析等提供了关键支持。
目前在实际应用落地的情况下,一种高效、可扩展的解决方案是基于Filebeat、Kafka、Flink、Elasticsearch和Grafana的日志系统,用于实时采集、传输、解析、存储和可视化日志数据。
日志采集:Filebeat 是 Elastic Stack 的一部分,是一个轻量级的日志收集器。它被设计用来安装在服务器上,监控指定的日志文件,并将其发送到Logstash或直接发送到Elasticsearch。Filebeat 支持多种输入源,如文件、syslog、HTTP等。
日志传输:Kafka 是一个分布式流处理平台,常用于构建实时数据管道和流应用程序。它能够高效地处理高吞吐量的数据流。在日志系统中,Kafka 用作消息队列,接收来自 Filebeat 的日志数据,并将数据传输到 Flink 进行进一步处理。
日志解析:Flink 是一个开源的流处理框架,用于处理无界和有界的数据流。它支持事件驱动的应用程序,能够实现复杂的事件处理逻辑。在日志系统中,Flink 可以对 Kafka 中的日志数据进行实时处理,如过滤、聚合、转换等。
日志存储:Elasticsearch 是一个基于 Lucene 的搜索和分析引擎,它提供了一个分布式、多租户能力的全文搜索引擎。它通常用于存储、搜索和分析大规模数据集。在日志系统中,Elasticsearch 用于存储经过 Flink 处理后的日志数据,提供快速的搜索和分析能力。
日志监控:Grafana 是一个开源的数据可视化和监控平台,支持多种数据源,如Elasticsearch、MySQL 等。在日志系统中,Grafana 用于创建仪表板,展示日志数据的可视化视图,帮助用户监控和分析日志信息。
整个日志系统的工作流程大致如下:Filebeat 部署在各个服务器上,监控日志文件,并将日志数据发送到 Kafka。Kafka 作为高吞吐量数据缓冲,存储和转发日志数据到 Flink。Flink 对日志数据进行实时处理,如过滤、聚合等,并可以将处理后的数据存储到 Elasticsearch 或 MySQL。Elasticsearch 存储处理后的日志数据,提供快速搜索和分析能力。Grafana 连接到Elasticsearch 或 MySQL,展示日志数据的可视化视图。
三、日志聚类算法
日志数据天然具有相似的特征,下图展示了单个应用产生日志的数据特征分布,显示出明显的类别区分。因此,算法的选择上更倾向于高效且实现简单的方法,如K-Means和层次聚类等。下方的折线图展示了K-Means聚类算法随着聚簇中心数量K的变化效果。然而,在实时环境中,该算法无法自动迭代更新聚簇数量。因此,在日志系统的大数据量要求下,日志聚类算法需要具备以下关键要素:
实时性:低延迟,算法不能复杂
可拓展性:支持增量
自动化:无需人工干预
模式识别:日志模式抽取并自动更新
| 3.1 算法对比
几种常用的无监督聚类算法的对比:
聚类算法 | 原理图示 | 优点 | 缺点 |
K-Means |
|
| |
层次聚类 |
|
| |
密度聚类 |
|
|
在日志系统大规模数据的场景下,K-Means算法虽然简单高效,但因为需要固定聚类个数,无法在实时的环境下做到增量拓展;层次聚类算法的计算复杂度太高,会造成整个日志系统的高延迟;而密度聚类的质量往往达不到业务的需要。所以,我们设计了一种持续聚类的算法,保证高效、低延迟和增量拓展。
持续聚类算法采用SimHash对分词后的日志进行特征抽取,再使用汉明距离计算相似度持续的形成聚簇,最后使用最长连续公共子串的算法进行模式抽取。下面详细介绍持续聚类算法的三个重要方面。
特征抽取的目标是将非结构化的日志数据转换为结构化的特征向量,以便后续的聚类分析和模式识别。常用的方法是词袋模型、SimHash、TF-IDF等。持续聚类算法采用SimHash将高维的特征向量映射为低维的哈希值(也称为指纹)。SimHash特征抽取的流程如图所示,分为分词、Hash、词频加权、合并累加和降维这几个流程。
考虑到过于复杂的向量化方法可能严重影响整个聚类系统的性能,SimHash采用了一种简单有效的方法,将一条日志数据压缩为一个【1×维度大小】的二进制特征向量,而不是【序列长度×维度大小】的向量。这样不仅大大提高了特征提取的效率,还降低了下游流程的计算复杂度。实践证明,对于日志这种具有明确特征且语义相对清晰的数据,SimHash是一种高效的解决方案。
3.2.2 相似度匹配
相似度匹配是指将提取的特征与已有的聚类中心进行比较的过程,以确定它们是否相似或属于同一聚簇。常用的方法是计算余弦相似度,计算距离等。持续聚类算法采用汉明距离(Hamming Distance)来计算两个日志特征的相似度,计算方法如下代码所示。汉明距离定义为两个字符串对应位置上不同字符的个数,用于衡量两个等长字符串之间的差异,如下图所示。
private static double hammingSimilarity(double[] v1, double[] v2) {
int hammingDistance = hammingDistance(v1, v2);
int maxLength = Math.max(v1.length, v2.length);
return 1.0 - ((double) hammingDistance / maxLength);
}
当日志特征向量是由01二进制组成的,汉明距离可以由位运算直接计算,速度非常快。即使当整个应用的聚簇中心很多时,匹配过程也可以高效的进行。另外,持续聚类算法中,相似度阈值是一个超参数,在上图例子中设置为80%,意指当新日志和某一个聚簇中心的相似度大于80%时,新日志才处于匹配就绪的状态,最后分配给相似度最大的聚簇,而新日志和所有聚簇中心都达不到相似度阈值时,说明该日志需要自成一类。这个阈值可以根据业务需求进行调整,值越大,聚簇个数越多,分类越精细。
3.2.3 更新聚簇中心与模式抽取
更新聚簇中心旨在矫正聚簇的特征表示。当聚簇中不断加入新日志的时候,聚簇中心的特征表示需要更新,以适应后续的迭代。均值表示法是一种简单有效的更新方式,计算聚簇中所有日志的均值,作为新的聚簇中心,再参与后面的匹配过程。
模式抽取的目标是将聚簇中的日志数据归纳为更精炼的、更抽象的模式,这些模式可以代表一组相似的日志条目。日志模式对于开发人员快速了解应用运行时的全貌具有关键作用,并能有效支持下游的日志治理和告警工作。持续聚类采用最长公共子串来抽取日志模式,具体的过程如上图所示,抽取的模式以供Elasticsearch进行聚合查询展示。
| 3.3 算法流程
持续聚类算法的详细流程图如下:
四、日志实时聚类实践
| 4.1 Flink实时聚类
日志系统的实时聚类是在解析层实现的,具体的Flink流过程如下:
Flink持续聚类在窗口中完成单次迭代的算法原理如下图:
核心逻辑:
1. 窗口的聚合函数,当新日志到来时,与当前的聚簇中心匹配,实现实时日志分发。
2. 当窗口满时,触发窗口处理函数,更新聚簇中心。
3. 模式抽取,更新聚簇中心对应的模式,并将新模式发送到流,存入MySQL。
根据日志模式聚合查询ES,并可视化展示日志模式的同环比变化,聚类查询成果展示:
根据日志模式进行日志质量管理,日志健康分排行展示:
持续聚类的算法保证了增量拓展和较低延迟,但是在日志规模庞大的场景下,这样的算法还是会对硬件资源有较高的要求。围绕聚类准确性和效率两个方面,算法的优化有以下几个思路:
特征优化:目前的simhash词权重是基于分词器分词单条日志得到的,该权重与单词在文本中出现的次数成正比,优化可以考虑采用全文词频来计算单词权重,以应用为维度记录所有日志的词频,类似于TF-IDF的词频计算,通过这种方式深入优化词表示。另外特征维度的大小也会很大程度上影响聚类的结果,特征维度越大,意味着可以更准确的表示一条日志,但也增加了计算的开销。
参数调整:根据不同的日志数据特性,调整算法参数,比如相似度阈值、窗口大小等,以获得更好的聚类效果。
模式抽取:对于抽取效果,可以建立用户反馈机制,根据用户的反馈调整和优化模式抽取的结果;对于抽取效率,设计复杂度更低的模式抽取方法,例如计算聚簇中所有日志的分词统计直方图,再整体归纳日志模式,比现有的最长公共子串算法(O(k×m×n),k为聚簇大小,m为日志A的长度,n为日志B的长度)更高效。
算法的优化无非是效率换精度,或者精度换效率,怎么取得平衡还需要在实际场景中进行验证。
4.3.2 聚类流程优化---嵌入大模型
大模型为开发者带来了很多提高效率的方式,但受限于大模型的性能与吞吐,大模型往往不适合应用在实时的线上环境。但可以试想这样一种可能,简单的流程框架如下图:
【离线分析数据+优化在线流程】:依然使用持续聚类的方式将日志聚合成簇,但通过 ChatGPT离线生成每类日志的模式,并提供正则表达式,然后将正则作为这个聚簇的聚类中心参与后续匹配。这样的好处是只要经过一段冷启动时间,绝大多数日志都会被正则匹配并抽取而不再依赖大模型。大模型通过代码生成能力"离线"作用于实时数据处理流程,以兼顾智能化与处理效率。
4.3.3 解析层优化---Flink
当日志数据量很大时,Flink的每个节点都会有很高的负载,并且处理大量的数据会造成更高的延迟。为保证日志系统的实时性和稳定性,可以考虑以下几个方面进行优化:
优化Flink作业的并行度,确保资源充分利用。
调整窗口大小,窗口大小直接影响到状态的大小,进而影响内存的使用量。较大的窗口意味着需要更多的内存来存储状态。
检查并优化算子实现,减少不必要的计算和数据转换。
使用合适的序列化和反序列化机制,减少序列化开销。在消费端开启专门的线程做反序列化,减少聚类主线程的压力。
日志聚类的具体应用主要从以下两方面进行建设:
【对于已发生的异常,及时告警】异常感知与告警:
应用场景:当系统或应用出现异常时,需要及时发出告警并通知相关人员。通过日志聚类技术,可以建立基于日志模式和时序数据的异常检测系统,当出现异常模式或规律时自动触发告警通知。
优势:基于日志聚类的异常感知系统可以帮助在异常发生后立即采取行动,减少故障排查和修复的时间。通过及时的告警通知,可以降低故障对系统正常运行的影响,提高系统的可靠性和稳定性。
【对于未发生的异常,提前预测】预测性维护:
应用场景:通过对历史日志数据的聚类和分析,可以发现系统运行的周期性模式和趋势。基于这些模式和趋势,可以建立预测性维护系统,提前预测潜在的系统故障,并采取相应的维护措施。
优势:预测性维护可以帮助避免系统因突发故障而导致的停机时间和生产损失。通过提前发现潜在故障,可以合理安排维护计划,提高设备和系统的可靠性,降低维护成本和风险。
在当前环境下,随着日志数据量的持续增长和日志来源的多样化,我们面临着数据量庞大、格式不统一以及包含大量噪音的挑战。为有效应对这些问题,我们采用了日志聚类技术,以提升数据处理的质量和效率。通过持续聚类算法,我们能够实时聚合海量日志中的相似数据,降低了数据的复杂性。这不仅简化了日志的管理和维护工作,还通过聚类分析形成的模式和趋势,为日志监控和告警系统提供了强有力的支持,帮助我们快速识别和响应潜在问题,从而提高整个系统的稳定性和可靠性。
---------- END ----------
推荐阅读
| 众安开源AIGC工具代码助手DevPilot,让AI赋能每个开发者
| 测量用户行为反馈的方法 —— INP (Interaction to Next Paint)
| 科技驱动金融,极客挑战极限!——众安1024程序员节:48-Hour Hackathon精彩回顾