Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

批量操作相同前缀的键

假设相同前缀是 user_cache:

  • 查询相同前缀键

    • (不推荐)内部直接keys

      ./redis-cli
      
      keys user_cache:*
      
      • 缺点
        • 只能列出全部,数据量大时会卡顿
          • 采用遍历算法,复杂度为O(n)
        • 会阻塞线程
          • 由于redis单线程特性,其它指令都会被延后
    • (少量数据)外部直接scan

      ./redis-cli --raw --scan --pattern "user_cache:*" | wc -l
      
      • 此命令调用的是内部SCAN命令,不会阻塞线程
    • (大量数据)内部游标scan

      ./redis-cli
      
      scan 0 match user_cache:* count 1000
      
      • 参数
        • 第二个值是游标
          • 这里指示0代表开始一次新的迭代
          • 后面的迭代 要填 上一次返回结果的第一个整数值,继续进行
        • 最后一个值是 limit hint
          • 给一个遍历槽位数量的提示,并不是指要返回的具体数量,但越大,就返回越多
      • 优点
        • 控制了数量,同时不堵塞其他指令
  • 批量删除相同前缀键

    • (用于少量数据)一次性删除

      ./redis-cli -h 172.20.0.252 --scan --pattern "user_cache:*" | xargs ./redis-cli -h 172.20.0.252 del
      
      • 当数据较多时,可以给xargs加上参数-L 5000,指定一次命令最多删除5000个,自动执行多次命令
    • (不够优化、用于超大量数据)分多次导出,然后循环分批删除 + 休眠机制 

      • 先输出到文件夹内多个文件,会进行预处理使每行附带del
        mkdir user_cache && ./redis-cli --raw -h 172.20.0.252 --scan --pattern "user_cache:*" | awk -v count=5000 'BEGIN {i=1} { print "del " $0 > "./user_cache/user_cache_"i".log"; if (NR >= i*count) {close("./user_cache/user_cache_"i".log"); i++}}'
        
      • 然后2秒钟执行一次文件内的所有加了del的指令
        for file in `ls user_cache`; do cat ./user_cache/$file | ./redis-cli -h 172.20.0.252 && sleep 2; done 
        
    • (优化)用xargs改进cat,一次执行1条命令删5000个 总比 执行5000条命令好

      • 先输出到文件夹内多个文件,不用附带del
        mkdir user_cache && ./redis-cli --raw -h 172.20.0.252 --scan --pattern "user_cache:*" | awk -v count=500 'BEGIN {i=1} { print $0 > "./user_cache/user_cache_"i".log"; if (NR >= i*count) {close("./user_cache/user_cache_"i".log"); i++}}'
        
      • 然后每隔2秒钟,用xargs执行一次文件内的所有参数
        for file in `ls user_cache`; do cat ./user_cache/$file | xargs ./redis-cli -h 172.20.0.252 del && sleep 2; done 
        
  • 批量获取相同前缀键的值

    • 先输出到文件夹内多个文件,记得每行附带get

      mkdir user_cache && ./redis-cli --raw -h 172.20.0.252 --scan --pattern "user_cache:*" | awk -v count=5000 'BEGIN {i=1} { print "get " $0 > "./user_cache/user_cache_"i".log"; if (NR >= i*count) {close("./user_cache/user_cache_"i".log"); i++}}'
      
    • 然后2秒钟执行一次文件内的所有加了get的指令

      for file in `ls user_cache`; do cat ./user_cache/$file | ./redis-cli -h 172.20.0.252 >>result.log && sleep 2; done 
      
      • 会全部追加输出到result.log中