阅读量:0
1. 通用代码
public SysUser getCache(String sysUserId) { String cacheKey = "litgery:warehouse:" + sysUserId; // 尝试从缓存中获取数据 CacheData cacheData = redisUtils.get(cacheKey); if (null != cacheData) { if (Boolean.TRUE.equals(cacheData.getExist())) { return cacheData.getSysUser(); } else { return null; } } // RedisLockClient 获取锁 RLock rLock = redisLockClient.getRLock("litgery:warehouse:lock"); try { // 尝试获取锁,如果锁已被其他线程持有,则等待 rLock.lock(); // 再次检查数据是否存在,因为可能在等待锁的过程中,其他线程已经填充了数据 cacheData = redisUtils.get(cacheKey); if (null != cacheData && Boolean.TRUE.equals(cacheData.getExist())) { return cacheData.getSysUser(); } //随机过期时间,随机生成0.5小时-1小时之内的时间(减少缓存同时失效的机会) Long expireTime = CacheUtils.getRandomExpireTimeInOneOrTowDay(); SysUser sysUser = sysUserService.getById(sysUserId); if (null == sysUser) { // 如果数据仍然不存在,从数据库中获取数据并填充缓存,避免不存在的数据一直请求打到数据库 CacheData emptyCache = new CacheData(); emptyCache.setExist(Boolean.FALSE); redisUtils.setEx(cacheKey, emptyCache, expireTime); return null; } CacheData cache = new CacheData(); cache.setSysUser(sysUser); cache.setExist(Boolean.TRUE); redisUtils.setEx(cacheKey, cache, expireTime); return sysUser; } finally { // 释放锁 rLock.unlock(); } }
redisUtils 为redis工具类,例如:设置缓存获取缓存等等。redisLockClient 为:RedisLockClient 的分布式锁
2.整体步骤
1. 获取缓存,若有值直接返回
2.获取一个分布式锁。
3. 加锁
4. 再次检查数据是否存在,因为可能在等待锁的过程中,其他线程已经填充了数据
5.从数据库获取。若为空,设置一个空值到redis。若不为空,直接返回,最好设置随机过期时间
6.释放锁
可优化的点,可添加布隆过滤器