HDFS均衡操作快速参考

快速判断是否需要均衡 # 计算当前均衡度(标准差) hdfs dfsadmin -report | python3 -c " import sys, re used_percents = [] for line in sys.stdin: if 'DFS Used%:' in line: percent = float(re.search(r'(\d+\.?\d*)%', line).group(1)) used_percents.append(percent) if used_percents: avg = sum(used_percents) / len(used_percents) variance = sum((x - avg) ** 2 for x in used_percents) / len(used_percents) std_dev = variance ** 0.5 print(f'标准差: {std_dev:.2f}%') if std_dev > 15: print('⚠️ 需要立即均衡') elif std_dev > 10: print('⚠️ 建议进行均衡') else: print('✅ 集群已均衡') " 常用均衡命令 基本均衡 # 标准均衡(推荐) nohup hdfs balancer -threshold 10 -policy datanode > /tmp/balancer.log 2>&1 & # 严格均衡 nohup hdfs balancer -threshold 5 -policy datanode > /tmp/balancer.log 2>&1 & # 宽松均衡 nohup hdfs balancer -threshold 15 -policy datanode > /tmp/balancer.log 2>&1 & 高级均衡 # 排除特定节点 nohup hdfs balancer -threshold 10 -exclude 192.168.1.100,192.168.1.101 > /tmp/balancer.log 2>&1 & # 只均衡特定节点 nohup hdfs balancer -threshold 10 -include 192.168.1.102,192.168.1.103 > /tmp/balancer.log 2>&1 & # 指定源节点 nohup hdfs balancer -threshold 10 -source 192.168.1.100,192.168.1.101 > /tmp/balancer.log 2>&1 & 参数说明 参数 用途 默认值 推荐值 -threshold 均衡阈值(%) 10 5-15 -policy 均衡策略 datanode datanode -exclude 排除节点 - 维护节点 -include 包含节点 - 特定节点 -source 源节点 - 高负载节点 -idleiterations 空闲迭代次数 5 3-5 监控命令 检查均衡状态 # 检查均衡进程 ps aux | grep balancer # 查看均衡日志 tail -f /tmp/balancer.log # 实时监控均衡进度 python3 /tmp/monitor_hdfs_balancer.py 停止均衡 # 查找并停止均衡进程 pkill -f "hdfs.*balancer" # 或者通过PID停止 kill $(cat /tmp/balancer.pid) 性能优化 调整均衡带宽 <!-- 在hdfs-site.xml中添加 --> <property> <name>dfs.datanode.balance.bandwidthPerSec</name> <value>52428800</value> <!-- 50MB/s --> </property> 系统优化 # 网络优化 echo 'net.core.rmem_max = 134217728' >> /etc/sysctl.conf echo 'net.core.wmem_max = 134217728' >> /etc/sysctl.conf sysctl -p # 磁盘优化 echo noop > /sys/block/sda/queue/scheduler 故障排除 常见问题 均衡进程无法启动 检查HDFS服务状态:hdfs dfsadmin -report 检查权限:whoami 查看日志:tail -f $HADOOP_LOG_DIR/hadoop-*-balancer-*.log ...

2024-05-01 · 3 分钟 · 431 字 · heyaohua

HDFS均衡操作完整指南

