First, the environment springBoot:
1) Import dependency:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
2)
spring: redis: host: 192.168.2.147 port: 6379 password: java1902 jedis: pool: max-active: 100
Two, redis as a database cache:
How it works: The first query uses the sql database, after the completion of the inquiry into redis data for subsequent queries until the data changes in sql, empty the cache corresponding redis reacquire;
Cache invalidation: update the database, using empty the cache redis way;
1) entity classes:
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) test:
@RunWith(SpringRunner.class) @SpringBootTest public class RedistestSpringData2ApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test public void cacheTest() { List<Product> products = (List<Product>) redisTemplate.opsForValue().get("product:"); if (products == null) { System.out.println("查询数据库......"); // 模拟从数据库查询数据 products = new ArrayList<Product>(); 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:"); } }
Third, resolve cache penetrating question:
Lost time slices a thread after accessing database information has not been written to the cache, repeat visits other threads from accessing the database, the database caused tremendous pressure;: Reason
solve:
1) synchronized to lock: because it is distributed development, synchronized scope is JVM, then synchronized across multiple services is invalid;
2) Redis Distributed Lock:
1, redis local use:
setnx Lock 1 //1 get Lock //1 setnx Lock 2 //00 del Lock setnx Locks 2 //1
2, springboot code implementation:
// try finally resolve the deadlock problem:
@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<Product> products = (List<Product>) redisTemplate.opsForValue().get("product:"); if (products == null) { Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent("product:lock", 1); if (ifAbsent) { try { System.out.println ( "Database Query ......" ); // analog data from a database query Products = new new the ArrayList <Product> (); products.add ( new new Product (1, "product 1" )) ; products.add ( new new product (2, "product 2" )); int I = 10/0 ; redisTemplate.opsForValue () SET (. "product:" , Products); } the 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:"); } }
Fourth, to solve the problem of cache breakdown:
The reason: repeated query is null, each time re-access the database;
Solution: query the value is null, returns an empty object to the redis as a cache, set a certain time has expired;
@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 ) { // analog data from a database query System.out.println ( "Database Query ...... " ); // if i is greater than 10, type is null Product = productById (i); // if an empty or null when IF (Product == null ) { Product = new 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:"); } }