简介
Redis可以部署在数据库前端作为旁路缓存使用,业务在访问数据时,可以先访问Redis查询其中是否有自己需要的数据,这时候会有两种情况:
- 缓存命中: Redis中有对应数据,业务请求直接命中,查询性能得到提升
- 缓存缺失: Redis中没有对应数据,业务请求至后端数据库查询数据,性能相对变慢。同时,为了使后续请求能够在Redis中命中数据,需要将缺失的数据写入到Redis中,即缓存更新。
伪代码
代码语言:javascript复制 String cacheKey = “productid_11010003”;
String cacheValue = redisCache.get(cacheKey);
//缓存命中
if ( cacheValue != NULL)
return cacheValue;
//缓存缺失
else
cacheValue = getProductFromDB();
redisCache.put(cacheValue) //缓存更新
缓存类型
按照Redis是否接受写请求,可以分为只读缓存和读写缓存。
只读缓存
这种使用场景下,具体实现逻辑是这样的
- 业务写请求 所有写请求发往后端数据库,在DB中增删改数据,如果Redis中已经缓存了这部分数据,则需要将缓存数据删除。后续请求再次读取这些数据则会发生缓存缺失以及对应的缓存更新场景
- 业务读请求 读请求发往Redis,命中则直接返回,否则则对应缓存缺失和缓存更新场景
优点
数据库和缓存的数据可以保持完全一致,并且缓存中永远保留的是热点数据
缺点
每次写操作都需要将缓存中数据删除,之后请求会触发缓存缺失和缓存更新,访问延迟变大
读写缓存
- 同步直写
写请求同时发往Redis和数据库,两边都写成功后才返回。这种情况下由于数据库和REDIS的写性能差异性,所以缓存的性能优势就不存在了。
- 优点 被修改后的数据永远能命中缓存,这个过程拥有较好的性能
- 缺点 由于写数据库较慢,所以写缓存的优势不存在;另外高并发场景下,如果未对缓存数据做资源访问控制(lock),多个操作同时修改一个key的话,可能会导致缓存和数据库的数据不一致
- 先修改缓存,后修改数据库
- 优点 这种情况可以加速写请求
- 缺点 如果异步修改数据库时失败了,则缓存和数据库的数据不一致
适用场景
如果对于数据一致性有要求并且写请求较少,可以考虑使用只读缓存
如果对于缓存和数据库数据的一致性要求不高,并且非高并发场景,则可以考虑使用读写缓存。
参考
https://time.geekbang.org/column/article/293929