[ 
https://issues.apache.org/jira/browse/IGNITE-13213?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Manuel Núñez updated IGNITE-13213:
----------------------------------
    Fix Version/s:     (was: 2.9)

> Improve Queue performance
> -------------------------
>
>                 Key: IGNITE-13213
>                 URL: https://issues.apache.org/jira/browse/IGNITE-13213
>             Project: Ignite
>          Issue Type: Improvement
>          Components: data structures
>    Affects Versions: 2.4, 2.5, 2.6, 2.7, 2.8, 2.7.5, 2.7.6, 2.8.1
>            Reporter: Manuel Núñez
>            Priority: Major
>         Attachments: image-2020-07-04-15-35-43-879.png
>
>
> Queue performance can be improved by making some changes, related to Queue 
> Item Key(1) , offer method (2) and collection configuration (3) and related 
> IGNITE-13203.
> With those changes queue structure is 10%-30% faster than first Ignite's 
> competitor:
> !image-2020-07-04-15-35-43-879.png!
> Queue performance benchmark with different queue message types, multiple 
> clients (M) and 2 server nodes (IMDG):
>  * string messages: 1KB, 10KB, 100KB
>  * byte[] messages: 1KB, 10KB, 100KB
>  * complex objects with cycle references (cpx) messages
> Legend:
>  * {color:#4c9aff}Blue{color}: first Ignite's competitor - on heap only, open 
> source version does not support off-heap neither OOTB persistence, we can see 
> GC pauses
>  * {color:#ffab00}Orange{color}: Ignite off-heap with native persistence 
> enabled
>  * {color:#de350b}Red{color}: Ignite off-heap only
> 1. Queue Item Key -> currently, queue hash code is computed for every single 
> item key using full queue name (> 20 chars) on Queue Item Key constructor.
>  Proposal compute hash on GridCacheQueueAdapter constructor and pass it to 
> itemKey method
> {code:java}
>     private static QueueItemKey itemKey(IgniteUuid id,
>         int queueNameHash,
>         boolean collocated,
>         long idx) {
>         return collocated ?
>             new CollocatedQueueItemKey(id, queueNameHash, idx) : new 
> GridCacheQueueItemKey(id, queueNameHash, idx);
>     }
> {code}
> 1.1. CollocatedQueueItemKey (fully compatible)
> {code:java}
> /*
>  * Licensed to the Apache Software Foundation (ASF) under one or more
>  * contributor license agreements.  See the NOTICE file distributed with
>  * this work for additional information regarding copyright ownership.
>  * The ASF licenses this file to You under the Apache License, Version 2.0
>  * (the "License"); you may not use this file except in compliance with
>  * the License.  You may obtain a copy of the License at
>  *
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> package org.apache.ignite.internal.processors.datastructures;
> import org.apache.ignite.cache.affinity.AffinityKeyMapped;
> import org.apache.ignite.internal.util.typedef.internal.S;
> import org.apache.ignite.lang.IgniteUuid;
> public class CollocatedQueueItemKey implements QueueItemKey {
>     /** */
>     private IgniteUuid queueId;
>     /** */
>     @AffinityKeyMapped
>     private int queueNameHash;
>     /** */
>     private long idx;
>     /**
>      * @param queueId Queue unique ID.
>      * @param queueName Queue name.
>      * @param idx Item index.
>      */
>     public CollocatedQueueItemKey(IgniteUuid queueId, int queueNameHash, long 
> idx) {
>         this.queueId = queueId;
>         this.queueNameHash = queueNameHash;
>         this.idx = idx;
>     }
>     /** {@inheritDoc} */
>     @Override public boolean equals(Object o) {
>         if (this == o)
>             return true;
>         if (o == null || getClass() != o.getClass())
>             return false;
>         CollocatedQueueItemKey itemKey = (CollocatedQueueItemKey)o;
>         return idx == itemKey.idx && queueId.equals(itemKey.queueId);
>     }
>     /** {@inheritDoc} */
>     @Override public int hashCode() {
>         int res = queueId.hashCode();
>         res = 31 * res + (int)(idx ^ (idx >>> 32));
>         return res;
>     }
>     /** {@inheritDoc} */
>     @Override public String toString() {
>         return S.toString(CollocatedQueueItemKey.class, this);
>     }
> }
> {code}
> 1.2. GridCacheQueueItemKey (not compatible with existing queues, need to be 
> analysed), remove queueName field as is not required at all (use queueId 
> instead), this will reduce network traffic and improve serialisation 
> performance.
> {code:java}
> /*
>  * Licensed to the Apache Software Foundation (ASF) under one or more
>  * contributor license agreements.  See the NOTICE file distributed with
>  * this work for additional information regarding copyright ownership.
>  * The ASF licenses this file to You under the Apache License, Version 2.0
>  * (the "License"); you may not use this file except in compliance with
>  * the License.  You may obtain a copy of the License at
>  *
>  *      http://www.apache.org/licenses/LICENSE-2.0
>  *
>  * Unless required by applicable law or agreed to in writing, software
>  * distributed under the License is distributed on an "AS IS" BASIS,
>  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>  * See the License for the specific language governing permissions and
>  * limitations under the License.
>  */
> package org.apache.ignite.internal.processors.datastructures;
> import java.io.Externalizable;
> import java.io.IOException;
> import java.io.ObjectInput;
> import java.io.ObjectOutput;
> import org.apache.ignite.internal.util.typedef.internal.S;
> import org.apache.ignite.internal.util.typedef.internal.U;
> import org.apache.ignite.lang.IgniteUuid;
> /**
>  * Queue item key.
>  */
> class GridCacheQueueItemKey implements Externalizable, QueueItemKey {
>     /** */
>     private static final long serialVersionUID = 0L;
>     /** */
>     private IgniteUuid queueId;
>     /** */
>     private long idx;
>     /**
>      * Required by {@link Externalizable}.
>      */
>     public GridCacheQueueItemKey() {
>         // No-op.
>     }
>     /**
>      * @param queueId Queue unique ID.
>      * @param queueNameHash the queue hash, not used
>      * @param idx Item index.
>      */
>     GridCacheQueueItemKey(IgniteUuid queueId, int queueNameHash, long idx) {
>         this.queueId = queueId;
>         this.idx = idx;
>     }
>     /**
>      * @return Item index.
>      */
>     public Long index() {
>         return idx;
>     }
>     /**
>      * @return Queue UUID.
>      */
>     public IgniteUuid queueId() {
>         return queueId;
>     }
>     /** {@inheritDoc} */
>     @Override public void writeExternal(ObjectOutput out) throws IOException {
>         U.writeGridUuid(out, queueId);
>         out.writeLong(idx);
>     }
>     /** {@inheritDoc} */
>     @Override public void readExternal(ObjectInput in) throws IOException, 
> ClassNotFoundException {
>         queueId = U.readGridUuid(in);
>         idx = in.readLong();
>     }
>     /** {@inheritDoc} */
>     @Override public boolean equals(Object o) {
>         if (this == o)
>             return true;
>         if (o == null || getClass() != o.getClass())
>             return false;
>         GridCacheQueueItemKey itemKey = (GridCacheQueueItemKey)o;
>         return idx == itemKey.idx && queueId.equals(itemKey.queueId);
>     }
>     /** {@inheritDoc} */
>     @Override public int hashCode() {
>         int res = queueId.hashCode();
>         res = 31 * res + (int)(idx ^ (idx >>> 32));
>         return res;
>     }
>     /** {@inheritDoc} */
>     @Override public String toString() {
>         return S.toString(GridCacheQueueItemKey.class, this);
>     }
> }
> {code}
> 2. Queue's offer method (fully compatible: this change affects 
> GridAtomicCacheQueueImpl and GridTransactionalCacheQueueImpl): Queue 
> structure is implemented as "client side structure", so 
> cache.getAndPut(itemKey(idx), item) call should be replaced by 
> cache.put(itemKey(idx), item) in offer method to avoid unnecessary network 
> traffic.
> 3. Optional but recommended, currently CollectionConfiguration does not allow 
> to change bounded cache configuration, but on some circustancies could be 
> interesting to improve performance, for example to change 
> CacheWriteSynchronizationMode from default FULL_SYNC to PRIMARY_SYNC, when we 
> have queues with backups.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to