Example of Redis cache + Spring Integration

Source: Internet
Author: User
Tags install redis redis server


《Integration of Spring 4 (including MVC, Context, ORM) + MyBatis 3 ExampleArticle briefly introduces the latest version of the Spring MVC, IOC, MyBatis ORM integration and declarative transaction processing. Now we need to integrate the cache, and we're using Redis, and this article will cover the integration of Redis cache + Spring on the basis of this example. For more information on Redis server construction, please refer to the blogRedhat5.8 install Redis and register it as a system service under the environment》。
1. Dependent package installation Pom.xml join:
 
 
<!-- redis cache related.....start -->  
<dependency>  
    <groupId>org.springframework.data</groupId>  
    <artifactId>spring-data-redis</artifactId>  
    <version>1.6.0.RELEASE</version>  
</dependency>  
<dependency>  
    <groupId>redis.clients</groupId>  
    <artifactId>jedis</artifactId>  
    <version>2.7.3</version>  
</dependency>  
<!-- redis cache related.....end -->  
2. Spring project integration into cache support to enable caching support, we need to create a new CacheManager Bean.CacheManager InterfaceThere are many implementations, and this article demonstrates the integration with Redis, which is naturally rediscachemanager. Redis is not an app's shared memory, it's just a memory server, like MYSQL, we need to connect the app to it and interact with some kind of "language," so we also need a connection factory and a redistemplate for the Spring and Redis conversations, These are the necessary configurations for the Redis cache and put them all in a custom cachingconfigurersupport:
 
/** 
 * File Name:RedisCacheConfig.java 
 * 
 * Copyright Defonds Corporation 2015  
 * All Rights Reserved 
 * 
 */  
package com.defonds.bdp.cache.redis;  
  
import org.springframework.cache.CacheManager;  
import org.springframework.cache.annotation.CachingConfigurerSupport;  
import org.springframework.cache.annotation.EnableCaching;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.data.redis.cache.RedisCacheManager;  
import org.springframework.data.redis.connection.RedisConnectionFactory;  
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;  
import org.springframework.data.redis.core.RedisTemplate;  
  
/** 
 *  
 * Project Name:bdp  
 * Type Name:RedisCacheConfig  
 * Type Description: 
 *  Author:Defonds 
 * Create Date:2015-09-21 
 *  
 * @version 
 *  
 */  
@Configuration  
@EnableCaching  
public class RedisCacheConfig extends CachingConfigurerSupport {  
  
    @Bean  
    public JedisConnectionFactory redisConnectionFactory() {  
        JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();  
  
        // Defaults  
        redisConnectionFactory.setHostName("192.168.1.166");  
        redisConnectionFactory.setPort(6379);  
        return redisConnectionFactory;  
    }  
  
    @Bean  
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory cf) {  
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();  
        redisTemplate.setConnectionFactory(cf);  
        return redisTemplate;  
    }  
  
    @Bean  
    public CacheManager cacheManager(RedisTemplate redisTemplate) {  
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);  
  
        // Number of seconds before expiration. Defaults to unlimited (0)  
        cacheManager.setDefaultExpiration(3000); // Sets the default expire time (in seconds)  
        return cacheManager;  
    }  
      
}  
Of course, don't forget to inject these beans into Spring, otherwise the configuration will be invalid. Add the following to the Applicationcontext.xml:
 
<context:component-scan base-package="com.defonds.bdp.cache.redis" /> 

3. Caching the execution results of some methods after setting the cache configuration we can use @Cacheable annotations to cache the results of the method execution, such as retrieving the city's Provincecities method according to the province name and retrieving the city's searchcity according to the City_code Method:
 
// R  
@Cacheable("provinceCities")  
public List<City> provinceCities(String province) {  
    logger.debug("province=" + province);  
    return this.cityMapper.provinceCities(province);  
}  
  
// R  
@Cacheable("searchCity")  
public City searchCity(String city_code){  
    logger.debug("city_code=" + city_code);  
    return this.cityMapper.searchCity(city_code);     
}  
4. Cache data consistency guarantees that the CRUD (create creation, Retrieve read, update, delete delete) operation, in addition to the power of R, the other three can cause cache results and database inconsistencies. In order to ensure the consistency of the cached data, we need to update or clear the cache that may be affected when the CUD operation is performed.
 
// C  
@CacheEvict(value = { "provinceCities"}, allEntries = true)  
public void insertCity(String city_code, String city_jb,   
        String province_code, String city_name,  
        String city, String province) {  
    City cityBean = new City();  
    cityBean.setCityCode(city_code);  
    cityBean.setCityJb(city_jb);  
    cityBean.setProvinceCode(province_code);  
    cityBean.setCityName(city_name);  
    cityBean.setCity(city);  
    cityBean.setProvince(province);  
    this.cityMapper.insertCity(cityBean);  
}  
// U  
@CacheEvict(value = { "provinceCities", "searchCity" }, allEntries = true)  
public int renameCity(String city_code, String city_name) {  
    City city = new City();  
    city.setCityCode(city_code);  
    city.setCityName(city_name);  
    this.cityMapper.renameCity(city);  
    return 1;  
}  
  
