本章介绍Hazelcast集群以及集群成员和本机客户端用于构成Hazelcast集群的方法。
Hazelcast集群是运行Hazelcast的集群成员网络。集群成员(也称为节点)自动连接在一起以形成集群。这种自动连接使用集群成员用于查找彼此的各种发现机制进行。
请注意,在群集形成后,群集成员之间的通信始终通过TCP / IP进行,无论使用何种发现机制。
Hazelcast使用以下发现机制。
您可以参考Hazelcast IMDG部署和操作指南,获取有关要使用的最佳发现机制的建议。 |
您可以将Hazelcast配置为完整的TCP / IP群集。有关配置详细信息,请参阅“ 通过TCP发现成员”部分。
不建议将生成多播机制用于生产,因为UDP通常在生产环境中被阻止,而其他发现机制更明确。
通过这种机制,Hazelcast允许集群成员使用多播通信找到彼此。请参阅“ 按组播发现成员”部分。
Hazelcast支持EC2自动发现。当您不想提供或无法提供可能的IP地址列表时,它非常有用。此发现功能作为Hazelcast插件提供。有关配置和使用它的信息,请参阅其文档。
5.1.4。Apachejclouds®CloudDiscovery
Hazelcast成员和本地客户支持jclouds®进行发现。此机制允许应用程序以与基础架构无关的方式部署在各种云基础架构生态系统中。此发现功能作为Hazelcast插件提供。有关配置和使用它的信息,请参阅其文档。
Hazelcast为在Azure上运行的Hazelcast应用程序提供了一种发现策略。此策略通过返回Azure资源组中标记有指定值的虚拟机来提供所有Hazelcast实例。此发现功能作为Hazelcast插件提供。有关配置和使用它的信息,请参阅其文档。
此发现机制通过使用Apache Curator与Zookeeper服务器进行通信来提供基于服务的发现策略。您可以在启用Discovery SPI的 Hazelcast 3.6.1及更高版本的应用程序中使用此插件。这是一个Hazelcast插件。有关配置和使用它的信息,请参阅其文档。
Consul是一个高度可用的分布式服务发现和键值存储,旨在支持现代数据中心,使分布式系统和配置变得简单。该机制为启用Hazelcast的应用程序(Hazelcast 3.6及更高版本)提供了基于Consul的发现策略,并使Hazelcast成员能够通过Consul动态发现彼此。此发现功能作为Hazelcast插件提供。有关配置和使用它的信息,请参阅其文档。
此机制为启用Hazelcast的应用程序(Hazelcast 3.6及更高版本)提供基于etcd的发现策略。这是一个易于配置的即插即用Hazelcast发现策略,可以选择使用etcd注册每个Hazelcast成员,并使Hazelcast成员能够通过etcd动态发现彼此。此发现功能作为Hazelcast插件提供。有关配置和使用它的信息,请参阅其文档。
使用可点击的Hazelcast Tile进行Pivotal Cloud Foundry(PCF),您可以在PCF上部署Hazelcast群集。此功能以Hazelcast插件的形式提供。请参阅其文档,了解如何安装,配置和使用插件Hazelcast for PCF。
Hazelcast可以在OpenShift内部运行,受益于其集群管理软件Kubernetes,用于发现成员。使用Hazelcast Docker映像,模板和默认配置文件,您可以将Hazelcast IMDG,Hazelcast IMDG Enterprise和管理中心部署到OpenShift上。请参阅文档:
另请参阅Hazelcast for OpenShift指南,其中介绍了如何设置本地OpenShift环境,启动Hazelcast集群,配置管理中心以及最终运行示例客户端应用程序。
Eureka是一种基于REST的服务,主要用于AWS云,用于定位服务,以实现中间层服务器的负载平衡和故障转移。Hazelcast支持Eureka V1发现; EC2虚拟私有云中的Hazelcast成员可以使用此机制发现彼此。此发现功能作为Hazelcast插件提供。请参阅其文档。
Heroku是一种平台即服务(PaaS),您可以使用它完全在云中构建,运行和运行应用程序。它是一个基于托管容器系统的云平台,具有集成的数据服务和强大的生态系统。Hazelcast提供了一个发现插件,通过在Heroku Private Spaces中针对Heroku DNS Discovery解析服务名称来查找其他成员的IP地址。此发现功能作为Hazelcast插件提供。请参阅其文档。
5.1.13。Kubernetes Cloud Discovery
Kubernetes是一个开源系统,用于自动化容器化应用程序的部署,扩展和管理。Hazelcast提供Kubernetes发现机制,通过解析针对Kubernetes Service Discovery系统的请求来查找其他成员的IP地址。它支持两种不同的解析发现注册表的选项:(i)对REST API的请求,(ii)针对给定DNS服务名称的DNS查找。此发现功能作为Hazelcast插件提供。有关配置和使用它的信息,请参阅其文档。
如果多播不是您的环境的首选发现方式,则可以将Hazelcast配置为完整的TCP / IP群集。配置Hazelcast以通过TCP / IP发现成员时,必须将成员的主机名和/或IP地址的全部或部分列为集群成员。您不必列出所有这些集群成员,但是当新成员加入时,至少有一个列出的成员必须在集群中处于活动状态。
要将Hazelcast设置为完整的TCP / IP群集,请设置以下配置元素。有关TCP / IP发现配置元素的完整说明,请参阅tcp-ip元素部分。
- 将元素的enabled属性设置multicast为“false”。
- 将元素的enabled属性设置aws为“false”。
- 将元素的enabled属性设置tcp-ip为“true”。
- 在member元素中设置tcp-ip元素。
以下是声明性配置示例。
<hazelcast>
...
<network>
...
<join>
<multicast enabled="false">
</multicast>
<tcp-ip enabled="true">
<member>machine1</member>
<member>machine2</member>
<member>machine3:5799</member>
<member>192.168.1.0-7</member>
<member>192.168.1.21</member>
</tcp-ip>
...
</join>
...
</network>
...
</hazelcast>
如上所示,您可以为member元素提供IP地址或主机名。您还可以提供一系列IP地址,例如192.168.1.0-7。
如上所示,您还可以选择使用该members元素并编写以逗号分隔的IP地址,而不是按行提供成员,如下所示。
<members>192.168.1.0-7,192.168.1.21</members>
如果您不为成员提供端口,Hazelcast会自动尝试端口5701,5702等。
默认情况下,Hazelcast绑定到所有本地网络接口以接受传入流量。您可以使用系统属性更改此行为hazelcast.socket.bind.any。如果将此属性设置为false,Hazelcast将使用interfaces元素中指定的接口(请参阅“ 接口配置”部分)。如果没有提供接口,那么它将尝试解析一个接口以从member元素绑定。
通过多播自动发现机制,Hazelcast允许集群成员使用多播通信找到彼此。集群成员不需要知道其他成员的具体地址,因为他们只是多播到所有其他成员进行监听。是否可以进行多播取决于您的环境。
要将Hazelcast设置为多播自动发现,请设置以下配置元素。有关多播发现配置元素的完整说明,请参阅多播元素部分。
- 将元素的enabled属性设置multicast为“true”。
- 集multicast-group,multicast-port,multicast-time-to-live,等你的多播值。
- 将enabledboth tcp-ip和awselements 的属性设置为“false”。
以下是声明性配置示例。
<hazelcast>
...
<network>
...
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
<multicast-time-to-live>32</multicast-time-to-live>
<multicast-timeout-seconds>2</multicast-timeout-seconds>
<trusted-interfaces>
<interface>192.168.1.102</interface>
</trusted-interfaces>
</multicast>
<tcp-ip enabled="false">
</tcp-ip>
<aws enabled="false">
</aws>
</join>
</network>
注意multicast-timeout-seconds元素。multicast-timeout-seconds指定成员在声明自己为领导成员(加入群集的第一个成员)并创建自己的群集之前,应等待来自网络中运行的另一个成员的有效多播响应的时间(以秒为单位)。这仅适用于尚未分配领导者的成员的启动。如果指定一个较高的值multicast-timeout-seconds,例如60秒,则表示在选择一个领导者之前,每个成员将等待60秒再继续前进。提供高价值时要小心。另外,注意不要将值设置得太低,否则成员可能会过早放弃并创建自己的集群。
Hazelcast本机客户端尚不支持多播自动发现。但是,我们为此提供了多播搜索插件。请参阅“ 发现本机客户端”部分。 |
Hazelcast成员和本机Java客户端可以通过多播发现插件找到彼此。该插件使用Hazelcast Discovery SPI实现。您应该在Hazelcast成员和Java客户端配置插件,以便使用多播发现。
要将群集配置为具有多播发现插件,请按照下列步骤操作:
- 禁用多播和TCP / IP连接机制。为此,请在配置文件中设置和元素的enabled属性multicasttcp-ipfalsehazelcast.xml
- 将enabled属性的hazelcast.discovery.enabled属性设置为true。
- 将多播发现策略配置添加到XML文件,即<discovery-strategies>元素。
以下是声明性配置示例。
...
<properties>
<property name="hazelcast.discovery.enabled">true</property>
</properties>
....
<join>
<multicast enabled="false">
</multicast>
<tcp-ip enabled="false">
</tcp-ip>
<discovery-strategies>
<discovery-strategy class="com.hazelcast.spi.discovery.multicast.MulticastDiscoveryStrategy" enabled="true">
<properties>
<property name="group">224.2.2.3</property>
<property name="port">54327</property>
</properties>
</discovery-strategy>
</discovery-strategies>
</join>
...
以下是多播发现插件配置属性及其说明。
- group:用于设置多播组的字符串值,以便您可以隔离群集。
- port:用于设置多播端口的整数值。
您可以创建群集组。为此,请使用group配置元素。
您可以通过指定组名以简单的方式分离群集。示例分组可以是开发,生产,测试,应用程序等。以下是声明性配置示例。
<hazelcast>
<group>
<name>production</name>
</group>
...
</hazelcast>
您还可以使用编程配置定义群集组。JVM可以托管多个Hazelcast实例。每个Hazelcast实例只能参与一个组。每个Hazelcast实例仅加入其自己的组,不与其他组交互。下面的代码示例创建三个单独Hazelcast instances-- h1属于production群集,而h2与h3属于development集群。
Config configProd = new Config();
configProd.getGroupConfig().setName( "production" );
Config configDev = new Config();
configDev.getGroupConfig().setName( "development" );
HazelcastInstance h1 = Hazelcast.newHazelcastInstance( configProd );
HazelcastInstance h2 = Hazelcast.newHazelcastInstance( configDev );
HazelcastInstance h3 = Hazelcast.newHazelcastInstance( configDev );
如果您的Hazelcast版本低于3.8.2,则还需要提供组密码和组名称。以下是使用密码元素的配置示例:
<hazelcast>
<group>
<name>production</name>
<password>prod-pass</password>
</group>
...
</hazelcast>
Config configProd = new Config();
configProd.getGroupConfig().setName( "production" ).setPassword( "prod-pass" );
Config configDev = new Config();
configDev.getGroupConfig().setName( "development" ).setPassword( "dev-pass" );
HazelcastInstance h1 = Hazelcast.newHazelcastInstance( configProd );
HazelcastInstance h2 = Hazelcast.newHazelcastInstance( configDev );
HazelcastInstance h3 = Hazelcast.newHazelcastInstance( configDev );
从3.8.2开始,不需要组密码。
Hazelcast可以从远程类库(通常包括lite成员)动态加载自定义类或域类。为此,Hazelcast提供了一个分布式动态类加载器。
使用此动态类加载器,您可以控制从其他成员加载的类的本地缓存,控制要提供给其他成员的类,以及创建类和包的黑名单或白名单。启用此功能后,您不必将类部署到所有集群成员。
以下是用户代码部署功能的简要工作机制:
- 动态类加载器首先检查自定义类的本地类,即类路径。如果它存在,Hazelcast不会尝试从远程类库中加载它。
- 然后,它检查从远程类库中加载的类的缓存(为此,应在本地启用缓存,请参阅配置用户代码部署部分)。如果您的类在此处再次找到,Hazelcast不会尝试从远程类库中加载它。
- 最后,动态类加载器检查远程类库。如果此存储库中的成员返回该类,则表示您的类已找到并将被使用。您也可以将此类放入本地类缓存中,如上一步所述。
默认情况下不启用用户代码部署功能。您可以以声明方式或以编程方式配置此功能。以下是示例配置代码段:
声明性配置
<user-code-deployment enabled="true">
<class-cache-mode>ETERNAL</class-cache-mode>
<provider-mode>LOCAL_CLASSES_ONLY</provider-mode>
<blacklist-prefixes>com.foo</blacklist-prefixes>
<whitelist-prefixes>com.bar.MyClass</whitelist-prefixes>
<provider-filter>HAS_ATTRIBUTE:lite</provider-filter>
</user-code-deployment>
程序化配置
Config config = new Config();
UserCodeDeploymentConfig distCLConfig = config.getUserCodeDeploymentConfig();
distCLConfig.setEnabled( true )
.setClassCacheMode( ClassCacheMode.ETERNAL )
.setProviderMode( ProviderMode.LOCAL_CLASSES_ONLY )
.setBlacklistedPrefixes( "com.foo" )
.setWhitelistedPrefixes( "com.bar.MyClass" )
.setProviderFilter( "HAS_ATTRIBUTE:lite" );
用户代码部署具有以下配置元素和属性:
- enabled:指定是否启用动态类加载。其默认值为“true”,它是必需属性。
- <class-cache-mode>:控制从远程类库中加载的类的本地缓存行为。可用值如下:
- ETERNAL:在本地缓存已加载的类。这是默认值,适用于加载长寿命对象,例如存储在地图中的域对象。
- OFF:不要在本地缓存已加载的类。它适用于加载runnables,callables,入门处理器等。
- <provider-mode>:控制如何将类提供给其他集群成员。可用值如下:
- LOCAL_AND_CACHED_CLASSES:服务从本地类路径和其他成员加载的类。这是默认值。
- LOCAL_CLASSES_ONLY:仅从本地类路径提供类。从其他成员加载的类将在本地使用,但不会向其他成员提供。
- OFF:永远不要为其他成员提供课程。
- <blacklist-prefixes>:逗号分隔的类/包的名称前缀,以防止动态类加载。例如,如果将其设置为“com.foo”,则“com.foo”包中所有类的远程加载将被列入黑名单,包括其所有子包中的类。如果将其设置为“com.foo.Class”,那么“Class”和所有在“com.foo”包中具有“Class”作为前缀的类将被列入黑名单。有一些内置前缀默认列入黑名单。这些如下:
- javax.
- java.
- sun.
- com.hazelcast.
- <whitelist-prefixes>:逗号分隔的类/包的名称前缀仅从中加载类。它允许仅为选定包中的类快速配置远程加载。它可以与黑名单一起使用。例如,您可以将前缀“com.foo”列入白名单,并将前缀“com.foo.secret”列入黑名单。
- <provider-filter>:当类在本地不可用时,过滤到要用于类加载请求的约束成员。值的格式为“HAS_ATTRIBUTE:foo”。当它设置为“HAS_ATTRIBUTE:foo”时,类加载请求将仅发送给具有“foo”作为成员属性的成员。将此值设置为null将允许从所有成员加载类。请参阅以下部分中的示例。
如上所述,配置元素provider-filter用于约束成员仅从所有集群成员的子集加载类。provider-filter必须将值设置为要从中加载类的所需成员中的成员属性。请参阅以下作为编程配置提供的示例用法。
以下示例配置将允许Hazelcast成员仅从具有class-provider属性集的成员加载类。它不会要求任何其他成员提供本地不可用的课程:
Config hazelcastConfig = new Config();
DistributedClassloadingConfig distributedClassloadingConfig = hazelcastConfig.getDistributedClassloadingConfig();
distributedClassloadingConfig.setProviderFilter("HAS_ATTRIBUTE:class-provider");
HazecastInstance instance = Hazelcast.newHazelcastInstance(hazelcastConfig);
以下示例配置设置class-provider成员的属性。因此,上面的成员将从具有以下属性的成员加载类class-provider:
Config hazelcastConfig = new Config();
MemberAttributeConfig memberAttributes = hazelcastConfig.getMemberAttributeConfig();
memberAttributes.setAttribute("class-provider", "true");
HazecastInstance instance = Hazelcast.newHazelcastInstance(hazelcastConfig);
在以下情况下,您可以在客户端使用用户代码部署:
- 您有将通过客户端,如在集群上运行的对象Runnable,Callable和输入处理器。
- 您有新的或修改的用户域对象(IMap设置的内存格式Object)需要部署到群集中。
启用此功能后,客户端将这些类部署到成员。通过这种方式,当客户端添加新类时,成员将不需要重新启动以在类路径中包含新类。
您还可以使用客户端权限策略指定允许哪些客户端使用用户代码部署。请参阅权限。
默认情况下不启用客户端用户代码部署功能。您可以以声明方式或以编程方式配置此功能。以下是示例配置代码段:
声明性配置
在你的hazelcast-client.xml:
<user-code-deployment enabled="true">
<jarPaths>
<jarPath>/User/sample/sample.jar</jarPath>
<jarPath>sample.jar</jarPath> <!--from class path -->
<jarPath>https://com.sample.com/sample.jar</jarPath>
<jarPath>file://Users/sample/sample.jar</jarPath>
</jarPaths>
<classNames>
<!-- for the classes available in client class path -->
<className>sample.ClassName</className>
<className>sample.ClassName2</className>
</classNames>
</user-code-deployment>
程序化配置
ClientConfig clientConfig = new ClientConfig();
ClientUserCodeDeploymentConfig clientUserCodeDeploymentConfig = new ClientUserCodeDeploymentConfig();
clientUserCodeDeploymentConfig.addJar("/User/sample/sample.jar");
clientUserCodeDeploymentConfig.addJar("https://com.sample.com/sample.jar");
clientUserCodeDeploymentConfig.addClass("sample.ClassName");
clientUserCodeDeploymentConfig.addClass("sample.ClassName2");
clientUserCodeDeploymentConfig.setEnabled(true);
clientConfig.setUserCodeDeploymentConfig(clientUserCodeDeploymentConfig);
请注意,还应在成员上启用用户代码部署以使用此功能。
Config config = new Config();
UserCodeDeploymentConfig userCodeDeploymentConfig = config.getUserCodeDeploymentConfig();
userCodeDeploymentConfig.setEnabled( true );
有关在成员端启用它及其配置属性的更多信息,请参阅“ 成员用户代码部署”部分。
对于属性class-cache-mode,客户端用户代码部署仅支持ETERNAL模式,无论在成员端设置的配置(可以是ETERNAL和OFF)。
对于属性,provider-mode,客户端用户代码部署仅支持LOCAL_AND_CACHED_CLASSES模式中,无论设定在部件侧(其可以是配置的LOCAL_AND_CACHED_CLASSES,LOCAL_CLASSES_ONLY和OFF)。
剩余的属性,它们是blacklist-prefixes,whitelist-prefixes和provider-filter在所述部件侧配置,将影响客户端用户代码部署的行为也是。例如,假设您com.foo在成员端提供黑名单前缀,该成员将丢弃具有com.foo客户端加载的前缀的类。
Hazelcast使用一致的散列算法将关键对象分配到分区中。为每个分区创建多个副本,并且这些分区副本在Hazelcast成员之间分发。条目存储在成员中,这些成员拥有分配了条目密钥的分区的副本。默认情况下,总分区数为271; 您可以使用配置属性更改它hazelcast.partition.count。请参阅系统属性附录。
拥有分区主副本的Hazelcast成员称为分区所有者。其他副本称为备份。根据配置,密钥对象可以保存在分区的多个副本中。成员最多只能拥有一个分区的副本(所有权或备份)。
默认情况下,假设群集中的所有成员都相同,Hazelcast会在群集成员之间随机分配分区副本。但是,如果某些成员共享相同的JVM或物理机器或机箱,并且您希望将这些成员的备份分配给另一台机器或机箱中的成员,该怎么办?如果某些成员的处理或内存容量不同并且您不希望将相同数量的分区分配给所有成员,该怎么办?
要处理此类方案,您可以对同一JVM(或物理机)中的成员或位于同一机箱中的成员进行分组。或者您可以将成员分组以创建相同的容量。我们称这些组为分区组。分区将分配给这些分区组而不是单个成员。由分区组拥有的分区的备份副本位于其他分区组中。
启用分区分组时,Hazelcast为您配置分区组提供了以下选择。
1. HOST_AWARE:
您可以使用成员的IP地址自动对成员进行分组,因此共享同一网络接口的成员将组合在一起。同一主机上的所有成员(IP地址或域名)将是单个分区组。这有助于避免物理服务器崩溃时数据丢失,因为同一分区的多个副本不存储在同一主机上。但是,如果每个物理机器有多个网络接口或域名,则会使此假设无效。
以下是声明性和编程式配置片段,介绍如何启用HOST_AWARE分组。
<partition-group enabled="true" group-type="HOST_AWARE" />
Config config = ...;
PartitionGroupConfig partitionGroupConfig = config.getPartitionGroupConfig();
partitionGroupConfig.setEnabled( true )
.setGroupType( MemberGroupType.HOST_AWARE );
2. CUSTOM:
您可以使用Hazelcast的接口匹配配置进行自定义分组。这样,您可以向组添加不同的和多个接口。您还可以在接口地址中使用通配符。例如,用户可以使用自定义分区分组创建机架感知或数据仓库分区组。
以下是声明性和编程式配置示例,说明如何启用和使用CUSTOM分组。
<partition-group enabled="true" group-type="CUSTOM">
<member-group>
<interface>10.10.0.*</interface>
<interface>10.10.3.*</interface>
<interface>10.10.5.*</interface>
</member-group>
<member-group>
<interface>10.10.10.10-100</interface>
<interface>10.10.1.*</interface>
<interface>10.10.2.*</interface>
</member-group>
</partition-group>
Config config = ...;
PartitionGroupConfig partitionGroupConfig = config.getPartitionGroupConfig();
partitionGroupConfig.setEnabled( true )
.setGroupType( MemberGroupType.CUSTOM );
MemberGroupConfig memberGroupConfig = new MemberGroupConfig();
memberGroupConfig.addInterface( "10.10.0.*" )
.addInterface( "10.10.3.*" ).addInterface("10.10.5.*" );
MemberGroupConfig memberGroupConfig2 = new MemberGroupConfig();
memberGroupConfig2.addInterface( "10.10.10.10-100" )
.addInterface( "10.10.1.*").addInterface( "10.10.2.*" );
partitionGroupConfig.addMemberGroupConfig( memberGroupConfig );
partitionGroupConfig.addMemberGroupConfig( memberGroupConfig2 );
当您的群集正在形成时,如果您将成员配置为通过其IP地址发现彼此,则应使用该<interface>元素的IP地址。如果您的成员通过其主机名发现对方,则应使用主机名。 |
3. PER_MEMBER:
您可以为每个成员提供自己的组。每个成员都是一个自己的组,主要和备份分区是随机分布的(不在同一个物理成员上)。这提供了最少量的保护,是Hazelcast群集的默认配置。当Hazelcast成员位于不同的主机上时,此分组类型可提供良好的冗余。但是,如果多个实例在同一主机上运行,则此类型不是一个好选择。
以下是声明性和编程式配置片段,说明如何启用PER_MEMBER分组。
<partition-group enabled="true" group-type="PER_MEMBER" />
Config config = ...;
PartitionGroupConfig partitionGroupConfig = config.getPartitionGroupConfig();
partitionGroupConfig.setEnabled( true )
.setGroupType( MemberGroupType.PER_MEMBER );
4. ZONE_AWARE:
您可以将ZONE_AWARE配置与Hazelcast AWS,Hazelcast jclouds或Hazelcast Azure Discovery Service插件配合使用。
作为发现服务,这些插件在发现过程中将区域信息放入Hazelcast 成员属性映射。当ZONE_AWARE配置为分区组类型时,Hazelcast会根据包含区域信息的成员属性映射条目创建分区组。这意味着在其他区域中创建备份,并且每个区域将被接受为一个分区组。
这是在Hazelcast成员启动期间由Discovery Service插件设置的受支持属性列表:
- hazelcast.partition.group.zone:对于同一区域的区域。
- hazelcast.partition.group.rack:对于同一区域中的不同机架。
- hazelcast.partition.group.host:对于共享物理成员,如果使用虚拟化。
除了基于云提供商的区域信息之外,hazelcast-jclouds还提供机架或主机信息。在这种情况下,Hazelcast按给定顺序查找区域,机架和主机信息,并创建包含可用信息的分区组。 |
以下是声明性和编程式配置片段,显示如何启用ZONE_AWARE分组。
<partition-group enabled="true" group-type="ZONE_AWARE" />
Config config = ...;
PartitionGroupConfig partitionGroupConfig = config.getPartitionGroupConfig();
partitionGroupConfig.setEnabled( true )
.setGroupType( MemberGroupType.ZONE_AWARE );
5. SPI:
您可以使用SPI配置提供自己的分区组实现。要创建分区组实现,您需要首先扩展DiscoveryStrategy发现服务插件的类,重写该方法public PartitionGroupStrategy getPartitionGroupStrategy(),然后PartitionGroupStrategy在该重写方法中返回配置。
以下是涵盖上段所述实施步骤的示例代码:
public class CustomDiscovery extends AbstractDiscoveryStrategy {
public CustomDiscovery(ILogger logger, Map<String, Comparable> properties) {
super(logger, properties);
}
@Override
public Iterable<DiscoveryNode> discoverNodes() {
Iterable<DiscoveryNode> iterable = //TODO implementation
return iterable;
}
@Override
public PartitionGroupStrategy getPartitionGroupStrategy() {
return new CustomPartitionGroupStrategy();
}
private class CustomPartitionGroupStrategy implements PartitionGroupStrategy {
@Override
public Iterable<MemberGroup> getMemberGroups() {
Iterable<MemberGroup> iterable = //TODO implementation
return iterable;
}
}
}
Hazelcast具有灵活的日志记录配置,并且不依赖于除JDK日志记录之外的任何日志记录框架。它具有用于许多日志记录框架的内置适配器,并且还通过提供日志记录接口来支持自定义记录器。
要使用内置适配器,请将hazelcast.logging.type属性设置为以下预定义类型之一。
- jdk:JDK日志记录(默认)
- log4j:Log4j
- log4j2:Log4j2
- slf4j:Slf4j
- none:禁用日志记录
您可以hazelcast.logging.type通过声明性配置,编程配置或JVM系统属性进行设置。
如果选择使用log4j,log4j2或slf4j,则应在类路径中包含正确的依赖项。 |
声明性配置
....
<properties>
<property name="hazelcast.logging.type">log4j</property>
....
</properties>
</hazelcast>
程序化配置
Config config = new Config() ;
config.setProperty( "hazelcast.logging.type", "log4j" );
系统属性
- 使用JVM参数: java -Dhazelcast.logging.type=slf4j
- 使用System类: System.setProperty( "hazelcast.logging.type", "none" );
如果提供的日志记录机制不满意,您可以使用自定义日志记录功能实现自己的日志记录机制 要使用它,请实现com.hazelcast.logging.LoggerFactory和com.hazelcast.logging.ILogger接口并将系统属性设置hazelcast.logging.class为自定义LoggerFactory类名。
-Dhazelcast.logging.class=foo.bar.MyLoggingFactory
您还可以通过注册来收听Hazelcast运行时生成的日志记录事件LogListener`s to `LoggingService。
LogListener listener = new LogListener() {
public void log( LogEvent logEvent ) {
// do something
}
};
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
LoggingService loggingService = instance.getLoggingService();
loggingService.addLogListener( Level.INFO, listener );
通过LoggingService,您可以获得当前使用的ILogger实现并记录您自己的消息。
如果您没有使用命令行来配置日志记录,则应该注意Hazelcast类。jdk在读取新配置的日志记录之前,它们可能默认为日志记录。选择日志记录机制时,它不会更改。 |
在使用编程配置时,所有与网络相关的配置都通过networkHazelcast XML配置文件或类中的元素执行NetworkConfig。以下小节介绍了可以在network元素下执行的可用配置。
public-address覆盖成员的公共地址。默认情况下,成员选择其套接字地址作为其公共地址。但是在网络地址转换(NAT)之后,两个端点(成员)可能无法彼此查看/访问。如果两个成员都将其公共地址设置为NAT上定义的地址,那么他们可以相互通信。在这种情况下,它们的公共地址不是本地网络接口的地址,而是NAT定义的虚拟地址。当您拥有私有云时,可以选择设置和使用。请注意,此元素的值应以格式给出host IP address:port number。请参阅以下示例。
声明:
<network>
<public-address>11.22.33.44:5555</public-address>
</network>
程序化:
Config config = new Config();
config.getNetworkConfig()
.setPublicAddress( "11.22.33.44:5555" );
您可以指定Hazelcast将用于在集群成员之间进行通信的端口。它的默认值是5701。以下是示例配置。
声明:
<network>
<port port-count="20" auto-increment="true">5701</port>
</network>
程序化:
Config config = new Config();
config.getNetworkConfig().setPort( 5701 )
.setPortAutoIncrement( true ).setPortCount( 20 );
根据上面的例子,Hazelcast将尝试在5701和5720之间找到空闲端口。
port 具有以下属性。
- port-count:默认情况下,Hazelcast将尝试绑定100个端口。这意味着,如果您将port的值设置为5701,则当成员加入群集时,Hazelcast会尝试在5701和5801之间查找端口。您可以选择更改端口数,例如在一台计算机上拥有大型实例或者只愿意分配几个端口。该参数port-count用于此目的,其默认值为100。
- auto-increment:在某些情况下,您可能希望选择仅使用一个端口。在这种情况下,您可以port通过设置auto-increment为禁用自动增量功能false。port-count禁用自动增量功能时不使用该属性。
默认情况下,Hazelcast允许系统在套接字绑定操作期间选择一个短暂的端口。但是,安全策略/防火墙可能要求您限制启用Hazelcast的应用程序使用的出站端口。要满足此要求,您可以将Hazelcast配置为仅使用已定义的出站端口。以下是示例配置。
声明:
<network>
<outbound-ports>
<!-- ports between 33000 and 35000 -->
<ports>33000-35000</ports>
<!-- comma separated ports -->
<ports>37000,37001,37002,37003</ports>
<ports>38000,38500-38600</ports>
</outbound-ports>
</network>
程序化:
...
NetworkConfig networkConfig = config.getNetworkConfig();
// ports between 35000 and 35100
networkConfig.addOutboundPortDefinition("35000-35100");
// comma separated ports
networkConfig.addOutboundPortDefinition("36001, 36002, 36003");
networkConfig.addOutboundPort(37000);
networkConfig.addOutboundPort(37001);
...
您可以使用端口范围和/或逗号分隔端口。 |
如编程配置中所示,您使用该方法addOutboundPort仅添加一个端口。如果需要添加一组端口,请使用该方法addOutboundPortDefinition。
在声明性配置中,该元素ports可用于单端口和多端口定义。当您将此元素设置为 0或时 *,您的操作系统(而不是Hazelcast)将从短暂范围中选择一个空闲端口。
关闭集群成员时,服务器套接字端口将在TIME_WAIT接下来的几分钟内处于该状态。如果在关闭它之后立即启动该成员,则可能无法将其绑定到同一端口,因为它处于该TIME_WAIT状态。如果将reuse-address元素设置为true,TIME_WAIT则忽略状态,并且可以再次将成员绑定到同一端口。
以下是示例配置。
声明:
<network>
<reuse-address>true</reuse-address>
</network>
程序化:
...
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setReuseAddress( true );
...
该join构造元件被用于发现Hazelcast构件,使它们能够形成群集。Hazelcast提供多播,TCP / IP,EC2和jclouds®发现机制。发现机制部分解释了这些机制。本节描述了元素的所有子元素和属性join。以下是示例配置。
声明:
<network>
<join>
<multicast enabled="true">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
<multicast-time-to-live>32</multicast-time-to-live>
<multicast-timeout-seconds>2</multicast-timeout-seconds>
<trusted-interfaces>
<interface>192.168.1.102</interface>
</trusted-interfaces>
</multicast>
<tcp-ip enabled="false">
<required-member>192.168.1.104</required-member>
<member>192.168.1.104</member>
<members>192.168.1.105,192.168.1.106</members>
</tcp-ip>
<aws enabled="false">
<access-key>my-access-key</access-key>
<secret-key>my-secret-key</secret-key>
<region>us-west-1</region>
<host-header>ec2.amazonaws.com</host-header>
<security-group-name>hazelcast-sg</security-group-name>
<tag-key>type</tag-key>
<tag-value>hz-members</tag-value>
</aws>
<discovery-strategies>
<discovery-strategy ... />
</discovery-strategies>
</join>
</network>
程序化:
Config config = new Config();
NetworkConfig network = config.getNetworkConfig();
JoinConfig join = network.getJoin();
join.getMulticastConfig().setEnabled( false )
.addTrustedInterface( "192.168.1.102" );
join.getTcpIpConfig().addMember( "10.45.67.32" ).addMember( "10.45.67.100" )
.setRequiredMember( "192.168.10.100" ).setEnabled( true );
该join元素具有以下子元素和属性。
该multicast元素包括用于微调多播连接机制的参数。
- enabled:指定是否启用多播发现,true或false。
- multicast-group:组播组IP地址。如果要在同一网络中创建群集,请指定它。值可以在224.0.0.0和239.255.255.255之间。默认值为224.2.2.3。
- multicast-port:Hazelcast成员侦听并通过发送发现消息的多播套接字端口。默认值为54327。
- multicast-time-to-live:发送的多播数据包的生存时间值,用于控制多播的范围。在此处查看更多信息。
- multicast-timeout-seconds:仅当成员启动时,此超时(以秒为单位)指定成员等待来自其他成员的多播响应的时间段。例如,如果将其设置为60秒,则每个成员将等待60秒,直到选择了引导成员。其默认值为2秒。
- trusted-interfaces:包括可信成员的IP地址。当成员想要加入群集时,如果加入请求不是受信任成员,则会拒绝其加入请求。您可以使用IP地址的最后一位数字上的通配符(*)来指定IP地址范围,例如192.168.1。\ *或192.168.1.100-110。
该tcp-ip元素包括微调TCP / IP连接机制的参数。
- enabled:指定是否启用TCP / IP发现。值可以是true或false。
- required-member:所需成员的IP地址。只有找到具有此IP地址的成员才会形成群集。
- member:一个或多个众所周知的成员的IP地址。一旦成员连接到这些众所周知的成员,所有成员地址将相互通信。您还可以使用该members元素为逗号分隔IP地址。
tcp-ipelement也接受interface参数。请参阅Interfaces元素说明。 |
- connection-timeout-seconds:定义连接超时。这是Hazelcast在放弃之前尝试连接到知名成员的最长时间。将其设置为太低的值可能意味着成员无法连接到群集。将其设置为太高的值意味着成员启动可能因为更长的超时而减慢,例如当一个众所周知的成员没有启动时。如果列出了许多IP且成员无法正确构建群集,则建议增加此值。其默认值为5。
该aws元素包括允许成员在Amazon EC2环境中形成集群的参数。
- enabled:指定是否启用EC2发现,true或false。
- access-key,secret-key:您在EC2上的帐户的访问密钥和密钥。
- region:您的成员正在运行的区域。默认值是us-east-1。如果区域不是默认区域,则需要指定此区域。
- host-header:作为Web服务入口点的URL。这是可选的。
- security-group-name:您在EC2管理控制台中指定的安全组的名称。它用于缩小Hazelcast成员在此组内的范围。这是可选的。
- tag-key,tag-value:要将云中的成员缩小为仅限Hazelcast成员,可以将这些参数设置为您在EC2控制台中指定的参数。它们是可选的。
- connection-timeout-seconds:Hazelcast在放弃之前尝试连接到知名成员的最长时间。将此值设置得太低可能意味着成员无法连接到群集。将值设置得太高意味着成员启动可能会因为更长的超时而减慢(例如,当一个众所周知的成员未启动时)。如果列出了许多IP且成员无法正确构建群集,则建议增加此值。其默认值为5。
如果您使用的是AWS以外的云提供程序,则可以使用编程配置来指定TCP / IP群集。需要从该提供者检索成员,例如jclouds。
该discovery-strategies元素基于Hazelcast Discovery SPI配置内部或外部发现策略。有关详细信息,请参阅Discovery SPI部分和使用的发现策略的供应商文档。
要确保正确找到EC2实例,您可以使用AWSClient该类。它确定要连接的EC2实例的私有IP地址。为AWSClient类提供您在aws元素中指定的参数的值,如下所示。您将看到是否找到了您的EC2实例。
public static void main( String[] args )throws Exception{
AwsConfig config = new AwsConfig();
config.setSecretKey( ... ) ;
config.setSecretKey( ... );
config.setRegion( ... );
config.setSecurityGroupName( ... );
config.setTagKey( ... );
config.setTagValue( ... );
config.setEnabled( true );
AWSClient client = new AWSClient( config );
Collection<String> ipAddresses = client.getPrivateIpAddresses();
System.out.println( "addresses found:" + ipAddresses );
for ( String ip: ipAddresses ) {
System.out.println( ip );
}
}
您可以指定Hazelcast应使用的网络接口。服务器通常具有多个网络接口,因此您可能希望列出有效的IP。范围字符('*'和' - ')可用于简化。例如,10.3.10。\ *是指10.3.10.0和10.3.10.255之间的IP。接口10.3.10.4-18是指10.3.10.4和10.3.10.18之间的IP(包括4和18)。如果启用了网络接口配置(默认情况下禁用),并且Hazelcast无法找到匹配的接口,则它将在控制台上打印消息,并且不会在该成员上启动。
以下是示例配置。
声明:
<hazelcast>
...
<network>
...
<interfaces enabled="true">
<interface>10.3.16.*</interface>
<interface>10.3.10.4-18</interface>
<interface>192.168.1.3</interface>
</interfaces>
</network>
...
</hazelcast>
程序化:
Config config = new Config();
NetworkConfig network = config.getNetworkConfig();
InterfacesConfig interfaceConfig = network.getInterfaces();
interfaceConfig.setEnabled( true )
.addInterface( "192.168.1.3" );
Hazelcast无缝支持IPv6地址(默认情况下,此支持已关闭,请参阅本节末尾的注释)。
您所需要的只是在网络配置中定义IPv6地址或接口。唯一的当前限制是您无法在TCP / IP连接配置(tcp-ip元素)中定义通配符IPv6地址。接口配置没有此限制,可以采用与IPv4接口相同的方式配置通配符IPv6接口。
<hazelcast>
...
<network>
<port auto-increment="true">5701</port>
<join>
<multicast enabled="false">
<multicast-group>FF02:0:0:0:0:0:0:1</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="true">
<member>[fe80::223:6cff:fe93:7c7e]:5701</member>
<interface>192.168.1.0-7</interface>
<interface>192.168.1.*</interface>
<interface>fe80:0:0:0:45c5:47ee:fe15:493a</interface>
</tcp-ip>
</join>
<interfaces enabled="true">
<interface>10.3.16.*</interface>
<interface>10.3.10.4-18</interface>
<interface>fe80:0:0:0:45c5:47ee:fe15:*</interface>
<interface>fe80::223:6cff:fe93:0-5555</interface>
</interfaces>
...
</network>
...
</hazelcast>
JVM有两个系统属性,用于设置首选协议堆栈(IPv4或IPv6)以及首选地址系列类型(inet4或inet6)。在双栈机器上,默认情况下首选IPv6堆栈,您可以通过java.net.preferIPv4Stack=<true|false>系统属性更改此值。查询名称服务时,JVM优先选择IPv6地址上的IPv4地址,并在可能的情况下返回IPv4地址。您可以通过java.net.preferIPv6Addresses=<true|false>系统属性更改此设置。
另请参阅Java中有关IPv6支持的其他详细信息。
默认情况下,IPv6支持已关闭,因为某些平台在使用IPv6堆栈时存在问题。亚马逊AWS等其他平台根本没有任何支持。要启用IPv6支持,只需将configuration属性设置hazelcast.prefer.ipv4.stack为false。有关详细信息,请参阅系统属性附录。 |
此SPI不用于提供Hazelcast实例将与其构成群集的其他群集成员的地址。为此,请参阅上面的其他网络配置部分。 |
默认情况下,Hazelcast选择公共和绑定地址。您可以通过public-address在配置中定义a 或使用上面提到的其他属性来影响选择。但是,在某些情况下,这些属性还不够,默认地址选择策略将选择错误的地址。在使用Docker时在某些云环境(例如AWS)中部署Hazelcast时,或者在NAT后面部署实例且public-address属性不足时,可能会出现这种情况(请参阅公共地址部分)。
在这些情况下,可以以更高级的方式配置绑定和公共地址。您可以提供com.hazelcast.spi.MemberAddressProvider接口的实现,该接口将提供绑定和公共地址。然后,实现可以以任何方式选择这些地址 - 它可以从系统属性或文件读取,甚至可以调用Web服务来检索公共和私有地址。
实施细节在很大程度上取决于部署Hazelcast的环境。因此,我们将演示如何配置Hazelcast以使用简化的自定义成员地址提供程序SPI实现。下面显示了一个实现示例:
public static final class SimpleMemberAddressProvider implements MemberAddressProvider {
@Override
public InetSocketAddress getBindAddress() {
// determine the address using some configuration, calling an API, ...
return new InetSocketAddress(hostname, port);
}
@Override
public InetSocketAddress getPublicAddress() {
// determine the address using some configuration, calling an API, ...
return new InetSocketAddress(hostname, port);
}
}
请注意,如果绑定地址端口是,0那么它将使用Hazelcast网络配置中配置的端口(请参阅端口部分)。如果将公共地址端口设置为,0则它将广播与其绑定的相同端口。如果您希望绑定到任何本地接口,您可以new InetSocketAddress((InetAddress) null, port)从该getBindAddress()地址返回。
以下配置示例包含将提供给提供的类的构造函数的属性。如果您不提供任何属性,则该类可能具有no-arg构造函数或接受单个java.util.Properties实例的构造函数。另一方面,如果确实在配置中提供了属性,则该类必须具有接受单个java.util.Properties实例的构造函数。
声明:
<network>
<member-address-provider enabled="true">
<class-name>SimpleMemberAddressProvider</class-name>
<properties>
<property name="prop1">prop1-value</property>
<property name="prop2">prop2-value</property>
</properties>
</member-address-provider>
<!-- other network configuration -->
</network>
程序化:
Config config = new Config();
MemberAddressProviderConfig memberAddressProviderConfig = config.getNetworkConfig().getMemberAddressProviderConfig();
memberAddressProviderConfig
.setEnabled(true)
.setClassName(MemberAddressProviderWithStaticProperties.class.getName());
Properties properties = memberAddressProviderConfig.getProperties();
properties.setProperty("prop1", "prop1-value");
properties.setProperty("prop2", "prop2-value");
config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
// perform other configuration
Hazelcast.newHazelcastInstance(config);
故障检测器负责确定群集中的成员是否无法访问或崩溃。故障检测中最重要的问题是区分成员是否仍然活着但是缓慢或已经崩溃。但是根据着名的FLP结果,在异步系统中不可能区分崩溃成员和慢成员。解决此限制的方法是使用不可靠的故障检测器。不可靠的故障检测器允许成员怀疑其他人失败,通常基于活跃标准,但它可能在一定程度上犯错误。
Hazelcast有两个内置故障检测器; 截止故障检测器和Phi应计故障检测器。
从3.9.1开始,Hazelcast提供了另一种故障检测器Ping故障检测器,如果启用,它将与上述并行工作,但识别OSI第3层(网络层)上的故障。默认情况下禁用此检测器。
请注意,Hazelcast还为其Java客户端提供故障检测器。有关更多信息,请参阅客户端故障检测器部分。
截止日期故障检测器使用绝对超时来丢失/丢失心跳。超时后,会员被视为崩溃/不可用并标记为可疑。
截止日期故障检测器有两个配置属性:
- hazelcast.heartbeat.interval.seconds:这是成员心跳消息相互发送的时间间隔。
- hazelcast.max.no.heartbeat.seconds:这是超时,它定义何时怀疑集群成员,因为它尚未发送任何心跳。
要使用截止日期故障检测器配置属性hazelcast.heartbeat.failuredetector.type应设置为"deadline"。
<hazelcast>
[...]
<properties>
<property name="hazelcast.heartbeat.failuredetector.type">deadline</property>
<property name="hazelcast.heartbeat.interval.seconds">5</property>
<property name="hazelcast.max.no.heartbeat.seconds">120</property>
[...]
</properties>
[...]
</hazelcast>
Config config = ...;
config.setProperty("hazelcast.heartbeat.failuredetector.type", "deadline");
config.setProperty("hazelcast.heartbeat.interval.seconds", "5");
config.setProperty("hazelcast.max.no.heartbeat.seconds", "120");
[...]
Deadline Failure Detector是Hazelcast中的默认故障检测器。 |
这是基于Hayashibara等人的Phi Accrual Failure Detector'的故障检测器。
Phi Accrual Failure Detector在滑动时间窗口中跟踪心跳之间的间隔,并测量这些样本的均值和方差,并计算怀疑水平(Phi)的值。当自上一次心跳变长以来的时间段内,phi的值将增加。如果网络变得缓慢或不可靠,则所得的均值和方差将增加,需要更长的时间段,在怀疑成员之前不会收到心跳。
hazelcast.heartbeat.interval.seconds 和hazelcast.max.no.heartbeat.seconds 属性仍将用作心跳消息的期间和心跳消息的截止时间。由于Phi Accrual Failure Detector适用于网络条件,hazelcast.max.no.heartbeat.seconds因此可以比Deadline Failure Detector的超时定义更低。
除上述两个属性外,Phi Accrual Failure Detector还有三个配置属性:
- hazelcast.heartbeat.phiaccrual.failuredetector.threshold:这是怀疑的phi门槛。计算出的phi超过此阈值后,会员被视为无法访问并被标记为可疑。低阈值允许更快地检测成员崩溃/故障,但可能产生更多错误并导致错误的成员怀疑。高阈值产生的错误更少,但检测实际崩溃/失败的速度较慢。
phi = 1意味着我们会犯错误的可能性10%。可能性1%与有phi = 2,0.1%有phi = 3等等有关。默认phi阈值为10。
- hazelcast.heartbeat.phiaccrual.failuredetector.sample.size:要保留历史记录的样本数。默认值为200。
- hazelcast.heartbeat.phiaccrual.failuredetector.min.std.dev.millis:计算phi时使用的正态分布的最小标准偏差。标准偏差太低可能导致灵敏度过高。
要使用Phi Accrual Failure Detector,配置属性hazelcast.heartbeat.failuredetector.type应设置为"phi-accrual"。
<hazelcast>
[...]
<properties>
<property name="hazelcast.heartbeat.failuredetector.type">phi-accrual</property>
<property name="hazelcast.heartbeat.interval.seconds">1</property>
<property name="hazelcast.max.no.heartbeat.seconds">60</property>
<property name="hazelcast.heartbeat.phiaccrual.failuredetector.threshold">10</property>
<property name="hazelcast.heartbeat.phiaccrual.failuredetector.sample.size">200</property>
<property name="hazelcast.heartbeat.phiaccrual.failuredetector.min.std.dev.millis">100</property>
[...]
</properties>
[...]
</hazelcast>
Config config = ...;
config.setProperty("hazelcast.heartbeat.failuredetector.type", "phi-accrual");
config.setProperty("hazelcast.heartbeat.interval.seconds", "1");
config.setProperty("hazelcast.max.no.heartbeat.seconds", "60");
config.setProperty("hazelcast.heartbeat.phiaccrual.failuredetector.threshold", "10");
config.setProperty("hazelcast.heartbeat.phiaccrual.failuredetector.sample.size", "200");
config.setProperty("hazelcast.heartbeat.phiaccrual.failuredetector.min.std.dev.millis", "100");
[...]
除了Deadline和Phi Accual Failure Detectors之一之外,还可以配置Ping故障检测器。它在OSI协议的第3层运行,并提供更快,更确定的硬件和其他低级事件检测。该检测器可以被配置为在成员被其他检测器之一怀疑之后执行额外检查,或者它可以并行工作,这是默认的。这样可以更快地检测到硬件和网络级问题。
该故障检测器基于InetAddress.isReachable()。当JVM进程具有足够的权限来创建RAW套接字时,实现将选择依赖于ICMP Echo请求。这是优选的。
如果没有足够的权限,则可以将其配置为在端口7上尝试TCP Echo时回退。在后一种情况下,成功连接或显式拒绝都将被视为“主机可访问”。或者,它可以被迫仅使用RAW套接字。这不是优选的,因为每次调用都会创建一个重量级的套接字,而且通常会禁用Echo服务。
要使Ping故障检测器仅依赖于ICMP Echo请求,需要满足一些标准。
- 支持的操作系统:从Java 1.8开始,仅支持Linux / Unix环境。该检测器依赖于ICMP,即ping命令背后的协议。它尝试定期发出ping尝试,并且它们的响应用于确定远程成员的可达性。但是,您不能简单地创建ICMP Echo请求,因为这些类型的数据包不依赖于任何预先存在的传输协议(如TCP)。要创建此类请求,您必须具有创建RAW套接字的权限(请参阅https://linux.die.net/man/7/raw)。大多数操作系统允许root用户使用,但基于Unix的操作系统更灵活,允许每个进程使用自定义权限,而不需要root访问权限。因此,此检测器仅在Linux上受支持。
- Java可执行文件必须具有该cap_net_raw功能。如上述要求所述,在Linux上,您可以为单个进程定义额外的功能,这将允许进程与RAW套接字进行交互。这种交互是通过该功能实现的cap_net_raw(请参阅https://linux.die.net/man/7/capabilities)。要启用此功能,请运行以下命令:
sudo setcap cap_net_raw=+ep <JDK_HOME>/jre/bin/java
- 使用自定义功能运行时,Linux上的动态链接器将拒绝从不受信任的路径加载库。由于您现在已经cap_net_raw成为进程的自定义功能,因此对动态链接器会产生怀疑,它会引发错误:java: error while loading shared libraries: libjli.so: cannot open shared object file: No such file or directory
- 为了克服这种拒绝,<JDK_HOME>/jre/lib/amd64/jli/需要在路径中添加路径ld.conf。运行以下命令来执行此操作:echo "<JDK_HOME>/jre/lib/amd64/jli/" >> /etc/ld.so.conf.d/java.conf && sudo ldconfig
- 接收主机不得阻止ICMP Echo请求。 /proc/sys/net/ipv4/icmp_echo_ignore_all设置为0。运行以下命令:
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all
如果不满足上述任何条件,那么isReachable将始终回退端口7上的TCP Echo尝试。
为了能够使用Ping故障检测器,请在Hazelcast声明性配置文件中添加以下属性:
<hazelcast>
[...]
<properties>
<property name="hazelcast.icmp.enabled">true</property>
<property name="hazelcast.icmp.parallel.mode">true</property>
<property name="hazelcast.icmp.timeout">1000</property>
<property name="hazelcast.icmp.max.attempts">3</property>
<property name="hazelcast.icmp.interval">1000</property>
<property name="hazelcast.icmp.ttl">0</property>
[...]
</properties>
[...]
</hazelcast>
- hazelcast.icmp.enabled (默认为false) - 启用传统ICMP检测模式,与现有故障检测器协同工作,并且仅在预定义时间段过后且没有来自成员的心跳时启动。
- hazelcast.icmp.parallel.mode (默认为true) - 启用并行ping检测器,与其他检测器分开工作。
- hazelcast.icmp.timeout (默认值1000) - 如果没有回复,则认为ping尝试失败的毫秒数。
- hazelcast.icmp.max.attempts (默认值3) - 检测器怀疑成员/节点之前的最大ping尝试次数。
- hazelcast.icmp.interval(默认值1000) - 每次ping尝试之间的间隔(以毫秒为单位)。1000毫秒(1秒)也是允许的最小间隔。
- hazelcast.icmp.ttl (默认值为0) - 数据包应通过的最大跳数或默认值为0。
在上面的配置中,Ping检测器将尝试3次ping,每秒一次,每次完成将等待1秒钟。如果3秒后没有成功ping,会员将被怀疑。
要强制执行要求,hazelcast.icmp.echo.fail.fast.on.startup还可以将属性设置为true,在这种情况下,如果未满足任何要求,Hazelcast将无法启动。
以下是ping故障检测器的所有可能配置组合的汇总表。
表2. Ping故障检测器可能的配置组合 | ||||||
ICMP | 平行 | 快速失败 | 描述 | Linux的 | 视窗 | 苹果系统 |
假 | 假 | 假 | 完全禁用 | N / A | N / A | N / A |
真正 | 假 | 假 | 传统ping模式。这与OSI第7层故障检测器密切配合(参见上文中的.phi或截止日期)。在此模式下Ping只会在收到没有听力的时间段后启动,在这种情况下,远程Hazelcast会员将被ping到最多5次。如果所有5次尝试都失败,则该成员被怀疑。 | 支持的ICMP Echo(如果可用) - 在端口7上回退TCP Echo | 端口7上支持的TCP Echo | 支持的ICMP Echo(如果可用) - 在端口7上回退TCP Echo |
真正 | 真正 | 假 | 并行ping检测器与配置的故障检测器并行工作。定期检查成员是否在线(OSI第3层),并立即怀疑它们,无论其他探测器如何。 | 支持的ICMP Echo(如果可用) - 在端口7上回退TCP Echo | 端口7上支持的TCP Echo | 支持的ICMP Echo(如果可用) - 在端口7上回退TCP Echo |
真正 | 真正 | 真正 | 并行ping检测器与配置的故障检测器并行工作。定期检查成员是否在线(OSI第3层),并立即怀疑它们,无论其他探测器如何。 | 支持 - 需要操作系统配置执行ICMP Echo(如果可用) - 如果不可用则不启动 | 不支持 | 不支持 - 需要root权限 |