Резюме
Guava Cache — это инструмент кэширования в Guava, библиотеке набора инструментов Java с открытым исходным кодом Google.
задний план
Очень просто абстрагироваться от функциональных требований, то есть запросить базу данных.sthMapper.findById(Long id)
Результат кэшируется. Но в то же время есть пакетные запросы, для повышения эффективности мы должны запрашивать базу данных в пакетном режиме.sthMapper.findByIds(Collection<Long> ids)
Для класса обработки кеша Гуавы
// 定义guava缓存
public SthCache() {
sthCache = CacheBuilder.newBuilder()
.maximumSize(SIZE)
.refreshAfterWrite(3, TimeUnit.SECONDS)
.build(new CacheLoader<Long, List<Long>>() {
@Override
public List<Long> load(final Long id) {
return doLoad(Arrays.asList(id)).get(id);
}
@Override
public Map<Long, List<Long>> loadAll(
final Iterable<? extends Long> ids)
throws Exception {
return doLoad(Lists.newArrayList(ids));
}
});
}
// 实际从数据库中加载数据
private Map<Long, List<Long>> doLoad(final List<Long> ids) {
return sthMapper.findByIds(ids);
}
// 批量获取数据
public Map<Long, List<Long>> getSthById(final List<Long> ids) {
return sthCache.getAll(ids);
}
Ничего плохого, Getall (Iterable Extendsk>) используется для выполнения пакетных запросов. По умолчанию каждый ключ не находится в кэше, метод GetAll вызывает CacheLoader.load Single для загрузки записи кэша. Если большая часть нагрузки, чем только нагрузка, все более и эффективнее, вы можете переопределить CACHELOADER.LoadAll, чтобы воспользоваться этим. Performance Getall (IteAleable) будет улучшена соответственно. Загрузка здесь определяет высокую эффективность.
проблема
При отладке обнаруживается, что loadAll действительно идет, а запросы к БД идут пачками. Однако после выхода в сеть данные онлайн-мониторинга показали, что этот интерфейс занимает много времени, путем анализа было обнаружено, что было много одиночных запросов sthMappper.findByIds(). то есть без звонкаloadAll
, перейдите к базе данных пакетных запросов.
Анализировать и решать
- Сначала посмотрите на реализацию кода гуавы
ImmutableMap<K, V> getAll(Iterable<? extends K> keys) throws ExecutionException {
int hits = 0;
int misses = 0;
// 省略一大坨
try {
if (!keysToLoad.isEmpty()) {
try {
// 调用loadAll
Map<K, V> newEntries = loadAll(keysToLoad, defaultLoader);
Во время пакетного запроса для тех, которые не попали, loadAll действительно вызывается для загрузки данных.
那问题就不是这边了。 существуетload()
Метод сделал точку останова по причинам.
Оказалось грузится при рефэше.refreshAfterWrite
Метод загрузки по-прежнему вызывается при обновлении кэшированных данных.
искал,GitHub.com/Google/Мелон В…Эта проблема все еще находится на github. пот! ! !
Наконец, мое решение здесь состоит в том, чтобы использоватьSpring Cache
Единое управление кэшем.
Суммировать
Использование библиотек с открытым исходным кодом не только известно, но и неизвестно.
Обратите внимание на паблик-аккаунт [Abbot's Temple], как можно скорее получите обновление статьи и начните путь технической практики вместе с настоятелем