如何使用才能让缓存更高效
Posted 小兀哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用才能让缓存更高效相关的知识,希望对你有一定的参考价值。
在大数据下,我们在追求性能的时候往往离不开缓存的使用,可是怎么使用缓存才能更高效呢?这一直是我们在追求解决的一个问题,今天我们就来介绍一种比较高效的使用方法。
1、代码展示
- 缓存类
public class ConfigCache
private static final Logger log = LoggerFactory
.getLogger(ConfigCache.class);
/** 科目缓存 */
private static Map<String, Map<String, TitleDO>> TITLE_MAP = new HashMap<>();
private static ScheduledExecutorService executorService = Executors
.newScheduledThreadPool(
1,
new NamedThreadFactory(
"bonus-config-cache",
true));
/** 科目DAO */
@Resource
private TitleDAO titleDAO;
/**
* 初始化,注入配置文件中启动时加载
*/
public void init()
log.debug("load p-general config information!");
reload();
executorService.scheduleWithFixedDelay(new Runnable()
@Override
public void run()
log.info("reload p-general config information!");
try
reload();
catch (Exception ex)
log.warn("reload p-general config occurs exception, wait for next time");
, 5, 5, TimeUnit.MINUTES);
/**
* 加载缓存
*/
public void reload()
// 从数据中查出科目信息
List<TitleDO> titleDOList = titleDAO.selectAll();
HashSet<String> titleSet = new HashSet<>();
for (TitleDO titleDO : titleDOList)
titleSet.add(titleDO.getReconInst());
for (String str : titleSet)
Map<String, TitleDO> map = new HashMap<>();
for (TitleDO titleDO : titleDOList)
if (StringUtils.equals(str, titleDO.getReconInst()))
map.put(String.format("%s%s%s", titleDO.getTitleCode(), titleDO.getReconInst(),
titleDO.getLedgerType()), titleDO);
TITLE_MAP.put(str, map);
/**
* 根据班级获取科目列表
*
* @param reconInst 班级
* @return 科目列表
*/
public List<TitleDO> getTitleList(String reconInst)
Assert.notBlank(reconInst, "归属机构不能为空");
List<TitleDO> list = new ArrayList<>();
// 存在缓存直接取值
if (TITLE_MAP.containsKey(reconInst))
Map<String, TitleDO> map = TITLE_MAP.get(reconInst);
Iterator<Entry<String, TitleDO>> it = map.entrySet().iterator();
while (it.hasNext())
list.add(it.next().getValue());
return list;
// 不存在缓存,去数据库查,然后放到缓存
if (!TITLE_MAP.containsKey(reconInst))
Map<String, String> condParam = new HashMap<String, String>();
condParam.put("reconInst", reconInst);
condParam.put("titleStatus", TitleStatusEnum.OPEN.getCode());
list = titleDAO.selectListByCond(condParam);
Map<String, TitleDO> map = new HashMap<>();
for (TitleDO titleDO : list)
map.put(
String.format("%s%s%s", titleDO.getTitleCode(), titleDO.getReconInst(),
titleDO.getLedgerType()), titleDO);
TITLE_MAP.put(reconInst, map);
return list;
- 使用
/** 缓存工具类 */
@Resource
private ConfigCache configCache;
public void test()
TitleDO titleDO = null;
String className="1";
try
//根据科班级查询出科目信息
titleDO = configCache.getTitleList(className);
catch (Exception e)
log.info("configCache.getTitleList()--利用缓存根据班级查询出科目信息失败", e);
2、分析
我们看代码,特别的地方就是有个单线程的定时任务。这样我们可以保证所需的数据在缓存里基本是能找到的,减少了数据库的访问次数,从而使性能更优。
scheduleWithFixedDelay
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
long initialDelay,
long delay,
TimeUnit unit)
//参数:
//command - 要执行的任务
//initialDelay - 首次执行的延迟时间
//delay - 一次执行终止和下一次执行开始之间的延迟
//unit - initialDelay 和 delay 参数的时间单
此方法是创建并执行一个在给定初始延迟后首次启用的定期操作,随后,在每一次执行终止和下一次执行开始之间都存在给定的延迟。如果任务的任一执行遇到异常,就会取消后续执行。否则,只能通过执行程序的取消或终止方法来终止该任务。
总结:
我们在性能优化的时候总是要考虑数据库的性能,因为在数据爆炸的这个年代,我们系统的瓶颈都在数据库。所以降低了数据库的损耗就会是性能得到很大提升。
以上是关于如何使用才能让缓存更高效的主要内容,如果未能解决你的问题,请参考以下文章