1. 本地缓存

    1. 说明

      1. 本地缓存 LocalCache,即 JVM 缓存,适用于存储访问频率高,缓存数据集又不是很大的场合,缓存类定义在 localcache.xml 里。
      2. 本地缓存又分为本地只读缓存、本地读写缓存两类
      3. 本地只读缓存,要求缓存数据一次性全量加载,确保缓存 100% 命中。[推荐]
      4. 本地读写缓存,适合那些没法一次性全量加载的场合,采用按需加载方式,即先看缓存有没有,没有再查数据库或读文件,再将数据缓存起来。
    2. 本地只读缓存

      业务级缓存类要求继承 AbstractReadOnlyCache,实现 loadData 接口,返回一个 Map<String, Object>

      示例代码:

      缓存定义示例:

      public class CacheTablesCache extends AbstractReadOnlyCache {
      
      	@Override
      	public Map<String, Object> loadData() throws Exception {
      		
      		Map<String, Object> rtn = new HashMap<String, Object>();
      		
      		IDataInput input = new DataInput();
      		IDataOutput output = ServiceFactory.call("SYS_CacheTables_GetList", input);
      		IDataset datas = output.getData();
      		
      		for (int i = 0, size = datas.size(); i < size; i++) {
      			IData data = datas.getData(i);
      			
      			String tableName = data.getString("TABLE_NAME");
      			String version = data.getString("VERSION");
      			
      			// 版本号只取"日时分", 格式:(DDHHMI),够用的情况下越短越好。
      			version = StringUtils.replaceChars(version, ":- ", "").substring(6, 12);
      			rtn.put(tableName, version);
      		}
      		
      		return rtn;
      	}
      }
      

      使用示例:

      // 获取版本号缓存
      IReadOnlyCache cache = CacheFactory.getReadOnlyCache(CacheTablesCache.class);
      String version = (String) cache.get(tableName);
      

      配置示例:

      <localcaches>    
      	<!-- 只读缓存,数据需要一次性全量加载。-->
      	<readonly>
      		<!--
      			className: 缓存实现类  (必配参数)
      			cronExpr: 缓存清理时间 (可选参数,默认不自动清空。)
      			init: 系统初始化时是否立即初始化缓存 (可选参数, 默认不初始化)
      		-->
      		<cache className="com.ailk.biz.cache.CacheTablesCache" cronExpr="30 1 * * ?" init="true" />
      	</readonly>
      	<readwrite>
      		......略
      	</readwrite>
      </localcaches>
      
    3. 本地读写缓存

      <localcaches>    
      	<readonly>
      		......略
      	</readonly>
      	
      	<!-- 读写缓存,数据按需加载,采用LRU淘汰机制。 -->
      	<readwrite>
      		<!--
      			name: 缓存名 (必配参数)
      			maxSize: 最大缓存记录数 (可选参数,默认10000条)
      			cronExpr: 缓存清理时间 (可选参数,默认不自动清空。)
      		-->
      		<cache name="COMMON_CACHE" maxSize="10000" cronExpr="29 10 * * ?" />
      	</readwrite>
      </localcaches>
      

      使用示例

      IReadWriteCache cache = CacheFactory.getReadWriteCache("COMMON_CACHE");
      String cacheValue = cache.get(cacheKey);
      if (null == cacheValue) {
      	cacheValue = ... // 查数据库或读文件
      	if (null != cacheValue) {
      		cache.put(cacheKey, cacheValue);
      	}
      }
      
  2. 分布式缓存

    1. 说明

      1. 缓存数据是基于集群的异构分布式存放,一份数据只会存放在一个节点;
      2. 客户端通过 Key 的一致性 hash 算法唯一确定缓存节点,并按段存取;
      3. 当缓存节点退出或新增时,只会影响故障节点的数据,并将按需重新加载;
      4. 支持定时与实时的数据增量刷新;
      5. 自定义 Memcached 客户端,采用 Hessian 序列化 Java 对象;
      6. 通过客户端心跳线程对 MC 长连接做健康检测;
      7. 支持超大对象(>1M)的数据压缩(Gzip)存储。
    2. 配置说明

      统一配置在 memcached.properties

      配置示例

      memcache.session_cache.cluster=192.168.102.254:11111,192.168.102.253:11111
      memcache.priv_cache.cluster=192.168.102.254:11211,192.168.102.253:11211
      memcache.codecode_cache.cluster=192.168.102.254:11311,192.168.102.253:11311
      memcache.staticparam_cache.cluster=192.168.102.254:11411,192.168.102.253:11411
      memcache.bcc_cache.cluster=192.168.102.254:11511,192.168.102.253:11511
      
    3. 示例代码

      获取缓存工厂类:com.ailk.cache.memcache.MemCacheFactory

      /**
       * 根据名称获取对应的Cache
       * @param cacheName
       * @return
       */
      public static IMemCache getCache(String cacheName)
      

      缓存实例类:com.ailk.cache.memcache.interfaces.IMemCache

      /**
       * 判断cacheKey是否存在
       * @param cacheKey
       * @return 存在返回true,否则返回false
       */
      public boolean keyExists(String cacheKey);
      
      /**
       * 返回cacheKey对应的缓存对象。
       * @param cacheKey
       * @return 如果对应的缓存找不到,则返回null。
       */
      public Object get(String cacheKey);
      	
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Object value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Byte value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Integer value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Character value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, String value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, StringBuffer value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, StringBuilder value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Float value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Short value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Double value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Date value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, byte[] value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Boolean value);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Long value);
      	
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Byte value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Integer value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Character value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, String value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, StringBuffer value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, StringBuilder value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Float value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Short value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Double value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Date value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, byte[] value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Boolean value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。
       * @param cacheKey
       * @param value
       * @return 如果数据被成功存储返回true
       */
      public boolean set(String cacheKey, Long value, int secTTL);
      
      /**
       * 在缓存中存放一个K-V键值对,同名键会被覆盖。设置多少秒后超时
       * @param cacheKey
       * @param value
       * @param secTTL 多少秒后超时
       * @return 执行成功返回true,否则返回false。
       */
      public boolean set(String cacheKey, Object value, int secTTL);
      
      /**
       * 删除缓存中cacheKey对应的缓存对象
       * @param cacheKey
       * @return 原缓存中有cacheKey时返回true,否则返回false
       */
      public boolean delete(String cacheKey);
      
      /**
       * 递增计数器(线程安全),步长为1,当递增到long可保存的最大值时,进行回绕。
       * 注:memcached会确保计数器线程安全的执行。
       * @param cacheKey
       * @return 返回计数器的当前值
       */
      public long incr(String cacheKey);
      
      /**
       * 递增计数器(线程安全),步长为inc。
       * 注:memcached会确保计数器线程安全的执行。
       * @param cacheKey
       * @param inc 步长
       * @return 返回计数器的当前值
       */
      public long incr(String cacheKey, int inc);
      
      /**
       * 递增计数器(线程安全),带超时的,超时是指key生成的那个时间。
       * 注:memcached会确保计数器线程安全的执行。
       * @param cacheKey
       * @param secTTL 超时时间,单位:秒
       * @return 返回计数器的当前值
       */
      public long incrWithTTL(String cacheKey, int secTTL);
      
      /**
       * 递增计数器(线程安全),步长为inc,带超时,超时是指key生成的那个时间。
       * 注:memcached会确保计数器线程安全的执行。
       * @param cacheKey
       * @param inc 步长
       * @param secTTL 超时时间,单位:秒
       * @return 返回计数器的当前值
       */
      public long incrWithTTL(String cacheKey, int inc, int secTTL);
      
      /**
       * 递减计数器, 步长为1,当递减到0时,始终为0。
       * 注:memcached会确保计数器线程安全的执行。
       * @param cacheKey
       * @return 返回计数器的当前值
       */
      public long decr(String cacheKey);
      
      /**
       * 递减计数器(线程安全), 步长为inc,当递减到0时,始终为0。
       * 注:memcached会确保计数器线程安全的执行。
       * @param cacheKey
       * @param inc
       * @return 返回计数器的当前值
       */
      public long decr(String cacheKey, int inc);
      
      /**
       * 往后顺延超时时间,单位:秒。
       * 注:memcached-1.4.15,及以上版本开始支持!
       * @param cacheKey
       * @param secTTL
       * @return 成功touch返回true,否则返回false
       */
      public boolean touch(String cacheKey, int secTTL);