博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis如何批量失效key
阅读量:6573 次
发布时间:2019-06-24

本文共 2325 字,大约阅读时间需要 7 分钟。

Redis如何批量失效key

问题

Redis的del key命令只能删除指定key。如果要删除满足指定模式的key,则会比较麻烦。这里提供一个使用数据时间戳的方案来实现批量失效缓存

场景描述

最近在写一个好友关系模块,类似于微信的好友机制。其中有一个方法Friendship getFriendship(long userId, long targerId);是用于获取两个用户是否有权限聊天

/*只要有一个字段为true,则可以聊天*/class Friendship{    boolean isFriend; //用户是否添加对方为好友,a添加b为好友,但是b未必添加a为好友,场景与微信类型。    boolean isWhite; //如果有一方是白名单用户可以直接聊天}复制代码

由于该方法调用比较频繁,所以决定对该数据进行缓存。既然使用缓存就要清楚什么场景下需要添加缓存,什么场景下需要失效缓存

添加缓存

什么时候添加缓存是比较明显,当一个用户查询与另外一个用户的好友关系时加入缓存

Friendship getFriendship(long userId, long targerId){    String key = String.format("Friendship:%s_%s", userId, targerId);    Friendship friendship = redisServer.getObject(key, Friendship.class);    if(friendship == null){        friendship = queryFriendship(userId, targerId);        redisServer.setObject(key, friendship);    }    return friendship;}复制代码

失效缓存

失效缓存分为两部分

  • isFriendship 这部分是比较简单的,只要userId方删除了targerId方,则删除为Friendship:userId_targertId的key即可
  • isWhite 这部分稍微比较麻烦一点。因为这个当一个用户被添加/删除白名单时,那么所有包含该用户的key都需要删除。虽然redis提供了keys pattern的命令用于检索关键字,但这个命令并不适合在生产上使用。比如添加/删除了一个id为123的白名单用户,那么所有符合正则Friendship:123_\d+Friendship:\d+_123的键就都要失效

解决方案

其实失效缓存并不一定要删除redis数据,只要提供一个时间戳字段用于判断缓存的有效性即可。 由于白名单用户变动比较少,为了实现上的简单,这里采用失效所有好友关系缓存的方式。即删除所有符合正则Friendship:\d+_\d+的key。问题本质与删除指定用户的key一样

白名单用户变更

void updateWhitelist(long userId, int operate){    //update whitelist    //保存最近一次变更白名单数据的时间    String key = "UpdateWhitelist";    long timestamp = System.currentTimeMillis();    redisService.setLong(key, tiemstamp);}复制代码

Friendship类

class Friendship{    boolean isFriend;     boolean isWhite;    long timestamp; //缓存数据时的时间戳}复制代码

getFriendship 方法

Friendship getFriendship(long userId, long targerId){    //如果没有更新,默认返回0    long updateWhitelistTimestamp = redisServer.getLong("UpdateWhitelist", 0);    String key = String.format("Friendship:%s_%s", userId, targerId);    Friendship friendship = redisServer.getObject(key, Friendship.class);    //好友关系缓存不存在或者缓存时间小于白名单更新时间,则重新查询数据库    if(friendship == null         || friendship.getTimestamp() <= updateWhitelistTimestamp){        friendship = queryFriendship(userId, targerId);        friendship.setTimestamp(System.currentTimeMillis())        redisServer.setObject(key, friendship);    }    return friendship;}复制代码

这样当Redis缓存了两个用户好友关系数据后,有新的用户被添加进了报名单。后续的查询根据timestamp的比较就会让当前缓存失效从而获取新的数据

转载于:https://juejin.im/post/5b1e33dd6fb9a01e3d1f9ca2

你可能感兴趣的文章
【追光者系列】Hikari连接池大小多大合适?(第一弹)
查看>>
一次性搞懂JavaScript 执行机制
查看>>
程序员思维看爱情是什么?
查看>>
Awesome Go
查看>>
如何正确上传一张图片?
查看>>
Android基础 写给新手的Android环境配置
查看>>
界面无小事(六):来做个好看得侧拉菜单!
查看>>
Spring 数据处理框架的演变
查看>>
为什么要使用git pull --rebase?
查看>>
SpringBoot集成gRPC微服务工程搭建实践
查看>>
requestAnimationFrame用法
查看>>
iOS 蓝牙使用小结 bluetooth
查看>>
computed、watch和methods特性比较
查看>>
MySQL——优化ORDER BY语句
查看>>
iOS:重识Transform和frame
查看>>
spring boot / cloud (二十) 相同服务,发布不同版本,支撑并行的业务需求
查看>>
docker任务调度工具: ofelia
查看>>
分布式Redis深度历险-复制
查看>>
微服务架构下的轻量级定时任务解决方案
查看>>
java架构-Spring MVC 与 Servlet
查看>>