当前位置: 代码网 > it编程>前端脚本>Powershell > shell脚本批量导出redis key-value方式

shell脚本批量导出redis key-value方式

2025年08月02日 Powershell 我要评论
1 背景需求:工作中需要导出线上redis数据,但需避免使用keys命令全量扫描,导致瞬间响应卡顿,从而引发超时等问题方法:最安全的方式是通过dump.rdb备份文件,在本地redis实例上恢复,然后

1 背景

需求:工作中需要导出线上redis数据,但需避免使用keys命令全量扫描,导致瞬间响应卡顿,从而引发超时等问题

方法:最安全的方式是通过dump.rdb备份文件,在本地redis实例上恢复,然后执行shell脚本,使用scan渐进扫描批量导出key-value。

2 详细步骤

2.1 本地docker启动redis

本地通过docker-compose创建redis实例,并挂载配置文件和数据目录

  • docker-compose.yml
version: '3'
services:
  redis:
    image: redis
    container_name: redis
    restart: always
    command: redis-server /etc/redis/redis.conf
    ports:
      - 46379:6379
    environment:
      tz: asia/shanghai
      lang: en_us.utf-8
    volumes:
      - ./mnt/conf/redis.conf:/etc/redis/redis.conf:rw
      - ./mnt/data:/data:rw
  • 在宿主机创建配置文件

指定dump恢复目录及文件,和redis实例密码

mkdir -p ./mnt/conf
vim ./mnt/conf/redis.conf
requirepass gsef7nooih5r
dbfilename dump.rdb
dir /data
  • 将dump.rdb备份文件放在宿主机./mnt/conf/data下,启动redis
docker-compose up -d
  • 通过日志查看备份恢复进度
docker logs -f redis
  • 验证恢复情况
# 进入容器
docker exec -it redis bash

# 认证
auth gsef7nooih5r

# 查询key数量
dbsize

2.2 shell批量导出脚本

  • 进入容器
docker exec -it redis bash
  • 为便于后续操作,在容器安装vim(也可在宿主机挂载目录创建shell脚本)
# 换源并安装vim
sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list  \
    && apt update -y \
    && apt-get install -y vim

# 解决vim中文乱码
echo -e "syntax on \nset termencoding=utf-8 \nset encoding=utf8 \nset fileencodings=utf8,ucs-bom,gbk,cp936,gb2312,gb18030" >> ~/.vimrc
  • 创建shell脚本

使用的scan命令渐进遍历,相对于keys命令全量遍历速度慢些,但胜在安全,对redis的负载低。其中:

  • 可通过cnt参数设定迭代元素的数量来以控制redis负载
  • 获取value值时,通过interval调整redis-cli的执行间隔,来控制redis负载
vim redis_export.sh
#!/bin/bash
redis_host=localhost
redis_port=6379
redis_password=gsef7nooih5r
cnt=1000

key_name=vc_*
key_file=key_list.txt
value_file=value_list.txt
result_file=kv_result.txt
interval=0.01

redis-cli -h $redis_host -p $redis_port -a $redis_password scan 0 match "$key_name"  count $cnt 2>/dev/null> scan_tmp_result
new_cursor=`sed -n '1p' scan_tmp_result`
sed -n '2,$p' scan_tmp_result > $key_file

while [ $new_cursor -ne 0 ]
do
  redis-cli -h $redis_host -p $redis_port -a $redis_password scan $new_cursor match "$key_name" count $cnt 2>/dev/null> scan_tmp_result
  new_cursor=`sed -n '1p' scan_tmp_result`
  echo `cat $key_file |wc -l`
  sed -n '2,$p' scan_tmp_result >> $key_file
done
total=`cat $key_file |wc -l`
echo $total

> $value_file
i=0
for key in `cat $key_file`
do
    i=$(($i+1))
    if [[ ${i}%1000 -eq 0 || ${i} -eq $total ]]; then
	    echo "$i / $total"
    fi
    echo "get $key" | redis-cli $interval -h $redis_host -p $redis_port -a $redis_password 2>/dev/null >> $value_file
done
paste $key_file $value_file > $result_file
rm -f scan_tmp_result $value_file $key_file
  • 运行脚本
bash ./redis_export.sh

3 附录

记录下实践时的其它方法/功能:

  • scan扫描不指定游标,相比keys pattern模式不会长时间阻塞redis。(可通过-i调整执行间隔控制负载)
redis-cli  -a gsef7nooih5r --scan --pattern "vc_*">/tmp/redis.log
  • keys全量扫描(慎用)
echo "keys vc_*" | redis-cli -a gsef7nooih5r >/tmp/redis.log

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com