当键为 BinaryObject 且没有 类 可用于键类型时,Ignite readThrough 出现问题
Problem with Ignite readThrough when key is BinaryObject and no classes available for key type
我有一个用例,我的 Ignite 缓存 key/value 没有对应的 Java class,我使用 BinaryObject 作为键和值类型。下面的代码工作正常(没有任何通读)。
CacheConfiguration cfg = new CacheConfiguration("cache1");
IgniteCache<BinaryObject, BinaryObject> cache1 = ignite.getOrCreateCache(cfg).withKeepBinary();
cache1.put(createBOKey("mykey", "k1"), createBOVal());
cache1.put(createBOKey("mykey", "k2"), createBOVal());
cache1.put(createBOKey("mykey", "k3"), createBOVal());
Object v1 = cache1.get(createBOKey("mykey", "k1"));
System.out.println("**** cache1 key " + v1); // shows value
Object v2 = cache1.get(createBOKey("mykey", "k10"));
System.out.println("**** cache1 key " + v2); // show null
BinaryObject createBOKey(String k, String v) {
BinaryObjectBuilder builder = ignite.binary().builder("key-type1");
builder.setField(k, v);
return builder.build();
}
BinaryObject createBOVal() {
BinaryObjectBuilder builder = ignite.binary().builder("value-type1");
builder.setField(fieldName("cache1", "f1"), "hello");
builder.setField(fieldName("cache1", "f2"), 10.75);
return builder.build();
}
现在,一旦我为此缓存启用 readThrough,它就会开始因缓存未命中而失败。
cfg.setReadThrough(true);
cfg.setCacheLoaderFactory(new Factory<CacheLoader<BinaryObject, BinaryObject>>() {
@Override
public CacheLoader<BinaryObject, BinaryObject> create() {
return new CacheLoader<BinaryObject, BinaryObject>() {
@Override
public BinaryObject load(BinaryObject obj) throws CacheLoaderException {
System.out.println("**** Loading from backingstore " + obj);
return null;
}
@Override
public Map<BinaryObject, BinaryObject> loadAll(Iterable<? extends BinaryObject> arg0) throws CacheLoaderException {
return null;
}
};
}
});
在缓存未命中时,它会抛出以下异常,甚至不会到达 cacheloader.load()。
Exception in thread "main" javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: key-type1
at org.apache.ignite.internal.processors.cache.GridCacheUtils.convertToCacheException(GridCacheUtils.java:1317)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.cacheException(IgniteCacheProxyImpl.java:2066)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.get(IgniteCacheProxyImpl.java:1093)
at org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.get(GatewayProtectedCacheProxy.java:676)
at com.basit.bo.btree.TestBinaryTreeMapKey.main(TestBinaryTreeMapKey.java:74)
Caused by: class org.apache.ignite.IgniteCheckedException: key-type1
at org.apache.ignite.internal.util.IgniteUtils.cast(IgniteUtils.java:7507)
at org.apache.ignite.internal.processors.closure.GridClosureProcessor.body(GridClosureProcessor.java:975)
at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:120)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: class org.apache.ignite.binary.BinaryInvalidTypeException: key-type1
at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:762)
at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1757)
at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1716)
at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:792)
at org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:142)
at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinary(CacheObjectUtils.java:176)
at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinaryIfNeeded(CacheObjectUtils.java:67)
at org.apache.ignite.internal.processors.cache.CacheObjectContext.unwrapBinaryIfNeeded(CacheObjectContext.java:136)
at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1808)
at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1796)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadFromStore(GridCacheStoreManagerAdapter.java:314)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.load(GridCacheStoreManagerAdapter.java:293)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAllFromStore(GridCacheStoreManagerAdapter.java:434)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAll(GridCacheStoreManagerAdapter.java:400)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.call(GridCacheAdapter.java:2225)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.call(GridCacheAdapter.java:2223)
at org.apache.ignite.internal.processors.cache.GridCacheContext.call(GridCacheContext.java:1479)
at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:7005)
at org.apache.ignite.internal.processors.closure.GridClosureProcessor.body(GridClosureProcessor.java:967)
... 4 more
Caused by: java.lang.ClassNotFoundException: key-type1
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at org.apache.ignite.internal.util.IgniteUtils.forName(IgniteUtils.java:8828)
at org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:324)
at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:753)
... 22 more
您还应该将 storeKeepBinary
设置为 true
。
我有一个用例,我的 Ignite 缓存 key/value 没有对应的 Java class,我使用 BinaryObject 作为键和值类型。下面的代码工作正常(没有任何通读)。
CacheConfiguration cfg = new CacheConfiguration("cache1");
IgniteCache<BinaryObject, BinaryObject> cache1 = ignite.getOrCreateCache(cfg).withKeepBinary();
cache1.put(createBOKey("mykey", "k1"), createBOVal());
cache1.put(createBOKey("mykey", "k2"), createBOVal());
cache1.put(createBOKey("mykey", "k3"), createBOVal());
Object v1 = cache1.get(createBOKey("mykey", "k1"));
System.out.println("**** cache1 key " + v1); // shows value
Object v2 = cache1.get(createBOKey("mykey", "k10"));
System.out.println("**** cache1 key " + v2); // show null
BinaryObject createBOKey(String k, String v) {
BinaryObjectBuilder builder = ignite.binary().builder("key-type1");
builder.setField(k, v);
return builder.build();
}
BinaryObject createBOVal() {
BinaryObjectBuilder builder = ignite.binary().builder("value-type1");
builder.setField(fieldName("cache1", "f1"), "hello");
builder.setField(fieldName("cache1", "f2"), 10.75);
return builder.build();
}
现在,一旦我为此缓存启用 readThrough,它就会开始因缓存未命中而失败。
cfg.setReadThrough(true);
cfg.setCacheLoaderFactory(new Factory<CacheLoader<BinaryObject, BinaryObject>>() {
@Override
public CacheLoader<BinaryObject, BinaryObject> create() {
return new CacheLoader<BinaryObject, BinaryObject>() {
@Override
public BinaryObject load(BinaryObject obj) throws CacheLoaderException {
System.out.println("**** Loading from backingstore " + obj);
return null;
}
@Override
public Map<BinaryObject, BinaryObject> loadAll(Iterable<? extends BinaryObject> arg0) throws CacheLoaderException {
return null;
}
};
}
});
在缓存未命中时,它会抛出以下异常,甚至不会到达 cacheloader.load()。
Exception in thread "main" javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: key-type1
at org.apache.ignite.internal.processors.cache.GridCacheUtils.convertToCacheException(GridCacheUtils.java:1317)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.cacheException(IgniteCacheProxyImpl.java:2066)
at org.apache.ignite.internal.processors.cache.IgniteCacheProxyImpl.get(IgniteCacheProxyImpl.java:1093)
at org.apache.ignite.internal.processors.cache.GatewayProtectedCacheProxy.get(GatewayProtectedCacheProxy.java:676)
at com.basit.bo.btree.TestBinaryTreeMapKey.main(TestBinaryTreeMapKey.java:74)
Caused by: class org.apache.ignite.IgniteCheckedException: key-type1
at org.apache.ignite.internal.util.IgniteUtils.cast(IgniteUtils.java:7507)
at org.apache.ignite.internal.processors.closure.GridClosureProcessor.body(GridClosureProcessor.java:975)
at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:120)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: class org.apache.ignite.binary.BinaryInvalidTypeException: key-type1
at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:762)
at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize0(BinaryReaderExImpl.java:1757)
at org.apache.ignite.internal.binary.BinaryReaderExImpl.deserialize(BinaryReaderExImpl.java:1716)
at org.apache.ignite.internal.binary.BinaryObjectImpl.deserializeValue(BinaryObjectImpl.java:792)
at org.apache.ignite.internal.binary.BinaryObjectImpl.value(BinaryObjectImpl.java:142)
at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinary(CacheObjectUtils.java:176)
at org.apache.ignite.internal.processors.cache.CacheObjectUtils.unwrapBinaryIfNeeded(CacheObjectUtils.java:67)
at org.apache.ignite.internal.processors.cache.CacheObjectContext.unwrapBinaryIfNeeded(CacheObjectContext.java:136)
at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1808)
at org.apache.ignite.internal.processors.cache.GridCacheContext.unwrapBinaryIfNeeded(GridCacheContext.java:1796)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadFromStore(GridCacheStoreManagerAdapter.java:314)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.load(GridCacheStoreManagerAdapter.java:293)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAllFromStore(GridCacheStoreManagerAdapter.java:434)
at org.apache.ignite.internal.processors.cache.store.GridCacheStoreManagerAdapter.loadAll(GridCacheStoreManagerAdapter.java:400)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.call(GridCacheAdapter.java:2225)
at org.apache.ignite.internal.processors.cache.GridCacheAdapter.call(GridCacheAdapter.java:2223)
at org.apache.ignite.internal.processors.cache.GridCacheContext.call(GridCacheContext.java:1479)
at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:7005)
at org.apache.ignite.internal.processors.closure.GridClosureProcessor.body(GridClosureProcessor.java:967)
... 4 more
Caused by: java.lang.ClassNotFoundException: key-type1
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at org.apache.ignite.internal.util.IgniteUtils.forName(IgniteUtils.java:8828)
at org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:324)
at org.apache.ignite.internal.binary.BinaryContext.descriptorForTypeId(BinaryContext.java:753)
... 22 more
您还应该将 storeKeepBinary
设置为 true
。