// D  
@CacheEvict(value = { "provinceCities", "searchCity" }, allEntries = true)  
public int deleteCity(String city_code) {  
    this.cityMapper.deleteCity(city_code);  
    return 1;  
}  
Business considerations, this example uses @CacheEvict to clear the cache. If your CUD can return to the city instance, you can also use the @CachePut to update the cache policy. I recommend that you use @CachePut where you do not use @CacheEvict, because the latter will all the relevant methods of the cache is cleared, such as any of the above three methods are called, the Provincecities method of all the cache will be cleared.
5. Custom cache Data key generation policy for the use of @Cacheable annotations, each cached key generation policy uses the parameter name + parameter value by default, such as the following methods:
@Cacheable("users")  
public User findByUsername(String username) 
The cache for this method will be stored in the cache with key Users~keys, and for username with the value "Zhao Defang", the key is "username-Zhao Defang". In general, there is no problem, the second case, if the method key value is equal and the parameter name is the same when the problem occurs, such as:
@Cacheable("users")  
public Integer getLoginCountByUsername(String username) 
The cache for this method will also be stored in the cache of key Users~keys. For a cache with a value of "Zhao Defang" for username, key is also "username-Zhao Defang", overwriting the cache of another method.
The workaround is to use a custom cache policy, for the same business (the same business logic processing method, even the cluster/distributed system), the generated key always consistent, for different business is inconsistent:
 
@Bean  
public KeyGenerator customKeyGenerator() {  
    return new KeyGenerator() {  
        @Override  
        public Object generate(Object o, Method method, Object... objects) {  
            StringBuilder sb = new StringBuilder();  
            sb.append(o.getClass().getName());  
            sb.append(method.getName());  
            for (Object obj : objects) {  
                sb.append(obj.toString());  
            }  
            return sb.toString();  
        }  
    };  
}  
So the above two methods, for the username value of "Zhao Defang" cache, although are still stored in the key is Users~keys cache, but because the key is "class name-findbyusername-username-Zhao Defang" and "Class name-getlo gincountbyusername-username-Zhao Defang ", so there's no problem.
This is important for sharing caches between clustered systems and distributed systems, and it really implements distributed caching.
The author suggests that the @Cacheable of the caching method is best to use the method name, avoid the @Cacheable values of the different methods consistent, and then with the above cache policy.
6. Validation of the cache 6.1 cache validation in order to determine if each cache method actually has a cache, we have opened the SQL log output of MyBatis, and we have emptied the test Redis database to demonstrate clearly.
To verify the Provincecities method cache, Eclipse starts the Tomcat loading project and uses JMeter to invoke the/bdp/city/province/cities.json interface:

The Eclipse console output is as follows:

Indicates that the request did not hit the cache, and the DB query was gone. JMeter request again, Eclipse console output:

Red section The following is the log for this request, no log to access the DB, and a cache hit. To view Redis storage for this request:

It is also possible to verify that the cache for the Searchcity method with City_code 1492 is valid:

The red part of the figure is the cache storage of searchcity.
6.2 Validation of Cache coherency first validates the cache configuration of the Insertcity method, JMeter calls the/bdp/city/create.json interface:

Then look at Redis storage:

It can be seen that the cache of the Provincecities method has been cleaned out and the cache of the Insertcity method works.
Then verify the cache configuration of the Renamecity method, JMeter calls the/bdp/city/rename.json interface:

Then look at Redis storage:

The cache of the Searchcity method has also been cleaned up, and the caching of the Renamecity method has worked.
7. Precautions
    1. The Java object to be cached must implement the Serializable interface, because Spring will serialize the object first into Redis, such as the Com.defonds.bdp.city.bean.City class in this article, if the Serializable is not implemented You will encounter something like this: Nested exception is java.lang.IllegalArgumentException:DefaultSerializer requires a Serializable payload But received an object of type [com.defonds.bdp.city.bean.City]].
    2. The life cycle of the cache we can configure and then host Spring CacheManager, and do not attempt to manage the cache through the REDIS-CLI command line. For example, the Provincecities method Cache, a province of the query results will be stored in the form of key-value in Redis,key is our custom generated Key,value is the serialized object, this key will be placed in the key named Provinc Ecities~keys Key-value Storage, refer to the "Provincecities method in Redis cache condition". Provincecities~keys can be deleted by REDIS-CLI using the Del command, but the cache for each province is not cleared.
    3. CacheManager must set the cache expiration time, otherwise the cached object will never expire, so for the reasons above, avoid some wild data "forever save". In addition, setting the cache expiration time also helps maximize resource utilization, because the cache is always kept hot data.
    4. The cache is suitable for applications where there is less read and write, the cache hit rate is very low, the write operation is very frequent, and the scenario is not suitable for caching.

PostScript This article complete Eclipse under the development project example has uploaded CSDN resources, interested friends can go to download down reference: http://download.csdn.net/detail/defonds/9137505.
Resources
    • Caching Data with Spring
    • Cache Abstraction part VII. Integration
    • Caching Data in Spring Using Redis
    • Caching with Spring Data Redis
    • Spring-redis-caching-example
This article transferred from: http://blog.csdn.net/defonds/article/details/48716161


Example of Redis cache + Spring Integration


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.