case-log-analysis
SKILL.md
案例日志分析器
概述
本技能提供全面的案例日志分析功能,涵盖ETL数据传输日志(基于Spark)、SQL执行日志(数据库查询日志)和通用系统日志。它帮助识别错误、性能瓶颈,并为数据管道操作和系统故障排查提供可操作的优化建议。
使用时机
- 分析Spark ETL任务日志中的错误或性能问题
- 审查SQL查询执行日志以寻找优化机会
- 排查数据管道中的数据库操作故障
- 比较不同管道阶段的执行时间
- 识别数据处理工作流中的资源约束
功能特性
ETL日志分析
- 错误检测: 识别常见的Spark错误(内存不足、shuffle错误、序列化问题、数据格式问题)
- 性能分析: 分析任务执行时间、阶段持续时间、shuffle数据大小
- 资源分析: 检查CPU、内存和磁盘使用模式
- 瓶颈识别: 定位最慢的阶段、数据倾斜问题、低效操作
SQL日志分析
- 查询错误分析: 检测SQL语法错误、约束违反、权限问题、死锁
- 查询性能分析: 分析执行计划、识别慢查询、检查索引使用情况
- 数据库指标: 检查锁等待、缓冲区缓存命中率、磁盘I/O模式
- 连接问题: 识别连接池耗尽、超时问题、网络延迟
优化建议
- 配置调优: 调整Spark配置(执行器内存、核心数、分区数)或SQL数据库设置
- 查询优化: 重写SQL查询、添加缺失索引、调整连接策略
- 资源分配: 根据工作负载模式推荐适当的资源分配
- 架构建议: 提出管道重新设计方案,以提高可扩展性和效率
常见错误模式
Spark ETL错误
| 错误类型 | 典型症状 | 根本原因 | 建议修复 |
|---|---|---|---|
| OutOfMemoryError | java.lang.OutOfMemoryError: Java heap space |
执行器/驱动内存不足 | 增加 spark.executor.memory,调整分区大小 |
| Shuffle Errors | FetchFailedException, shuffle write failed |
shuffle数据过多,网络问题 | 减少分区数量,增加 spark.shuffle.memoryFraction |
| Serialization Errors | java.io.NotSerializableException |
闭包中的不可序列化对象 | 使对象可序列化或使用广播变量 |
| Data Format Issues | ParseException, NumberFormatException |
源文件中的数据无效 | 添加数据验证,使用模式强制 |
| Resource Exhaustion | No space left on device, GC overhead limit exceeded |
磁盘/GC压力 | 清理临时文件,调整GC设置 |
SQL执行错误
| 错误类型 | 典型症状 | 根本原因 | 建议修复 |
|---|---|---|---|
| Syntax Errors | ERROR: syntax error at or near "XYZ" |
SQL语法无效 | 检查查询语法,检查保留字 |
| Constraint Violations | violates foreign key constraint |
数据完整性问题 | 插入前验证数据,检查约束 |
| Permission Denied | permission denied for relation XYZ |
权限不足 | 授予用户/角色适当的权限 |
| Deadlocks | deadlock detected |
并发事务冲突 | 实现重试逻辑,调整隔离级别 |
| Connection Issues | timeout expired, too many connections |
资源耗尽 | 调整连接池设置,实现连接限制 |
数据湖/表管理错误
| 错误类型 | 典型症状 | 根本原因 | 建议修复 |
|---|---|---|---|
| Amoro小文件合并冲突 | 列出大量Parquet文件路径,触发 ValidationException.check, ManifestFilterManager.validateRequiredDeletes |
Amoro小文件合并任务与操作同一表的定时ETL任务冲突,导致元数据冲突 | 1. 协调Amoro合并任务和数据插入任务的时间窗口2. 增加合并间隔或暂停自动合并3. 检查表锁定机制4. 优化小文件合并策略 |
| Iceberg表写入验证失败 | org.apache.iceberg.exceptions.ValidationException,列出大量数据文件路径 |
Iceberg表元数据在数据写入期间验证失败,可能由于并发操作、模式不匹配或小文件过多 | 1. 检查表状态和分区策略2. 验证数据类型兼容性3. 调整写入模式(pass、overwrite、merge)4. 增加验证超时设置 |
| 并发写入冲突 | Concurrent modification 或 ConflictException |
多个任务同时写入同一Iceberg/Amoro表 | 1. 实现写入队列机制2. 使用表锁或事务管理3. 调整任务调度时间4. 实现重试机制 |
性能分析模式
ETL性能指标
- 阶段持续时间: 长时间运行的阶段表明计算瓶颈
- Shuffle大小: 大量的shuffle数据表明数据分区效率低下
- GC时间: 高垃圾回收时间表明内存压力
- 数据倾斜: 不均匀的分区大小导致落后任务
SQL性能指标
- 查询执行时间: 慢查询需要优化
- 行数: 意外的行数可能表明连接效率低下
- 索引使用: 缺失索引导致全表扫描
- 锁等待: 高锁等待时间表明并发问题
Usage Examples
示例1: Spark内存错误
输入日志:
[ERROR] 2026-03-23 10:30:00 - Job aborted due to stage failure: Task 5 in stage 3.0 failed 4 times, most recent failure: Lost task 5.3 in stage 3.0 (TID 25): java.lang.OutOfMemoryError: Java heap space
分析:
- 错误类型: Spark执行器中的OutOfMemoryError
- 根本原因: 数据处理堆内存不足
- 建议:
- 增加执行器内存:
--executor-memory 8g - 减少分区数量:
spark.sql.shuffle.partitions = 200 - 启用堆外内存:
spark.memory.offHeap.enabled = true - 检查数据倾斜,如有需要则重新分区
- 增加执行器内存:
示例2: 慢SQL查询
输入日志:
[QUERY] 2026-03-23 11:15:00 - Query ID 1234, Duration: 45.2s, Rows: 1000000
SELECT * FROM orders o JOIN customers c ON o.customer_id = c.id WHERE o.order_date > '2026-01-01'
分析:
- 问题: 由于缺失索引导致全表扫描
- 根本原因:
order_date列上没有索引 - 建议:
- 创建索引:
CREATE INDEX idx_orders_order_date ON orders(order_date) - 优化查询: 添加选择性WHERE条件
- 考虑按日期范围分区
- 检查连接策略并考虑查询重写
- 创建索引:
Example 3: YARN Application States Analysis
Input Log:
26/03/23 18:45:37 INFO Client: Application report for application_1750834992812_2796215 (state: ACCEPTED)
diagnostics: [Mon Mar 23 18:45:37 +0800 2026] Application is Activated, waiting for resources to be assigned for AM...
26/03/23 18:45:58 INFO Client: Application report for application_1750834992812_2796215 (state: RUNNING)
Analysis:
- ACCEPTED状态: Spark应用已提交到YARN,正在等待资源分配
- 意味着应用在队列中排队,等待分配ApplicationMaster容器资源
- 如果长时间处于ACCEPTED状态(>60秒),表明队列资源紧张
- RUNNING状态: 资源已分配,ApplicationMaster和Executor容器正在运行
- 表示Spark作业正在执行中,可以开始处理数据
- 优化建议:
- 对于长时间ACCEPTED状态:
- 检查队列资源和队列容量
- 增加队列资源配额或调整队列优先级
- 考虑调整
spark.driver.memory和spark.executor.memory以减少资源需求
- 监控指标:
- ACCEPTED到RUNNING的时间间隔(理想值 <30秒)
- 队列等待时间和资源使用率
- 配置优化:
// 减少资源需求以缩短等待时间 spark.driver.memory = "2G" # 从4G减少到2G spark.executor.memory = "4G" # 从8G减少到4G // 调整YARN配置 spark.yarn.queue = "higher_priority_queue" spark.yarn.am.waitTime = "10000" # 设置等待时间
- 对于长时间ACCEPTED状态:
按问题类型的详细建议
内存优化
-
Spark内存调优:
- 调整
spark.executor.memory和spark.driver.memory - 配置
spark.memory.fraction和spark.memory.storageFraction - 对于大型数据集考虑使用堆外内存
- 调整
-
SQL内存管理:
- 调整数据库共享缓冲区
- 为排序操作配置 work_mem
- 监控并优化缓存命中率
查询优化
-
Spark SQL优化:
- 使用适当的分区策略
- 启用自适应查询执行
- 对小表利用广播连接
- 实现谓词下推
-
数据库查询优化:
- 使用EXPLAIN分析执行计划
- 根据查询模式创建缺失索引
- 优化连接顺序和策略
- 对复杂聚合使用物化视图
资源管理
-
计算资源:
- 根据工作负载调整Spark执行器大小
- 配置适当的并行度设置
- 监控CPU利用率并相应调整核心数
-
存储优化:
- 选择合适的存储格式(Parquet、ORC)
- 实现数据压缩
- 考虑分区和分桶策略
-
YARN应用状态优化:
-
ACCEPTED状态: Spark应用已提交到YARN,在队列中等待资源分配
- 监控指标:ACCEPTED到RUNNING的时间间隔
- 建议阈值:>60秒表明队列资源紧张
- 优化方案:
- 增加队列资源配额
- 调整资源请求大小:
spark.driver.memory,spark.executor.memory - 提高队列优先级:
spark.yarn.queue = "higher_priority_queue"
-
RUNNING状态: 资源已分配,作业执行中
- 监控指标:作业执行时间,阶段耗时,数据吞吐量
- 建议阈值:根据作业类型和数据量设定合理时间
- 优化方案:
- 优化Spark配置提高执行效率
- 调整数据分区策略
- 启用动态资源分配:
spark.dynamicAllocation.enabled = true
-
状态切换分析:
- 正常模式:ACCEPTED → RUNNING(<30秒) → FINISHED
- 资源紧张模式:长时间ACCEPTED(>60秒) → 可能需要增加队列资源
- 执行缓慢模式:RUNNING时间过长 → 需要优化作业配置或资源
-
最佳实践
-
日志收集:
- 始终提供带时间戳的完整日志文件
- 包含配置详情(Spark配置、数据库参数)
- 捕获系统指标(CPU、内存、磁盘I/O)
-
上下文信息:
- 指定数据管道架构
- 提及最近的系统变更或部署
- 提供数据量和特征
-
分析方法:
- 在性能分析之前先从错误模式开始
- 将当前日志与基线性能进行比较
- 同时考虑即时修复和长期优化
参考文件
本技能在 references/ 目录中包含参考资料:
spark_error_codes.md- 全面的Spark错误代码参考sql_performance_patterns.md- 常见的SQL性能模式和修复方法configuration_guidelines.md- 推荐的配置设置
脚本
scripts/ 目录中有用的脚本:
log_parser.py- 解析并从日志文件中提取指标
本技能旨在帮助工程师和管理员快速诊断和解决数据管道、ETL过程、数据库操作和通用系统日志中的问题。