美文网首页
Redis 大Key使用遇到的问题

Redis 大Key使用遇到的问题

作者: 莫妮卡笔记 | 来源:发表于2020-12-03 22:01 被阅读0次
    timg.jpg

    A)故事背景

    创建 人群包,每一个用户访问系统时,需要判断用户是否存在 人群包中。
    场景条件1:人群包数量在10W~6亿数据不等(这个人群包数据大的情况下有50G左右了)。
    场景条件2:每次请求处理10毫秒(ms)以内。
    场景条件3:高峰每秒处理能力最大达到8W左右QPS。

    B)处理方案

    1、关系型数据库存储查询肯定是不能满足要求了。存储,查询性能都有问题,还容易影响别的业务。
    2、最终采用Redis的 SET 数据结构来实现。

    伪代码示例:

    存数据:

    jedisCluster.sadd(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
    

    验证数据:

    boolean flag = jedisCluster.sismember(redisKey, deviceId.toUpperCase());
    

    C)大Key存储带来的问题

    1、带来的问题1:redis 单Key是存储在固定槽位,也就是存储在集群中某个节点之中。由于单Key存储数据量比较大,随机到某个节点,一旦内存占满,【对外】直接影响其他业务对当前节点读写数据,【对内】集群之间的通信 同步数据 自然有问题,直接会影响整个集群运行。

    2、带来的问题2:在3.X的版本中,由于Redis是单线程 直接删除大Key 耗时较长,占用线程资源,影响其他业务使用,拖慢整体业务,在性能要求比较高的系统 是比较可怕的事件。

    D)解决方案

    1、拆解大Key,分片到不同节点存储。

    伪代码:

    String key ="data:clean:" + Math.abs(deviceId).hashCode()%10);
    

    这里是每个请求过来,根据时间用户唯一表示(deviceId) 随机1~10个 Key来存值,取值验证也是如此。

    2、对于大Key删除,把Redis升级到4.X 使用新特性 UNLINK 命令用于执行大KEY异步删除,Redis会创建一个独立的线程删除大Key ,与其他用户使用Redis互不干扰。

    相关文章

      网友评论

          本文标题:Redis 大Key使用遇到的问题

          本文链接:https://www.haomeiwen.com/subject/tbvvwktx.html