Яма для пакетного сбора кеша гуавы

Java

Резюме

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, перейдите к базе данных пакетных запросов.

Анализировать и решать

  1. Сначала посмотрите на реализацию кода гуавы
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], как можно скорее получите обновление статьи и начните путь технической практики вместе с настоятелем

在这里插入图片描述