Integrate Memcached and Redis access
Reference resources
Integrating Memcached and Redis access source code used by flea-frame-cache
rely on
No more, see my blog entry below:
Memcached access used by flea-frame-cache
Redis access used by flea-frame-cache
Use Instructions
After the last two posts, Memcached and Redis believe that many friends will be able to successfully access system applications.As the complexity of applications increases, the application scenarios of caching become more and more complex. Individual docking of a caching system can no longer meet the requirements of business development.This paper focuses on integrating multiple sets of cache access: one cache corresponds to one cache-data, one cache-data corresponds to one cache-group, multiple cache-server s associate one cache-group, and one cache-group corresponds to a specific cache access implementation.(Memcached and Redis are currently supported).Now listen to me slowly:
1. Flea cache profile flea-cache-config.xml
<?xml version="1.0" encoding="UTF-8"?> <flea-cache-config> <!-- Flea Cache Configuration Itemset --> <cache-items key="FleaCacheBuilder" desc="Flea Cache Builder Implementation"> <cache-item key="MemCached" desc="MemCached Of Flea Cache Builder Implementation">com.huazie.frame.cache.memcached.MemCachedFleaCacheBuilder</cache-item> <cache-item key="Redis" desc="Redis Of Flea Cache Builder Implementation">com.huazie.frame.cache.redis.RedisFleaCacheBuilder</cache-item> </cache-items> <!-- Redis Cache parameter set --> <cache-params key="Redis" desc="Redis Cache configuration data"> <cache-param key="connectionTimeout" desc="Redis Client socket Connection timeout">2000</cache-param> <cache-param key="soTimeout" desc="Redis Client socket Read-Write Timeout">2000</cache-param> <cache-param key="hashingAlg" desc="Redis Distributed hash algorithm(1:MURMUR_HASH,2:MD5)">1</cache-param> <cache-param key="pool.maxTotal" desc="Redis Client Jedis Maximum Connections in Connection Pool">8</cache-param> <cache-param key="pool.maxIdle" desc="Redis Client Jedis Maximum number of idle connections in connection pool">8</cache-param> <cache-param key="pool.minIdle" desc="Redis Client Jedis Connection pool minimum number of idle connections">0</cache-param> <cache-param key="pool.maxWaitMillis" desc="Redis Client Jedis Maximum number of milliseconds to wait for a connection to be acquired by the connection pool">2000</cache-param> </cache-params> <!-- MemCached Cache parameter set --> <cache-params key="MemCached" desc="MemCached Cache configuration data"> <cache-param key="initConn" desc="Number of connections made to each server at initialization">20</cache-param> <cache-param key="minConn" desc="Minimum number of connections per server">20</cache-param> <cache-param key="maxConn" desc="Maximum number of connections per server">500</cache-param> <cache-param key="maintSleep" desc="Self-checking thread cycles for work, each time it hibernates">60000</cache-param> <cache-param key="nagle" desc="Socket Parameter, if true Send out immediately without buffering while writing data">true</cache-param> <cache-param key="socketTO" desc="Socket Timeout to block reading data">3000</cache-param> <cache-param key="socketConnectTO" desc="Socket Connection timeout">3000</cache-param> <!-- 0 - native String.hashCode(); 1 - original compatibility 2 - new CRC32 based 3 - MD5 Based --> <cache-param key="hashingAlg" desc="MemCached Distributed hash algorithm">3</cache-param> </cache-params> <!-- Flea Cached Dataset --> <cache-datas> <cache-data type="auth" desc="Flea Configuration of the group in which permission cached data resides">authGroup</cache-data> <cache-data type="jersey" desc="Flea Jersey Configuration of the group in which the cached data resides">configGroup</cache-data> <cache-data type="fleafs" desc="FleaFs Configuration Data in Group Configuration">configGroup</cache-data> </cache-datas> <!-- Flea Cache Group Set --> <cache-groups> <cache-group group="authGroup" desc="Flea Permission Data Cache Group">MemCached</cache-group> <cache-group group="configGroup" desc="Flea Configure Data Cache Group">Redis</cache-group> </cache-groups> <!-- Flea Cache Server Set --> <cache-servers> <cache-server group="authGroup" weight="1" desc="MemCached Cache Server Configuration">127.0.0.1:31113</cache-server> <cache-server group="authGroup" weight="1" desc="MemCached Cache Server Configuration">127.0.0.1:31114</cache-server> <cache-server group="configGroup" password="huazie123" weight="1" desc="Redis Cache Server Configuration">127.0.0.1:10001</cache-server> <cache-server group="configGroup" password="huazie123" weight="1" desc="Redis Cache Server Configuration">127.0.0.1:10002</cache-server> <cache-server group="configGroup" password="huazie123" weight="1" desc="Redis Cache Server Configuration">127.0.0.1:10003</cache-server> </cache-servers> </flea-cache-config>
2. Flea cache definition file flea-config.xml
<?xml version="1.0" encoding="UTF-8"?> <flea-cache> <!-- Cache Definition --> <caches> <!-- key : Cache Primary Key, Cache Name type : Cache type expiry : Cache expiration time (units: s),This field can be configured (default persistent) desc : Cache description --> <cache key="fleaparadetail" type="fleafs" expiry="86400" desc="Flea Configure Data Cache" /> <cache key="fleajerseyi18nerrormapping" type="jersey" desc="Flea Jersey International Code and Error Code Mapping Cache" /> <cache key="fleajerseyresservice" type="jersey" desc="Flea Jersey Resource Service Cache" /> <cache key="fleajerseyresclient" type="jersey" desc="Flea Jersey Resource Client Cache" /> <cache key="fleajerseyresource" type="jersey" desc="Flea Jersey Resource Cache" /> </caches> </flea-cache>
3. Define CoreFleaCache, the core Flea cache class
The class also inherits the abstract Flea cache AbstractFleaCache, which implements the abstract method of its definition; the internal definition member variable fleaCache is used to specify a specific Flea cache implementation (this specific implementation can refer to the previous Memcached and Redis access), which implements the three methods getNativeValue, putNativeValue, deleteNativeValue FleaCache implements read cache, write cache and delete cache by specific Flea cache. From the construction method, fleaCache is obtained from FleaCacheFactory.getFleaCache(name).
/** * <p> Core Flea Cache Class </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class CoreFleaCache extends AbstractFleaCache { private static final Logger LOGGER = LoggerFactory.getLogger(CoreFleaCache.class); private AbstractFleaCache fleaCache; // Specify Flea Cache Implementation /** * <p> Initialize core Flea cache class </p>with parametric construction method * * @param name Cache Primary Key * @since 1.0.0 */ public CoreFleaCache(String name) { super(name, CacheConfigManager.getExpiry(name)); // Gets the specified Flea cache object based on the cache primary key name fleaCache = FleaCacheFactory.getFleaCache(name); // Takes the cache type of the specified Flea cache cache = fleaCache.getCache(); } @Override public Object getNativeValue(String key) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("CoreFleaCache##getNativeValue(String) KEY = {}", key); } return fleaCache.getNativeValue(key); } @Override public void putNativeValue(String key, Object value, long expiry) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("CoreFleaCache##putNativeValue(String, Object, long) KEY = {}", key); LOGGER.debug("CoreFleaCache##putNativeValue(String, Object, long) VALUE = {}", value); LOGGER.debug("CoreFleaCache##putNativeValue(String, Object, long) EXPIRY = {}s", expiry); } fleaCache.putNativeValue(key, value, expiry); } @Override public void deleteNativeValue(String key) { if (LOGGER.isDebugEnabled()) { LOGGER.debug("CoreFleaCache##deleteNativeValue(String) KEY = {}", key); } fleaCache.deleteNativeValue(key); } }
4. Define Flea CacheFactory class
Flea caches created by this class based on the cache name (that is, the cache primary key) are stored in ConcurrentMap < String, AbstractFleaCache >.The newCache method mainly finds the cache based on the cache name, then finds the cache-data, then finds the cache group cache-group, and finally finds the cache configuration item cache-item based on the cache system to which the cache group belongs, to get the builder implementation of the corresponding Flea cache, see the flea-cache-config.xml configuration.
/** * <p> Flea Cache Factory Class </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class FleaCacheFactory { private static final ConcurrentMap<String, AbstractFleaCache> fleaCacheMap = new ConcurrentHashMap<String, AbstractFleaCache>(); /** * <p> Gets the specified Flea cache object from the cache primary key name </p> * * @param name Cache Primary Key (corresponding to flea-cache.xml {@code <cache key= "Cache Primary Key"></cache>}) * @return Flea Cache Object * @since 1.0.0 */ public static AbstractFleaCache getFleaCache(String name) { if (!fleaCacheMap.containsKey(name)) { synchronized (fleaCacheMap) { if (!fleaCacheMap.containsKey(name)) { fleaCacheMap.put(name, newFleaCache(name)); } } } return fleaCacheMap.get(name); } /** * <p> Create a Flea cache object from the cache primary key name </p> * * @param name Cache Primary Key (corresponding to flea-cache.xml {@code <cache key= "Cache Primary Key"></cache>}) * @return Flea Cache Object * @since 1.0.0 */ private static AbstractFleaCache newFleaCache(String name) { // Get Flea Cache Configuration Information Cache cache = CacheConfigManager.getCache(name); if (ObjectUtils.isEmpty(cache)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache.xml Configuration [<cache key=" + name + " >]"); } // Get Flea Cache Attribution Data Configuration Information CacheData cacheData = CacheConfigManager.getCacheData(cache.getType()); if (ObjectUtils.isEmpty(cacheData)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache-config.xml Configuration [<cache-data type=" + cache.getType() + " >]"); } // Get Flea Cache Group CacheGroup cacheGroup = CacheConfigManager.getCacheGroup(cacheData.getGroup()); if (ObjectUtils.isEmpty(cacheGroup)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache-config.xml Configuration [<cache-group group=" + cacheData.getGroup() + " >]"); } // Get Cache System Name String cacheSystem = cacheGroup.getCache(); // Get Flea Cache Parameters CacheParams cacheParams = CacheConfigManager.getCacheParams(cacheSystem); if (ObjectUtils.isEmpty(cacheParams)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache-config.xml Configuration [<cache-params key=" + cacheGroup.getCache() + " >]"); } // Get Flea Cache Server List<CacheServer> cacheServerList = CacheConfigManager.getCacheServer(cacheGroup.getGroup()); if (CollectionUtils.isEmpty(cacheServerList)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache-config.xml Configuration [<cache-server group=" + cacheGroup.getGroup() + " >]"); } // Gets the Flea cache builder corresponding to the specified cache system name CacheItem cacheItem = CacheConfigManager.getCacheItem(CacheConstants.FleaCacheConfigConstants.FLEA_CACHE_BUILDER, cacheSystem); if (ObjectUtils.isEmpty(cacheItem)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache-config.xml Configuration [<cache-item key=" + cacheSystem + " >]"); } // Flea Cache Builder String builder = cacheItem.getValue(); if (ObjectUtils.isEmpty(builder)) { throw new RuntimeException("Unable to initialize Flea Cache, please check flea-cache-config.xml Configuration [<cache-item key=" + cacheSystem + " ></cache-item>]Configuration item value cannot be empty"); } AbstractFleaCache fleaCache; try { IFleaCacheBuilder fleaCacheBuilder = (IFleaCacheBuilder) ReflectUtils.newInstance(builder); fleaCache = fleaCacheBuilder.build(name, cacheServerList, cacheParams); } catch (Exception e) { throw new RuntimeException("structure Flea Cache exception:\n" + e); } return fleaCache; } }
5. Define the Flea cache builder interface class IFleaCacheBuilder
/** * <p> Flea Cache Builder Interface Class </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public interface IFleaCacheBuilder { /** * <p> Build Flea Cache Object </p> * * @param name Cache Primary Key * @param cacheServerList Cache Server Set * @param cacheParams Cache parameter set * @return Flea Cache Object * @since 1.0.0 */ AbstractFleaCache build(String name, List<CacheServer> cacheServerList, CacheParams cacheParams); }
6. Define Memcached Flea cache builder MemCached FleaCacheBuilder
This class implements IFleaCacheBuilder, which is used to build a Memcached-based Flea cache by creating a MemCached FleaCache.
/** * <p> MemCached Flea cache builder implementation for </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class MemCachedFleaCacheBuilder implements IFleaCacheBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(MemCachedFleaCacheBuilder.class); @Override public AbstractFleaCache build(String name, List<CacheServer> cacheServerList, CacheParams cacheParams) { if (CollectionUtils.isEmpty(cacheServerList)) { return null; } // Get Failure Time long expiry = CacheConfigManager.getExpiry(name); // Get the group name of the MemCached server String group = cacheServerList.get(0).getGroup(); // Get the MemCached client class by group name MemCachedClient memCachedClient = new MemCachedClient(group); // Get the MemCachedPool and initialize the connection pool MemCachedPool memCachedPool = MemCachedPool.getInstance(group); memCachedPool.initialize(cacheServerList, cacheParams); // Create a MemCached Flea cache class AbstractFleaCache fleaCache = new MemCachedFleaCache(name, expiry, memCachedClient); if (LOGGER.isDebugEnabled()) { LOGGER.debug("MemCachedFleaCacheBuilder#build(String, List<CacheServer>, CacheParams) Pool Name = {}", memCachedPool.getPoolName()); LOGGER.debug("MemCachedFleaCacheBuilder#build(String, List<CacheServer>, CacheParams) Pool = {}", memCachedPool.getSockIOPool()); } return fleaCache; } }
7. Define RedisFleaCacheBuilder, the Redis Flea cache builder
This class implements IFleaCacheBuilder, which is used to build a Redis-based Flea cache by creating a RedisFleaCache.
/** * <p> Redis Flea cache builder implementation for </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class RedisFleaCacheBuilder implements IFleaCacheBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(RedisFleaCacheBuilder.class); @Override public AbstractFleaCache build(String name, List<CacheServer> cacheServerList, CacheParams cacheParams) { if (CollectionUtils.isEmpty(cacheServerList)) { return null; } // Get Failure Time long expiry = CacheConfigManager.getExpiry(name); // Get Cache Group Name String group = cacheServerList.get(0).getGroup(); // Initialize connection pool RedisPool.getInstance(group).initialize(cacheServerList, cacheParams); // Get Redis Client Proxy Class RedisClient redisClient = RedisClientProxy.getProxyInstance(group); // Create a Redis Flea cache AbstractFleaCache fleaCache = new RedisFleaCache(name, expiry, redisClient); if (LOGGER.isDebugEnabled()) { LOGGER.debug("RedisFleaCacheBuilder#build(String, List<CacheServer>, CacheParams) Pool Name = {}", RedisPool.getInstance(group).getPoolName()); LOGGER.debug("RedisFleaCacheBuilder#build(String, List<CacheServer>, CacheParams) Pool = {}", RedisPool.getInstance(group).getJedisPool()); } return fleaCache; } }
8. Define Core FleaCache Manager, the core Flea cache management class
Core Flea Cache is ready for use after the above steps; it inherits AbstractFleaCache Manager and implements the newCache method to create a core Flea cache.
/** * <p> Core Flea Cache Management Class </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class CoreFleaCacheManager extends AbstractFleaCacheManager { @Override protected AbstractFleaCache newCache(String name, long expiry) { return new CoreFleaCache(name); } }
9. Cache self-testing
@Test public void testCoreFleaCacheManager() { try { AbstractFleaCacheManager manager = new CoreFleaCacheManager(); AbstractFleaCache cache = manager.getCache("fleaparadetail"); LOGGER.debug("Cache={}", cache); //##### 1. Simple string // cache.put("menu1", "huazie"); // cache.put("menu2", "helloworld"); // cache.get("menu1"); // cache.delete("menu2"); cache.getCacheKey(); LOGGER.debug(cache.getCacheName() + ">>>" + cache.getCacheDesc()); } catch (Exception e) { LOGGER.error("Exception:", e); } }
After the above introduction, the core Flea cache related content is basically explained.On the basis of unchanged existing business code, related cache caches can migrate seamlessly between caches by modifying the type of cache data they belong to.
Advanced Practice
1. Define Core Spring Cache
The class also inherits the abstract Spring cache AbstractSpring Cache, which is used to dock Spring; from the construction method, it initializes using the core Flea cache class CoreFleaCache.
/** * <p> Core Spring Cache Class </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class CoreSpringCache extends AbstractSpringCache { /** * <p> Construction method with parameters </p> * * @param name Cache Primary Key * @param fleaCache Flea Cache Specific implementation * @since 1.0.0 */ public CoreSpringCache(String name, IFleaCache fleaCache) { super(name, fleaCache); } /** * <p> Construction method with parameters </p> * * @param name Cache Primary Key * @since 1.0.0 */ public CoreSpringCache(String name) { super(name, new CoreFleaCache(name)); } }
2. Define Core Spring Cache Manager, a core Spring cache management class
This class inherits the abstract Spring cache management class AbstractSpring Cache Manager, which is used to dock Spring; it basically implements Core Flea Cache Manager, the only difference being the implementation of newCache, which is a new core Spring cache CoreSpring Cache.
/** * <p> Core Spring Cache Management Class </p> * * @author huazie * @version 1.0.0 * @since 1.0.0 */ public class CoreSpringCacheManager extends AbstractSpringCacheManager { @Override protected AbstractSpringCache newCache(String name, long expiry) { return new CoreSpringCache(name); } }
3. Spring Configuration
<!-- Configuration Core Flea Cache Management Class RedisSpringCacheManager --> <bean id="coreSpringCacheManager" class="com.huazie.frame.cache.core.CoreSpringCacheManager" /> <!-- Open Cache --> <cache:annotation-driven cache-manager="coreSpringCacheManager" proxy-target-class="true"/>
4. Cache self-testing
private ApplicationContext applicationContext; @Before public void init() { applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); LOGGER.debug("ApplicationContext={}", applicationContext); } @Test public void testCoreSpringCache() { try { AbstractSpringCacheManager manager = (CoreSpringCacheManager) applicationContext.getBean("coreSpringCacheManager"); LOGGER.debug("CoreSpringCacheManager={}", manager); AbstractSpringCache cache = manager.getCache("fleaparadetail"); LOGGER.debug("Cache={}", cache); //##### 1. Simple string // cache.put("menu1", "huazie"); // cache.get("menu1"); // cache.get("menu1", String.class); //##### 2. Simple objects (if serializable) // String user = new String("huazie"); // cache.put("user", user); // LOGGER.debug(cache.get("user", String.class)); // cache.get("FLEA_RES_STATE"); cache.clear(); //##### 3. Listplug object // List<String> userList = new ArrayList<String>(); // userList.add("huazie"); // userList.add("lgh"); // cache.put("user_list", userList); // LOGGER.debug(cache.get("user_list",userList.getClass()).toString()); } catch (Exception e) { LOGGER.error("Exception:", e); } }
5. Business Logic Layer Access Cache Management
@Cacheable, value is the cache name, also the cache primary key, key is the specific cache key
@Cacheable(value = "fleaparadetail", key = "#paraType + '_' + #paraCode") public FleaParaDetail getParaDetail(String paraType, String paraCode) throws Exception { List<FleaParaDetail> fleaParaDetails = fleaParaDetailDao.getParaDetail(paraType, paraCode); FleaParaDetail fleaParaDetailValue = null; if (CollectionUtils.isNotEmpty(fleaParaDetails)) { fleaParaDetailValue = fleaParaDetails.get(0); } return fleaParaDetailValue; }
So far, the integration of Memcached and Redis access has been completed, and you are confident that you can access the system~