Redsi常见问题

缓存在高平发和安全压力下的一些问题


缓存击穿

是某一个热点key在高并发访问的情况下,突然失效,导致大量的并发大金mysql数据库的情况


缓存穿透

是利用redis和mysql的机制(redis缓存一旦不存在,就访问mysql),直接让过缓存访问mysql,而制造的db请求压力

一般在代码中防止

解决: 为防止缓存穿透,将null或者空字符串设置给redis


缓存雪崩

缓存是采用了相同的过期时间,导致缓存在某一时刻同时全部失效,导致的db崩溃

解决:设计不同的缓存失效时间


如何解决缓存击穿的问题 ?

分布式锁

穿透:利用不存在的key去攻击mysql数据库

雪崩:缓存中的很多key失效,导致数据库负载过重宕机

击穿:在正常的访问情况下,如果缓存失效,如果保护mysql,重启缓存的过程

使用redis数据库的分布式锁,解决mysql的访问压力问题

第一种分布式锁:redis自带一个分布式锁,set px nx

用完之后需要删除,不然别人不能访问。

错误自旋代码(B为孤儿线程)

正确自旋代码

问题1 如果在redis中的锁已经过期了,然后锁过期的那个请求又执行完毕,回来删锁,删除了其他线程的锁,怎么办?

问题2 如果碰巧在查询redis锁还没删除的时候,正在网络传输时,锁过期了,怎么办?

  1. String script ="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
  2. jedis.eval(script, Collections.singletonList("lock"),Collections.singletonList(token));

第二种分布式锁:redisson框架,一个redis的带有juc的lock功能的客户端(既有jedis的功能,又有juc的功能)

整合

引入pom

  1. <!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
  2. <dependency>
  3. <groupId>org.redisson</groupId>
  4. <artifactId>redisson</artifactId>
  5. <version>3.10.5</version>
  6. </dependency>

配置

  1. spring.redis.host=192.168.159.130
  2. spring.redis.port=6379

配置类

  1. @Configuration
  2. public class GmallRedissonConfig {
  3. @Value("${spring.redis.host}")
  4. private String host;
  5. @Value("${spring.redis.port}")
  6. private String port;
  7. @Bean
  8. public RedissonClient redissonClient(){
  9. Config config = new Config();
  10. config.useSingleServer().setAddress("redis://"+host+":"+port);
  11. RedissonClient redisson = Redisson.create(config);
  12. return redisson;
  13. }
  14. }

Redisson实现了juc的lock锁,并且可以在分布式的redis环境下使用

添加gmall-redisson-text

把需要的依赖添加的pom上

配置application.properties

  1. # 服务端口
  2. server.port=8082
  3. # 日志级别
  4. logging.level.root=info

RedissonController

  1. package com.atguigu.gmallredisson.redissonTest;
  2. import com.atguigu.gmall.util.RedisUtil;
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.redisson.api.RLock;
  5. import org.redisson.api.RedissonClient;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.ResponseBody;
  10. import redis.clients.jedis.Jedis;
  11. @Controller
  12. public class RedissonController {
  13. @Autowired
  14. RedisUtil redisUtil;
  15. @Autowired
  16. RedissonClient redissonClient;
  17. @RequestMapping("testRedisson")
  18. @ResponseBody
  19. public String testRedisson(){
  20. Jedis jedis = redisUtil.getJedis();
  21. RLock lock = redissonClient.getLock("lock");// 声明锁
  22. lock.lock();//上锁
  23. try {
  24. String v = jedis.get("k");
  25. if (StringUtils.isBlank(v)) {
  26. v = "1";
  27. }
  28. System.out.println("->" + v);
  29. jedis.set("k", (Integer.parseInt(v) + 1) + "");
  30. }finally {
  31. jedis.close();
  32. lock.unlock();// 解锁
  33. }
  34. return "success";
  35. }
  36. }

设置非单例模式启动

点击取消单一示例

启动3个示例,端口分别为8080,8081,8082

配置nginx

下载安装apache测试工具(apache)

1 下载地址

https://www.apachehaus.com/cgi-bin/download.plx

2 安装即解压

3 修改apache服务的配置文件(服务器的根目录)

修改服务的根目录路径:

4 启动服务

查看443端口是否被占用

  1. D:\ap\Apache24\bin>netstat -ano | findstr "443"

没有被占用,启动httpd.exe

  1. D:\ap\Apache24\bin>httpd.exe

5 压测命令(另起cmd输入命令)

D:\apache24\bin>ab -c 200 -n 1000 http:nginx负载均衡/压力方法

测试:

  1. D:\ap\Apache24\bin>ab -c 100 -n 10000 http://www.der-matech.com.cn/

  1. public String testRedisson(){
  2. Jedis jedis = redisUtil.getJedis();
  3. RLock lock = redissonClient.getLock("lock");// 声明锁
  4. lock.lock();//上锁
  5. try {
  6. String v = jedis.get("k");
  7. if (StringUtils.isBlank(v)) {
  8. v = "1";
  9. }
  10. System.out.println("->" + v);
  11. jedis.set("k", (Integer.parseInt(v) + 1) + "");
  12. }finally {
  13. jedis.close();
  14. lock.unlock();// 解锁
  15. }
  16. return "success";
  17. }

