手机电脑网站建设短视频微信小程序+网站开发

当前位置: 首页 > news >正文

手机电脑网站建设短视频,微信小程序+网站开发,利用阿里云虚拟主机做网站,淘宝优惠券网站怎么做的Redis与本地缓存组合使用 前言 我们开发中经常用到Redis作为缓存#xff0c;将高频数据放在Redis中能够提高业务性能#xff0c;降低MySQL等关系型数据库压力#xff0c;甚至一些系统使用Redis进行数据持久化#xff0c;Redis松散的文档结构非常适合业务系统开发#xf…Redis与本地缓存组合使用 前言 我们开发中经常用到Redis作为缓存将高频数据放在Redis中能够提高业务性能降低MySQL等关系型数据库压力甚至一些系统使用Redis进行数据持久化Redis松散的文档结构非常适合业务系统开发在精确查询数据统计业务有着很大的优势。但是高频数据流处理系统中Redis的压力也会很大同时I/0开销才是耗时的主要原因这时候为了降低Redis读写压力我们可以用到本地缓存Guava为我们提供了优秀的本地缓存API包含了过期策略等等编码难度低个人非常推荐。 设计示例 Redis懒加载缓存 数据在新增到MySQL不进行缓存在精确查找进行缓存做到查询即缓存不查询不缓存 流程图 代码示例 // 伪代码示例 Xx代表你的的业务对象 如User Goods等等 public class XxLazyCache {Autowiredprivate RedisTemplateString, Xx redisTemplate;Autowiredprivate XxService xxService;// 你的业务service/*** 查询 通过查询缓存是否存在驱动缓存加载 建议在前置业务保证id对应数据是绝对存在于数据库中的/public Xx getXx(int id) {// 1.查询缓存里面有没有数据Xx xxCache getXxFromCache(id);if(xxCache ! null) {return xxCache;// 卫语句使代码更有利于阅读}// 2.查询数据库获取数据 我们假定到业务这一步传过来的id都在数据库中有对应数据Xx xx xxService.getXxById(id);// 3.设置缓存、这一步相当于Redis缓存懒加载下次再查询此id则会走缓存setXxFromCache(xx);return xx;}}/** 对xx数据进行修改或者删除操作 操作数据库成功后 删除缓存* 删除请求 - 删除数据库数据 删除缓存* 修改请求 - 更新数据库数据 删除缓存 下次在查询时候就会从数据库拉取新的数据到缓存中/public void deleteXxFromCache(long id) {String key Xx: xx.getId();redisTemplate.delete(key);}private void setXxFromCache(Xx xx) {String key Xx: xx.getId();redisTemplate.opsForValue().set(key, xx);}private Xx getXxFromCache(int id) {// 通过缓存前缀拼装唯一主键作为缓存Key 如Xxx信息 就是Xxx:idString key Xx: id;return redisTemplate.opsForValue().get(key);}} // 业务类 public class XxServie {Autowiredprivate XxLazyCache xxLazyCache;// 查询数据库public Xx getXxById(long id) {// 省略实现return xx;}public void updateXx(Xx xx) {// 更新MySQL数据 省略// 删除缓存xxLazyCache.deleteXxFromCache(xx.getId());}public void deleteXx(long id) {// 删除MySQL数据 省略// 删除缓存xxLazyCache.deleteXxFromCache(xx.getId());} } // 实体类 Data public class Xx {// 业务主键private Long id;// …省略 }优点 保证最小的缓存量满足精确查询业务避免冷数据占用宝贵的内存空间对增删改查业务入侵小、删除即同步可插拔对于老系统升级历史数据无需在启动时初始化缓存 缺点 数据量需可控在无限增长业务场景不适用在微服务场景不利于全局缓存应用 总结 空间最小化满足精确查询场景总数据量可控推荐使用微服务场景不适用 Redis结合本地缓存 微服务场景下多个微服务使用一个大缓存流数据业务下高频读取缓存对Redis压力很大我们使用本地缓存结合Redis缓存使用降低Redis压力同时本地缓存没有连接开销性能更优。 流程图 业务场景 在流处数处理过程中微服务对多个设备上传的数据进行处理每个设备有一个code,流数据的频率高在消息队列发送过程中使用分区发送我们需要为设备code生成对应的自增号用自增号对kafka中topic分区数进行取模这样如果有10000台设备自增号就是0~9999在取模后就进行分区发送就可以做到每个分区均匀分布。这个自增号我们使用redis的自增数生成生成后放到redis的hash结构进行缓存每次来一个设备我们就去这个hash缓存中取没有取到就使用自增数生成一个然后放到redis的hash缓存中这时候每个设备的自增数一经生成是不会再发生改变的我们就想到使用本地缓存进行优化避免高频的调用redis去获取降低redis压力。 代码示例 /** 此缓存演示如何结合redis自增数 hash 本地缓存使用进行设备自增数的生成、缓存、本地缓存* 本地缓存使用Guava Cache/ public class DeviceIncCache {/** 本地缓存/private CacheString, Integer localCache CacheBuilder.newBuilder().concurrencyLevel(16) // 并发级别.initialCapacity(1000) // 初始容量.maximumSize(10000) // 缓存最大长度.expireAfterAccess(1, TimeUnit.HOURS) // 缓存1小时没被使用就过期.build();Autowiredprivate RedisTemplateString, Integer redisTemplate;/** redis自增数缓存的key/private static final String DEVICE_INC_COUNT device_inc_count;/** redis设备编码对应自增数的hash缓存key/private static final String DEVICE_INC_VALUE device_inc_value;/** 获取设备自增数*/public int getInc(String deviceCode){// 1.从本地缓存获取Integer inc localCache.get(deviceCode);if(inc ! null) {return inc;}// 2.本地缓存未命中从redis的hash缓存获取inc (Integer)redisTemplate.opsForHash().get(DEVICE_INC_VALUE, deviceCode);// 3. redis的hash缓存中没有说明是新设备先为设备生成一个自增号if(inc null) {inc redisTemplate.opsForValue().increment(DEVICE_INC_COUNT).intValue;// 添加到redis hash缓存redisTemplate.opsForHash().put(DEVICE_INC_VALUE, deviceCode, inc);}// 4.添加到本地缓存localCache.put(deviceCode, inc);// 4.返回自增数return inc;}}优点 redis保证数据可持久本地缓存保证超高的读取性能微服务共用redis大缓存的场景能有效降低redis压力guava作为本地缓存提供了丰富的api过期策略最大容量保证服务内存可控冷数据不会长期占据内存空间服务重启导致的本地缓存清空不会影响业务进行微服务及分布式场景使用分布式情况下每个服务实例只会缓存自己接入的那一部分设备的自增号本地内存空间最优在示例业务中自增数满足了分布区发送的均匀分布需求也可以满足统计设备接入数目的业务场景一举两得 缺点 增加编码复杂度不直接只适用于缓存内容只增不改的场景 总结 本地缓存空间可控过期策略优适用于微服务及分布式场景缓存内容不能发生改变性能优