oa软件排行,windows7系统优化工具,东莞网推广网站建设,python做h5网站- 缓存的使用场景 系统查询性能较低#xff0c;且对数据实时性要求不高的
- 两种常见的缓存 本地缓存#xff1a; java中的Map、List 的确这种方式简单有效#xff0c;但是带来的弊端就是过于简单#xff0c;功能也就过于缺乏#xff0c;而且如果使用不当#xff0c;将带…- 缓存的使用场景 系统查询性能较低且对数据实时性要求不高的
- 两种常见的缓存 本地缓存 java中的Map、List 的确这种方式简单有效但是带来的弊端就是过于简单功能也就过于缺乏而且如果使用不当将带来可怕的内存溢出 java private static final MapK,V LOCAL_CACHE new ConcurrentHashMap(); 第三方中间件缓存redis等 。可以同时多台服务器依赖于同一个缓存实现数据的一致性
Redis缓存的常见问题 1. 缓存穿透访问不存在的key,导致请求打到了数据存储层 策略对空值也进行缓存使用布隆过滤器过滤掉不存在的key的请求 2. 缓存击穿热点key失效导致大量请求打到了数据存储层 策略热点key永不过期 3.缓存雪崩短时间内大量缓存过期导致大量请求打到了数据存储层 策略避免key过期时间一致 使用互斥锁在缓存失效时可以使用互斥锁来控制对数据库的访问确保只有一个请求可以去数据库加载数据并重建缓存其他请求等待缓存重建完成后再进行访问。
- 缓存不一致问题 更新缓存与更新数据库不是一个原子操作
常见真实场景: (1)代码先执行更新缓存操作成功后执行更新数据库操作失败了。 (2)同时有两个进程在交替执行更新缓存更新数据库的操作可能最终结果缓存是A进程更新的值数据库是B进程更新的值。
解决策略 使用分布式锁保证不同进程的操作顺序 采用延迟双删策略 首次删除缓存当有数据更新时首先删除Redis中对应的缓存数据。这是为了确保后续的读操作不会读取到旧的缓存数据。 更新数据库紧接着更新数据库中的数据以确保所有持久化存储的数据都是最新的。 延时等待在更新数据库后不立即进行第二次删除操作而是等待一段时间通常是几百毫秒。这个延时是为了确保数据库的更新操作能够完成。如果在数据库更新完成之前就进行第二次删除可能会导致在这段时间内有请求访问到过期的数据。 再次删除缓存延时结束后再次删除Redis中的缓存数据。这次删除是为了处理在第一次删除和更新数据库之间可能已经读取了旧数据的请求。这些请求可能在第一次删除后仍然持有旧数据通过第二次删除可以确保这些请求在下一次访问时会去数据库中获取最新的数据。 需要注意的是延时双删策略并不是强一致性保证它只能减轻数据不一致的问题但无法完全避免。此外对于经常修改的数据表不建议使用Redis作为缓存因为频繁的更新操作会增加维护缓存的复杂性和成本。
不同服务器结点的缓存数据不一致本地缓存 本地缓存更新时只更新到了处理该请求的服务节点其他结点的缓存没有更新。 常见解决方案发送更新请求到mq,广播更新缓存
应用热搜使用了redis缓存中的zset
伙伴匹配系统中使用redis的GEO实现搜索附近用户功能 在 User (用户) 表中添加两个字段 longitude (经度)和 dimension (维度)用以存储用户的经纬度坐标。因为Redis GEO 通过每个用户的经纬度坐标计算用户间的距离同时其 Redis 数据结构为ZSETZSET 是一个有序的 List 类似 Java 的 SortedSet。在此场景 value 就是用户idscore 是经纬度信息 ( ZSET 根据 score值升序排序) 。
Test
public void importUserGEOByRedis(){ListUser userList userService.list0; // 查询所有用户String key RedisConstant.USER GEO KEY // Redis的keyListRedisGeoCommands.GeoLocationString locationList new ArrayList(userList.size(); // 初始化地址(经纬度) for (User user : userList) locationList.add(new RedisGeoCommands.GeoLocationString.value0f(user.getId0), new Point (user.getLongitude(),user.getDimension0))); // 往locationList添加每个用户的经纬度数stringRedisTemplate.opsForGeo .add(keylocationList); // 将每个用户的经纬度信息写入Redis中
}