1. 首页 > Hadoop教程 > 正文

大数据教程FG016-HDFS归档与小文件优化实战

内容简介:本文详细介绍HDFS归档与小文件优化实战,包括小文件问题分析、HAR归档技术、小文件合并方案、小文件治理策略等核心内容。风哥教程参考Hadoop官方文档HDFS Archives、Small Files Problem等内容。

目录大纲

Part01-基础概念与理论知识
  1.1 小文件问题概述
  1.2 HAR归档原理
  1.3 小文件优化策略
Part02-生产环境规划与建议
  2.1 小文件治理规划
  2.2 归档策略规划
  2.3 监控告警规划
Part03-生产环境项目实施方案
  3.1 小文件检测与分析
  3.2 HAR归档实施
  3.3 小文件合并方案
  3.4 小文件预防措施
Part04-生产案例与实战讲解
  4.1 日志小文件归档案例
  4.2 数据仓库小文件优化案例
  4.3 小文件治理自动化案例
Part05-风哥经验总结与分享
  5.1 小文件治理最佳实践
  5.2 归档优化经验总结

Part01-基础概念与理论知识

1.1 小文件问题概述

小文件是指文件大小明显小于HDFS数据块大小(默认128MB)的文件。更多视频教程www.fgedu.net.cn 小文件过多会严重影响HDFS性能,主要表现在NameNode内存压力大、MapReduce处理效率低等方面。

风哥提示:每个文件、目录和数据块的元数据约占用150字节内存,100万个文件约需要150MB内存。大量小文件会迅速消耗NameNode内存。

1.2 HAR归档原理

HAR(Hadoop Archive)是HDFS提供的归档工具,可以将多个小文件打包成一个归档文件。学习交流加群风哥微信: itpux-com HAR文件内部保持原有的目录结构,支持透明访问。

HAR归档特点:
– 将多个小文件打包成一个大文件
– 保持原有目录结构
– 支持透明访问,无需解压
– 减少NameNode元数据占用
– 适合冷数据归档

1.3 小文件优化策略

小文件优化策略包括源头预防、定期合并、归档存储等。from bigdata视频:www.itpux.com

小文件优化策略:
– 源头预防:写入时合并小文件
– 定期合并:定期执行小文件合并任务
– 归档存储:将历史小文件归档
– 配置优化:调整MapReduce输入参数

Part02-生产环境规划与建议

2.1 小文件治理规划

小文件治理需要建立完善的监控和治理机制。更多学习教程公众号风哥教程itpux_com

小文件治理规划建议:
– 建立小文件监控告警机制
– 制定小文件治理标准(如文件数阈值)
– 定期执行小文件合并任务
– 历史数据定期归档

2.2 归档策略规划

归档策略需要根据数据访问频率制定。学习交流加群风哥QQ113257174

# 查看当前文件分布
hdfs fsck /bigdata/warehouse/fgedu -files -blocks | grep “Total files”

# 文件统计
Total files: 125000
Total blocks: 375000
Total size: 107374182400 B

2.3 监控告警规划

小文件监控告警需要关注文件数量和文件大小分布。风哥提示:建议设置文件数量阈值告警。

# 统计小文件数量
hdfs fsck /bigdata/warehouse/fgedu -files -blocks | grep -c “size: [0-9]\{1,7\} bytes”

# 小文件数量(小于1MB的文件)
45000

Part03-生产环境项目实施方案

3.1 小文件检测与分析

3.1.1 小文件检测脚本

#!/bin/bash
# small_file_detect.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

DIR=$1
THRESHOLD=${2:-134217728} # 默认128MB

echo “=== Small File Detection Report ===”
echo “Directory: ${DIR}”
echo “Threshold: $((${THRESHOLD}/1024/1024))MB”
echo “Date: $(date)”

# 统计文件大小分布
echo “
File Size Distribution:”
hdfs fsck ${DIR} -files -blocks 2>/dev/null | \
awk -v threshold=${THRESHOLD} ‘{
if (match($0, /size: ([0-9]+) bytes/, arr)) {
size = arr[1];
if (size < 1048576) count["<1MB"]++;
else if (size < 10485760) count["1-10MB"]++;
else if (size < 104857600) count["10-100MB"]++;
else if (size < threshold) count["100MB-128MB"]++;
else count[“>128MB”]++;
total++;
}
}
END {
for (k in count) print k “: ” count[k] ” files”;
print “Total: ” total ” files”;
}’

# 执行检测
./small_file_detect.sh /bigdata/warehouse/fgedu

