簡體   English   中英

IgniteCache不調用loadCache()

[英]IgniteCache does not call loadCache()

我遵循了點燃文檔並創建了商店適配器:

import java.io.Serializable;
import java.util.Map;
import java.util.Optional;
import javax.cache.Cache;
import javax.cache.integration.CacheLoaderException;
import javax.cache.integration.CacheWriterException;

import org.apache.ignite.Ignite;
import org.apache.ignite.cache.store.CacheStoreAdapter;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.my.calendar.dao.jpa.ChannelDetailsJpaRepository;
import com.my.calendar.entity.ChannelDetails;

@Service
public class CacheChannelStoreAdapter extends CacheStoreAdapter<Long, ChannelDetails> implements Serializable {
    private static final Logger LOGGER = LogManager.getLogger(CacheChannelStoreAdapter.class);

    private static ChannelDetailsJpaRepository channelDetailsJpaRepository;

    // Will be automatically injected. !!! apacheignite info, but it DOES NOT
    @IgniteInstanceResource
    private Ignite ignite;

    public Ignite getIgnite() {
        return ignite;
    }

    public void setIgnite(Ignite ignite) {
        this.ignite = ignite;
    }

    @Autowired
    public CacheChannelStoreAdapter(ChannelDetailsJpaRepository channelDetailsJpaRepository) {
        this.channelDetailsJpaRepository = channelDetailsJpaRepository;
    }

    @Override
    public void loadCache(IgniteBiInClosure<Long, ChannelDetails> clo, Object... args) {
        LOGGER.trace("load cache...");
        super.loadCache(clo, args);
    }

    @Override
    public Map<Long, ChannelDetails> loadAll(Iterable<? extends Long> keys) {
        LOGGER.trace("load all. keys: {}", keys);
        return super.loadAll(keys);
    }

    @Override
    public ChannelDetails load(Long key) throws CacheLoaderException {
        LOGGER.debug("object to load: {}", key);
        return channelDetailsJpaRepository.findOne(key);
    }

    @Override
    public void write(Cache.Entry<? extends Long, ? extends ChannelDetails> entry) throws CacheWriterException {
        LOGGER.debug("object to save: {}", entry);
        Optional.ofNullable(entry)
                .map(Cache.Entry::getValue)
                .ifPresent(channelDetailsJpaRepository::save);
    }

    @Override
    public void delete(Object key) throws CacheWriterException {
        LOGGER.debug("object to delete: {}", key);
        Optional.ofNullable(key)
                .filter(Long.class::isInstance)
                .map(Long.class::cast )
                .ifPresent(channelDetailsJpaRepository::delete);
    }
}

緩存適配器已注入到緩存配置中cacheConfiguration.setCacheStoreFactory(new FactoryBuilder.SingletonFactory<>(cacheStoreAdapter));


我同時遇到幾個問題:

  • 看不到CacheStore.loadCache()調用| IgniteCache.loadCache() (應調用以下文檔@Override public ChannelDetails load(Long key)
  • 看不到由ignite @IgniteInstanceResource private Ignite ignite;注入的@IgniteInstanceResource private Ignite ignite;

有修復或檢查的想法嗎? ...可能錯過了重要的部分,我應該直接在startTime或其他地方調用緩存加載嗎?

添加更多細節

在緩存時,所有緩存的數據都保存到我的數據庫中。 在服務器啟動服務器時,沒有從db加載數據。

我的適配器的緩存配置部分:

cacheConfiguration.setCacheStoreFactory(new FactoryBuilder.SingletonFactory<>(cacheStoreAdapter));
// Configure cache to use store.
cacheConfiguration.setReadThrough(true);
cacheConfiguration.setWriteThrough(true);
// Enable database batching.
cacheConfiguration.setWriteBehindEnabled(true);

Ignite從Web服務器開始(在同一個jvm ,我知道它很丑陋,但是我不能將我的測試弄壞)。

感謝Nikolay的建議。 他沒有提供代碼,所以我認為最好解決我的問題。 我有完整的解決方案。

Ignite配置部分,我們應該調用

igniteConcreteCache.loadCache(
    (IgniteBiPredicate) (key, val) -> {
        System.out.println(" =========>>>> Loading [key=" + key + ", val=" + val + ']');
        return true;
    });

要從存儲中加載數據,我們需要在StoreAdapter重寫對應方法:

@Override
public void loadCache(IgniteBiInClosure<Long, ChannelDetails> clo, Object... args) {
    LOGGER.trace("load cache...");
    super.loadCache(clo, args);
}

應該 :

@Override
public void loadCache(IgniteBiInClosure<Long, ChannelDetails> clo, Object... args) {
    LOGGER.trace("Load all cache data from db. this part should be used if Ignite starts.");
    if (args == null || args.length == 0) {
        channelDetailsJpaRepository.findAll()
                .forEach(channelDetails -> clo.apply(channelDetails.getId(), channelDetails));
    } else {
        throw new NotImplementedException("Handle to load objects by id collection.");
    }
}

這個解決方案不是完美的(它有很多部分可以做得更好),但是它可以工作並且我們可以使用它。

Ignite不會隱式調用IgniteCache#loadCache方法。 您應該自己進行操作,否則只能通過get操作從存儲中加載條目。

另外,我已經檢查並確保Ignite將本地實例注入商店。 您如何檢查? 請注意,存儲實例在集群中的所有節點上都不能相同。 Ignite是分布式系統,此對象將在所有節點上進行序列化和反序列化,並且該對象(cacheStoreAdapter)的文件名可能恰好為null 當Ignite調用store時,您應該會看到此注入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM