0

I'm trying to add x number of objects via a simple for-loop to a distributed hazelcast queue (IQueue).

        HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
        BlockingQueue<String> configs = hazelcastInstance.getQueue("test"); 
        for(int i = 0; i<1000;i++) {
            configs.add("Some string"+i);
        }

Changing the values and in the config (see below) doesn't have any influence on the execution speed. I'd assume that increasing would block the insert operations and increasing would not (actually the loop should be run through as quickly as if the #add operation was on a local queue). However, the time executing the for-loop is the same. Even if i set both values to 0. Why is that (it's a two-node cluster with one node on a different vm)?

<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xsi:schemaLocation=
  "http://www.hazelcast.com/schema/config hazelcast-config-3.7.xsd"
  xmlns="http://www.hazelcast.com/schema/config"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <network>
        <port auto-increment="true" port-count="20">5701</port>
        <join>
            <multicast enabled="false">
        </multicast>
        <tcp-ip enabled="true">
            <member>172.105.66.xx</member> 
        </tcp-ip>
        </join>
    </network>

    <queue name="test">
        <statistics-enabled>false</statistics-enabled>
        <max-size>0</max-size>
        <backup-count>0</backup-count>
        <async-backup-count>1</async-backup-count>
        <empty-queue-ttl>-1</empty-queue-ttl>
    </queue>
</hazelcast>
cobby
  • 484
  • 3
  • 18

1 Answers1

2

The async-backups are not blocking your calls, so there should be a minimal difference in setting 0 or 1. Setting another value is meaningless on the 2 nodes cluster.

What makes the difference is the fact if the owner of the partition with your data structure is a local one or a remote one. The performance issues are in such case usually caused by the network latency between the caller (your test) and data structure owner (remote Hazelcast instance).

HazelcastInstance hazelcastInstance = Hazelcast.newHazelcastInstance();
IQueue<String> configs = hazelcastInstance.getQueue("test"); 
for(int i = 0; i<1000;i++) {
    configs.add("Some string"+i);
}
Member localMember = hazelcastInstance.getCluster().getLocalMember();
Member partitionOwner = hazelcastInstance.getPartitionService().getPartition(configs.getName()).getOwner();
boolean localCall = localMember.equals(partitionOwner);
System.out.println("Local calls to IQueue: " + localCall);
kwart
  • 3,154
  • 1
  • 21
  • 22
  • What do you mean with "blocking your calls"? What exactly is blocked when let's say node A makes an insert operation on a distributed queue that is on node B? Is the next statement on node A, node B or on both nodes delayed until the backup is completed? – cobby Jun 17 '19 at 16:21
  • When backup-count (i.e synchronized backup count) is greater than zero, then operation from member A goes to partition owner - i.e. member B. B proceeds with the operation and sends the backup operation to the given count of partition backup owners. Once all the partition backup owners confirms the backup operations to partition owner (B), it confirms the operation to the caller (A). – kwart Jun 17 '19 at 19:41
  • So you're saying that A only continues with code execution once it receives the acknowledgement from B? Or is A and the backup owner also blocked in a way? – cobby Jun 17 '19 at 20:32
  • There are 2 possible types of asynchronous processing in Hazelcast - async data operations (e.g. IMap.putAsync() method) and async backup operations. Async data operations don't wait for ACK from the partition owner. The IQueue data structure doesn't have asynchronous data operations so it always waits for an acknowledgment from the partition owner. Nevertheless, if there is no synchronous backup configured (backup-count=0), then the partition owner sends the ACK immediately after processing without waiting for ACK from async backups (even if async-backup-count>0). – kwart Jun 18 '19 at 06:02
  • Ok, let me put it another way. Node A makes an insert operation on a distributed queue that is on node B. Node B makes synchronized backups. Obviously node A thread is blocked as long as it receives the ACK from node B. But what about node B itself. Is its thread blocked as well, as long as it receives the ACKs from the backup nodes? – cobby Jun 18 '19 at 07:25
  • Which thread on Node B are you talking about - partition thread or application thread? If partition thread then Node B will have to wait for all backup partition owners to confirm (Node A in this case) before acking back to Node A for operation completion. – wildnez Jun 26 '19 at 01:48