边缘缓存模式(Cache-Aside Pattern)
1 模式
- 先从缓存查询数据
- 如果没有命中缓存则从数据存储查询
- 将从数据写入缓存
public async Task<MyEntity> GetMyEntityAsync(int id) { // Define a unique key for this method and its parameters. var key = string.Format("StoreWithCache_GetAsync_{0}", id); var expiration = TimeSpan.FromMinutes(3); bool cacheException = false; try { // Try to get the entity from the cache. var cacheItem = cache.GetCacheItem(key); if (cacheItem != null) { return cacheItem.Value as MyEntity; } } catch (DataCacheException) { // If there is a cache related issue, raise an exception // and avoid using the cache for the rest of the call. cacheException = true; } // If there is a cache miss, get the entity from the original store and cache it. // Code has been omitted because it is data store dependent. var entity = ...; if (!cacheException) { try { // Avoid caching a null value. if (entity != null) { // Put the item in the cache with a custom expiration time that // depends on how critical it might be to have stale data. cache.Put(key, entity, timeout: expiration); } } catch (DataCacheException) { // If there is a cache related issue, ignore it // and just return the entity. } } return entity; } public async Task UpdateEntityAsync(MyEntity entity) { // Update the object in the original data store await this.store.UpdateEntityAsync(entity).ConfigureAwait(false); // Get the correct key for the cached object. var key = this.GetAsyncCacheKey(entity.Id); // Then, invalidate the current cache object this.cache.Remove(key); } private string GetAsyncCacheKey(int objectId) { return string.Format("StoreWithCache_GetAsync_{0}", objectId); }
2 关注点
2.1 缓存数据的选择
2.2 缓存数据的生命周期
2.3 缓存过期策略的选择
2.4 本地缓存与分布式缓存的选择
2.5 一致性问题
3 一致性
3.1 淘汰还是更新缓存
3.2 操作顺序
3.3 一致性问题
非并发场景——场景为Application修改数据(考虑操作失败的影响)
先操作缓存,再操作数据存储
并发场景——场景位Application1修改数据,Application2读取数据,(不考虑操作失败的影响,仅考虑执行顺序的影响)
4 缓存穿透、缓存击穿、缓存雪崩
4.1 缓存穿透
-
- 增加数据校验
- 查询不到时,缓存空对象
4.2 缓存击穿
-
- 使用二级缓存
- 通过加锁或者队列降低查询数据库存储的并发数量
- 考虑延长部分数据是过期时间,或者设置为永不过期
4.3 缓存雪崩
-
- 使用二级缓存
- 通过加锁或者队列降低查询数据库存储的并发数量
- 根据数据的变化频率,设置不同的过期时间,避免在同一时间大量失效
- 考虑延长部分数据是过期时间,或者设置为永不过期
总之,设计不能脱离具体需求和业务场景而存在,这里没有最优的组合方式,以上对该模式涉及问题的讨论,旨在发掘潜在的问题,以便合理应对。