=== Small File Detection Report ===
Directory: /bigdata/warehouse/fgedu
Threshold: 128MB
Date: Wed Jan 17 10:00:00 CST 2024

File Size Distribution:
<1MB: 45000 files
1-10MB: 30000 files
10-100MB: 20000 files
100MB-128MB: 15000 files
>128MB: 15000 files
Total: 125000 files

3.1.2 小文件目录分析

# 查找小文件最多的目录
hdfs dfs -du -h /bigdata/warehouse/fgedu/* | sort -n | head -20
# 统计目录文件数量
hdfs dfs -count /bigdata/warehouse/fgedu/*

# 目录大小排序
10.0 M 30.0 M /bigdata/warehouse/fgedu/tmp
50.0 M 150.0 M /bigdata/warehouse/fgedu/logs
100.0 M 300.0 M /bigdata/warehouse/fgedu/config

# 目录文件数统计
12 45000 10485760 /bigdata/warehouse/fgedu/tmp
15 30000 52428800 /bigdata/warehouse/fgedu/logs
20 20000 104857600 /bigdata/warehouse/fgedu/config

3.2 HAR归档实施

3.2.1 创建HAR归档

# 创建HAR归档
hadoop archive -archiveName fgedu_logs.har -p /bigdata/warehouse/fgedu logs /bigdata/archive/fgedu/
# 查看归档文件
hdfs dfs -ls /bigdata/archive/fgedu/fgedu_logs.har

# 归档创建过程
24/01/17 10:30:00 INFO archive.HadoopArchives: Creating archive fgedu_logs.har
24/01/17 10:30:05 INFO archive.HadoopArchives: Number of files: 30000
24/01/17 10:30:10 INFO archive.HadoopArchives: Total size: 52428800
24/01/17 10:45:00 INFO archive.HadoopArchives: Archive created successfully

# 归档文件内容
Found 3 items
-rw-r–r– 3 hdfs hdfs 52428800 2024-01-17 10:45 /bigdata/archive/fgedu/fgedu_logs.har/part-0
-rw-r–r– 3 hdfs hdfs 256 2024-01-17 10:45 /bigdata/archive/fgedu/fgedu_logs.har/_index
-rw-r–r– 3 hdfs hdfs 128 2024-01-17 10:45 /bigdata/archive/fgedu/fgedu_logs.har/_masterindex

3.2.2 访问HAR归档文件

# 列出归档内容
hdfs dfs -ls har:///bigdata/archive/fgedu/fgedu_logs.har/
# 读取归档中的文件
hdfs dfs -cat har:///bigdata/archive/fgedu/fgedu_logs.har/app.log | head -10
# 复制归档中的文件
hdfs dfs -cp har:///bigdata/archive/fgedu/fgedu_logs.har/app.log /bigdata/warehouse/fgedu/restored/

# 归档内容列表
Found 30000 items
-rw-r–r– 3 hdfs hdfs 1024 2024-01-17 10:30 har:///bigdata/archive/fgedu/fgedu_logs.har/app_001.log
-rw-r–r– 3 hdfs hdfs 2048 2024-01-17 10:30 har:///bigdata/archive/fgedu/fgedu_logs.har/app_002.log

# 读取文件内容
2024-01-01 10:00:00 INFO Application started
2024-01-01 10:00:01 INFO Loading configuration

# 复制成功
# 验证复制结果
hdfs dfs -ls /bigdata/warehouse/fgedu/restored/app.log
-rw-r–r– 3 hdfs hdfs 1024 2024-01-17 10:50 /bigdata/warehouse/fgedu/restored/app.log

3.3 小文件合并方案

3.3.1 使用MapReduce合并小文件

# 使用MapReduce合并小文件
hadoop jar /bigdata/app/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-*.jar \
org.apache.hadoop.tools.HadoopArchives \
-D mapreduce.job.reduces=1 \
-archiveName merged_files.har \
-p /bigdata/warehouse/fgedu/tmp . /bigdata/warehouse/fgedu/merged/

# 合并执行
24/01/17 11:00:00 INFO client.RMProxy: Connecting to ResourceManager
24/01/17 11:00:05 INFO mapreduce.JobSubmitter: number of splits:45000
24/01/17 11:00:10 INFO mapreduce.Job: Job job_1705473600000_0001 completed successfully

# 合并结果
# 原始文件数:45000
# 合并后文件数:1

3.3.2 使用Spark合并小文件

# Spark合并小文件脚本
spark-shell –master yarn –deploy-mode client <<'EOF'
val df = spark.read.parquet(“/bigdata/warehouse/fgedu/tmp/*.parquet”)
df.coalesce(10).write.mode(“overwrite”).parquet(“/bigdata/warehouse/fgedu/merged/”)
System.exit(0)
EOF

# Spark合并执行
24/01/17 11:30:00 INFO SparkContext: Running Spark
24/01/17 11:30:05 INFO DAGScheduler: Job 0 finished
24/01/17 11:35:00 INFO SparkContext: Successfully stopped SparkContext

# 合并结果
hdfs dfs -ls /bigdata/warehouse/fgedu/merged/
Found 10 items
-rw-r–r– 3 fgedu fgedu 52428800 2024-01-17 11:35 /bigdata/warehouse/fgedu/merged/part-00000.parquet
-rw-r–r– 3 fgedu fgedu 52428800 2024-01-17 11:35 /bigdata/warehouse/fgedu/merged/part-00001.parquet

3.4 小文件预防措施

3.4.1 配置优化

# 配置MapReduce输入合并
cat /bigdata/app/hadoop/etc/hadoop/mapred-site.xml | grep -A3 “combine”

<!– 启用Map输入合并 –>
<property>
<name>mapreduce.input.fileinputformat.split.minsize</name>
<value>134217728</value> # 128MB
</property>

<!– 小文件合并阈值 –>
<property>
<name>mapreduce.input.fileinputformat.split.maxsize</name>
<value>268435456</value> # 256MB
</property>

3.4.2 写入优化配置

# Hive配置小文件合并
cat /bigdata/app/hive/conf/hive-site.xml | grep -A3 “merge”

<!– 启用Hive小文件合并 –>
<property>
<name>hive.merge.mapfiles</name>
<value>true</value>
</property>

<property>
<name>hive.merge.mapredfiles</name>
<value>true</value>
</property>

<property>
<name>hive.merge.size.per.task</name>
<value>268435456</value> # 256MB
</property>

<property>
<name>hive.merge.smallfiles.avgsize</name>
<value>16777216</value> # 16MB
</property>

Part04-生产案例与实战讲解

4.1 日志小文件归档案例

日志数据是小文件问题的重灾区。更多视频教程www.fgedu.net.cn

#!/bin/bash
# log_archive.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

LOG_DIR=”/bigdata/warehouse/fgedu/logs”
ARCHIVE_DIR=”/bigdata/archive/fgedu/logs”
DATE=$(date -d “30 days ago” +%Y%m%d)

# 创建归档目录
hdfs dfs -mkdir -p ${ARCHIVE_DIR}

# 查找30天前的日志目录
for dir in $(hdfs dfs -ls ${LOG_DIR} | grep “^d” | awk ‘{print $NF}’); do
DIR_NAME=$(basename ${dir})
if [[ “${DIR_NAME}” < "${DATE}" ]]; then
echo “Archiving ${dir}”
# 创建HAR归档
hadoop archive -archiveName ${DIR_NAME}.har -p ${LOG_DIR} ${DIR_NAME} ${ARCHIVE_DIR}/
# 删除原始目录
hdfs dfs -rm -r -skipTrash ${dir}
fi
done

echo “Log archive completed”

# 执行归档
./log_archive.sh
Archiving /bigdata/warehouse/fgedu/logs/20231201
Archiving /bigdata/warehouse/fgedu/logs/20231202

Log archive completed

# 归档结果
hdfs dfs -ls ${ARCHIVE_DIR}/
Found 30 items
-rw-r–r– 3 hdfs hdfs 52428800 2024-01-17 12:00 /bigdata/archive/fgedu/logs/20231201.har
-rw-r–r– 3 hdfs hdfs 52428800 2024-01-17 12:00 /bigdata/archive/fgedu/logs/20231202.har

4.2 数据仓库小文件优化案例

数据仓库小文件优化需要结合业务场景。学习交流加群风哥微信: itpux-com

# Hive表小文件优化
# 1. 分析表文件分布
hdfs dfs -count /bigdata/warehouse/fgedu/ods/*

# 2. 合并小文件
hive -e “
SET hive.merge.mapfiles=true;
SET hive.merge.mapredfiles=true;
SET hive.merge.size.per.task=256000000;
SET hive.merge.smallfiles.avgsize=16000000;

INSERT OVERWRITE TABLE fgedu.ods_user_log
SELECT * FROM fgedu.ods_user_log;

# 3. 验证合并结果
hdfs dfs -count /bigdata/warehouse/fgedu/ods/ods_user_log

# 文件分布分析
1 50000 52428800 /bigdata/warehouse/fgedu/ods/ods_user_log

# 合并执行
Hive Session ID = 12345678-1234-1234-1234-123456789012
Loading data to table fgedu.ods_user_log
Table fgedu.ods_user_log stats: [numFiles=50000, numRows=1000000, totalSize=52428800]
Merging files…
Table fgedu.ods_user_log stats: [numFiles=10, numRows=1000000, totalSize=52428800]
OK

# 合并结果验证
1 10 52428800 /bigdata/warehouse/fgedu/ods/ods_user_log
# 文件数从50000减少到10

4.3 小文件治理自动化案例

4.3.1 自动化治理脚本

#!/bin/bash
# small_file_governance.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

THRESHOLD=10000 # 文件数阈值
LOG_FILE=”/bigdata/logs/small_file_governance_$(date +%Y%m%d).log”

echo “$(date): Starting small file governance” >> ${LOG_FILE}

# 遍历需要治理的目录
for dir in $(hdfs dfs -ls -R /bigdata/warehouse/fgedu | grep “^d” | awk ‘{print $NF}’); do
FILE_COUNT=$(hdfs dfs -count ${dir} | awk ‘{print $2}’)

if [ ${FILE_COUNT} -gt ${THRESHOLD} ]; then
echo “$(date): Processing ${dir} with ${FILE_COUNT} files” >> ${LOG_FILE}

# 判断是否为历史数据
if [[ “${dir}” == *”/archive/”* ]] || [[ “${dir}” == *”/history/”* ]]; then
# 历史数据归档
ARCHIVE_NAME=$(echo ${dir} | tr ‘/’ ‘_’).har
hadoop archive -archiveName ${ARCHIVE_NAME} -p $(dirname ${dir}) $(basename ${dir}) /bigdata/archive/fgedu/
hdfs dfs -rm -r -skipTrash ${dir}
else
# 热数据合并
spark-submit –master yarn –deploy-mode client \
–class org.apache.spark.sql.execution.datasources.FileMerger \
–conf spark.sql.shuffle.partitions=10 \
/bigdata/app/spark/tools/file-merger.jar ${dir}
fi
fi
done

echo “$(date): Small file governance completed” >> ${LOG_FILE}

# 执行治理
./small_file_governance.sh
Wed Jan 17 13:00:00 CST 2024: Starting small file governance
Wed Jan 17 13:00:05 CST 2024: Processing /bigdata/warehouse/fgedu/logs with 45000 files
Wed Jan 17 13:00:10 CST 2024: Processing /bigdata/warehouse/fgedu/tmp with 30000 files
Wed Jan 17 14:00:00 CST 2024: Small file governance completed

# 治理效果
# 治理前:125000个文件
# 治理后:35000个文件
# 减少比例:72%

Part05-风哥经验总结与分享

5.1 小文件治理最佳实践

在实际生产环境中,小文件治理需要注意以下几点:from bigdata视频:www.itpux.com

风哥经验总结:
1. 源头预防比事后治理更重要
2. 建立小文件监控告警机制
3. 定期执行小文件合并任务
4. 历史数据及时归档
5. 合理配置写入参数

5.2 归档优化经验总结

5.2.1 归档策略建议

风哥提示:归档策略需要平衡存储效率和访问便利性。

归档注意事项:
– 归档后文件不支持修改
– HAR文件访问性能略低于普通文件
– 归档操作会消耗集群资源
– 建议在业务低峰期执行归档
– 归档前做好数据备份

5.2.2 小文件治理监控脚本

#!/bin/bash
# small_file_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: http://www.fgedu.net.cn

ALERT_THRESHOLD=50000 # 总文件数告警阈值
SMALL_FILE_THRESHOLD=10000000 # 小文件大小阈值(10MB)

TOTAL_FILES=$(hdfs fsck / -files -blocks 2>/dev/null | grep “Total files” | awk ‘{print $3}’)

if [ ${TOTAL_FILES} -gt ${ALERT_THRESHOLD} ]; then
MESSAGE=”WARNING: Total HDFS files (${TOTAL_FILES}) exceeds threshold (${ALERT_THRESHOLD})”
echo ${MESSAGE} | mail -s “HDFS Small File Alert” admin@fgedu.net.cn
fi

# 生成报告
echo “=== HDFS File Statistics ===” > /bigdata/logs/file_stats_$(date +%Y%m%d).txt
echo “Total Files: ${TOTAL_FILES}” >> /bigdata/logs/file_stats_$(date +%Y%m%d).txt
hdfs fsck / -files -blocks 2>/dev/null | grep “Total” >> /bigdata/logs/file_stats_$(date +%Y%m%d).txt

# 监控报告
=== HDFS File Statistics ===
Total Files: 125000
Total blocks: 375000
Total size: 107374182400 B

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息