我已关注ignite documentation并创建了我的商店适配器:
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)
)@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
中,我知道它很难看,但我不能解释我的测试中断的原因。)
答案 0 :(得分:2)
感谢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.");
}
}
这个解决方案并不完美(它有很多部分可以做得更好)但它有效,我们可以使用它。
答案 1 :(得分:1)
Ignite不会隐式调用IgniteCache#loadCache
方法。你应该自己做,否则只能通过获取操作从商店加载。
此外,我已检查并确保Ignite将本地实例注入商店。你怎么检查它?请注意,群集中的所有节点上的实例实例不能相同。 Ignite是分布式系统,该对象将在所有节点上进行序列化和预期化,并且该对象(cacheStoreAdapter)可能具有归档null
。当Ignite调用商店时,你会看到这个注入。