关于Redis因OAuth 2.0内存溢出解决方案

一、背景介绍

1.问题简介

  本次问题是由OAuth 2.0授权框架(用于授权第三方应用程序【客户端】访问受保护的资源。)存储在Redis集群中的一个key引起的:client_id_to_access(或称为 “client ID to access”)通常是指在OAuth 2.0认证流程中,客户端(Client)使用的唯一标识符。导致溢出原因:当使用命名空间存储client_id_to_accessuname_to_access的列表数据时,整个键的过期时间会随列表数据的更新而刷新。这可能导致与同一clientIdusername相关的令牌过期后,键却没有被及时删除,从而导致内存溢出问题。简单来说TTL过期时间一直处于被无限重置状态从而是数据变成了变相的永久存储导致Redis内存溢出。

2.Redis相关信息

  Redis 采取的是三主三从集群模式,部署在k8s上采取了固定集群ip池的方案。集群详细信息如图:
关于Redis因OAuth 2.0内存溢出解决方案_第1张图片

二、发现&解决

1.发现

根据监控观察redis近1个月的内存使用情况如图:

关于Redis因OAuth 2.0内存溢出解决方案_第2张图片

可以看到Redis内存稳步增长至100%导致内存溢出系统崩溃

使用工具进行 内存分析 研究:

关于Redis因OAuth 2.0内存溢出解决方案_第3张图片
关于Redis因OAuth 2.0内存溢出解决方案_第4张图片

从图中看出client_id_to_access大小已经达到了1GB存储的个数也是上升到了近8W之多!

2.解决

修改Redis配置文件增加配置 notify-keyspace-events Ex,使其永久生效

关于Redis因OAuth 2.0内存溢出解决方案_第5张图片

连接服务端输入命令:config set notify-keyspace-events Ex,使其即刻生效

关于Redis因OAuth 2.0内存溢出解决方案_第6张图片

介绍:

Redis的notify-keyspace-events选项的 Ex参数:
该选项启用了对键过期事件的通知,使你能够在键过期时执行相应的操作。

  然后,在你的应用程序中,订阅Redis的键过期事件通知。你可以使用Redis的客户端库(如Jedis或Lettuce)订阅过期事件,并在事件触发时执行相应的操作,例如删除与过期键相关的数据或执行其他清理操作。

Jedis jedis = new Jedis("localhost");
JedisPubSub jedisPubSub = new JedisPubSub() {
    @Override
    public void onPMessage(String pattern, String channel, String message) {
        // 在这里处理过期键的事件
        System.out.println("键过期:" + message);
         
        // 执行相应的操作,如删除与过期键相关的数据
        // jedis.del("your_key");
    }
};
 
// 订阅过期事件,通配符匹配以 "__keyevent@*__:expired" 结尾的键
jedis.psubscribe(jedisPubSub, "__keyevent@*__:expired");

3.检验

关于Redis因OAuth 2.0内存溢出解决方案_第7张图片
关于Redis因OAuth 2.0内存溢出解决方案_第8张图片

三、结束语

  本次关于RedisOAuth 2.0内存溢出解决方案就到此结束了,后期会给大家带来更多的脚本,感谢认真读完,如果觉得还可以,那么给作者点赞、收藏、关注吧!

你可能感兴趣的:(redis,数据库,缓存)