# 竞价系统-高校端缓存设计

# 概述

目前独立端的缓存使用Ehcache,集中部署的缓存使用Redis。 为了统一代码,使用MidCacheUtil进行了封装,程序调用时直接使用该工具类即可, 而不需要关心底层是Ehcache还是Redis。 其中,参数、操作、节点均使用了缓存。

# 缓存类型

底层使用缓存类型由co_init_config中的USING_REDIS进行控制,如果为0,则使用Ehcache; 如果为1,则使用Redis。

# 基本使用

基本用法为,根据键名插入值、获取值

//插入值
MidCacheUtil.put("cacheName", "key", "value");
//批量插入值(使用Map)
MidCacheUtil.putMulti("cacheName", map);
//获取值
Object value = MidCacheUtil.get("cacheName", "key");

这种cacheName-key-value的结构和Ehcache的结构是一致的, 而Redis则是key-value结构,因此将工具类的"cacheName:key"作为Redis的key。

# 进阶使用

部分情况需要遍历或者批量删除,如获取申购单对应的流程列表就需要遍历缓存, Redis使用模糊查询进行遍历的代价比较高,因此改为使用HASH结构, 相当于MidCacheUtil.get("cacheName", "key")对应的是一个HASH表(无法实际回去回来), 这时需要再提供一个HASH表的key,才能得到最后的value。 因此MidCacheUtil增加了md开头的方法,用于处理这种情况。

//插入值
MidCacheUtil.mdPut("cacheName", "midKey", "key", "value");
//获取单个值
Object value = MidCacheUtil.mdGet("cacheName", "midKey", "key");
//获取cacheName-midKey下的所有键值对
Map map = MidCacheUtil.mdGetAll("cacheName", "midKey");
//批量插入值
MidCacheUtil.mdPutMulti("cacheName", "midKey", map);
//移除值
MidCacheUtil.mdRemove("cacheName", "midKey", "key");
//清空值
MidCacheUtil.mdRemoveAll("cacheName", "midKey");

由于Ehcache的cacheName-key-value的结构与上面这种cacheName-midKey-key-value的结构不符, 因此将MidCacheUtil的"midKey:key"作为Ehcache中的'key'部分, mdGetAll则使用Ehcache的模糊查询功能来实现(该缓存需要开启模糊搜索, 即在ehcache.xml该缓存的部分添加<searchable/>)。

# 注意事项

  • 在Redis中,进行模糊的key查询的代价非常高,在生产代码中不能使用
  • Redis的HASH的遍历(MidCacheUtil.mdGetAll有用到)在元素数量很大时(如上万), 同样会引起性能问题,因此在使用时需要考虑实际数据的数量级。 比如,节点信息在使用Redis缓存时,每个HASH只存放一个高校某个申购单的节点信息,数量在10-20个, 完全不会引发性能问题。
Last Updated: 3/12/2020, 2:07:22 PM