前言

由于redis的keys命令是线上禁用,所以就有了SCANSSCANHSCANZSCAN四个命令。

但是这四个命令也不是每次返回全部匹配结果,因此需要一遍遍执行下去,而且每次返回的cursor要作为下一个的参数。

因此查找也不太方便,我写了一个简单的方法,用来查找scan的所有结果。关于这几个命令可以参考【详细解释

代码分享

package main

import (
"errors"
"flag"
"fmt"
"strings" "github.com/gomodule/redigo/redis"
) func main() {
addr := flag.String("addr", "redis://127.0.0.1:6379", "url")
cmd := flag.String("cmd", "SCAN", "SCAN or SSCAN or HSCAN or ZSCAN")
key := flag.String("key", "", "key")
match := flag.String("match", "", "MATCH pattern")
count := flag.Int("count", 10, "COUNT count")
max := flag.Int("max", 1000, "max count")
flag.Parse() err := scanHandle(*addr, *cmd, *key, *match, *count, *max)
if err != nil {
fmt.Println(err)
}
} func scanHandle(addr, cmd, key, match string, count, max int) error {
switch cmd = strings.ToUpper(cmd); cmd {
case "SCAN", "SSCAN", "HSCAN", "ZSCAN":
default:
return errors.New("cmd error")
} c, err := redis.DialURL(addr)
if err != nil {
return err
}
defer c.Close() var (
i = 0 // cursor下标位置
cursor = 0 // 默认从0开始
args = make([]interface{}, 0, 5)
) if cmd != "SCAN" {
if key == "" {
return errors.New(cmd + " must have key")
}
args = append(args, key)
i++
} args = append(args, cursor)
if match != "" {
args = append(args, "MATCH", match)
}
if count <= 0 {
count = 16
}
args = append(args, "COUNT", count) for {
args[i] = cursor
res, err := redis.Values(c.Do(cmd, args...))
if err != nil {
return err
} var tmp []string
_, err = redis.Scan(res, &cursor, &tmp)
if err != nil {
return err
} if lt := len(tmp); lt > 0 {
for _, v := range tmp {
// 打印结果
fmt.Println(v)
} if max -= lt; max <= 0 {
break
}
} if cursor == 0 {
break // 查询结束
}
}
return nil
}

总结

其实我们应该避免查找相关key,因为代码里面会保存相应的key,而且可以通过设置过期时间自动删除相关key。

不过redis提供了scan等方案,虽然可以达到效果,但是使用上是存在一点不方便的,总之应该尽量避免这些逻辑。

redis中使用SCAN代替KEYS的更多相关文章

  1. 在RedisTemplate中使用scan代替keys指令

    keys * 这个命令千万别在生产环境乱用.特别是数据庞大的情况下.因为Keys会引发Redis锁,并且增加Redis的CPU占用.很多公司的运维都是禁止了这个命令的 当需要扫描key,匹配出自己需要 ...

  2. Redis中的Scan命令踩坑记

    1 原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限.所以记录下这 ...

  3. Redis中的Scan命令的使用

    Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行 ...

  4. Redis 中的数据类型及基本操作

    Redis 内置的数据类型有 5种:字符串String.哈希Hash.列表List.集合Set.有序集合ZSet 字符串类型 String 是 Redis 中最基本的类型,一个 key 对应着一个 v ...

  5. redis中scan和keys的区别

    scan和keys的区别 redis的keys命令,通来在用来删除相关的key时使用,但这个命令有一个弊端,在redis拥有数百万及以上的keys的时候,会执行的比较慢,更为致命的是,这个命令会阻塞r ...

  6. redis 用scan 代替keys,hgetAll

    转载自:https://blog.csdn.net/w05980598/article/details/80264568 众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会 ...

  7. redis中keys命令带来的线上性能问题

    起因 下午接到运维反馈,生产redis有个执行keys的命令请求太慢了,要两三秒才能响应 涉及命令如下: KEYS ttl_600::findHeadFootData-15349232-*-head ...

  8. Redis解读(4):Redis中HyperLongLog、布隆过滤器、限流、Geo、及Scan等进阶应用

    Redis中的HyperLogLog 一般我们评估一个网站的访问量,有几个主要的参数: pv,Page View,网页的浏览量 uv,User View,访问的用户 一般来说,pv 或者 uv 的统计 ...

  9. 超大批量删除redis中无用key+配置

    目前线上一个单实例redis中无用的key太多,决定删除一部分. 1.删除指定用户的key,使用redis的pipeline 根据一定条件把需要删除的用户统计出来,放到一个表里面,表为 del_use ...

随机推荐

  1. python import 导入两个模块同时有同一名称的方法如何调用 ?

    from moudule import *(这种方法不推荐) 一般不推荐使用"from 模块 import"这种语法导入指定模块内的所有成员,因为它存在潜在的风险. 比如同时导入 ...

  2. Pytorch系列:(七)模型初始化

    为什么要进行初始化 首先假设有一个两层全连接网络,第一层的第一个节点值为 \(H_{11}= \sum_{i=0}^n X_i*W_{1i}\), 这个时候,方差为 \(D(H_{11}) = \su ...

  3. odoo12里面的RPC【远程过程调用】

    odoo的RPC有两种:RPC API:1.xml-rpc                                                      2.json-rpc 案例   x ...

  4. lwIP(Light Weight IP)协议

    信号量 信号量结构体:struct sys_semt struct _sys_sem { void *sem; };  err_t sys_sem_new(sys_sem_t *sem, u8_t c ...

  5. 又一本springmvc学习指南 之---第22篇 springmvc 加载.xml文件的bean标签的过程

    writedby 张艳涛,今天看spring mvc 学习指南的第2章,特意提下这个作者是how tomcat works 俩个作者之一, 喜欢上一本书的风格,使用案例来讲述原理, 在做第一个案例的时 ...

  6. lis分析之一一批处理(任务)如何连接数据库的

    public class ZFBCheckAccountTask extends TaskThread { } 这个类运行时候自动加载了数据库连接,不明白是如何提前加载的,开始用static { } ...

  7. Find-set-root-ignore-floppies-ignore-cd /bootmgr 解决办法(用win 7安装盘)

    出现标题此种现象,一般是mgr引导程序丢失有关,现在排除bootloader 选择是硬盘引导, 然后修改为cd盘引导,并重启,在win7安装程序启动后,选择修复系统. 打开相应的commnd,并执行如 ...

  8. C# MongoDB添加索引

    场景: 在最近的项目中,用到了Mongodb,用它来保存大量工业数据.同时是会根据用户自动建立对应的数据表.这要求同时建立索引来加快查询. 解决: 1.在Nuget包中查询"mongocsh ...

  9. 记录一次现网MySQL内存增长超限问题定位过程

    问题现象现网物理机内存近几日内爆涨使用率超过了90%,可用内存从250G,降低到20G以下,报告警.服务器使用情况来看,并没有什么异常.除了QPS缓慢增长外. MySQL内存分配结构 定位这个问题,先 ...

  10. 【LeetCode】209. 长度最小的子数组

    209. 长度最小的子数组 知识点:数组:前缀和:二分法:双指针:滑动窗口 题目描述 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小 ...