大数据工程师生存手册:Hadoop/Spark/Flink 集群运维、日志排查、性能监控、自动化脚本、生产环境案例,从入门到精通
📌 前言
真实工作场景
场景 1:集群告警,紧急排查
凌晨 3 点,手机告警:
- "NameNode 内存使用率 95%"
- "YARN 队列积压 1000+ 任务"
- "HDFS 磁盘使用率 90%"
怎么办?
- SSH 登录集群
- 查看进程状态
- 分析日志定位问题
- 紧急扩容/清理
需要技能:
✓ Linux 命令熟练
✓ 日志分析能力
✓ 脚本编写能力
场景 2:任务失败,定位原因
Spark 任务失败:
- 提交任务 → 运行 10 分钟 → Failed
- 错误信息:Container killed by YARN for exceeding memory limits
怎么办?
- 查看 YARN 日志
- 分析 Spark Executor 日志
- 调整内存参数
- 重新提交
需要技能:
✓ 日志 grep/awk 分析
✓ 参数调优
✓ 脚本自动化
场景 3:数据异常,排查溯源
业务反馈:
- "今天 GMV 数据比昨天少了 50%"
- "某个报表数据对不上"
怎么办?
- 检查数据源(MySQL binlog)
- 检查 Kafka 积压
- 检查 Flink/Spark 任务
- 检查 Hive 表分区
需要技能:
✓ 数据比对
✓ 链路追踪
✓ 脚本自动化
本书价值:
- 30+ 大数据开发常用命令
- 10+ 实用脚本(可以直接用)
- 5+ 生产环境案例
- 排查问题的思路和方法
🔧 基础命令速查
1. 文件操作
查看文件内容:
# 查看前 N 行(看表头/结构)
head -100 data.csv
# 查看后 N 行(看最新数据)
tail -100 data.csv
# 实时跟踪日志(排查问题必备)
tail -f /var/log/hadoop/hdfs.log
# 查看文件中间部分(跳过前 1000 行,看 100 行)
tail -n +1000 data.csv | head -100
# 分页查看(大文件)
less huge_file.log
# 操作:空格翻页,b 上一页,/关键词 搜索,q 退出
# 查看文件大小
ls -lh data.csv
du -sh /data/hive/warehouse/
# 查找文件
find /data -name "*.log" -mtime -7 # 7 天内的日志
find /data -size +1G # 大于 1GB 的文件
文件内容处理:
# 统计行数(数据量检查)
wc -l data.csv
# 去重
sort data.csv | uniq
# 去重并计数
sort data.csv | uniq -c | sort -rn | head -20
# 提取列(CSV 文件)
cut -d',' -f1,3,5 data.csv
# 替换内容
sed 's/old/new/g' data.csv
sed -i 's/old/new/g' data.csv # 直接修改文件
# 删除空行
grep -v '^$' data.csv
# 删除重复行
awk '!seen[$0]++' data.csv
2. 文本分析(grep/awk/sed)
grep(搜索):
# 搜索关键词
grep "ERROR" hadoop.log
# 忽略大小写
grep -i "error" hadoop.log
# 显示匹配行前后 N 行
grep -A 5 -B 5 "Exception" spark.log
# 显示行号
grep -n "Failed" yarn.log
# 递归搜索目录
grep -r "OutOfMemory" /var/log/hadoop/
# 排除某些文件
grep -r "ERROR" /var/log/ --exclude="*.gz"
# 统计匹配行数
grep -c "ERROR" hadoop.log
# 多关键词(或)
grep -E "ERROR|Exception|Failed" hadoop.log
# 多关键词(与)
grep "ERROR" hadoop.log | grep "OutOfMemory"
awk(文本分析):
# 提取列(CSV)
awk -F',' '{print $1, $3, $5}' data.csv
# 条件过滤
awk -F',' '$3 > 100 {print $1, $3}' data.csv
# 统计
awk -F',' '{sum+=$3} END {print "Sum:", sum}' data.csv
# 分组统计
awk -F',' '{count[$2]++} END {for(k in count) print k, count[k]}' data.csv
# 格式化输出
awk -F',' '{printf "%-20s %-10s %10.2f\n", $1, $2, $3}' data.csv
# 复杂计算
awk -F',' '
BEGIN {sum=0; count=0}
{
if($3 > 0) {
sum += $3
count++
}
}
END {
print "Count:", count
print "Sum:", sum
print "Avg:", (count>0 ? sum/count : 0)
}
' data.csv
sed(流编辑):
# 替换
sed 's/old/new/g' file.txt
sed -i 's/old/new/g' file.txt # 直接修改
# 删除行
sed '1,10d' file.txt # 删除前 10 行
sed '/^$/d' file.txt # 删除空行
sed '/ERROR/d' file.txt # 删除包含 ERROR 的行
# 提取行
sed -n '100,200p' file.txt # 提取 100-200 行
sed -n '/ERROR/p' file.txt # 提取包含 ERROR 的行
3. 系统监控
进程监控:
# 查看进程
ps aux | grep java
ps -ef | grep NameNode
# 查看进程树
pstree -p | grep java
# 查看资源占用
top
htop # 更直观(需要安装)
# 查看内存
free -h
cat /proc/meminfo
# 查看 CPU
lscpu
cat /proc/cpuinfo
# 查看磁盘
df -h
df -i # inode 使用率
# 查看磁盘 IO
iostat -x 1 5 # 每秒一次,共 5 次
iotop # 查看进程 IO(需要安装)
网络监控:
# 查看网络连接
netstat -tunlp | grep 8088
ss -tunlp | grep 9000
# 查看网络流量
iftop # 实时流量(需要安装)
nethogs # 按进程查看(需要安装)
# 测试连通性
ping hadoop1
telnet hadoop1 9000
nc -zv hadoop1 9000
# 查看端口占用
lsof -i :8088
netstat -tunlp | grep 8088
🔧 Hadoop 集群运维
1. 集群状态检查
# HDFS 状态
hdfs dfsadmin -report
hdfs dfsadmin -safemode get
hdfs dfsadmin -safemode leave # 退出安全模式
# 查看 HDFS 空间
hdfs dfs -df -h
hdfs dfs -du -h /user/hive/warehouse
# 查看 HDFS 文件
hdfs dfs -ls /user/hive/warehouse/order_info
hdfs dfs -cat /user/hive/warehouse/order_info/dt=2026-03-24/part-00000 | head
# YARN 状态
yarn node -list
yarn node -list -all # 包括失活节点
# 查看 YARN 应用
yarn application -list
yarn application -list -appStates ALL
# 查看应用详情
yarn application -status application_1234567890
# 查看应用日志
yarn logs -applicationId application_1234567890
yarn logs -applicationId application_1234567890 -log_files stderr
2. 常见故障排查
NameNode 内存高:
# 1. 查看 NameNode 堆内存
jmap -heap $(jps | grep NameNode | awk '{print $1}')
# 2. 查看 HDFS 文件数
hdfs dfs -count /
# 3. 查看小文件
hdfs dfs -ls -R / | awk '$3 < 1048576 {print}' | wc -l
# 4. 清理回收站
hdfs dfs -expunge
# 5. 合并小文件(Hive 表)
ALTER TABLE table_name CONCATENATE;
DataNode 磁盘满:
# 1. 查看磁盘使用
df -h
# 2. 查看 HDFS 块分布
hdfs fsck / -files -blocks -racks
# 3. 清理过期快照
hdfs dfsadmin -deleteSnapshot /path snapshot_name
# 4. 扩容(添加 DataNode)
# 在新节点启动 DataNode
hdfs --daemon start datanode
YARN 队列积压:
# 1. 查看队列状态
yarn queue -status default
# 2. 查看排队任务
yarn application -list -appStates ACCEPTED
# 3. 杀死占用资源的应用
yarn application -kill application_1234567890
# 4. 调整队列资源
# capacity-scheduler.xml 修改队列配置
3. 日志分析
Hadoop 日志位置:
# NameNode 日志
/var/log/hadoop/hdfs/hdfs-namenode-*.log
# DataNode 日志
/var/log/hadoop/hdfs/hdfs-datanode-*.log
# ResourceManager 日志
/var/log/hadoop/yarn/yarn-resourcemanager-*.log
# NodeManager 日志
/var/log/hadoop/yarn/yarn-nodemanager-*.log
# 任务日志(YARN)
/var/log/hadoop/yarn/userlogs/application_*/container_*/
日志分析脚本:
#!/bin/bash
# analyze_hadoop_logs.sh
LOG_DIR="/var/log/hadoop"
DATE="2026-03-24"
echo "=== Hadoop 日志分析 ==="
echo "日期:\\$DATE"
echo ""
# ERROR 统计
echo "【ERROR 统计】"
grep -r "ERROR" $LOG_DIR --include="*.log" | \
grep "\$DATE" | \
wc -l
# 按类型统计
echo ""
echo "【按类型统计】"
grep -r "ERROR" $LOG_DIR --include="*.log" | \
grep "\$DATE" | \
grep -oE "OutOfMemory|Connection refused|Timeout|BlockMissing" | \
sort | uniq -c | sort -rn
# Top 错误信息
echo ""
echo "【Top 10 错误信息】"
grep -r "ERROR" $LOG_DIR --include="*.log" | \
grep "\$DATE" | \
awk -F'ERROR' '{print $2}' | \
sort | uniq -c | sort -rn | head -10
🔧 Spark 任务排查
1. 任务提交与监控
# 提交 Spark 任务
spark-submit \
--master yarn \
--deploy-mode cluster \
--executor-memory 4G \
--executor-cores 2 \
--num-executors 10 \
--class com.example.SparkJob \
/path/to/spark-job.jar \
arg1 arg2
# 查看任务状态(Web UI)
# http://resource-manager:8088/cluster/apps/
# 查看 Spark History
# http://spark-history:18080/
2. 任务失败排查
# 1. 查看应用 ID
yarn application -list | grep spark
# 2. 查看应用状态
yarn application -status application_1234567890
# 3. 查看 Driver 日志
yarn logs -applicationId application_1234567890 -log_files stdout
# 4. 查看 Executor 日志
yarn logs -applicationId application_1234567890 -log_files stderr
# 5. 查看特定 Executor 日志
yarn logs -applicationId application_1234567890 -containerId container_123 -log_files stderr
3. 性能分析脚本
#!/bin/bash
# analyze_spark_job.sh
APP_ID=$1
if [ -z "$APP_ID" ]; then
echo "用法:$0 <application_id>"
exit 1
fi
echo "=== Spark 任务分析 ==="
echo "应用 ID: $APP_ID"
echo ""
# 应用基本信息
echo "【应用信息】"
yarn application -status $APP_ID | grep -E "State|Final-State|Diagnostics"
# 错误统计
echo ""
echo "【错误统计】"
yarn logs -applicationId $APP_ID 2>/dev/null | \
grep -c "ERROR"
# 异常类型
echo ""
echo "【异常类型】"
yarn logs -applicationId $APP_ID 2>/dev/null | \
grep -oE "Exception: [^)]+" | \
sort | uniq -c | sort -rn | head -10
# 运行时间
echo ""
echo "【运行时间】"
yarn application -status $APP_ID | grep "Start-Time"
yarn application -status $APP_ID | grep "Finish-Time"
🔧 Flink 任务运维
1. 任务管理
# 查看运行任务
flink list --running
# 查看所有任务
flink list --all
# 取消任务
flink cancel <job_id>
# 保存点
flink savepoint <job_id> /flink/savepoints
# 从保存点恢复
flink run -s /flink/savepoints/savepoint-xxx-xxx.jar
# 查看详情
curl http://jobmanager:8081/flink-ui/api/v1/jobs/<job_id>
2. 监控指标
# Checkpoint 状态
curl http://jobmanager:8081/flink-ui/api/v1/checkpoints
# 反压监控
curl http://jobmanager:8081/flink-ui/api/v1/jobs/<job_id>/backpressure
# 任务指标
curl http://jobmanager:8081/flink-ui/api/v1/jobs/<job_id>/metrics
# 常用指标
# - numRecordsIn: 输入记录数
# - numRecordsOut: 输出记录数
# - busyTimeMsPerSecond: 繁忙时间
# - backpressuredTimeMsPerSecond: 反压时间
3. 反压排查脚本
#!/bin/bash
# check_backpressure.sh
JOB_ID=$1
JM_HOST="jobmanager"
echo "=== Flink 反压检查 ==="
echo "任务 ID: $JOB_ID"
echo ""
# 获取反压数据
curl -s "http://$JM_HOST:8081/flink-ui/api/v1/jobs/$JOB_ID/backpressure" | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
for vertex in data.get('vertices', []):
print(f\"算子:{vertex['name']}\")
print(f\" 状态:{vertex['backpressureLevel']}\")
print(f\" 反压时间占比:{vertex.get('backpressuredTimeMsPerSecond', 0)/1000:.1f}s/s\")
print()
"
🔧 实用脚本集合
1. 数据质量检查
#!/bin/bash
# check_data_quality.sh
# 检查 Hive 表数据质量
TABLE=$1
PARTITION=$2
if [ -z "$TABLE" ] || [ -z "$PARTITION" ]; then
echo "用法:$0 <table_name> <partition>"
echo "示例:$0 order_info dt=2026-03-24"
exit 1
fi
echo "=== 数据质量检查 ==="
echo "表名:$TABLE"
echo "分区:$PARTITION"
echo ""
# 记录数
COUNT=$(hive -S -e "SELECT COUNT(1) FROM $TABLE WHERE $PARTITION;" 2>/dev/null)
echo "【记录数】$COUNT"
# 空值检查
echo ""
echo "【空值检查】"
hive -S -e "
SELECT 'user_id', COUNT(1) FROM $TABLE WHERE $PARTITION AND user_id IS NULL
UNION ALL
SELECT 'order_id', COUNT(1) FROM $TABLE WHERE $PARTITION AND order_id IS NULL
UNION ALL
SELECT 'pay_amount', COUNT(1) FROM $TABLE WHERE $PARTITION AND pay_amount IS NULL;
" 2>/dev/null
# 重复检查
echo ""
echo "【重复数据】"
hive -S -e "
SELECT COUNT(1) - COUNT(DISTINCT order_id) AS dup_count
FROM $TABLE
WHERE $PARTITION;
" 2>/dev/null
# 数据量波动
echo ""
echo "【近 7 天数据量】"
hive -S -e "
SELECT dt, COUNT(1) AS cnt
FROM $TABLE
WHERE dt >= DATE_SUB(CURRENT_DATE, 7)
GROUP BY dt
ORDER BY dt;
" 2>/dev/null
2. Kafka 积压检查
#!/bin/bash
# check_kafka_lag.sh
# 检查 Kafka 消费者组积压
KAFKA_HOME="/opt/kafka"
BOOTSTRAP_SERVERS="kafka1:9092,kafka2:9092,kafka3:9092"
echo "=== Kafka 积压检查 ==="
echo ""
# 列出所有消费者组
$KAFKA_HOME/bin/kafka-consumer-groups.sh \
--bootstrap-server $BOOTSTRAP_SERVERS \
--list
echo ""
echo "【消费者组积压详情】"
# 检查每个消费者组
$KAFKA_HOME/bin/kafka-consumer-groups.sh \
--bootstrap-server $BOOTSTRAP_SERVERS \
--describe \
--all-groups | \
awk '
NR==1 {print "GROUP\tTOPIC\tPARTITION\tCURRENT\tEND\tLAG"}
NR>1 && $6 != "-" {
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $1, $2, $3, $4, $5, $6
if ($6 > 1000000) {
print " ⚠️ 警告:积压超过 100 万!"
}
}
'
3. HDFS 小文件清理
#!/bin/bash
# clean_hdfs_small_files.sh
# 合并 HDFS 小文件
TARGET_DIR=$1
MIN_SIZE=1048576 # 1MB
if [ -z "$TARGET_DIR" ]; then
echo "用法:$0 <hdfs_directory>"
echo "示例:$0 /user/hive/warehouse/order_info"
exit 1
fi
echo "=== HDFS 小文件清理 ==="
echo "目标目录:$TARGET_DIR"
echo "最小文件大小:$MIN_SIZE 字节"
echo ""
# 查找小文件
echo "【小文件列表】"
hdfs dfs -ls -R $TARGET_DIR | \
awk -v min=$MIN_SIZE '$3 < min && $NF ~ /\.parquet$|\.orc$/ {print $NF, $3}'
# 统计小文件数量
SMALL_FILE_COUNT=$(hdfs dfs -ls -R $TARGET_DIR | \
awk -v min=$MIN_SIZE '$3 < min && $NF ~ /\.parquet$|\.orc$/ {count++} END {print count+0}')
echo ""
echo "【统计】小文件数量:$SMALL_FILE_COUNT"
if [ $SMALL_FILE_COUNT -gt 1000 ]; then
echo ""
echo "⚠️ 警告:小文件过多,建议合并!"
echo ""
echo "【合并方案】"
echo "1. Hive 表:ALTER TABLE table_name CONCATENATE;"
echo "2. Spark 合并:repartition/coalesce"
echo "3. 手动合并:hdfs dfs -get + put"
fi
4. 日报自动化
#!/bin/bash
# daily_report.sh
# 大数据平台日报
DATE=${1:-$(date -d "yesterday" '+%Y-%m-%d')}
echo "========================================"
echo " 大数据平台日报 - \$DATE"
echo "========================================"
echo ""
# 1. 集群状态
echo "【集群状态】"
hdfs dfsadmin -report | grep -E "Configured Capacity|DFS Used|DataNodes"
echo ""
# 2. 任务统计
echo "【YARN 任务统计】"
yarn application -list -appStates ALL -startedDate $(date -d "\$DATE" +%s)000 -finishedDate $(date -d "\$DATE +1day" +%s)000 2>/dev/null | \
awk '
/SUCCEEDED/ {succeeded++}
/FAILED/ {failed++}
/KILLED/ {killed++}
END {
print "成功:", succeeded
print "失败:", failed
print "取消:", killed
print "成功率:", (succeeded>0 ? succeeded/(succeeded+failed+killed)*100 : 0) "%"
}
'
echo ""
# 3. 数据量统计
echo "【核心表数据量】"
hive -S -e "
SELECT 'order_info' AS table_name, COUNT(1) AS cnt FROM ecommerce.order_info WHERE dt='\$DATE'
UNION ALL
SELECT 'user_info', COUNT(1) FROM ecommerce.user_info
UNION ALL
SELECT 'product_info', COUNT(1) FROM ecommerce.product_info;
" 2>/dev/null
echo ""
# 4. 告警统计
echo "【告警统计】"
grep -r "ERROR\|WARN" /var/log/hadoop/ --include="*.log" | \
grep "\$DATE" | \
wc -l
echo ""
echo "========================================"
echo " 报告完成"
echo "========================================"
🏭 生产环境案例
案例 1:NameNode OOM 排查
问题:
- 告警:NameNode 内存使用率 95%
- 症状:HDFS 响应变慢,部分操作超时
排查过程:
# 1. 确认问题
$ hdfs dfsadmin -report
Configured Capacity: 10TB
DFS Used: 8TB
DataNodes: 10
# 2. 查看文件数
$ hdfs dfs -count /
50000000 100000000 8000000000000 /
发现:5000 万目录,1 亿文件
# 3. 查找小文件
$ hdfs dfs -ls -R / | awk '$3 < 1048576' | wc -l
10000000 # 1000 万个小文件
# 4. 查看回收站
$ hdfs dfs -ls -R /trash
5000000 # 500 万个待删除文件
解决方案:
# 1. 清空回收站
$ hdfs dfs -expunge
# 2. 合并小文件(Hive 表)
$ hive -e "ALTER TABLE order_info CONCATENATE;"
$ hive -e "ALTER TABLE user_log CONCATENATE;"
# 3. 调整 NameNode 内存
# hdfs-site.xml
dfs.namenode.handler.count=200
dfs.namenode.name.dir=file:///data/namenode
结果:
- 文件数:1 亿 → 5000 万
- 内存使用率:95% → 60%
- 响应时间:5s → 200ms
案例 2:Spark 任务 OOM 排查
问题:
- Spark 任务失败:Container killed by YARN for exceeding memory limits
- 错误日志:java.lang.OutOfMemoryError: Java heap space
排查过程:
# 1. 查看任务配置
$ yarn application -status application_1234567890
Executor Memory: 4G
Executor Cores: 2
# 2. 分析日志
$ yarn logs -applicationId application_1234567890 | grep "OutOfMemory"
Exception in thread "Executor task launch worker": java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3210)
# 3. 查看数据倾斜
$ hive -e "
SELECT user_id, COUNT(1) AS cnt
FROM user_log
WHERE dt='2026-03-24'
GROUP BY user_id
ORDER BY cnt DESC
LIMIT 10;
"
user_id_001 10000000 # 某个用户 1000 万条
user_id_002 10000 # 其他用户 1 万条
发现:数据倾斜
解决方案:
# 1. 加盐分散
spark.sql("
SELECT
CONCAT(user_id, '_', FLOOR(RAND() * 10)) AS salted_key,
user_id,
COUNT(1) AS cnt
FROM user_log
WHERE dt='2026-03-24'
GROUP BY CONCAT(user_id, '_', FLOOR(RAND() * 10)), user_id
")
# 2. 增加内存
spark-submit \
--executor-memory 8G \
--executor-cores 2 \
--conf spark.memory.fraction=0.8 \
...
# 3. 调整并行度
spark-submit \
--conf spark.sql.shuffle.partitions=2000 \
...
结果:
- 任务状态:Failed → Succeeded
- 运行时间:30 分钟 → 15 分钟
案例 3:Kafka 积压处理
问题:
- 告警:Kafka 积压 1000 万消息
- 消费延迟:2 小时
排查过程:
# 1. 查看积压
$ kafka-consumer-groups.sh --bootstrap-server kafka1:9092 --describe --group order_consumer
GROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG
order_consumer order_topic 0 1000000 11000000 10000000
order_consumer order_topic 1 2000000 2100000 100000
发现:Partition 0 积压严重(数据倾斜)
# 2. 查看 Key 分布
$ kafka-console-consumer.sh --bootstrap-server kafka1:9092 --topic order_topic --from-beginning | \
jq -r '.key' | sort | uniq -c | sort -rn | head -10
10000000 key_001 # 某个 Key 1000 万条
10000 key_002
发现:Key 分布不均
解决方案:
# 1. 临时扩容
# 创建新 Topic(分区数 x2)
$ kafka-topics.sh --create --topic order_topic_new --partitions 20 --replication-factor 3
# 2. 数据迁移
$ kafka-reassign-partitions.sh --reassignment-json-file reassign.json --execute
# 3. 增加消费者
# 部署 10 个消费者(原 5 个)
# 4. 优化 Key 设计
# 原:key = user_id
# 新:key = user_id + "_" + (timestamp % 10) # 分散到多个分区
结果:
- 积压:1000 万 → 0
- 延迟:2 小时 → 3 秒
📋 最佳实践清单
日常运维
- 每日检查集群状态(HDFS/YARN)
- 监控磁盘使用率(< 80%)
- 监控 NameNode 内存(< 70%)
- 检查任务失败率(< 5%)
- 清理回收站(每周)
问题排查
- 先看日志(ERROR/WARN)
- 检查资源(CPU/内存/磁盘)
- 分析数据倾斜(Top Key)
- 对比历史(是否异常波动)
- 记录排查过程(便于复盘)
脚本编写
- 参数化(不要硬编码)
- 错误处理(检查返回值)
- 日志输出(便于调试)
- 权限控制(不要 rm -rf /)
- 定期 review(优化改进)
文档沉淀
- 运维手册(集群架构/配置)
- 故障记录(问题/原因/解决)
- 脚本说明(用途/用法/示例)
- 联系人清单(负责人/联系方式)
📌 总结
核心技能
| 技能 | 重要性 | 使用频率 |
|---|---|---|
| grep/awk/sed | ⭐⭐⭐⭐⭐ | 每天 |
| 日志分析 | ⭐⭐⭐⭐⭐ | 每天 |
| 脚本编写 | ⭐⭐⭐⭐⭐ | 每周 |
| 集群监控 | ⭐⭐⭐⭐ | 每天 |
| 故障排查 | ⭐⭐⭐⭐ | 每周 |
学习建议
1. 先熟练基础命令
ls/cd/cat/grep/awk/sed
2. 多动手写脚本
从简单到复杂,解决实际问题
3. 积累排查经验
记录每次故障的原因和解决方法
4. 建立知识体系
命令 → 脚本 → 工具 → 平台
💡 Linux 是大数据工程师的基本功,建议熟练掌握!
👋 感谢阅读!
🔗 系列文章
- [01-SQL 窗口函数从入门到精通](./01-SQL 窗口函数从入门到精通.md)
- [02-Spark 性能优化 10 个技巧](./02-Spark 性能优化 10 个技巧.md)
- 03-数据仓库分层设计指南
- 04-维度建模实战
- [05-Flink 实时数仓实战](./05-Flink 实时数仓实战.md)
- [06-Kafka 消息队列实战指南](./06-Kafka 消息队列实战指南.md)
- [07-Hive 性能优化实战](./07-Hive 性能优化实战.md)
- 08-Linux 大数据开发必备工具(本文)
- [下一篇:缓慢变化维 SCD Type 2 详解](./09-缓慢变化维 SCD Type2 详解.md)