使用谓词加载缓存

Load cache with predicate

我有一个缓存,里面有很多类型。我是 运行 纯 Java 节点。我在部署服务之前在启动时加载缓存。缓存由 CacheJdbcPojoStore 支持。我正在使用 Ignite 1.8。

当我加载空谓词时,一切正常。所有类型及其实例都加载到内存中。但是,当我加载谓词时,出现以下错误。奇怪的是,在 windows 上,错误没有发生并且谓词工作正常。但是在 Linux 上,它失败了。这里可能出了什么问题?

缓存加载代码。 ServiceStatus 和 ServiceMetric 只是我的数据库支持的两种 pojo 类型。

        log.info("Local load cache started.");
        cache.localLoadCache(new IgniteBiPredicate() {
            @Override
            public boolean apply(Object key, Object value) {
                // include by default, exclude explicitly

                // no service status before today
                if (value instanceof ServiceStatus) {
                    if (((ServiceStatus)value).getLastUpdated().before(Timestamp.valueOf(LocalDate.now().atStartOfDay()))){
                        return false;
                    }
                }

                // no service metrics before today
                if (value instanceof ServiceMetric) {
                    if (((ServiceMetric)value).getLastUpdated().before(Timestamp.valueOf(LocalDate.now().atStartOfDay()))){
                        return false;
                    }
                }

                return true;
            }
        }, null);
        log.info("Local load cache finished.");

错误。

[错误] 2017-01-30 13:01:28.913 [main] ServiceGrid - 异常失败。 javax.cache.integration.CacheLoaderException:加载缓存失败:D9Cache 在 org.apache.ignite.cache.store.jdbc.CacheAbstractJdbcStore.loadCache(CacheAbstractJdbcStore.java:847) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadCache(GridCacheStoreManagerAdapter.java:512) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.localLoadCache(GridDhtCacheAdapter.java:497) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.IgniteCacheProxy.localLoadCache(IgniteCacheProxy.java:413) ~[ignite-core-1.8.0.jar:1.8.0] 在 com.nmf.model.persistence.CacheUtil.loadCache(CacheUtil.java:87) ~[shared-data-model-1.0-SNAPSHOT.jar:?] 在 com.nmf.grid.ServiceGrid.main(ServiceGrid.java:75) [dragon9-service-grid-1.0-SNAPSHOT.jar:?] 由以下原因引起:org.apache.ignite.binary.BinaryObjectException:ID 的 class 解析失败:292145121 在 org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:696) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1491) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1450) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:637) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:142) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.loadEntry(GridDhtCacheAdapter.java:528) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.access$300(GridDhtCacheAdapter.java:94) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter$4.apply(GridDhtCacheAdapter.java:501) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter$4.apply(GridDhtCacheAdapter.java:497) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter$3.apply(GridCacheStoreManagerAdapter.java:528) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.cache.store.jdbc.CacheAbstractJdbcStore$1.call(CacheAbstractJdbcStore.java:462) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.cache.store.jdbc.CacheAbstractJdbcStore$1.call(CacheAbstractJdbcStore.java:429) ~[ignite-core-1.8.0.jar:1.8.0] 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_111] 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_111] 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_111] 在 java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_111] 原因:org.apache.ignite.IgniteCheckedException:在编组器缓存和本地文件中找不到 Class 定义。 [id=292145121, file=/tmp/ignite/work/marshaller/292145121.classname] 在 org.apache.ignite.internal.MarshallerContextImpl.className(MarshallerContextImpl.java:218) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.MarshallerContextAdapter.getClass(MarshallerContextAdapter.java:174) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:680) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1491) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1450) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:637) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:142) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.loadEntry(GridDhtCacheAdapter.java:528) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter.access$300(GridDhtCacheAdapter.java:94) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter$4.apply(GridDhtCacheAdapter.java:501) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheAdapter$4.apply(GridDhtCacheAdapter.java:497) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter$3.apply(GridCacheStoreManagerAdapter.java:528) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.cache.store.jdbc.CacheAbstractJdbcStore$1.call(CacheAbstractJdbcStore.java:462) ~[ignite-core-1.8.0.jar:1.8.0] 在 org.apache.ignite.cache.store.jdbc.CacheAbstractJdbcStore$1.call(CacheAbstractJdbcStore.java:429) ~[ignite-core-1.8.0.jar:1.8.0] 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_111] 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[?:1.8.0_111] 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[?:1.8.0_111] 在 java.lang.Thread.run(Thread.java:745) ~[?:1.8.0_111]

没有其他信息,很难给出建议,但您可以使用 cache.withKeepBinary() 检查它是否可重现。另外,尝试反弹整个集群。奇怪的是这个案例只代表 Linux.

我也看到了这个问题(为了节省时间)让我完全放弃使用谓词。在使用谓词加载缓存时,我 有时 会收到您在上面提到的异常。我在 Linux 和 windows 上都观察到了这一点,但它并不一致。有时缓存会加载,有时不会。正如我所说,我被赶时间所以假设它是 Ignite 代码中某处的竞争条件,即 运行 谓词并解决了这个问题。

如果任何 Ignite 专家可以进一步阐明问题的潜在根源,我很乐意尽可能提供帮助。

--更新-- 在尝试从后备存储加载日期之前,我已经通过 "warming" 二进制编组器解决了这个问题(这导致文件未找到错误)

所以我所做的是沿着以下几行:

 IgniteCache cache = ignite.getOrCreateCache("my-cache");
 warmBinaryMarshaller(cache);
 cache.localLoadCache(cache, new MyPredicate(), (Object[])null);

...

private static void warmBinaryMarshaller(IgniteCache cache) throws Exception
{
    final IgniteCache transientCache = cache.withSkipStore();
    try{
        CacheKey key = new CacheKey();
        CacheEntity entity = CacheEntity(); 
        key.setId(0);
        entity.setId(0);
        transientCache.put(key, entity);
        transientCache.remove(key);
     } catch (Exception e) {
         log.error(e.getMessage(), e);
     }
}

...

然后我可以成功地从我的数据库加载对象