多节点群集启动后,hazelcast队列的吞吐量就会降低吗?

时间:2019-06-15 16:05:49

标签: java performance distributed-computing hazelcast

我使用下面的测试来评估我的吞吐时间。当我运行本地一个节点群集时,吞吐时间约为90k消息/秒。一旦将另一个本地节点添加到群集,吞吐量就会下降到〜5k消息/秒。我会错过任何重要的配置吗?我将hazelcast配置为跳过跨节点的数据复制,所以无论有多少节点,速度都应该相同,对吧?

我在以下配置中使用Hazelcast 3.11:

<?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>localhost</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>0</async-backup-count>
        <empty-queue-ttl>-1</empty-queue-ttl>
    </queue>

</hazelcast>

吞吐量测试类:

package de.wipk.application.imdg;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IQueue;

public class HCTest {
  private static final int TOTAL = 1000000;
  private static final int LAP   = 100000;

  public static void main(String[] args) throws InterruptedException {
    final HazelcastInstance hz = Hazelcast.newHazelcastInstance();
    final IQueue<Object> queue = hz.getQueue("test");

    final long start = System.currentTimeMillis();
    long lastLap = start;

    Thread t = new Thread() {
      long lastLap = start;

      @Override
      public void run() {
        System.out.println((System.currentTimeMillis() - lastLap) + " Start receiving msgs");
        for (int i = 1; i < TOTAL + 1; ++i) {
          try {
            Object msg = queue.take();

            if (i % LAP == 0) {
              final long lapTime = System.currentTimeMillis() - lastLap;
              System.out.printf("<- messages %d/%d = %dms (%f msg/sec)\n", i, TOTAL, lapTime, ((float) LAP * 1000 / lapTime));
              lastLap = System.currentTimeMillis();
            }

          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
    };
    t.start();

    System.out.println((System.currentTimeMillis() - lastLap) + " Start sending msgs");
    for (int i = 1; i < TOTAL + 1; ++i) {
      queue.offer(i);

      if (i % LAP == 0) {
        final long lapTime = System.currentTimeMillis() - lastLap;
        System.out.printf("-> messages %d/%d = %dms (%f msg/sec)\n", i, TOTAL, lapTime, ((float) LAP * 1000 / lapTime));
        lastLap = System.currentTimeMillis();
      }
    }

    System.out.println((System.currentTimeMillis() - start) + " Finished sending msgs");

    t.join();

    System.out.println((System.currentTimeMillis() - start) + " Test finished");
  }
}

1 个答案:

答案 0 :(得分:0)

对于单节点群集,此行

final IQueue<Object> queue = hz.getQueue("test");

为您提供对当前实例中队列的引用,本质上是本地引用。

添加更多实例后,队列本身可能会迁移为由另一个实例托管,因此现在的引用是指向远程队列。

有很多方法可以验证这一点。可能最简单的方法是延长测试时间,让第二个节点参与其中,并查看性能是否发生了变化。显然,您只希望第一个进程执行offer() / take()操作。

如果需要,添加此

System.out.println(hz.getPartitionService().getPartition("test").getOwner());

查找队列在其他成员加入集群时所处的位置。