批量导入千万数据到Redis集群处理方案,shell脚本处理(使用pipe处理)

本文介绍了一种从Hive查询数据并使用Shell脚本将数据导入Redis的方法。通过解析Redis集群信息,动态确定数据槽(slot),并针对每个槽执行Hive查询,将结果转换为Redis命令格式,最后批量导入指定的Redis实例。此过程优化了数据迁移效率,适用于大规模数据处理场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从hive查询数据,使用shell脚本导入到Redis。

样例如下:

#!/bin/bash
/usr/local/bin/redis-cli -h 172.28.xx.xx -a xxxxx cluster nodes | grep master > info.txt
sed -i 's/@/:/g' info.txt
sed -i 's/-/:/g' info.txt
info=`cat info.txt | awk '{print $2":"$9}' | awk -F ':' '{print $1" "$2" "$4" "$5}'`
array=(${info// / })
len=${#array}
cnt=`expr $len / 4`
for((i=0;i<$cnt;i++));
 do
  a=`expr $i \* 4`
  b=`expr $a + 1`
  c=`expr $a + 2`
  d=`expr $a + 3`
  ip=${array[$a]}
  port=${array[$b]}
  slot1=${array[$c]}
  slot2=${array[$d]}
  hive -e "select concat('*3\n','$','3\n','set\n','$',length(key),'\n',key,'\n','$',length(value),'\n',value) from (select concat('key1:phone:', user_id) as key, concat('\"', pro_id,'\"') as value from dbName.table_name where crc16(concat('key1:phone:', user_id)) >= $slot1 and crc16(concat('key1:phone:', user_id)) <= $slot2)t;" | grep -v "^WARN" > $slot1"_"$slot2".data"
  unix2dos $slot1"_"$slot2".data"
  cat $slot1"_"$slot2".data" | /usr/local/bin/redis-cli -h $ip -p $port -a xxxxx--pipe
 done

改进版如下:

#!/bin/bash

cd /home/abc
param_date=`date -d '-2 days' +%Y%m%d`
/apprun/redis.20200206/bin/redis-cli -h 172.26.xxx.xx -a pwdpwd cluster nodes | grep master > info.txt
sed -i 's/@/:/g' info.txt
sed -i 's/-/:/g' info.txt
info=`cat info.txt | awk '{print $2":"$9}' | awk -F ':' '{print $1" "$2" "$4" "$5}'`
array=(${info// / })
len=${#array}
cnt=`expr $len / 4`
cd res
crc_slot=`hive -e "select crc16('recommend:hot:list');" | grep -v "WARN"`
for((i=0;i<$cnt;i++));
  do
    a=`expr $i \* 4`
    b=`expr $a + 1`
    c=`expr $a + 2`
    d=`expr $a + 3`
    ip=${array[$a]}
    port=${array[$b]}
    slot1=${array[$c]}
    slot2=${array[$d]}
    if (($crc_slot>=$slot1)) && (($crc_slot<=$slot2));then
      hive -e "
      set hive.execution.engine=mr;
      select concat('*3\n', '$', '3\n', 'set\n', '$', length(key), '\n', key, '\n', '$', length(value), '\n', value) from
      (select concat('recommend:hot:list') as key, concat('\"', concat_ws(',', collect_set(prod_id)), '\"') as value from
      (select * from abc_db.t_tbl_prodhot_score where dayid=${param_date} order by hot_score desc limit 300)t1)t;"  | grep -v "WARN" > hot.data
      unix2dos hot.data
      cat "related_"$slot1"_"$slot2.data | /usr/local/bin/redis-cli -h $ip -p $port -a xxxxxxx --pipe
    fi
  done

### 如何使用 Redis 批量执行 SET 命令 #### 使用 Pipeline 实现批量设置键值对 为了提高性能并减少网络往返次数,可以采用 `PIPELINE` 来一次性发送多条命令给 Redis 服务端。这种方式不仅能够显著提升效率,而且还能保持较好的响应速度。 ```python import redis r = redis.Redis(host='localhost', port=6379, db=0) with r.pipeline() as pipe: keys_values = [ ('key1', 'value1'), ('key2', 'value2'), ('key3', 'value3') ] for key, value in keys_values: pipe.set(key, value) response = pipe.execute() ``` 此 Python 脚本展示了如何通过 `pipeline()` 方法构建一个管道对象,在其中连续调用多次 `SET` 操作,并最终通过一次性的 `execute()` 提交所有指令到服务器[^1]。 #### 利用 Shell Script 和 Cat 命令进行批量设置 对于不需要编程的情况,可以直接利用 Linux 的 shell script 结合 cat 命令向 Redis 发送一系列预定义好的命令字符串: 创建包含要执行的命令列表文件(例如名为 commands.txt),其内容如下所示: ``` set user:1000:name Alice set user:1000:age 25 set product:sku123:title "Wireless Mouse" ... ``` 接着可以通过以下方式快速应用这些配置: ```bash cat commands.txt | redis-cli --pipe ``` 这行命令将会读取文本文件并将每行当作独立的 Redis 请求发出,从而完成批量数据写入工作[^3]。 #### 处理 Redis 集群环境下的批量设置 当面对的是 Redis Cluster 架构时,则需要注意命令分发机制可能会因为哈希槽位分布而有所不同。如果尝试在一个节点上直接执行涉及不同分区的数据修改操作,那么很可能会遇到错误提示。因此建议要么确保所有的 KEY 属于同一个 slot,要么分别针对各个 master node 上实施相应的更新动作[^5]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值