Wir testen die Leistung unseres Systems in Apache Ignite. Um ein Leistungsproblem zu isolieren, testen wir auf einem einzelnen Knoten. Wir haben 10 Teile erstellt und variieren die Größe der Teile. Ein Teil in unserem Fall ist eine Arraylist von Datensätzen, also haben wir 100 Datensätze, 1000, 10000 usw.Warum ist der Zugriff auf lokale Einträge im Cache bei größeren Partitionen langsamer?
Das Problem ist, dass, wenn wir versuchen, die Leistung sinkt als Wert durch die lokalen Einträge iterieren Steigerungen Größe. Beachten Sie, dass hier der Iterator durchlaufen wird und nicht die ArrayList
Datensätze durchlaufen werden. Dies ist nicht das erwartete Verhalten. Im Gegensatz dazu verringert sich (und sollte nicht) die Performance für einen lokalen Iterator/eine Iterationsgruppe, die durch die Werte iteriert.
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;
};
Anfangs dachten wir, es Cluster über Kopf oder etwas für die Koordination war da dieser Iterator Teil eines Clusters ist, aber das macht keinen Sinn, wenn die Leistung von der Größe des Wertes abhängt. Es verhält sich fast so, als würde es den Wert deserialisieren, jedoch (soweit ich weiß) haben wir alles auf dem Haufen, also sollte es diesen Overhead nicht geben. Kann jemand sehen, warum das Iterieren und Erhalten der Werte des Caches so lange dauert?
Hier ist meine Cache-Konfiguration:
<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>
Ok, wird einen eigenständigen Testfall morgen. Vielen Dank –