如何用Shell脚本加载数据到HBase表?求排查脚本问题
问题排查与修正方案
让我帮你梳理下这个HBase导入脚本里的几个关键错误,以及对应的修正方法:
核心错误点分析
错误1:无效的文件处理逻辑
你用awk把原文件的&替换成空格并输出到uid1.txt,但后续循环依然读取原文件$file,等于这步处理完全没生效。而且原文件每行是UID,ARTIST&ARTIST&ARTIST结构,awk用&做分割符的处理逻辑也不符合需求。错误2:艺术家列表提取方式完全错误
你用users=echo $line | cut -d'&' -f2``获取艺术家列表,这会导致严重问题:比如第一行U100,A300&A301&A302,用&做分隔符的话,-f2只会取到A301,而不是完整的A300&A301&A302部分。正确的逻辑应该是先按逗号拆分行,拿到第二部分后再处理&分隔的艺术家。错误3:频繁调用HBase Shell的低效操作
循环里每次执行echo "put..." | hbase shell会反复启动HBase Shell进程,不仅速度慢,还可能因为频繁交互出现异常。更合理的方式是把所有PUT命令写入临时文件,最后一次性执行。
修正后的完整脚本
# 创建HBase表(若不存在) echo "create 'uid-map', 'users'" | hbase shell file="/home/abc/lookupfiles/uid.txt" # 用于存储所有HBase命令的临时文件 temp_cmd_file="/home/abc/lookupfiles/hbase_put_cmds.txt" # 清空临时文件(避免残留旧命令) > "$temp_cmd_file" # 逐行处理原数据文件 while IFS= read -r line do # 按逗号拆分,分离UID和艺术家字符串 uid=$(echo "$line" | cut -d',' -f1) artist_list_str=$(echo "$line" | cut -d',' -f2) num=1 # 将艺术家字符串按&拆分成数组,遍历每个艺术家 IFS='&' read -ra artists <<< "$artist_list_str" for artist in "${artists[@]}" do # 把PUT命令写入临时文件 echo "put 'uid-map', '$uid', 'users:artist$num', '$artist'" >> "$temp_cmd_file" let "num=num+1" done done < "$file" # 一次性执行所有HBase命令,提升效率 hbase shell < "$temp_cmd_file" # 可选:执行完成后清理临时文件 # rm "$temp_cmd_file"
修正说明
- 先按逗号拆分每行数据,正确分离UID和艺术家列表;
- 用
IFS='&' read -ra将艺术家字符串转为数组,遍历更稳定可靠; - 所有PUT命令集中写入临时文件,最后一次性执行,大幅提升导入效率并减少异常风险;
- 移除了无用的
uid1.txt处理步骤,直接基于原文件完成逻辑。
内容的提问来源于stack exchange,提问作者R.Gold




