【问题标题】:Query with predicate on indexed field在索引字段上使用谓词进行查询
【发布时间】:2018-02-15 16:49:37
【问题描述】:

在我的项目中,我最近遇到了一个与配置了 QueryCache 的 Map 相关的问题。

我有两个字段的实体:

class AccountingRule {
    long key;
    String code;
}

它的 Map 的 Map 配置,包括 QueryCache 配置:

MapConfig mapConfig = new MapConfig("AccountingRule")
    .setInMemoryFormat(InMemoryFormat.BINARY)
    .setReadBackupData(true)
    .setBackupCount(1)
    .addQueryCacheConfig(new QueryCacheConfig()
        .setName("AccountingRule")
        .setPredicateConfig(new PredicateConfig(TruePredicate.INSTANCE))
        .setIncludeValue(true)
        .setPopulate(true)
        .setDelaySeconds(0)
    );

在 main 中,我使用我的配置运行 hazelcast 实例,然后:

  • 为 QueryCache 添加索引
  • 将实体放入 IMap
  • 通过检查 QueryCache.get 是否返回插入的实体,等到插入传播到 QueryCache
  • 使用索引字段上的谓词从 QueryCache 中获取相同的实体

例如:

HazelcastInstance hazelcast = createHazelcastInstance();
IMap<Long, AccountingRule> map = hazelcast.getMap("AccountingRule");
QueryCache<Long, AccountingRule> queryCache = map.getQueryCache("AccountingRule");

queryCache.addIndex("code", false);

while (true) {
    AccountingRule ar = newAccountingRule();
    map.put(ar.getKey(), ar);

    // wait for query cache
    AccountingRule fromQueryCache = queryCache.get(ar.getKey());
    while (fromQueryCache == null) {
        log.info("Waiting for query cache");
        fromQueryCache = queryCache.get(AccountingRule.class, ar.getKey());
     }
    log.info("query cache updated");

    // get entity from query cache using predicate
    Predicate codePredicate = equal("code", ar.getCode());
    AccountingRule fromQueryCacheWithPredicate = getOnlyElement(queryCache.values(codePredicate), null);
    if (fromQueryCacheWithPredicate == null) {
        log.error("AccountingRule with id {} from query cash is null", ar.getKey());
        System.exit(1);
    }
}

不幸的是,它失败了。 QueryCache.get 返回实体,但基于索引字段谓词的查询不返回任何内容。当我稍等片刻并重试查询时,就可以了。看起来索引是异步更新的,对吗?有什么办法可以避免吗?

当它起作用时有两种选择:

  • 删除索引->没有索引没问题:)
  • 像这样在 QueryCache conf 中声明索引,而不是在 main 中:

代码:

MapConfig mapConfig = new MapConfig("AccountingRule")
    .setInMemoryFormat(InMemoryFormat.BINARY)
    .setReadBackupData(true)
    .setBackupCount(1)
    .addQueryCacheConfig(new QueryCacheConfig()
        .setName("AccountingRule")
        .setPredicateConfig(new PredicateConfig(TruePredicate.INSTANCE))
        .setIncludeValue(true)
        .setPopulate(true)
        .setDelaySeconds(0)
        .addIndexConfig(new MapIndexConfig("code", false))
    );

问题是为什么当我在配置中添加索引时它不能正常工作?

【问题讨论】:

    标签: indexing hazelcast query-cache


    【解决方案1】:

    看起来有关于这个问题的错误。执行QueryCache.addIndex 时,仅当查询缓存中有条目时才会创建索引。此外,根本不会创建源自Config(编程或声明)的索引,并且在查询缓存上运行的查询会进行全扫描。

    我看到你已经创建了一个关于这个问题的 Github 问题 (#12358),请跟进它以进行修复。

    【讨论】:

    • 您对源自 Config 的索引是正确的。我进行了小型性能测试,看起来使用QueryCacheConfig.addIndexConfig 添加索引配置根本不会创建索引。关于QueryCache.addIndex,它仅在 QueryCache 为空时添加索引。
    猜你喜欢
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多