redis中使用SCAN代替KEYS
前言
由于redis的keys命令是线上禁用,所以就有了
SCAN、SSCAN、HSCAN和ZSCAN四个命令。
但是这四个命令也不是每次返回全部匹配结果,因此需要一遍遍执行下去,而且每次返回的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的更多相关文章
- 在RedisTemplate中使用scan代替keys指令
keys * 这个命令千万别在生产环境乱用.特别是数据庞大的情况下.因为Keys会引发Redis锁,并且增加Redis的CPU占用.很多公司的运维都是禁止了这个命令的 当需要扫描key,匹配出自己需要 ...
- Redis中的Scan命令踩坑记
1 原本以为自己对redis命令还蛮熟悉的,各种数据模型各种基于redis的骚操作.但是最近在使用redis的scan的命令式却踩了一个坑,顿时发觉自己原来对redis的游标理解的很有限.所以记录下这 ...
- Redis中的Scan命令的使用
Redis中有一个经典的问题,在巨大的数据量的情况下,做类似于查找符合某种规则的Key的信息,这里就有两种方式,一是keys命令,简单粗暴,由于Redis单线程这一特性,keys命令是以阻塞的方式执行 ...
- Redis 中的数据类型及基本操作
Redis 内置的数据类型有 5种:字符串String.哈希Hash.列表List.集合Set.有序集合ZSet 字符串类型 String 是 Redis 中最基本的类型,一个 key 对应着一个 v ...
- redis中scan和keys的区别
scan和keys的区别 redis的keys命令,通来在用来删除相关的key时使用,但这个命令有一个弊端,在redis拥有数百万及以上的keys的时候,会执行的比较慢,更为致命的是,这个命令会阻塞r ...
- redis 用scan 代替keys,hgetAll
转载自:https://blog.csdn.net/w05980598/article/details/80264568 众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会 ...
- redis中keys命令带来的线上性能问题
起因 下午接到运维反馈,生产redis有个执行keys的命令请求太慢了,要两三秒才能响应 涉及命令如下: KEYS ttl_600::findHeadFootData-15349232-*-head ...
- Redis解读(4):Redis中HyperLongLog、布隆过滤器、限流、Geo、及Scan等进阶应用
Redis中的HyperLogLog 一般我们评估一个网站的访问量,有几个主要的参数: pv,Page View,网页的浏览量 uv,User View,访问的用户 一般来说,pv 或者 uv 的统计 ...
- 超大批量删除redis中无用key+配置
目前线上一个单实例redis中无用的key太多,决定删除一部分. 1.删除指定用户的key,使用redis的pipeline 根据一定条件把需要删除的用户统计出来,放到一个表里面,表为 del_use ...
随机推荐
- linux驱动之LED驱动
通过之前的学习,了解到linux驱动编写的流程是:先通过注册函数注册我们编写的入口函数,然后在入口函数中获取设备号->注册字符设备->自动创建设备节点->获取设备树信息,最后通过销毁 ...
- Codeforces Round#704 Div2 题解(A,B,C,D,E)
FST ROUND !!1 A Three swimmers: 直接整除一下向上取整就好了: #include <bits/stdc++.h> using namespace std; t ...
- scrapy::Max retries exceeded with url
运行scrapy时出错这个错误:Max retries exceeded with url解决方法: img1=requests.get(url=aa,headers=header1,timeout= ...
- MQTT 4 ——MQTT的Spring Mvc 配置接收字节流数据
本篇记录一下MQTT整合Spring Mvc配置直接收发字节流数据 设备方是纯C开发,并且为了交互数据的安全,将传送的数据用了AES CBC进行了加密. 接下来正常方便做法应该是 将加密后的字节流转换 ...
- Appium和Python实现蚂蚁森林自动化收取能量
准备环境 Window10系统 Appium1.21.0 AndroidSDK r24.1.1 Python3.7.5 支付宝apk文件 查看支付宝apk包信息 使用android sdk aapt命 ...
- POJ1934 Trip 题解
LCS 模板,但要输出具体方案,这就很毒瘤了. 神奇的预处理:fa[i][j]表示在 \(a\) 串的前 \(i\) 个字符中,字母表第 \(j\) 个字母最晚出现的位置,fb[i][j]同理. 这样 ...
- java正则匹配字符串例子
import java.util.regex.Matcher;import java.util.regex.Pattern; public class sss { public static void ...
- QML用Instantiator动态创建顶级窗口
关键点 使用Model驱动Instantiator QML里面的hashmap: QQmlPropertyMap 上一次说到用 QQmlApplicationEngine 多次load的方式创建多个一 ...
- 【java基础】枚举
目录 枚举的定义 枚举的使用 原理 枚举的扩展 单例模式 避免反射攻击 反序列化 策略模式 总结 枚举的定义 public enum Color { Red,Blue,Green; } 枚举的使用 C ...
- JAVASE:01数据类型及其拓展
JAVASE:01数据类型及其拓展 八大基本数据类型 与c不同的地方:long类型后加L:float类型后加F: public class Demo02 { public static void ma ...