为什么在较大的分区上访问Cache中的LocalEntries会变慢?

时间:2016-11-07 21:10:12

标签: performance ignite

我们正在Apache Ignite中测试我们系统的性能。为了隔离性能问题,我们正在单个节点上进行测试。我们已经创建了10个零件并且改变了零件的尺寸。我们案例中的一个部分是记录的ArrayList,因此我们有100条记录,1000,10000等。

问题在于,当我们尝试迭代本地条目时,随着的增加,性能会下降。 注意,这是迭代迭代器,而不是遍历记录的ArrayList这不是预期的行为。相反,对于局部迭代器/集合,迭代值不会(也不应该)降低性能。

    IgniteCallable<Map<String,Long>> closure = () -> {
        Map<String,Long> results = new LinkedHashMap<>();
        // Get all the local entries for this node
        long startTime = System.nanoTime();
        Iterable<Entry<Long, List<Object>>> localEntries = cache.localEntries(CachePeekMode.PRIMARY);
        results.put("getCache",System.nanoTime() - startTime);


        startTime = System.nanoTime();
        List<Entry<Long, List<Object>>> entries = new LinkedList();
        for(Entry<Long, List<Object>> entry : localEntries){
            entries.add(entry);
        }
        List<List<Object>> iteratedList = new LinkedList();
        // THIS is the part that takes like 90% of the time
        results.put("traverseIterator",System.nanoTime()-startTime);


        startTime = System.nanoTime();
        for(Entry<Long, List<Object>> entry : entries){
            iteratedList.add(entry.getValue());
        }
        results.put("getValues",System.nanoTime()-startTime);

        startTime = System.nanoTime();
        int prtCnt = 0;
        int totalCnt = 0;
        for(List<Object> list : iteratedList){
            int i = 0;
            for(Object mr: list){
                i++;
            }
            prtCnt++;
            totalCnt += i;
        }
        results.put("traverseSet",System.nanoTime()-startTime);

        results.put("checksum",new Long(totalCnt));
        return results;
    };

最初我们认为它是集群开销或协调的东西,因为这个迭代器是集群的一部分,但如果性能取决于值的大小,则没有意义。它几乎表现得好像是反序列化值,但是(据我所知)我们在堆上有所有东西,所以不应该有这样的开销。任何人都可以看到为什么迭代和获取缓存的值花了这么长时间?

这是我的缓存配置:

    <property name="cacheConfiguration">
        <bean class="org.apache.ignite.configuration.CacheConfiguration">
            <!-- Set a cache name. -->
            <property name="name" value="monthly" />
            <property name="rebalanceMode" value="ASYNC" />
            <property name="cacheMode" value="PARTITIONED" />
            <property name="atomicityMode" value="ATOMIC"/>
            <property name="backups" value="1" />
            <property name="memoryMode" value="ONHEAP_TIERED" />
            <property name="offHeapMaxMemory" value="0" />
            <property name="swapEnabled" value="false" />
            <property name="cacheStoreFactory">
                <bean class="javax.cache.configuration.FactoryBuilder" factory-method="factoryOf">
                    <constructor-arg value="com.ignite.datastore.ListDataStore" />
                </bean>
            </property>
            <property name="readThrough" value="true" />
            <property name="writeThrough" value="true" />
            <property name="copyOnRead" value="false" />
        </bean>
    </property>

1 个答案:

答案 0 :(得分:2)

当您在本地读取数据时,不应发生copyOnRead=false反序列化(总是只有一个节点的情况)。如果您在特定情况下看到不同的行为,那么它可能是一个错误。我建议你创建一个测试并给Ignite社区[1]。有人会看一看并提供反馈。

[1] http://ignite.apache.org/community/resources.html#mail-lists