一、环境springBoot:
1)导入依赖:
文章图片
文章图片
org.springframework.boot spring-boot-starter-data-redis
依赖 2)配置文件 application.yml
文章图片
文章图片
spring: redis: host: 192.168.2.147 port: 6379 password: java1902 jedis: pool: max-active: 100
application.yml 二、redis作为数据库缓存:
原理:第一次查询使用sql数据库,查询完成后把数据存入redis用于后续查询,直到sql中的数据变化,清空相应的redis缓存,重新获取;
缓存失效:更新数据库,采用清空redis缓存的方式;
1)实体类:
文章图片
文章图片
public class Product implements Serializable { private Integer id; private String name; public Product() { }public Product(Integer id, String name) { this.id = id; this.name = name; }public Integer getId() { return id; }public void setId(Integer id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }@Override public String toString() { return "Product{" + "id=" + id + ", name='" + name + '\'' + '}'; } }
实体类 2)测试:
@RunWith(SpringRunner.class) @SpringBootTest public class RedistestSpringData2ApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test public void cacheTest() { List products = (List) redisTemplate.opsForValue().get("product:"); if (products == null) { System.out.println("查询数据库......"); // 模拟从数据库查询数据 products = new ArrayList(); products.add(new Product(1, "商品1")); products.add(new Product(2, "商品2")); redisTemplate.opsForValue().set("product:", products); } else { System.out.println("查询缓存......"); } }@Test public void delCacheTest() { redisTemplate.delete("product:"); }}
三、解决缓存穿透问题:
原因:一个线程在访问数据库信息后还未写入到缓存时丢失了时间片,其它线程访问时重复访问了数据库,造成数据库巨大压力;
解决:
1)synchronized来加锁:因为是分布式开发,synchronized的作用域是JVM,则在多个服务间synchronized是无效的;
2)Redis分布式锁:
1、在redis本地使用:
setnx Lock 1 //1 get Lock //1 setnx Lock 2 //00 del Lock setnx Locks 2 //1
2、springboot代码实现:
//try finally解决死锁问题:
@RunWith(SpringRunner.class) @SpringBootTest public class RedistestSpringData2ApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test public void multiThreadTest() throws InterruptedException { ExecutorService pool = new ThreadPoolExecutor(100, 200, 100, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(100)); for (int i = 0; i < 100; i++) { pool.submit(new Runnable() { @Override public void run() { cacheTest(); } }); } Thread.sleep(1000000); }@Test public void cacheTest() { List products = (List) redisTemplate.opsForValue().get("product:"); if (products == null) { Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent("product:lock", 1); if (ifAbsent) { try { System.out.println("查询数据库......"); // 模拟从数据库查询数据 products = new ArrayList(); products.add(new Product(1, "商品1")); products.add(new Product(2, "商品2")); int i = 10 / 0; redisTemplate.opsForValue().set("product:", products); } finally { redisTemplate.delete("product:lock"); } } else { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } cacheTest(); } } else { System.out.println("查询缓存......"); } }@Test public void delCacheTest() { redisTemplate.delete("product:"); } }
四、解决缓存击穿问题:
原因:重复查询为null时,每次都会重新访问数据库;
解决:查询到为null值时,返回一个空的对象给redis作为缓存,设置一定时间失效;
@RunWith(SpringRunner.class) @SpringBootTest public class RedistestSpringData2ApplicationTests { @Autowired private RedisTemplate redisTemplate; public Product productById(Integer id) { if (id > 10) { return null; } return new Product(); }@Test public void cachePenetrationTest() { for (int i = 11; i < 20; i++) { Product product = (Product) redisTemplate.opsForValue().get("product:" + i); if (product == null) { // 模拟从数据库查询数据 System.out.println("查询数据库......"); // 如果i大于10,type都是null product = productById(i); // 如果时null返回一个空 if (product == null) { product = new Product(i, ""); redisTemplate.opsForValue().set("product:" + i, product); redisTemplate.expire("product:" + i, 10, TimeUnit.MINUTES); } else { redisTemplate.opsForValue().set("product:" + i, product); redisTemplate.expire("product:" + i, 20, TimeUnit.MINUTES); } } else { System.out.println("查询缓存......"); } } }@Test public void delCacheTest() { redisTemplate.delete("product:"); } }
【数据库|Redis——作为sql数据库缓存】转载于:https://www.cnblogs.com/Tractors/p/11304252.html
推荐阅读
- Redis|Redis——Redis用作缓存(内存回收/穿透/击穿/雪崩)
- redis|Redis集群——分布式缓存
- redis|Redis——缓存雪崩、缓存击穿、缓存穿透
- 安卓源码探究|android源码学习-Handler机制及其六个核心点
- Java|idea 设置导航栏显示前进和后退返回键
- idea|idea前进和后退按钮如何显示
- idea|IDEA软件: 前进和后退添加到工具栏
- Java IDEA 编辑器代码前进后退快捷键
- intellij-idea|基于ssm购物商城系统含后台管理系统源码