Как программно настроить Hazelcast для механизма многоадресного обнаружения?
Как программно настроить Hazelcast для механизма многоадресного обнаружения?
Подробности:
Документация содержит только пример для TCP/IP и устарела: она использует Config.setPort(), который больше не существует.
Моя конфигурация выглядит так, но обнаружение не работает (т.е. я получаю вывод "Members: 1"
:
Config cfg = new Config();
NetworkConfig network = cfg.getNetworkConfig();
network.setPort(PORT_NUMBER);
JoinConfig join = network.getJoin();
join.getTcpIpConfig().setEnabled(false);
join.getAwsConfig().setEnabled(false);
join.getMulticastConfig().setEnabled(true);
join.getMulticastConfig().setMulticastGroup(MULTICAST_ADDRESS);
join.getMulticastConfig().setMulticastPort(PORT_NUMBER);
join.getMulticastConfig().setMulticastTimeoutSeconds(200);
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
System.out.println("Members: "+hazelInst.getCluster().getMembers().size());
Обновление 1, принимая во внимание ответ Асимарслана
Если я возился с MulticastTimeout, я либо получаю "Members: 1"
или же
05.12.2013 20:50:42 com.hazelcast.nio.ReadHandler ПРЕДУПРЕЖДЕНИЕ: [192.168.0.9]:4446 [dev] hz._hzInstance_1_dev.IO.thread-in-0 Закрытие сокета для адреса конечной точки [192.168.0.7]:4446, Причина:java.io.EOFException: Удаленный сокет закрыт! 05 дек. 2013 г. 20:57:24 com.hazelcast.instance.Node SEVERE: [192.168.0.9]:4446 [dev] Не удалось присоединиться к кластеру, завершение работы! com.hazelcast.core.HazelcastException: не удалось присоединиться через 300 секунд!
Обновление 2, принимая во внимание ответ pveentjer об использовании tcp/ip
Если я изменю конфигурацию на следующую, я все равно получу только 1 участника:
Config cfg = new Config();
NetworkConfig network = cfg.getNetworkConfig();
network.setPort(PORT_NUMBER);
JoinConfig join = network.getJoin();
join.getMulticastConfig().setEnabled(false);
join.getTcpIpConfig().addMember("192.168.0.1").addMember("192.168.0.2").
addMember("192.168.0.3").addMember("192.168.0.4").
addMember("192.168.0.5").addMember("192.168.0.6").
addMember("192.168.0.7").addMember("192.168.0.8").
addMember("192.168.0.9").addMember("192.168.0.10").
addMember("192.168.0.11").setRequiredMember(null).setEnabled(true);
//this sets the allowed connections to the cluster? necessary for multicast, too?
network.getInterfaces().setEnabled(true).addInterface("192.168.0.*");
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
System.out.println("debug: joined via "+join+" with "+hazelInst.getCluster()
.getMembers().size()+" members.");
Точнее, этот прогон производит вывод
отладка: присоединен через JoinConfig{multicastConfig=MulticastConfig [enabled=false, multicastGroup=224.2.2.3, multicastPort=54327, multicastTimeToLive=32, multicastTimeoutSeconds=2,rustInterfaces=[]], tcpIpConfig=TcpIp =true, подключения = TcpIpecons члены =[192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.0.4, 192.168.0.5, 192.168.0.6, 192.168.0.7, 192.168.0.8, 192.168.0.9, 192.168.0.10, 192.168.0.11], обязательный член =null], awsConfig=AwsConfig{enabled=false, region='us-east-1', securityGroupName='null', tagKey='null', tagValue='null', hostHeader='ec2.amazonaws.com', connectionTimeoutSeconds=5}} с 1 участниками.
Моя не-hazelcast-реализация использует UDP multicast и работает нормально. Так может ли проблема с брандмауэром?
Обновление 3, принимая во внимание ответ pveentjer о проверке сети
Так как у меня нет разрешений для iptables или для установки iperf, я использую com.hazelcast.examples.TestApp
чтобы проверить, работает ли моя сеть, как описано в разделе " Начало работы с Hazelcast" в главе 2, "Прямая демонстрация":
Я звоню java -cp hazelcast-3.1.2.jar com.hazelcast.examples.TestApp
на 192.168.0.1 и получить вывод
...Dec 10, 2013 11:31:21 PM com.hazelcast.instance.DefaultAddressPicker
INFO: Prefer IPv4 stack is true.
Dec 10, 2013 11:31:21 PM com.hazelcast.instance.DefaultAddressPicker
INFO: Picked Address[192.168.0.1]:5701, using socket ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5701], bind any local is true
Dec 10, 2013 11:31:22 PM com.hazelcast.system
INFO: [192.168.0.1]:5701 [dev] Hazelcast Community Edition 3.1.2 (20131120) starting at Address[192.168.0.1]:5701
Dec 10, 2013 11:31:22 PM com.hazelcast.system
INFO: [192.168.0.1]:5701 [dev] Copyright (C) 2008-2013 Hazelcast.com
Dec 10, 2013 11:31:22 PM com.hazelcast.instance.Node
INFO: [192.168.0.1]:5701 [dev] Creating MulticastJoiner
Dec 10, 2013 11:31:22 PM com.hazelcast.core.LifecycleService
INFO: [192.168.0.1]:5701 [dev] Address[192.168.0.1]:5701 is STARTING
Dec 10, 2013 11:31:24 PM com.hazelcast.cluster.MulticastJoiner
INFO: [192.168.0.1]:5701 [dev]
Members [1] {
Member [192.168.0.1]:5701 this
}
Dec 10, 2013 11:31:24 PM com.hazelcast.core.LifecycleService
INFO: [192.168.0.1]:5701 [dev] Address[192.168.0.1]:5701 is STARTED
Я тогда звоню java -cp hazelcast-3.1.2.jar com.hazelcast.examples.TestApp
на 192.168.0.2 и получить вывод
...Dec 10, 2013 9:50:22 PM com.hazelcast.instance.DefaultAddressPicker
INFO: Prefer IPv4 stack is true.
Dec 10, 2013 9:50:22 PM com.hazelcast.instance.DefaultAddressPicker
INFO: Picked Address[192.168.0.2]:5701, using socket ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5701], bind any local is true
Dec 10, 2013 9:50:23 PM com.hazelcast.system
INFO: [192.168.0.2]:5701 [dev] Hazelcast Community Edition 3.1.2 (20131120) starting at Address[192.168.0.2]:5701
Dec 10, 2013 9:50:23 PM com.hazelcast.system
INFO: [192.168.0.2]:5701 [dev] Copyright (C) 2008-2013 Hazelcast.com
Dec 10, 2013 9:50:23 PM com.hazelcast.instance.Node
INFO: [192.168.0.2]:5701 [dev] Creating MulticastJoiner
Dec 10, 2013 9:50:23 PM com.hazelcast.core.LifecycleService
INFO: [192.168.0.2]:5701 [dev] Address[192.168.0.2]:5701 is STARTING
Dec 10, 2013 9:50:23 PM com.hazelcast.nio.SocketConnector
INFO: [192.168.0.2]:5701 [dev] Connecting to /192.168.0.1:5701, timeout: 0, bind-any: true
Dec 10, 2013 9:50:23 PM com.hazelcast.nio.TcpIpConnectionManager
INFO: [192.168.0.2]:5701 [dev] 38476 accepted socket connection from /192.168.0.1:5701
Dec 10, 2013 9:50:28 PM com.hazelcast.cluster.ClusterService
INFO: [192.168.0.2]:5701 [dev]
Members [2] {
Member [192.168.0.1]:5701
Member [192.168.0.2]:5701 this
}
Dec 10, 2013 9:50:30 PM com.hazelcast.core.LifecycleService
INFO: [192.168.0.2]:5701 [dev] Address[192.168.0.2]:5701 is STARTED
Таким образом, многоадресное обнаружение обычно работает на моем кластере, верно? 5701 также является портом для обнаружения? Является 38476
в последнем выводе идентификатор или порт?
Присоединение все еще не работает для моего собственного кода с программной конфигурацией:(
Обновление 4, принимая во внимание ответ pveentjer об использовании конфигурации по умолчанию
Модифицированный TestApp дает вывод
joinConfig{multicastConfig=MulticastConfig [enabled=true, multicastGroup=224.2.2.3,
multicastPort=54327, multicastTimeToLive=32, multicastTimeoutSeconds=2,
trustedInterfaces=[]], tcpIpConfig=TcpIpConfig [enabled=false,
connectionTimeoutSeconds=5, members=[], requiredMember=null],
awsConfig=AwsConfig{enabled=false, region='us-east-1', securityGroupName='null',
tagKey='null', tagValue='null', hostHeader='ec2.amazonaws.com', connectionTimeoutSeconds=5}}
и обнаруживает других участников через пару секунд (после того, как каждый экземпляр один раз перечисляет только себя как участника, если все запущены одновременно), тогда как
myProgram дает вывод
joined via JoinConfig{multicastConfig=MulticastConfig [enabled=true, multicastGroup=224.2.2.3, multicastPort=54327, multica\
stTimeToLive=32, multicastTimeoutSeconds=2, trustedInterfaces=[]], tcpIpConfig=TcpIpConfig [enabled=false, connectionTimeoutSecond\
s=5, members=[], requiredMember=null], awsConfig=AwsConfig{enabled=false, region='us-east-1', securityGroupName='null', tagKey='nu\
ll', tagValue='null', hostHeader='ec2.amazonaws.com', connectionTimeoutSeconds=5}} with 1 members.
и не обнаруживает участников в течение примерно 1 минуты (я считаю участников каждые 5 секунд).
НО, если хотя бы один экземпляр TestApp работает одновременно в кластере, все экземпляры TestApp и все экземпляры myProgram обнаруживаются, и моя программа работает нормально. В случае, если я запускаю TestApp один раз, а затем дважды параллельно myProgram, TestApp дает следующий вывод:
java -cp ~/CaseStudy/jtorx-1.10.0-beta8/lib/hazelcast-3.1.2.jar:. TestApp
Dec 12, 2013 12:02:15 PM com.hazelcast.instance.DefaultAddressPicker
INFO: Prefer IPv4 stack is true.
Dec 12, 2013 12:02:15 PM com.hazelcast.instance.DefaultAddressPicker
INFO: Picked Address[192.168.180.240]:5701, using socket ServerSocket[addr=/0:0:0:0:0:0:0:0,localport=5701], bind any local is true
Dec 12, 2013 12:02:15 PM com.hazelcast.system
INFO: [192.168.180.240]:5701 [dev] Hazelcast Community Edition 3.1.2 (20131120) starting at Address[192.168.180.240]:5701
Dec 12, 2013 12:02:15 PM com.hazelcast.system
INFO: [192.168.180.240]:5701 [dev] Copyright (C) 2008-2013 Hazelcast.com
Dec 12, 2013 12:02:15 PM com.hazelcast.instance.Node
INFO: [192.168.180.240]:5701 [dev] Creating MulticastJoiner
Dec 12, 2013 12:02:15 PM com.hazelcast.core.LifecycleService
INFO: [192.168.180.240]:5701 [dev] Address[192.168.180.240]:5701 is STARTING
Dec 12, 2013 12:02:21 PM com.hazelcast.cluster.MulticastJoiner
INFO: [192.168.180.240]:5701 [dev]
Members [1] {
Member [192.168.180.240]:5701 this
}
Dec 12, 2013 12:02:22 PM com.hazelcast.core.LifecycleService
INFO: [192.168.180.240]:5701 [dev] Address[192.168.180.240]:5701 is STARTED
Dec 12, 2013 12:02:22 PM com.hazelcast.management.ManagementCenterService
INFO: [192.168.180.240]:5701 [dev] Hazelcast will connect to Management Center on address: http://localhost:8080/mancenter-3.1.2/
Join: JoinConfig{multicastConfig=MulticastConfig [enabled=true, multicastGroup=224.2.2.3, multicastPort=54327, multicastTimeToLive=32, multicastTimeoutSeconds=2, trustedInterfaces=[]], tcpIpConfig=TcpIpConfig [enabled=false, connectionTimeoutSeconds=5, members=[], requiredMember=null], awsConfig=AwsConfig{enabled=false, region='us-east-1', securityGroupName='null', tagKey='null', tagValue='null', hostHeader='ec2.amazonaws.com', connectionTimeoutSeconds=5}}
Dec 12, 2013 12:02:22 PM com.hazelcast.partition.PartitionService
INFO: [192.168.180.240]:5701 [dev] Initializing cluster partition table first arrangement...
hazelcast[default] > Dec 12, 2013 12:03:27 PM com.hazelcast.nio.SocketAcceptor
INFO: [192.168.180.240]:5701 [dev] Accepting socket connection from /192.168.0.8:38764
Dec 12, 2013 12:03:27 PM com.hazelcast.nio.TcpIpConnectionManager
INFO: [192.168.180.240]:5701 [dev] 5701 accepted socket connection from /192.168.0.8:38764
Dec 12, 2013 12:03:27 PM com.hazelcast.nio.SocketAcceptor
INFO: [192.168.180.240]:5701 [dev] Accepting socket connection from /192.168.0.7:54436
Dec 12, 2013 12:03:27 PM com.hazelcast.nio.TcpIpConnectionManager
INFO: [192.168.180.240]:5701 [dev] 5701 accepted socket connection from /192.168.0.7:54436
Dec 12, 2013 12:03:32 PM com.hazelcast.partition.PartitionService
INFO: [192.168.180.240]:5701 [dev] Re-partitioning cluster data... Migration queue size: 181
Dec 12, 2013 12:03:32 PM com.hazelcast.cluster.ClusterService
INFO: [192.168.180.240]:5701 [dev]
Members [3] {
Member [192.168.180.240]:5701 this
Member [192.168.0.8]:5701
Member [192.168.0.7]:5701
}
Dec 12, 2013 12:03:43 PM com.hazelcast.partition.PartitionService
INFO: [192.168.180.240]:5701 [dev] Re-partitioning cluster data... Migration queue size: 181
Dec 12, 2013 12:03:45 PM com.hazelcast.partition.PartitionService
INFO: [192.168.180.240]:5701 [dev] All migration tasks has been completed, queues are empty.
Dec 12, 2013 12:03:46 PM com.hazelcast.nio.TcpIpConnection
INFO: [192.168.180.240]:5701 [dev] Connection [Address[192.168.0.8]:5701] lost. Reason: Socket explicitly closed
Dec 12, 2013 12:03:46 PM com.hazelcast.cluster.ClusterService
INFO: [192.168.180.240]:5701 [dev] Removing Member [192.168.0.8]:5701
Dec 12, 2013 12:03:46 PM com.hazelcast.cluster.ClusterService
INFO: [192.168.180.240]:5701 [dev]
Members [2] {
Member [192.168.180.240]:5701 this
Member [192.168.0.7]:5701
}
Dec 12, 2013 12:03:48 PM com.hazelcast.partition.PartitionService
INFO: [192.168.180.240]:5701 [dev] Partition balance is ok, no need to re-partition cluster data...
Dec 12, 2013 12:03:48 PM com.hazelcast.nio.TcpIpConnection
INFO: [192.168.180.240]:5701 [dev] Connection [Address[192.168.0.7]:5701] lost. Reason: Socket explicitly closed
Dec 12, 2013 12:03:48 PM com.hazelcast.cluster.ClusterService
INFO: [192.168.180.240]:5701 [dev] Removing Member [192.168.0.7]:5701
Dec 12, 2013 12:03:48 PM com.hazelcast.cluster.ClusterService
INFO: [192.168.180.240]:5701 [dev]
Members [1] {
Member [192.168.180.240]:5701 this
}
Dec 12, 2013 12:03:48 PM com.hazelcast.partition.PartitionService
INFO: [192.168.180.240]:5701 [dev] Partition balance is ok, no need to re-partition cluster data...
Единственное отличие, которое я вижу в конфигурации TestApp, это
config.getManagementCenterConfig().setEnabled(true);
config.getManagementCenterConfig().setUrl("http://localhost:8080/mancenter-"+version);
for(int k=1;k<= LOAD_EXECUTORS_COUNT;k++){
config.addExecutorConfig(new ExecutorConfig("e"+k).setPoolSize(k));
}
поэтому я добавил это в отчаянной попытке в myProgram, тоже. Но это не решает проблему - все же каждый экземпляр только обнаруживает себя в качестве участника в течение всего цикла.
Обновление о том, как долго работает myProgram
Может ли быть так, что программа работает недостаточно долго (как выразился pveentjer)?
Мои эксперименты, кажется, подтверждают это: если время t между Hazelcast.newHazelcastInstance(cfg);
и инициализация cleanUp()
(т.е. больше не общаются через hazelcast и больше не проверяют количество участников)
- менее 30 секунд, нет связи и
members: 1
- более 30 секунд: все участники найдены, и происходит общение (что странно, кажется, происходит гораздо дольше, чем t - 30 секунд).
Является ли 30 секунд реалистичным промежутком времени, в котором нуждается кластер Hazelcast, или происходит что-то странное? Вот журнал из 4 запущенных одновременно программ myProgram (при поиске членов класса hazelcast 30 секунд перекрываются для экземпляра 1 и экземпляра 3):
instance 1: 2013-12-19T12:39:16.553+0100 LOG 0 (START) engine started
looking for members between 2013-12-19T12:39:21.973+0100 and 2013-12-19T12:40:27.863+0100
2013-12-19T12:40:28.205+0100 LOG 35 (Torx-Explorer) Model SymToSim is about to\ exit
instance 2: 2013-12-19T12:39:16.592+0100 LOG 0 (START) engine started
looking for members between 2013-12-19T12:39:22.192+0100 and 2013-12-19T12:39:28.429+0100
2013-12-19T12:39:28.711+0100 LOG 52 (Torx-Explorer) Model SymToSim is about to\ exit
instance 3: 2013-12-19T12:39:16.593+0100 LOG 0 (START) engine started
looking for members between 2013-12-19T12:39:22.145+0100 and 2013-12-19T12:39:52.425+0100
2013-12-19T12:39:52.639+0100 LOG 54 (Torx-Explorer) Model SymToSim is about to\ exit
INSTANCE 4: 2013-12-19T12:39:16.885+0100 LOG 0 (START) engine started
looking for members between 2013-12-19T12:39:21.478+0100 and 2013-12-19T12:39:35.980+0100
2013-12-19T12:39:36.024+0100 LOG 34 (Torx-Explorer) Model SymToSim is about to\ exit
Как лучше всего запустить мой фактический распределенный алгоритм только после того, как в кластере Hazelcast будет достаточно участников? Могу ли я установить hazelcast.initial.min.cluster.size
программно? https://groups.google.com/forum/ звучит так, как будто это заблокирует Hazelcast.newHazelcastInstance(cfg);
пока не будет достигнут исходный.min.cluster.size. Правильный? Насколько синхронно (в течение какого промежутка времени) будут разблокироваться разные экземпляры?
7 ответов
Очевидно, проблема в том, что кластер запускается (и останавливается) и не ждет, пока в кластере окажется достаточно участников. Вы можете установить свойство hazelcast.initial.min.cluster.size, чтобы предотвратить это.
Вы можете установить "hazelcast.initial.min.cluster.size" программно, используя:
Config config = new Config();
config.setProperty("hazelcast.initial.min.cluster.size","3");
Ваша конфигурация верна, НО вы установили очень длительное время многоадресной рассылки 200 секунд, где по умолчанию 2 секунды. установка меньшего значения решит это.
Из документа Hazelcast Java API: MulticastConfig.html # setMulticastTimeoutSeconds (int)
Указывает время в секундах, в течение которого узел должен ожидать действительный многоадресный ответ от другого узла, работающего в сети, прежде чем объявить себя главным узлом и создать свой собственный кластер. Это относится только к запуску узлов, где еще не был назначен мастер. Если вы задаете высокое значение, например 60 секунд, это означает, что до тех пор, пока не будет выбран мастер, каждый узел будет ждать 60 секунд, прежде чем продолжить, поэтому будьте осторожны с предоставлением высокого значения. Если значение установлено слишком низким, может случиться так, что узлы слишком рано сдаются и будут создавать свой собственный кластер.
Похоже, что Hazelcast использует многоадресный адрес 224.2.2.3 для UDP-порта 54327 (по умолчанию) для обнаружения, а затем порт 5701 для связи TCP. Открытие UDP-порта 54327 в брандмауэре исправило обнаружение для меня. (Я также открыл TCP-порт 5701, но этого было недостаточно.)
Кажется, вы используете кластеризацию TCP/IP, так что это хорошо. Попробуйте следующее (из книги фундука)
Если вы используете iptables, для разрешения исходящего трафика через порты 33000-31000 можно добавить следующее правило:
iptables -A OUTPUT -p TCP --dport 33000:31000 -m state --state NEW -j ACCEPT
и контролировать входящий трафик с любого адреса на порт 5701:
iptables -A INPUT -p tcp -d 0/0 -s 0/0 --dport 5701 -j ACCEPT
и разрешить входящий многоадресный трафик:
iptables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT
Тест подключения Если у вас возникли проблемы из-за того, что машины не присоединяются к кластеру, вы можете проверить сетевое соединение между двумя компьютерами. Для этого вы можете использовать инструмент под названием iperf. На одной машине вы выполняете: iperf -s -p 5701 Это означает, что вы прослушиваете порт 5701.
На другом компьютере вы выполняете следующую команду:
iperf -c 192.168.1.107 -d -p 5701
Где вы замените "192.168.1.107" на IP-адрес вашей первой машины. Если вы запустите команду, и вы получите такой вывод:
------------------------------------------------------------
Server listening on TCP port 5701
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
------------------------------------------------------------
Client connecting to 192.168.1.107, TCP port 5701
TCP window size: 59.4 KByte (default)
------------------------------------------------------------
[ 5] local 192.168.1.105 port 40524 connected with 192.168.1.107 port 5701
[ 4] local 192.168.1.105 port 5701 connected with 192.168.1.107 port 33641
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.2 sec 55.8 MBytes 45.7 Mbits/sec
[ 5] 0.0-10.3 sec 6.25 MBytes 5.07 Mbits/sec
Вы знаете, что 2 машины могут соединяться друг с другом. Однако, если вы видите что-то вроде этого:
Server listening on TCP port 5701
TCP window size: 85.3 KByte (default)
------------------------------------------------------------
connect failed: No route to host
Тогда вы знаете, что у вас может быть проблема с сетевым подключением.
Можете ли вы сначала попробовать с кластером tcp/ip, чтобы убедиться, что все остальное в порядке? Как только вы подтвердите, что проблем нет, попробуйте многоадресную рассылку. Это также может быть проблема с брандмауэром.
Похоже, что Multicast работает в вашей сети; и это хорошо.
Не могли бы вы попробовать это со следующими настройками:
Config cfg = new Config();
NetworkConfig network = cfg.getNetworkConfig();
JoinConfig join = network.getJoin();
join.getTcpIpConfig().setEnabled(false);
join.getAwsConfig().setEnabled(false);
join.getMulticastConfig().setEnabled(true);
HazelcastInstance instance = Hazelcast.newHazelcastInstance(cfg);
Как видите, я удалил все настройки.
Можете ли вы попытаться создать свой экземпляр Hazelcast следующим образом:
Config cfg = new Config();
HazelcastInstance hz = Hazelcast.newHazelcastInstance(cfg);
Работа с центром управления и создание исполнителей не имеют значения (я добавил этот код в testapp, так что я на 100% уверен в этом).
Тогда у вас должна быть точно такая же конфигурация сети, как и у TestApp.