Redis-- as sql database cache

First, the environment springBoot:

  1) Import dependency:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
rely

  2) Profile application.yml

spring:
  redis:
    host: 192.168.2.147
    port: 6379
    password: java1902
    jedis:
      pool:
        max-active: 100
application.yml

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 + '\'' +
                '}';
    }
}
Entity class

  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:");
    }
}

 

Guess you like

Origin www.cnblogs.com/Tractors/p/11304252.html