Redsi缓存问题(穿透,击穿,雪崩)以及解决办法(分布式锁)【高并发问题】的更多相关文章

  1. 高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发)

    高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发) 一.总结 1.什么是负载均衡:当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能.那么,在服 ...

  2. php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结)

    php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结) 一.总结 从外到内解决网站大流量高并发问题---从提交一个url开始(从用户按下搜索栏回车键开始) url最开始会到d ...

  3. redis缓存雪崩、穿透、击穿概念及解决办法

    缓存雪崩 对于系统 A,假设每天高峰期每秒 5000 个请求,本来缓存在高峰期可以扛住每秒 4000 个请求,但是缓存机器意外发生了全盘宕机.缓存挂了,此时 1 秒 5000 个请求全部落数据库,数据 ...

  4. NoSQL & Redis 介绍、缓存穿透 & 击穿 & 雪崩

    1. NoSql 简介 2. Redis 简介 2.1 Redis 的起源 2.2 缓存过期 & 缓存淘汰 3. 缓存异常 1)缓存穿透 2)缓存击穿 3)缓存雪崩 4)总结 1. NoSQL ...

  5. Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了

    Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,有一个 ...

  6. REDIS 缓存的穿透,雪崩和热点key

    穿透 穿透:频繁查询一个不存在的数据,由于缓存不命中,每次都要查询持久层.从而失去缓存的意义. 解决办法:①用一个bitmap和n个hash函数做布隆过滤器过滤没有在缓存的键.   ②持久层查询不到就 ...

  7. SpringCache @Cacheable 在同一个类中调用方法,导致缓存不生效的问题及解决办法

    由于项目需要使用SpringCache来做一点缓存,但自己之前没有使用过(其实是没有听过)SpringCache,于是,必须先学习之. 在网上找到一篇文章,比较好,就先学习了,地址是: https:/ ...

  8. 【分布式缓存系列】集群环境下Redis分布式锁的正确姿势

    一.前言 在上一篇文章中,已经介绍了基于Redis实现分布式锁的正确姿势,但是上篇文章存在一定的缺陷——它加锁只作用在一个Redis节点上,如果通过sentinel保证高可用,如果master节点由于 ...

  9. Mysql错误: ERROR 1205: Lock wait timeout exceeded解决办法(MySQL锁表、事物锁表的处理方法)

    Java执行一个SQL查询未提交,遇到1205错误. java.lang.Exception: ### Error updating database.  Cause: java.sql.SQLExc ...

  10. 使用Redis分布式锁处理并发,解决超卖问题

    一.使用Apache ab模拟并发压测 1.压测工具介绍 $ ab -n 100 -c 100 http://www.baidu.com/ -n表示发出100个请求,-c模拟100个并发,相当是100 ...

随机推荐

  1. openssl rsa加密,解密以及X509证书的使用

    Openssl的相关使用 生成证书 生成证书见:使用 openssl 生成证书 代码实现 Cert.h #ifndef _CERT_H #define _CERT_H ///header files ...

  2. CodeForces 1236D(模拟)

    题意 https://vjudge.net/problem/CodeForces-1236D 最近,爱丽丝得到了一个新玩偶.它甚至可以走路! 爱丽丝为玩偶建造了一个迷宫,并想对其进行测试.迷宫具有n行 ...

  3. 线性回归——lasso回归和岭回归(ridge regression)

    目录 线性回归--最小二乘 Lasso回归和岭回归 为什么 lasso 更容易使部分权重变为 0 而 ridge 不行? References 线性回归很简单,用线性函数拟合数据,用 mean squ ...

  4. 多线程(六)多线程同步_SemaPhore信号量

    信号量依然是一种内核同步对象,它的作用在于控制共享资源的最大访问数量 例如:我们有一个服务器,为这服务器创建一个线程池,线程池有五个线程,每个线程处理1个请求.当五个线程都在处理请求时,这个线程池己到 ...

  5. 解决Django-Error: That port is already in use

    Error: That port is already in use. 1.使用python manage.py runserver 8001 开一个新的端口. 2.kill掉原来的端口(在root条 ...

  6. git报错_you are not allowed to push code to protected branches on this project

    问题描述 今天在提交代码的时候,由于使用的是新库,写完代码后,进行push,发现报错 you are not allowed to push code to protected branches on ...

  7. O2O 线下业务 和 线上业务,在特征工程上的差异

    人工智能在外卖送达时预估上的应用 这篇讲清楚了 O2O 线下业务 和 线上业务,在特征工程上的差异:

  8. 有缓存区的管道channel

    package main import ( "fmt" "time" ) func main() { //创建一个有缓存区的管道 ch := make(chan ...

  9. 【解决错误】Non-reversible reg-exp portion: '(?i'

    在将Django升级到2.1后,运行 Django 自带后台后,或 使用 redirect 方法,就一直报错:Non-reversible reg-exp portion: '(?i'. 错误一 Dj ...

  10. HTML连载32-背景颜色、背景图片、背景填充

    一.背景 1.如何设置标签的背景颜色 (1)在CSS中有一个background-color:属性值:,就是专门用来设置标签的背景颜色. (2)取值:具体单词.RGB.RGBA.十六进制 例子: &l ...