请大佬指点一下, redis 模糊匹配 key 查询缓慢问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yoloMiss
V2EX    Redis

请大佬指点一下, rdis 模糊匹配 key 查询缓慢问题

  •  
  •   yoloMiss 2022-03-28 23:27:45 +08:00 3954 次点击
    这是一个创建于 1356 天前的主题,其中的信息可能已经有所发展或是发生改变。

    起因--->最近接手的项目,有个需求需要通过 redis 做数据缓存,需要缓存当天和昨天的共二十几万条左右的数据。

    问题--->起初项目刚开始跑的时候没问题,过了一段时间后发现前端拿不到 redis 的数据了,排查程序日志发现全部请求超时了;遂排查 redis 是否有问题;发现 redis 占用 cpu 百分之百。通过 slowlog 排查发现所有占用 redis 的命令都是 keys 123* 做的数据查询。

    尝试解决--->替换 keys 命令匹配,使用 scan 进行扫描;并通过程序 log 观察匹配占用时间;发现 cup 占用率下来了,但是 scan 命令扫描比 keys 命令的扫描时间还要长。

    请问各位大佬该怎么解决这个问题。

    19 条回复    2022-07-07 00:59:36 +08:00
    Jooooooooo
        1
    Jooooooooo  
       2022-03-28 23:36:34 +08:00
    分成多个 key 然后并行去查这些 key.
    crysislinux
        2
    crysislinux  
       2022-03-28 23:38:54 +08:00 via Android
    改变实现逻辑去掉 keys 调用。谁在 production 用 keys 谁挨打。楼上说的并行没用
    cweijan
        3
    cweijan  
       2022-03-28 23:43:04 +08:00
    你总不会一下子获取 20 万条数据吧, 拿一部分数据就行了
    ch2
        4
    ch2  
       2022-03-28 23:52:41 +08:00
    戒掉"我要用 keys 做模糊查询"这个想法
    用更复杂的机制间接实现你的想法
    zakokun
        5
    zakokun  
       2022-03-28 23:59:15 +08:00
    1. 绝对禁止使用 keys
    2. 写入 key 的时候记录下 key 名,然后在获取的时候,通过记录的 key 名,使用 MGET key1 key2 key3... 获取
    zakokun
        6
    zakokun  
       2022-03-29 00:07:39 +08:00
    @zakokun 当然这里 MGET 分批去获取,比如一次 1000 个 key 。或者使用 redis 的 pipline
    rockyliang
        7
    rockyliang  
       2022-03-29 00:07:45 +08:00
    1 )并发量不高的话改为用 MySQL 存储,只要建立好索引,像 123*这种模式的匹配,十几二十万的数据量完全撑得住
    2 )上 ElasticSearch
    GeruzoniAnsasu
        8
    GeruzoniAnsasu  
       2022-03-29 01:37:07 +08:00   1
    随手一搜: https://www.cnblogs.com/yinkw/p/redis_keys.html

    在 kv db 里全文扫描是否搞错了什么? 这样还不如 sqlite :memory: 呢
    night98
        9
    night98  
       2022-03-29 01:42:37 +08:00
    1.为啥会有这种需求?
    2. 能不能在数据生成的时候基于需求扔到对应 list 里去,比如 123* 的 string 放到 123 的 list 里面
    3. 换其他服务处理,比如 es ,数据量不大直接 mysql
    CEBBCAT
        10
    CEBBCAT  
       2022-03-29 01:47:55 +08:00
    zhs227
        11
    zhs227  
       2022-03-29 08:24:22 +08:00
    产生环境使用 keys 会导致灾难性后果。
    james2013
        12
    james2013  
       2022-03-29 09:10:58 +08:00
    1.使用 mysql 建 1 张新表,这个表只保存当天和昨天的数据
    2.将查询结果根据查询条件进行短时间缓存
    zmal
        13
    zmal  
       2022-03-29 09:17:06 +08:00
    怎么敢在生产环境用 keys ,要丢饭碗的啊
    zmal
        14
    zmal  
       2022-03-29 09:20:46 +08:00
    redis 内部是一个伪单线程实现,一个 keys 会阻塞后面所有的查询,导致全部超时。
    raptor
        15
    raptor  
       2022-03-29 09:53:23 +08:00
    模糊查询请使用 ES 集群,redis 不是这样用的
    sadfQED2
        16
    sadfQED2  
       2022-03-29 11:45:36 +08:00 via Android
    生产环境直接禁用 keys 命令,谁服务挂了就喷谁
    earneet
        17
    earneet  
       2022-03-29 12:21:41 +08:00
    对 key 维护一个字典树,需要模糊的时候先从字典树里找到具体的 key ,再去查
    DarkFaith
        18
    DarkFaith  
       2022-03-29 15:45:52 +08:00
    keys 的实现可以粗略的理解为遍历全部键,找到所有匹配的键然后全部返回。
    scan 的实现可以粗略的理解为分批次遍历,遍历完一部分后立即返回,然后开始下一次遍历。

    遍历是 O(n)的,也就是随着键的增多,消耗的时间是线性增加的。

    这个时候需要更高效的查询方法。

    需要分析存储的键是否可以 Hash ,如果可以 hash ,则可以使用 hash map 来存储数据。如果键是需要范围查询的,比如 top_n ,比如时间等等,可以采用 zset 来存储。
    erquiasz0825
        19
    erquiasz0825  
       2022-07-07 00:59:36 +08:00
    scan 难道不耗费 cpu 吗,可能就 100% 了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     902 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 23:03 PVG 07:03 LAX 15:03 JFK 18:03
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86