JuiceFS 是一款基于 Apache 2.0 开源协议,面向云原生设计的高性能分布式文件系统。提供完备的 POSIX 兼容性,可将几乎所有对象存储接入本地作为海量本地磁盘使用,也可同时在跨平台、跨地区的不同主机上挂载读写。
每个 JuiceFS 客户端都有访问日志,其中详细记录了文件系统上的所有操作,如操作类型、用户 ID、用户组 ID、文件 inode 及其花费的时间。
JuiceFS 的访问日志用途广泛,如性能分析、审计、故障诊断。但日志分布在多个客户端和服务器,收集和分析都比较困难,难以建立完整的监控和告警机制。
火山引擎日志服务(TLS)是一站式日志管理平台,提供日志采集、存储、查询、分析、可视化和告警等功能。日志服务 TLS 可对 JuiceFS 的访问日志分析提供以下帮助:
本文介绍如何从日志服务 TLS 采集 JuiceFS 的访问日志,并实现各种分析大盘和实时监控告警。
日志分析流程为日志采集、日志分析大盘和实时监控告警。流程如下:
JuiceFS 访问日志保存在 JuiceFS 客户端内,输出的日志字段在同一行,无法直接进行统计,需要进行提取解析。
日志服务 TLS 自研的日志采集器 Logcollector 提供多种采集模式和丰富的日志处理插件,特点是兼容性好、性能高,可适配多家云厂商和 idc 环境,单 core 性能最高可达 100MB/s。同等性能要求下,对资源的消耗更少,可节省更多资源成本。
通过在日志服务控制台中依次创建机器组、日志项目、日志主题及采集规则等资源,即可上报服务器的日志数据到日志服务。
由于 JuiceFS 客户端的访问日志详细记录了文件系统的所有操作,且每个文件系统操作对应的访问日志结构有所差异,所以需要使用fullregex 插件进行链式结构化处理。 - 针对 JuiceFS 客户端访问日志的原始内容字段__content__,使用正则表达式提取基础字段。
- 针对不同操作类型op,选择对应的正则表达式,对操作结果result进行详细解析,提取具体的操作参数和状态。
对于采集到的日志,配置索引后才能进行日志检索和分析操作。
在日志服务控制台的常用功能 > 检索分析中,选择日志项目 > 日志主题,单击索引配置,即可配置具体的索引类型及其详细字段。详情可参考配置索引。
为 JuiceFS 访问日志配置的键值索引字段解释如下:
在 JuiceFS 的使用场景中,有许多关键指标需要重点关注,例如读、写、删除等操作的次数与数据量统计、IO 大小与执行耗时的分布,以及顺序读占比、覆盖写情况等。
日志服务 TLS 支持自定义仪表盘,同时针对核心的分析场景,TLS 已将其提炼为仪表盘模板,可基于模板一键快速创建出分析大盘。详情可参考创建空白仪表盘。 通过介绍写 IO 大小分布、顺序读占比分布、覆盖写分析、文件生命周期分布示例展示了从简单的操作统计,到复杂的顺序读检测、覆盖写检测、生命周期分析,均可以通过 SQL + TLS 可视化仪表盘轻松实现,为 JuiceFS 用户提供了灵活且深入的访问日志洞察能力。
在实际日志分析中,经常需要对特定文件或路径进行筛选。TLS 仪表盘提供了过滤器功能,用户可在控制台添加过滤器,并配置过滤条件。
例如,访问日志时,不同任务的日志存储路径不同,可基于字段__path__创建名为task的过滤器,取值来源于实际日志的 SQL 运行结果。
配置完成后,即可在控制台上勾选需要分析的日志文件,实现针对性分析。
- 应用过滤器后,系统自动向 SQL 中添加了 __path__ 过滤条件:
通过设置过滤器,可以快速筛选出关注的日志范围并生成统计结果。
从上述示例 SQL 中可以获取到 __path__ 为 extract.log、bev_cpu.log 的 write 操作对应的总次数、写入数据的平均大小、平均执行时间、最大执行时间、最小执行时间,对应如下表格:
写操作的 IO 大小分布能反映业务负载特征。
写 IO 大小分布示例 SQL:
通过 CASE WHEN 把写操作长度分为不同区间,并统计每个区间的次数。
在 TLS 仪表盘中可将结果以饼图形式展示,更直观地反映不同写 IO 大小的占比,例如 128K~256K 区间的写操作次数最多,占比 33.35%。
顺序读是指当前读操作与上一次读操作的偏移范围连续(即上次读的结束位置 = 当前读的起始位置)。
顺序读占比分布示例 SQL:
通过 WITH ... AS ... 子句定义了一个临时表 flagged,可以复用在其他 SQL 中以简化 SQL 的书写。
- 临时表包含句式:LAG(...) OVER(PARTITION BY ... ORDER BY ...)
- 临时表句式 SQL 示例:LAG(offset) OVER (PARTITION BY __path__, inode ORDER BY time )
- __path__, inode:根据这两个字段联合分区。
- LAG(offset):取排序后位于当前数据上一行的 offset 值。
- 表格中相同的__path__、 inode, 属于同一个分区,在各自的分区内按time进行升序排列。
- 共存在 3 个分区:第 1 行~第 5 行为第 1 个分区;第 6 行~第 7 行为第 2 个分区;第 8 行为第 3 个分区。
- 对于第1行,不存在上一行,因此结果 offset为 NULL。
- 对于第2行,上一行是第1行,因此结果 offset取第1行的 offset,也就是 32。
- 对于第5行,由于其所在分区只有1行,不存在上一行,因此结果 offset也是 NULL。
- 如果当前读操作起始位置 offset 等于紧挨着的上一次读操作的 offset + length(也就是上次读的结束位置),那么当前读操作就是一次顺序读,此时返回当前读操作的长度 length,否则返回 0。这就是一次顺序读操作的 IO 大小,也就是 sequentialReadSize。
- 然后按 __path__、 inode 分组,求每个文件的顺序读总大小sum(sequentialReadSize)与读总大小sum(length)的占比 ratio,再按ratio分组求文件个数。
说明
其中GROUP BY 1为 SQL 简写,1 代表 SELECT 子句中的第一个字段,即重命名后的 scope。
- 得到类似以下的饼状图,即顺序读 IO 占比在 0~20% 的文件数量有 3139 个,占比为 48.73%。
-
覆盖写指当前写操作与上一次写操作的偏移范围有重叠。
例如,当前写范围 [32, 1024) 与上次写范围 [512, 2048) 有交集。
覆盖写分析示例 SQL:
第一个和第二个CASE WHEN 子句计算的分别是同一个日志文件(__path__)、同一个操作对象(inode),每次写操作紧挨着的上一次写操作对应的 offset、length。
然后在每一行写操作的数据中加入了其紧挨着的上次写对应的 offset 和 length,并重命名为 lastOffset 和 lastLength。
即对于每一行数据,都有两个数值范围 [offset, offset + length),[lastOffset, lastOffset + lastLength),这两个左闭右开的数值范围的交集是:
于是上述覆盖写 SQL 的思路是:
- 通过 LAG(...) OVER(PARTITION BY ... ORDER BY...) 获取每次写操作紧挨着的上次写操作对应的 offset 和 length。
- 通过 CASE ... WHEN ... THEN ... ELSE ... END将不存在上次写操作的 lastOffset 和 lastLength 赋值为 -1。
- 去除 lastOffset 和 lastLength 为-1的写操作,然后计算与上次写操作的重叠大小,也就是覆盖写的大小。
文件生命周期定义为从创建到删除的时间长度。
文件生命周期分布示例 SQL:
- 通过关联创建和删除两个操作,可以获取到同一个文件的创建时间和删除时间。
- unlinkTable LEFT JOIN createTable:用创建文件时记录的 inode 与删除文件时记录的 inode 进行关联。
- filename 和 __path__:标识文件的唯一性。
- DATE_PARSE :将毫秒时间戳转换为格式化的日期类型。
- DATE_DIFF计算文件的 删除时间(unlinkTime)减去创建时间(createTime)得到的分钟数,然后将其划分为四个范围,即:'0~10min'、'10~30min'、'30~60min'、'大于60min'。
- 最后按上面的四个范围统计文件数量就可以画出以下的饼状统计图:
-
日志服务提供强大的告警能力,设置监控规则,实时监控日志,及时发现并响应异常。
通过“监控各个文件的写耗时是否有耗时异常过长”这一典型场景,介绍如何通过火山引擎日志服务(TLS)的日志告警功能,来实现监控告警能力。操作详情可参考快速设置日志告警。 - 内容模板是一种预定义的文本模板,日志服务会按照内容模板中定义的内容向指定的通知渠道发送告警通知。
- 本案例基于日志服务提供的默认模板 default-template 创建自定义内容模板。
-
- Webhook 集成配置用于管理您的飞书机器人 Webhook 地址。
-
- 通知组用于管理告警通知的行动策略与通知对象。创建通知组时,需选择前两步创建的 webhook 和内容模板。
-
- 告警策略中需要设置基本信息、监控任务和告警通知等配置。日志服务会基于告警策略定期分析日志,并定期将符合触发条件的告警发送给指定的通知对象。
-
- 执行任务:监控对象选择对应的日志主题,输入分析语句,每个任务会定期通过该语句进行检索与分析。
- 触发条件:检索分析结果中存在数据满足条件表达式时,触发告警。
- 图中案例表示如果 consumedTime 大于 2 则触发告警,级别为警告。每隔10分钟执行一次检查。
- 附加通知内容:添加内容变量 FireResults,可以将触发告警的数据通知出来。
- 监控任务会周期性执行,当告警触发时,便会通过所配置的通知组进行通知。
- 本案例会通过配置的 Webhook 飞书机器人,将告警信息发送至指定的飞书。
借助火山引擎日志服务 TLS 的一站式日志采集、存储、查询、分析、可视化、监控告警能力,能够帮助 JuiceFS 的用户高效解决日志分散、结构复杂等问题,实现从日志采集解析到多维分析、实时监控的全链路可观测能力。
无论是基础的操作统计,还是复杂的顺序读检测、覆盖写分析,TLS 的 SQL 查询与可视化功能均能轻松应对,并通过预设仪表盘模板可一键创建出同款仪表盘。
上述所提到的日志采集配置和日志分析大盘均已发布 TLS Demo 体验中心,欢迎前往体验(点击前往)。