首页 > 解决方案 > call put 后​​获取旧数据

问题描述

我在客户端节点上使用“put”方法将对象放入缓存;然后我在其他客户端节点上获取它,执行一些逻辑并放置一个与以前具有相同密钥的新对象。我认为新对象会因为使用相同的密钥而恢复旧对象,但实际上我在几分钟后得到了旧对象。奇怪的是我在几分钟后得到了新对象。我有三个服务器节点,cacheWriteSynchronizationMode 是“FULL_SYNC”。

样本:

// The problem code. 
// The mothed means getting the Object from cache by key and using only once. 
// In fact, I still get the old one by using this method after few minutes, and get right one after more few minutes.
private MyEntity getAndClear(long entityId) {   
    MyEntity pocketLineEntity = dao.selectByEntityId(entityId);// get Object may used by other place from cache
    if(pocketLineEntity == null) {
        return null;
    }
    // I want to use only once, so clear the content of Object here. My method is inserting a new empty Object into cache with same key.
    MyEntity entity = new MyEntity();
    entity.setEntityId(entityId);
    dao.insert(entity);// insert new Object

    // return old one getted before
    return pocketLineEntity; // do some thing in other code, and only use once, because I insert new one
}




// Here is the code of dao
// select method
public MyEntity selectByEntityId(long entityId) {
    MyEntityKey key = new MyEntityKey();
    key.setEntityId(entityId);
    MyEntity entity = cache.get(key);// ignite cache (IgniteCache<MyEntityKey, MyEntity>)
    return entity;

}

// insert method
public void insert(MyEntity entity) {
    MyEntityKey key = new MyEntityKey();
    key.setEntityId(entity.getEntityId());
    cache.put(key, entity);// ignite cache (IgniteCache<MyEntityKey, MyEntity>)
}






// The class of MyEntityKey 
public class MyEntityKey {
    private long entityId;

    public MyEntityKey() {
    }

    public MyEntityKey(long entityId) {
        this.entityId = entityId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        MyEntityKey key = (MyEntityKey) o;
        return entityId == key.entityId;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (entityId ^ (entityId >>> 32));
        return result;
    }

    public long getEntityId() {
        return entityId;
    }

    public void setEntityId(long entityId) {
        this.entityId = entityId;
    }
}

缓存配置的一部分:

    private void init(Ignite ignite) {
    // cache config
    CacheConfiguration<MyEnityKey, MyEnity> cfg = new CacheConfiguration<>();
    cfg.setName(MyEnity.class.getSimpleName().toUpperCase());
    cfg.setCacheMode(CacheMode.PARTITIONED);
    cfg.setAtomicityMode(CacheAtomicityMode.ATOMIC);
    cfg.setBackups(1);
    cfg.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC);
    cfg.setCopyOnRead(true);
    cfg.setOnheapCacheEnabled(true);
    cfg.setRebalanceMode(CacheRebalanceMode.ASYNC);
    cfg.setPartitionLossPolicy(PartitionLossPolicy.IGNORE);
    cfg.setQueryEntities(Arrays.asList(createQueryEntity()));
    cfg.setSqlIndexMaxInlineSize(30);
    CacheKeyConfiguration cacheKeyConfiguration = new CacheKeyConfiguration(MyEnityKey.class);
    cacheKeyConfiguration.setAffinityKeyFieldName("entityId");
    cfg.setKeyConfiguration(cacheKeyConfiguration);

    // lru
    cfg.setDataRegionName(MyEnity.class.getSimpleName());
    LruEvictionPolicy evictionPolicy = new LruEvictionPolicy(3600000);
    cfg.setEvictionPolicy(evictionPolicy);



    // read through
    cfg.setCacheStoreFactory(FactoryBuilder.factoryOf(MyEnityMongoStore.class));
    cfg.setCacheStoreSessionListenerFactories(daoConfig.getCacheStoreSessionListenerFactories());

    cfg.setReadThrough(true);
    cfg.setWriteThrough(true);
    cfg.setWriteBehindEnabled(true);
    cfg.setWriteBehindFlushThreadCount(1);
    cfg.setWriteBehindFlushSize(10240);
    cfg.setWriteBehindFlushFrequency(300000);
    cfg.setWriteBehindBatchSize(512);
    IgniteCache<MyEnityKey, MyEnity> cache = ignite.getOrCreateCache(cfg);  

}

private QueryEntity createQueryEntity() {
    QueryEntity queryEntity = new QueryEntity();

    // key-value
    queryEntity.setKeyType(MyEnityKey.class.getName());
    queryEntity.setValueType(MyEnity.class.getName());

    // fields
    LinkedHashMap<String, String> fields = new LinkedHashMap<>();
    fields.put("entityId", long.class.getName());
    fields.put("pocketLines", String.class.getName());
    queryEntity.setFields(fields);

    return queryEntity;
}

标签: ignite

解决方案


此问题似乎与以下错误有关:https ://issues.apache.org/jira/browse/IGNITE-5795

计划在 Ignite 2.8 中对其进行修复

目前,您可以通过在所有节点上指定BinaryConfiguration#classNames来解决它。请参阅以下问题:AffinityKeyMapped not working with Ignite 2.4/2.5/2.6 and Scala


推荐阅读