目录 概述 什么时候需要HDFS均衡 HDFS均衡原理 均衡参数详解 操作步骤 监控和管理 故障排除 最佳实践 性能优化建议 概述 HDFS均衡器(Balancer)是Hadoop分布式文件系统中的一个重要工具,用于重新分布数据块,确保集群中所有DataNode的存储使用率保持相对均衡。当集群中添加新节点或删除节点后,数据分布可能会变得不均匀,这时就需要使用均衡器来重新分布数据。 什么时候需要HDFS均衡 1. 集群扩容后 新增DataNode节点:新节点加入集群后,存储使用率为0%,而原有节点可能已经接近满载 添加存储设备:为现有DataNode添加新的磁盘后 2. 集群缩容后 移除DataNode节点:节点下线前需要将其数据迁移到其他节点 磁盘故障:某个磁盘故障后,需要重新分布数据 3. 数据倾斜 节点间使用率差异过大:标准差超过10-15% 热点数据:某些节点存储了过多的热点数据 写入模式不均:应用写入模式导致的数据分布不均 4. 性能优化 负载均衡:提高集群整体I/O性能 故障恢复:确保数据副本分布合理 判断标准 # 计算节点使用率标准差 # 标准差 > 10%:建议进行均衡 # 标准差 > 20%:强烈建议立即均衡 # 标准差 < 5%:认为已均衡 HDFS均衡原理 1. 均衡策略 DataNode策略:基于整个DataNode的使用率进行均衡 BlockPool策略:基于命名空间的使用率进行均衡(适用于Federation) 2. 均衡算法 识别源节点:使用率高于平均值的节点 识别目标节点:使用率低于平均值的节点 选择数据块:从源节点选择合适的数据块 数据迁移:通过三阶段复制进行数据迁移 验证完整性:确保数据迁移成功 3. 数据迁移过程 源节点 → 中间节点 → 目标节点 避免直接复制,减少网络压力 通过中间节点进行数据转发 确保数据完整性和一致性 均衡参数详解 1. 基本参数 -threshold <threshold> 用途:设置均衡阈值,单位为百分比 默认值:10% 说明:只有当节点使用率差异超过此阈值时才开始均衡 推荐值: 生产环境:5-10% 测试环境:10-15% 紧急情况:20% # 示例 hdfs balancer -threshold 5 # 5%阈值,更严格的均衡 hdfs balancer -threshold 15 # 15%阈值,更宽松的均衡 -policy <policy> 用途:指定均衡策略 可选值: datanode:基于DataNode使用率(默认) blockpool:基于BlockPool使用率 推荐:一般使用datanode策略 # 示例 hdfs balancer -policy datanode # DataNode策略 hdfs balancer -policy blockpool # BlockPool策略 2. 节点选择参数 -exclude [-f <hosts-file> | <comma-separated list of hosts>] 用途:排除指定的DataNode节点 使用场景: 节点维护期间 性能较差的节点 网络不稳定的节点 # 排除单个节点 hdfs balancer -exclude 192.168.1.100 # 排除多个节点 hdfs balancer -exclude 192.168.1.100,192.168.1.101 # 从文件读取排除列表 hdfs balancer -exclude -f /path/to/exclude_hosts.txt -include [-f <hosts-file> | <comma-separated list of hosts>] 用途:只对指定的DataNode节点进行均衡 使用场景: 只均衡特定节点 测试环境 部分节点维护 # 只均衡指定节点 hdfs balancer -include 192.168.1.100,192.168.1.101 -source [-f <hosts-file> | <comma-separated list of hosts>] 用途:指定源节点(数据来源) 使用场景: 特定节点需要减少负载 节点即将下线 # 指定源节点 hdfs balancer -source 192.168.1.100,192.168.1.101 3. 性能控制参数 -idleiterations <idleiterations> 用途:设置连续空闲迭代次数 默认值:5 说明:连续N次迭代没有数据移动时退出 推荐值: 生产环境:3-5 测试环境:1-2 # 示例 hdfs balancer -idleiterations 3 # 连续3次无移动则退出 -runDuringUpgrade 用途:在HDFS升级期间运行均衡器 默认值:false 说明:通常不建议在升级期间运行 4. 高级参数 -blockpools <comma-separated list of blockpool ids> 用途:指定要均衡的BlockPool ID 适用场景:Federation环境 # 示例 hdfs balancer -blockpools BP-REPLACE_WITH_NEW_PASSWORD789-192.168.1.100-REPLACE_WITH_NEW_PASSWORD7890123 操作步骤 1. 环境检查 检查集群状态 # 检查HDFS状态 hdfs dfsadmin -report # 检查NameNode状态 hdfs haadmin -getServiceState nn1 # 检查DataNode状态 hdfs dfsadmin -printTopology 检查磁盘空间 # 检查各节点磁盘使用情况 for node in $(hdfs dfsadmin -printTopology | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+'); do echo "=== $node ===" ssh $node "df -h" done 检查网络状况 # 检查节点间网络延迟 hdfs dfsadmin -printTopology | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+' | while read node; do echo "Testing $node..." ping -c 3 $node done 2. 均衡前准备 备份重要配置 # 备份HDFS配置 cp -r $HADOOP_CONF_DIR /backup/hdfs_conf_$(date +%Y%m%d) # 记录当前状态 hdfs dfsadmin -report > /backup/hdfs_report_$(date +%Y%m%d_%H%M%S).txt 设置均衡参数 # 设置均衡带宽(可选) # 在hdfs-site.xml中添加: # <property> # <name>dfs.datanode.balance.bandwidthPerSec</name> # <value>10485760</value> <!-- 10MB/s --> # </property> 3. 执行均衡 基本均衡命令 # 标准均衡命令 nohup hdfs balancer -threshold 10 -policy datanode > /tmp/hdfs_balancer.log 2>&1 & # 获取进程ID BALANCER_PID=$! # 记录PID echo $BALANCER_PID > /tmp/hdfs_balancer.pid 高级均衡命令 # 排除特定节点的均衡 nohup hdfs balancer -threshold 5 -policy datanode \ -exclude 192.168.1.100,192.168.1.101 \ -idleiterations 3 > /tmp/hdfs_balancer.log 2>&1 & # 只对特定节点进行均衡 nohup hdfs balancer -threshold 10 -policy datanode \ -include 192.168.1.102,192.168.1.103 > /tmp/hdfs_balancer.log 2>&1 & 4. 监控均衡进度 实时监控脚本 #!/usr/bin/env python3 # monitor_hdfs_balancer.py import subprocess import time import re from datetime import datetime def get_hdfs_report(): try: result = subprocess.run(['hdfs', 'dfsadmin', '-report'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, check=True) return result.stdout except subprocess.CalledProcessError as e: print("获取HDFS报告失败: {}".format(e)) return None def parse_datanode_info(report): datanodes = [] lines = report.split('\n') current_node = {} in_datanode_section = False for line in lines: line = line.strip() if line.startswith('Name:'): if current_node: datanodes.append(current_node) current_node = {'name': line.split(':', 1)[1].strip()} in_datanode_section = True elif in_datanode_section and line.startswith('DFS Used%:'): current_node['used_percent'] = float(line.split(':')[1].strip().replace('%', '')) elif in_datanode_section and line.startswith('DFS Remaining%:'): current_node['remaining_percent'] = float(line.split(':')[1].strip().replace('%', '')) if current_node: datanodes.append(current_node) return datanodes def calculate_balance_metrics(datanodes): if not datanodes: return None used_percents = [node.get('used_percent', 0) for node in datanodes] avg_used_percent = sum(used_percents) / len(used_percents) # 计算标准差 variance = sum((x - avg_used_percent) ** 2 for x in used_percents) / len(used_percents) std_dev = variance ** 0.5 # 找出最高和最低使用率节点 max_used_node = max(datanodes, key=lambda x: x.get('used_percent', 0)) min_used_node = min(datanodes, key=lambda x: x.get('used_percent', 0)) return { 'avg_used_percent': avg_used_percent, 'std_dev': std_dev, 'max_used_node': max_used_node, 'min_used_node': min_used_node, 'datanodes': datanodes } def monitor_balancer(): print("HDFS均衡监控开始...") print("=" * 80) start_time = datetime.now() try: while True: current_time = datetime.now() elapsed = current_time - start_time report = get_hdfs_report() if not report: print("[{}] 无法获取HDFS报告".format(current_time.strftime('%H:%M:%S'))) time.sleep(30) continue datanodes = parse_datanode_info(report) if not datanodes: print("[{}] 无法解析datanode信息".format(current_time.strftime('%H:%M:%S'))) time.sleep(30) continue metrics = calculate_balance_metrics(datanodes) if not metrics: continue # 显示当前状态 print("\n[{}] 运行时间: {}".format(current_time.strftime('%H:%M:%S'), elapsed)) print("平均使用率: {:.2f}%".format(metrics['avg_used_percent'])) print("均衡度(标准差): {:.2f}%".format(metrics['std_dev'])) print("最高使用率节点: {} ({:.2f}%)".format( metrics['max_used_node'].get('name', 'N/A'), metrics['max_used_node'].get('used_percent', 0))) print("最低使用率节点: {} ({:.2f}%)".format( metrics['min_used_node'].get('name', 'N/A'), metrics['min_used_node'].get('used_percent', 0))) print("\n各节点使用率:") for node in sorted(metrics['datanodes'], key=lambda x: x.get('used_percent', 0), reverse=True): name = node.get('name', 'N/A') used_pct = node.get('used_percent', 0) remaining_pct = node.get('remaining_percent', 0) print(" {}: {:.2f}% (剩余: {:.2f}%)".format(name, used_pct, remaining_pct)) # 检查是否达到均衡 if metrics['std_dev'] < 5.0: print("\n🎉 均衡完成! 标准差: {:.2f}%".format(metrics['std_dev'])) break print("=" * 80) time.sleep(60) except KeyboardInterrupt: print("\n\n监控已停止") except Exception as e: print("\n监控出错: {}".format(e)) if __name__ == "__main__": monitor_balancer() 手动检查命令 # 检查均衡进程状态 ps aux | grep balancer # 查看均衡日志 tail -f /tmp/hdfs_balancer.log # 检查集群状态 hdfs dfsadmin -report | grep -A 20 "Live datanodes" # 计算当前均衡度 python3 -c " import subprocess import re result = subprocess.run(['hdfs', 'dfsadmin', '-report'], stdout=subprocess.PIPE, universal_newlines=True) report = result.stdout used_percents = [] for line in report.split('\n'): if 'DFS Used%:' in line: percent = float(re.search(r'(\d+\.?\d*)%', line).group(1)) used_percents.append(percent) if used_percents: avg = sum(used_percents) / len(used_percents) variance = sum((x - avg) ** 2 for x in used_percents) / len(used_percents) std_dev = variance ** 0.5 print(f'平均使用率: {avg:.2f}%') print(f'标准差: {std_dev:.2f}%') print(f'最高使用率: {max(used_percents):.2f}%') print(f'最低使用率: {min(used_percents):.2f}%') " 监控和管理 1. 均衡状态监控 实时监控 # 启动监控脚本 python3 /tmp/monitor_hdfs_balancer.py # 后台运行监控 nohup python3 /tmp/monitor_hdfs_balancer.py > /tmp/balancer_monitor.log 2>&1 & 定期检查 # 创建定期检查脚本 cat > /tmp/check_balance.sh << 'EOF' #!/bin/bash LOG_FILE="/tmp/balance_check.log" DATE=$(date '+%Y-%m-%d %H:%M:%S') echo "[$DATE] 开始检查HDFS均衡状态" >> $LOG_FILE # 检查均衡进程 if pgrep -f "hdfs.*balancer" > /dev/null; then echo "[$DATE] 均衡进程正在运行" >> $LOG_FILE else echo "[$DATE] 警告: 均衡进程未运行" >> $LOG_FILE fi # 检查集群状态 hdfs dfsadmin -report | grep -A 20 "Live datanodes" >> $LOG_FILE echo "[$DATE] 检查完成" >> $LOG_FILE echo "----------------------------------------" >> $LOG_FILE EOF chmod +x /tmp/check_balance.sh # 添加到crontab,每10分钟检查一次 echo "*/10 * * * * /tmp/check_balance.sh" | crontab - 2. 均衡进程管理 启动均衡 # 基本启动 nohup hdfs balancer -threshold 10 > /tmp/balancer.log 2>&1 & # 高级启动 nohup hdfs balancer -threshold 5 -policy datanode \ -exclude 192.168.1.100 -idleiterations 3 \ > /tmp/balancer.log 2>&1 & 停止均衡 # 查找均衡进程 BALANCER_PID=$(pgrep -f "hdfs.*balancer") # 停止均衡进程 if [ ! -z "$BALANCER_PID" ]; then kill $BALANCER_PID echo "均衡进程 $BALANCER_PID 已停止" else echo "未找到运行中的均衡进程" fi 重启均衡 # 停止现有均衡 pkill -f "hdfs.*balancer" # 等待进程完全停止 sleep 5 # 重新启动均衡 nohup hdfs balancer -threshold 10 > /tmp/balancer.log 2>&1 & 3. 日志分析 均衡日志分析 # 统计移动的数据块数量 grep "Successfully moved" /tmp/hdfs_balancer.log | wc -l # 统计移动的数据量 grep "Successfully moved" /tmp/hdfs_balancer.log | \ awk '{sum += $NF} END {print "总移动数据量: " sum/1024/1024/1024 " GB"}' # 分析移动速度 grep "Successfully moved" /tmp/hdfs_balancer.log | \ awk '{print $1, $2, $NF}' | \ tail -100 | \ awk 'BEGIN{prev_time=""} { if(prev_time != "") { split($1" "$2, time_arr, ":") current_sec = time_arr[1]*3600 + time_arr[2]*60 + time_arr[3] split(prev_time, prev_arr, ":") prev_sec = prev_arr[1]*3600 + prev_arr[2]*60 + prev_arr[3] if(current_sec > prev_sec) { speed = $3 / (current_sec - prev_sec) print "移动速度: " speed/1024/1024 " MB/s" } } prev_time = $1" "$2 }' 故障排除 1. 常见问题 均衡进程无法启动 症状:执行均衡命令后立即退出 可能原因: ...

2024-05-01 · 10 分钟 · 2069 字 · heyaohua