个人网站审批,网站首页被k 内页还有,可以悬赏做任务的叫什么网站,做网站沈阳一 redis-缓存中间件 什么是redis redis是c语言开发的#xff0c;一个高性能key-value键值对内存数据库#xff0c;可以用来做数据库、缓存、消息中间件的一种非关系型数据库。 redis数据存储在哪里 内存和磁盘中#xff0c;但是redis的读写都在内存中#xff0c;…一 redis-缓存中间件 什么是redis redis是c语言开发的一个高性能key-value键值对内存数据库可以用来做数据库、缓存、消息中间件的一种非关系型数据库。 redis数据存储在哪里 内存和磁盘中但是redis的读写都在内存中这也是速度快的原因之一。 对于高频繁访问的数据存储在内存中方便访问。 为了避免服务宕机或者重启数据丢失也可以将数据存储在磁盘中持久化。 redis的数据类型 String、set、zset、list、hash redis为什么响应速度快 1 基于内存存储redis的读写都是基于内存的key-value操作。内存远大于磁盘响应速度。 2 单线程操作避免了多线程cpu来回切换和各种加锁和解锁的资源消耗。 redis的单线程操作是指一个模块的操作单线程其他该多线程的还是使用多线程。 3丰富的数据结构 redis是基于key-velue键值对存储的缓存数据库对于key都是string类型但是vlue有多种数据类型 4高性能的多复用IO模型 为什么需要使用redis redis的响应速度快读10w写8w对于一些业务场景可以将计算的结果-菜单等存储到缓存中下次直接getfromredis redis怎么配置、步骤 1 pom文件加上依赖 org.springframework.boot spring-boot-starter-data-redis io.lettuce lettuce-core
2 配置文件加上redis服务器的host port user psw等信息 3使用springboot自动配置好的StringRedisTemplete工具来操作redis进行读写操作 Autowired StringRedisTemplete stringRedisTemplete; // 读 stringRedisTemplete.opsForValue.get(“keyName”) // 写 stringRedisTemplate.opsForValue().set(“keyName”, value, 1, TimeUnit.DAYS); // 设置过期时间 防止缓存数据与数据库不一致 redis怎么进行getset读写数据 使用StringRedisTemplete .get(“keyname”) /.set(“keyname”,“value”,“time”,“时间单位”) redis有哪些参数 key-String value-liststring、set、zset、hash 过期时间-过期删除重新sql获取set到缓存中与数据库数据保持一致 过期时间的单位 redis缓存容易出现的问题 1缓存穿透 reason: 大量并发请求一个不存在的数据到缓存中null之后大量请求到了数据库中数据库压力过大崩了。这种是缓存穿透。 way: 即使数据库中为null的数据也存储一个标识到缓存中并且设置一个过期时间。
2缓存雪崩 r大量不同业务模块的请求到缓存但是对应的数据同时过期了导致所有的请求到db-压力大。 w设置不同的过期时间可以在配置文件中统一配置因为不同业务key存储的时间不同过期点也不会相同。
3缓存击穿 r大量恶意请求到一个热点词刚好这个key过期了。db压力过大 w加锁-记得双重验证每次只允许一个请求进入db-get-db,其他没有进去锁的去访问缓存即可。 本地锁不是redis分布式锁加关键字Synchronized等 本地锁只能锁住同一个进程里面的线程如果是分布式下即使每个服务仅仅放一个线程进来相互是隔离的不能只锁住一个。这个时候需要分布式锁-redisson使用redis分布式锁-没有看门狗机制 redis怎么保证与数据库数据一致更新数据库 1双写模式 先更新数据库再去更新缓存对应的key这种缓存中可能会短暂出现脏数据稳定后缓存过期-重新读取db即可保证最新数据。 2失效模式 先写数据库后删除缓存。这种也可能短暂出现缓存有脏数据稳定后即可 无论是更新缓存还是删除缓存都会有脏数据解决如下1失效模式-使用双删模式 先删除缓存-更新db-隔几秒再去删除缓存 2使用MQ消息队列消费者监听queue消息去删除缓存 生产者更新db-MQ-queue有数据-customer监听到-删除缓存-告知queue是否删除成功失败queue再次发送。不需要写代码mq本身会重复出队。解耦修改数据库和查询数据库解耦不会造成缓存有脏数据
11.缓存锁使用的原则 正常数据缓存加上过期时间就可以实现数据一致性。 对于实时性要求高的最好是到数据库中读取。 对于频繁修改的数据不建议加读写锁性能会慢。
二 redisson-分布式锁 redisson是什么 redisson是基于redis的分布式框架提供了分布式锁等服务 为什么需要分布式锁 本地锁只能锁住当前进程-一个服务的线程所以需要分布式锁。 redission配置步骤 1pom文件加上依赖前提是有redis依赖 org.redisson redisson 3.12.0 2配置redis配置信息 redisson提供的分布式锁与redis自己的分布式锁区别 1redisson提供的分布式锁 -分布式下也只能有一个线程占用锁执行业务代码直至解锁下一个thread才能进来执行。 使用RedissonClient加锁—不会出现死锁----锁会自动过期 Autowried RedissonClient client; // 1. 获取锁mylock 只要锁的名字相同 就是同一把锁 RLock myLock redisson.getLock(“myLock”); // 2. 加锁 myLock.lock(); // 阻塞锁 // 业务代码 try { System.out.println(“加锁成功执行业务…” Thread.currentThread().getId()); Thread.sleep(3000); } catch (Exception e) { } finally { // 3. 解锁 // 即使业务代码执行失败或者断电没有解锁成功也不会出现死锁 // RedissonClient不会出现死锁 System.out.println(“释放锁” Thread.currentThread().getId()); myLock.unlock(); }
2redis提供的分布式锁 使用StringRedisTemplate加锁 Boolean lock stringRedisTemplate.opsForValue().setIfAbsent( “lockValue”, uuid, 5, TimeUnit.SECONDS);
3 redis-StringRedisTemplate分布式锁与redisson-RedissonClient 分布式锁区别。 区别在于 1.–redisson分布式锁有看门狗机制一个线程占用锁之后如果锁没有释放之前redisson会自动给锁续期10s检查一次锁是否释放续期time-30s不会过期直至线程结束锁释放。 2- -redis 的stringRedisTemplate分布式锁不会自动续期。 redisson加锁的业务代码只要完成就不会自动给锁续期即使不unlock锁默认在30s后自动删除。即使服务宕机-业务结束也不会出现死锁锁会自动过期。 读写锁相关 // 6.1 读写锁(可以获read-write) RReadWriteLock readWriteLock redissonClient.getReadWriteLock(“catalogJson-lock”); // 6.2 写锁 RLock wLock readWriteLock.writeLock(); // 6.3 读锁 RLock rLock lock.readLock(); 注意 1)一个读锁可以被多个thread线程占用不互斥。 2写锁与其他锁都互斥一次只能有一个线程占用锁其他写或者读必须等待。 分布式锁的几个参数 创建锁的过期时间时间单位redisson分布式锁默认是10s查看一次锁是否还在如果在自动延长30s前提是没有手动设置过期时间 redisson分布式锁的特点 1一次只能有一个进程的一个线程进来 2有看门狗机制redisson–自动续期30s业务未执行完其他锁进来造成数据紊乱 3自动过期-避免死锁什么是死锁加锁-执行业务-执行完解锁没有解锁业务代码出异常或者服务挂了锁就一直存在redis缓存数据库中-死锁 redisson看门狗机制给线程看门线程进去执行业务redisson看门 redisson-redissonClient提供的分布锁一旦某个线程进入到占了锁在业务代码没有执行完成释放锁之前redisson没10s会自动检测锁是否还在并续期30s。直至业务完成解锁不再自动续期。这种情况只针对没有手动配置过期时间的前提如果配置了则失效。 redission的可重入锁机制 Redisson 可重入锁是一种分布式锁它基于 Redis 实现。可重入指的是同一个线程在持有锁的情况下可以多次获取该锁而不会造成死锁。
三SpringCache-分布式缓存使用 springcache是什么 spring提供的一个缓存框架使用一些注解解决缓存的问题不需要关心底层代码逻辑如何实现 使用redis作为缓存工具cache使用步骤 1pom文件加上依赖 引入依赖 spring-boot-starter-cache spring-boot-starter-data-redis 2手动在配置文件加上缓存类型其他配置后面使用场景再说 spring.cache.typeredis 3开启缓存EnableCaching // 开启缓存加在对应Configuration类上面
3.springcache 主要的注解 1EnableCaching-开启缓存 2Cacheable 加上方法上面触发方法更新缓存如果缓存不是null则不存储db数据到缓存中 3CacheEvict更新数据库触发删除缓存对应的数据-失效模式 4CachePut更新数据库在不影响更新数据库的情况下更新缓存数据-双写模式。 springcache有哪些不足之处该缓存框架默认不加锁 1读模式Cacheable-读db-set-redis 只要涉及读db数据到redis缓存且不加锁的情况大并发就会暴露redis存储缺陷。 a. 缓存穿透-开启db空值也存到redis中 配置文件加 spring.cache.redis.cache-null-valuestrue b. 缓存雪崩-配置设置缓存的过期时间 spring.cache.redis.time-to-live600000 c. 缓存击穿-加锁 springCache默认是不加分布式锁的可以对应方法上 Cacheable注解上面加上sync “true”线程加锁-一次只允许一个线程占用锁访问db-避免热点击穿db。 Cacheable(value “category”, key “#root.method.name”, sync true) 2写模式 数据写模式对应的是更新数据势必涉及更新db与更新缓存两者存在数据一致性问题。 解决方法对于读多写少的数据直接使用springcache缓存即可key设置过期时间查询触发再次更新db数据到缓存redis中。
总结 redis-缓存中间件-暂时的非关系key-value键值对数据库StringRedisTemplate操作。 redisson-基于redis操作的数据库提供分布式锁解决分布式下操作redis缺陷。-使用redissonClient操作分布式锁单体不需要redisson本地锁就可以解决 springcache-spring提供的分布式缓存框架可以使用多种缓存中间件存储数据本文type是redis直接使用一些注解实现redis读-存储写-写/删数据。不需要再单独使用redis执行一些列繁琐的代码实现。