数据库|Redis——作为sql数据库缓存

一、环境springBoot:
1)导入依赖:
数据库|Redis——作为sql数据库缓存
文章图片
数据库|Redis——作为sql数据库缓存
文章图片

org.springframework.boot spring-boot-starter-data-redis

依赖 2)配置文件 application.yml
数据库|Redis——作为sql数据库缓存
文章图片
数据库|Redis——作为sql数据库缓存
文章图片
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)实体类:
数据库|Redis——作为sql数据库缓存
文章图片
数据库|Redis——作为sql数据库缓存
文章图片
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

    推荐阅读