天天看點

Hazelcast.xml 配置檔案說明

配置

Hazelcast的使用可以通過XML配置和程式設計來實作,或者是兩者共同配合使用來完成其功能;

1-配置聲明

如果你建立Hazelcast執行個體的時候,不傳遞參數給Hazelcast的話(即:newHazelcastInstance(null))或者使用空的工廠方法(Hazelcast.newHazelcastInstance)來建立,Hazelcast将會自己自動的檢查兩個地方來尋找Hazelcast的配置檔案:

§   系統屬性:Hazelcast 首先會檢查是否”hazelcast.config”系統屬性被設定到某個配置檔案下。例如:

-Dhazelcast.config=C:/myhazelcast.xml

§   Classpath:如果配置檔案配置成系統屬性,Hazelcast将會繼續檢查classpath 來尋找hazelcast.xml檔案。

如果Hazelcast 沒有找到任何配置檔案,它将很樂意的使用預設的配置檔案(hazelcast-default.xml),它在hazelcast.jar包下。(在配置Hazelcast之前,建議您使用預設的配置檔案來看看是否Hazelcast能正常的工作。預設的配置檔案對于大部分的開發者來說已經是很好的了。如果您不想這樣,那麼就考慮為您的環境親自配置一份吧)。

如果您想指定自己的配置檔案來建立配置的話,Hazelcast提供了幾種方式來供您選擇,包括-filesystem,classpath,InputStream,URL等等:

§   Config cfg = new XmlConfigBuilder(xmlFileName).build();

§   Config cfg = new XmlConfigBuilder(inputStream).build();

§   Config cfg = new ClasspathXmlConfig(xmlFileName);

§   Config cfg = new FileSystemXmlConfig(configFilename);

§   Config cfg = new UrlXmlConfig(url);

§   Config cfg = new InMemoryXmlConfig(xml);

2- 可程式設計配置

根據您的需求,初始化Config對象設定/修改屬性,完成程式設計式的配置Hazelcast。

    Config config =new Config();

    config.getNetworkConfig().setPort(5900 );

    config.getNetworkConfig().setPortAutoIncrement(false );

NetworkConfig network = config.getNetworkConfig();

JoinConfig join = network.getJoin();

join.getMulticastConfig().setEnabled( false );

join.getTcpIpConfig().addMember( "10.45.67.32").addMember( "10.45.67.100" ) .setRequiredMember("192.168.10.100" ).setEnabled( true );

network.getInterfaces().setEnabled( true ).addInterface("10.45.67.*" );

MapConfig mapConfig = new MapConfig();

mapConfig.setName( "testMap" );

mapConfig.setBackupCount( 2 );

mapConfig.getMaxSizeConfig().setSize( 10000 );

mapConfig.setTimeToLiveSeconds( 300 );

MapStoreConfig mapStoreConfig = new MapStoreConfig();

mapStoreConfig.setClassName("com.hazelcast.examples.DummyStore" )

    .setEnabled(true );

mapConfig.setMapStoreConfig( mapStoreConfig );

NearCacheConfig nearCacheConfig = new NearCacheConfig();

nearCacheConfig.setMaxSize( 1000 ).setMaxIdleSeconds( 120)

   .setTimeToLiveSeconds( 300 );

mapConfig.setNearCacheConfig( nearCacheConfig );

config.addMapConfig( mapConfig );

然後建立Config對象,你就可以用這個對象來建立Hazelcast執行個體。

  • HazelcastInstance hazelcast = Hazelcast.newHazelcastInstance( config );
  • 建立一個名為HazelcastInstance對象,将config對象傳給它。

Config config = new Config();

config.setInstanceName( "my-instance" );

Hazelcast.newHazelcastInstance( config );

·        用它的名字來取得一個已經存在的HazelcastInstance;

Hazelcast.getHazelcastInstanceByName("my-instance" );

·        用它的名字來取得所有已經存在的HazelcastInstance;

Hazelcast.getAllHazelcastInstances();

使用通配符

Hazelcast支援為所有分布式資料結構的通配符配置,它可以使用Config來配置(但除了 IatomicLong,IatomicReference)。在不同的map,queues,topics,semaphores執行個體等名字中使用星号(*)簡單的配置。

注意,這種簡單的用法,星号(*)可以放在配置中的任何位置。

比如:一個名叫‘com.hazelcast.test.mymap’的map可以使用以下的幾種配置方式:

<map name="com.hazelcast.test.*">

...

</map>

<map name="com.hazel*">

...

</map>

<map name="*.test.mymap">

...

</map>

<map name="com.*test.mymap">

...

</map>

或者 一個queue ‘com.hazelcast.test.myqueue’;

<queue name="*hazelcast.test.myqueue">

...

</queue>

<queue name="com.hazelcast.*.myqueue">

...

</queue>

網絡配置

配置TCP/IP叢集

如果你的環境中多點傳播不是首選的話,那麼你可以配置Hazelcast完整叢集。像下面的配置顯示那樣,當多點傳播屬性被設定成false時,tcp-ip就不得不設定為true。

對于一個沒有多點傳播選擇的環境,所有或者主機和IP節點必須列出。注意,所有的叢集節點必須列出來,但是至少有一個是活動的當有一個新的節點進來時。

<hazelcast>

  ...

  <network>

    <portauto-increment="true">5701</port>

    <join>

      <multicastenabled="false">

       <multicast-group>224.2.2.3</multicast-group>

       <multicast-port>54327</multicast-port>

     </multicast>

      <tcp-ipenabled="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>

鑒于它需要被看到,IP位址和主機名可以作為節點的标簽。你還可以給出一個IP範圍,例如:192.168.1.0-7.

為了不一行一行的配置,你可以使用逗号作為标簽,寫在IP之間,如下所示:

<members>192.168.1.0-7,192.168.1.21</members>

如果節點的端口不支援,Hazelcast可以自動的嘗試5701,5702等端口。

Hazelcast預設情況下,會自動的綁定本網絡接口的所有通信資料流。當然,這也可以通過系統屬性來改變。

Hazelcast.socket.bind.any。當這個屬性值被設定為false時,Hazelcast使用接口之間的特定接口(請參考 Specifying Network Interfaces 章節)。如果沒有接口提供,那它會試着解析任何一個綁定的端口,在這個節點标簽上讓步。

Tcp-ip标簽接收一個叫connection-timeout-seconds的屬性,它的預設值是 5。推薦您增加這個值,如果你有許多IP清單的話,并且當節點不能很好的建立叢集的話。

還有一個标簽,required-member,用來識别特定的節點,需要設定在一個叢集前面。

<hazelcast>

  ...

  <network>

    <join>

      <tcp-ipenabled="true">

       <required-member>192.168.1.21</required-member>

       <member>machine2</member>

       <member>machine3:5799</member>

       <member>192.168.1.0-7</member>

     </tcp-ip>

    </join>

    ...

  </network>

  ...

</hazelcast>

在這個例子中,這個叢集不會生效,除非節點的IP  192.168.1.21 是有效的。

指定網絡接口

你可以指定Hazelcast使用哪個你指派的接口。伺服器大部分都有超過一個的網絡接口,是以你需要列出有效的所有IP。可以簡易的使用 ‘*’ 和 ‘-’。例如 10.3.10.* ,可以替代10.3.10.0-10.3.10.255 .接口是 10.3.10.4-18(4,18也包括)。如果網絡接口是配置為允許的(預設不允許),并且Hazelcast不能找到比對的接口,那麼它将會在控制台列印出一條資訊,在那個節點上不能啟動。

<hazelcast>

  ...

  <network>

    ...

    <interfacesenabled="true">

     <interface>10.3.16.*</interface>

     <interface>10.3.10.4-18</interface>

     <interface>192.168.1.3</interface>        

   </interfaces>   

  </network>

  ...

</hazelcast>

EC2(彈性計算雲) 自動發現

Hazelcast 支援EC2自動發現機制,這當你不想或是不能提供可能的IP位址時,會是很有用的東西。可以你的叢集配置成能夠使用EC2自發發現功能,禁用加入多點傳播和TCP / IP和啟用AWS。還可以給你提供認資訊(權限和秘鑰)。

這需要你将hazelcast-cloud.jar添加到你的項目依賴中。注意,這個jar包被綁定到了hazelcast-all.jar包中。Hazelcast 不依賴其他任何第三方插件。

下面是一個配置樣本:

<join>

  <multicast enabled="false">

   <multicast-group>224.2.2.3</multicast-group>

   <multicast-port>54327</multicast-port>

  </multicast>

  <tcp-ip enabled="false">

   <interface>192.168.1.2</interface>

  </tcp-ip>

  <aws enabled="true">

    <access-key>my-access-key</access-key>

   <secret-key>my-secret-key</secret-key>

    <!-- optional, default is us-east-1-->

<region>us-west-1</region>

<!—預設是ec2.amazonaws.com,如果你要設定的話,請不要覆寫此屬性-->

 <host-header>ec2.amazonaws.com</host-header>

    <!-- optional -->

    <security-group-name>hazelcast-sg</security-group-name>

    <!-- optional -->

    <tag-key>type</tag-key>

    <!-- optional -->

    <tag-value>hz-nodes</tag-value>

  </aws>

</join>

标簽aws 的屬性值是一個叫做 connection-timeout-seconds 的屬性,預設是5(s)。如果你有許多IP和并且節點不能很好适應叢集的話,是可以增加這個值的。

Region參數指定了哪個節點的機器是運作的。預設值是 us-east-1。如果叢集在不同的地方運作,必須指定地點。否則,叢集将會不穩定,因為他們不能互相發現對方。

Tag-key 和 tag-value 參數提供不同的key和value值,讓你可以在同一個資料中心建立多個叢集。

Securit-group-name 參數還可以用來過濾/組合節點。

注意:如果你采用了雲的方式,而不是AWS,你可以使用程式化的叢集配置指定一個TCP / IP。節點需要從提供方那重新擷取。

AWSClient:

確定EC2已經正确建立了,這時候AWSClient就可以使用了。它為EC2連接配接提供私有的IP位址。隻要給它提供參數值,并在aws标簽中指定即可。如下所示,你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 );

  List<String> ipAddresses = client.getPrivateIpAddresses();

  System.out.println( "addressesfound:" + ipAddresses );

  for ( String ip: ipAddresses ) {

    System.out.println( ip );

  }

}可以知道你的EC2是否已經建立。

調試:

在需要的時候,Hazelcast會記錄下在一個域的事件日志,改變日志等級為FINEST或DEBUG檢視當叢集的時候,活動節點發生了什麼。之後,你還可以檢視是否執行個體被接收了或是被拒絕,導緻的原因在日志檔案中。注意,改變日志等級,也許會影響叢集的效果。

相關資訊

你可以從Hazelcast.com上 下載下傳Hazelcast on AWS: Best Practices for Deployment 白皮書。

端口

你可以為叢集中的節點之間指定通信端口。端口預設是 5701.

<network>

 <port>5701</port>

</network>

預設情況下,Hazelcast将會試着綁定100個端口,也就是說,如果你将端口設定為了5701,當有新節點進來的時候,Hazelcast會自動查找在5701-5801之間的節點。

如果在你的叢集中節點過多,或是過少的話,你可以改變這種端口數參數  port-count,預設就是100.

<network>

  <portport-count="20">5781</port>

</network>

根據上面的配置,Hazelcast會尋找從5781到5801的空閑端口。正常情況下,你不要去改變這個值,當需要的時候,也很友善設定。也許還有一種情況,你隻需要使用一個端口,那麼你可以取消自動增加查找使用auto-increment功能。如下所示:

<network>

  <portauto-increment="false">5701</port>

</network>

當然,這種情況下,port-count參數會被忽略掉。

外部端口

預設情況下,Hazelcast允許系統在Socket操作時,打開一個臨時端口。但是安全政策和防火牆也許會嚴格控制外部端口的通路。為了解決這個問題,你可以配置Hazelcast來配置自定義的外部端口。

<hazelcast>

  ...

  <network>

    <portauto-increment="true">5701</port>

    <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>

  ...

</hazelcast>

或者以程式設計的方式:

...

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);

...

注意:你可以定義一個端口範圍或是用逗号來隔開各個端口。

IPv6 支援

Hazelcast很好的支援Ipv6(預設是被關閉的)。詳細請看本章節最後部分。

你所要做的就是定義IPv6位址或網絡配置中的接口配置。此刻僅有的限制是,你不能在tcp - ip連接配接配置中定義IPv6位址通配符。接口的話,沒有這個限制,你可以像在IPv4中那樣定義通配符。

<hazelcast>

  ...

  <network>

    <portauto-increment="true">5701</port>

    <join>

      <multicastenabled="false">

       <multicast-group>FF02:0:0:0:0:0:0:1</multicast-group>

       <multicast-port>54327</multicast-port>

     </multicast>

      <tcp-ipenabled="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>

    <interfacesenabled="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就像inet4和inet6一樣,有兩個系統屬性來配置IPv4 和 IPv6。在一個雙協定棧中,IPv6是預設首選的。這也可以通過java.net.preferIPv4Stack=<true|false>系統屬性配置。當查詢服務名的時候,JVM首選IPv4位址而不是IPv6,并且傳回IPv4位址也是有可能的。這個可以通過java.net.preferIPv6Addresses=<true|false>來改變。

請看補充細節:​​details on IPv6 support in Java​​

注意:IPv6支援預設是關閉的。因為一些平台在使用IPv6的時候出現了一些問題。其他平台像AWS根本就不支援的。想要IPv6支援生效,隻要配置hazelcast.prefer.ipv4.stack 的屬性為false 即可。請看詳細說明:​​Advanced Configuration Properties​​.

分區分組

Hazelcast 使用一緻性哈希雜湊演算法将關鍵的主機分到分區中。這些分區都指派了節點。預設所有分區值是 271,通過hazelcast.map.partition.count值進行改變。詳細參考​​Advanced Configuration Properties​​.

在這些分區之間,需要拷貝作為備份所有。在配置中配置back count值,就可以設定多個備份了。比如,第一備份區,第二備份區...通常來說,一個節點不能擁有超過一份的備份(所有者 或 備份)。預設Hazelcast是随機分區和備份的,并且叢集節點之間的備份是公平的,就像所有的節點都一樣似得。

現在,如果某些節點共享相同的JVM或實體機器,如果你想要備份這些節點配置設定給其他節點,那該怎麼辦?如果某些節點的處理和記憶能力是不同的,并且你不希望配置設定相同數量的分區配置設定給所有節點,又該怎麼辦?

你可以将同在一個JVM中或在同一個架構中的節點機器組合為一組。或者,你可以組合這些節點來達到同樣的功能。我們稱這叫做分組。這中分組方式代替了單節點分組。備份的内容,放在其他的分組中。

當你授權分組的時候,Hazelcast給你提供了三種選擇配置分組資訊。

  • 第一個是通過IP位址自動的分組節點,節點将會以相同的網絡接口組合在一起。在同一個主機上的所有成員是一個單獨的分組。這将有助于在實體伺服器收到損壞的時候避免資料的丢失。但是當在每個實體機上有多個網絡接口的話,這種情況就無效了。

<partition-group enabled="true"group-type="HOST_AWARE" />

Config config = ...;

PartitionGroupConfig partitionGroupConfig =config.getPartitionGroupConfig();

partitionGroupConfig.setEnabled( true )

    .setGroupType(MemberGroupType.HOST_AWARE );

•   第二個是通過Hazelcast接口比對配置自定義分組。這種方式下,你可以增加多個不同的接口到你的分組中。還可以在位址接口中使用通配符。比如,使用者可以通過自定義分組建立機架感覺或者資料倉庫在分組中。

<partition-groupenabled="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 = ...;

PartitionGroupConfigpartitionGroupConfig = config.getPartitionGroupConfig();

partitionGroupConfig.setEnabled(true )

    .setGroupType( MemberGroupType.CUSTOM );

MemberGroupConfigmemberGroupConfig = new MemberGroupConfig();

memberGroupConfig.addInterface("10.10.0.*" )

.addInterface("10.10.3.*" ).addInterface("10.10.5.*" );

MemberGroupConfigmemberGroupConfig2 = new MemberGroupConfig();

memberGroupConfig2.addInterface("10.10.10.10-100" )

.addInterface("10.10.1.*").addInterface( "10.10.2.*" );

partitionGroupConfig.addMemberGroupConfig(memberGroupConfig );

partitionGroupConfig.addMemberGroupConfig(memberGroupConfig2 );

•   第三個是給每個成員它自己的分組。這意味着,每個成員是一群自己的随機分布和備份分區。這是Hazelcast叢集的預設配置并且給出了最少保護數。

<partition-groupenabled="true" group-type="PER_MEMBER" />

Config config = ...;

PartitionGroupConfig partitionGroupConfig= config.getPartitionGroupConfig();

partitionGroupConfig.setEnabled(true )

.setGroupType(MemberGroupType.PER_MEMBER );

監聽器配置

事件監聽器可以使用HazelcastAPI從相關的對象中增加或是移除。

通過API方式來配置監聽器的趨勢有所下降,可能是由于建立對象和注冊監聽的時候丢失事件的原因。為了克服這個問題,Hazelcast提供了在配置檔案中注冊監聽器的方式。監聽器的注冊可以通過聲明式和程式設計式或是Spring的配置檔案方式來配置

  • 成員監聽器

o    聲明式配置

o    <listeners>

o    <listener>com.hazelcast.examples.MembershipListener</listener>

o    </listeners>

o    程式設計式配置

o    config.addListenerConfig(

o       new ListenerConfig("com.hazelcast.examples.MembershipListener" ) );

o    Spring XMLconfiguration

o    <hz:listeners>

o    <hz:listenerclass-name="com.hazelcast.spring.DummyMembershipListener"/>

o    <hz:listener implementation="dummyMembershipListener"/>

o    </hz:listeners>

•  分布式監聽器

o  聲明式配置

o  <listeners>

o  <listener>com.hazelcast.examples.DistributedObjectListener</listener>

o  </listeners>

o  程式設計式配置

o  config.addListenerConfig(

o     new ListenerConfig("com.hazelcast.examples.DistributedObjectListener" ) );

o  Spring XML配置

o  <hz:listeners>

o  <hz:listenerclass-name="com.hazelcast.spring.DummyDistributedObjectListener"/>

o  <hz:listenerimplementation="dummyDistributedObjectListener"/>

o  </hz:listeners>

•  移動式監聽器

o  聲明配置

o  <listeners>

o  <listener>com.hazelcast.examples.MigrationListener</listener>

o  </listeners>

o  程式設計式配置

o  config.addListenerConfig(

o     new ListenerConfig("com.hazelcast.examples.MigrationListener" ) );

o  Spring XML配置

o  <hz:listeners>

o  <hz:listenerclass-name="com.hazelcast.spring.DummyMigrationListener"/>

o  <hz:listenerimplementation="dummyMigrationListener"/>

o  </hz:listeners>

•  周期性監聽器

o   聲明配置

o   <listeners>

o   <listener>com.hazelcast.examples.LifecycleListener</listener>

o   </listeners>

o   程式設計式配置

o   config.addListenerConfig(

o     new ListenerConfig( "com.hazelcast.examples.LifecycleListener") );

o   Spring XML配置

o   <hz:listeners>

o   <hz:listenerclass-name="com.hazelcast.spring.DummyLifecycleListener"/>

o   <hz:listenerimplementation="dummyLifecycleListener"/>

o   </hz:listeners>

•    Map 條目監聽器

o   聲明式配置

o   <map name="default">

o   ...

o   <entry-listeners>

o     <entry-listener include-value="true"local="false">

o         com.hazelcast.examples.EntryListener

o      </entry-listener>

o   </entry-listeners>

o   </map>

o   程式設計式配置

o   mapConfig.addEntryListenerConfig(

o      newEntryListenerConfig( "com.hazelcast.examples.EntryListener",

o                               false, false ) );

o   Spring XML配置

o   <hz:map name="default">

o   <hz:entry-listeners>

o     <hz:entry-listener include-value="true"

o          class-name="com.hazelcast.spring.DummyEntryListener"/>

o     <hz:entry-listener implementation="dummyEntryListener"local="true"/>

o   </hz:entry-listeners>

o   </hz:map>

•    多種映射的條目監聽器

o   聲明式配置

o   <multimapname="default">

o   <value-collection-type>SET</value-collection-type>

o     <entry-listeners>

o        <entry-listenerinclude-value="true" local="false">

o            com.hazelcast.examples.EntryListener

o        </entry-listener>

o     </entry-listeners>

o   </multimap>

o   程式設計式配置

o   multiMapConfig.addEntryListenerConfig(

o     new EntryListenerConfig("com.hazelcast.examples.EntryListener",

o                               false, false ) );

o   Spring XML配置

o   <hz:multimapname="default" value-collection-type="LIST">

o   <hz:entry-listeners>

o     <hz:entry-listener include-value="true"

o          class-name="com.hazelcast.spring.DummyEntryListener"/>

o     <hz:entry-listener implementation="dummyEntryListener"local="true"/>

o   </hz:entry-listeners>

o   </hz:multimap>

•       Queue條目監聽器

o   聲明式配置

o   <queuename="default">

o   ...

o   <item-listeners>

o      <item-listenerinclude-value="true">

o          com.hazelcast.examples.ItemListener

o      </item-listener>

o   </item-listeners>

o   </queue>

o   程式設計式配置

o   queueConfig.addItemListenerConfig(

o      new ItemListenerConfig("com.hazelcast.examples.ItemListener", true ) );

o   Spring XML配置

o   <hz:queuename="default" >

o   <hz:item-listeners>

o      <hz:item-listenerinclude-value="true"

o          class-name="com.hazelcast.spring.DummyItemListener"/>

o   </hz:item-listeners>

o   </hz:queue>

•  主題資訊監聽器

o  聲明式配置

o   <topic name="default">

o   <message-listeners>

o     <message-listener>

o         com.hazelcast.examples.MessageListener

o     </message-listener>

o   </message-listeners>

o   </topic>

o   程式設計式配置

o   topicConfig.addMessageListenerConfig(

o      newListenerConfig( "com.hazelcast.examples.MessageListener" ) );

o   Spring XML配置

o   <hz:topic name="default">

o   <hz:message-listeners>

o     <hz:message-listener

o         class-name="com.hazelcast.spring.DummyMessageListener"/>

o   </hz:message-listeners>

o   </hz:topic>

•  用戶端監聽器

o   聲明式配置

o   <listeners>

o   <listener>com.hazelcast.examples.ClientListener</listener>

o   </listeners>

o   程式設計式配置

o   topicConfig.addMessageListenerConfig(

o   new ListenerConfig("com.hazelcast.examples.ClientListener" ) );

o   Spring XML配置

o   <hz:listeners>

o   <hz:listenerclass-name="com.hazelcast.spring.DummyClientListener"/>

o   <hz:listenerimplementation="dummyClientListener"/>

o   </hz:listeners>

日志配置

Hazelcast提供了靈活的日志配置,并且不依賴任何日志架構,僅僅依靠JDK的日志功能。它有内置的擴充卡來完成日志架構功能,并且提供日志接口來自定義日志功能。

想使用内置的擴充卡,你需要配置hazelcast.logging.type屬性來使用下列預置的類型。

•   jdk: JDK logging (default)

•   log4j: Log4j

•   slf4j: Slf4j

•   none: disable logging

你可以通過聲明式,程式設計式或JVM系統屬性來配置hazelcast.logging.type.

注意: 如果你選擇log4j或是slf4j的話,一些依賴也要加載進來(classpath下)。

•   聲明式配置

 <hazelcastxsi:schemaLocation="http://www.hazelcast.com/schema/config

​​   http://www.hazelcast.com/schema/config/hazelcast-config-3.0.xsd"​​

   xmlns="http://www.hazelcast.com/schema/config"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  ....

  <properties>

    <propertyname="hazelcast.logging.type">jdk</property>

    ....

  </properties>

</hazelcast>

•   程式設計式配置

Configconfig = new Config() ;

config.setProperty("hazelcast.logging.type", "log4j" );

•   系統屬性

o   使用JVM參數:java -Dhazelcast.logging.type=slf4j

o   使用系統類: System.setProperty("hazelcast.logging.type", "none" );

如果你提供了一個不是靜态工廠的日志機制,你可以使用自定義日志來實作它。要使用這個,你需要實作com.hazelcast.logging.LoggerFactory 和com.hazelcast.logging.ILogger 接口。并且設定系統屬性hazelcast.logging.class作為你自定義的日志工廠類名。

-Dhazelcast.logging.class=foo.bar.MyLoggingFactory

你還可以通過注冊日志監聽器(LogListeners)到日志服務(LoggingService)在Hazelcast運作時來監聽日志事件的過程。

LogListenerlistener = new LogListener() {

  public void log( LogEvent logEvent ) {

    // do something

  }

}

HazelcastInstanceinstance = Hazelcast.newHazelcastInstance();

LoggingServiceloggingService = instance.getLoggingService();

loggingService.addLogListener(Level.INFO, listener );

通過這個日志服務(LoggingService),你可以得到目前使用的日志接口,也可以記錄你自己的資訊。

注意 :如果你不是使用的指令行來配置你的日志,你應該注意Hazelcast類,因為預設情況下有可能在最新配置的日志機制之前使用jdk日志。當日志機制被標明的話,這就不會變了。

進階屬性配置

Hazelcasth還提供了一些進階的屬性配置。這些屬性可以通過聲明式和程式設計式或JVM系統屬性方式來設定key-value鍵值對進行配置。

聲明配置

<hazelcastxsi:schemaLocation="http://www.hazelcast.com/schema/config

​​   http://www.hazelcast.com/schema/config/hazelcast-config-3.0.xsd"​​

   xmlns="http://www.hazelcast.com/schema/config"

   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  ....

 <properties>

    <propertyname="hazelcast.property.foo">value</property>

    ....

 </properties>

</hazelcast>

聲明式配置

Config config = new Config() ;

config.setProperty( "hazelcast.property.foo","value" );

系統屬性

  1. 使用JVM參數: java -Dhazelcast.property.foo=value
  2. 使用系統類: System.setProperty( "hazelcast.property.foo", "value" );

下面的兩張表列出了進階屬性的配置以及說明。

屬性名 預設值 類型說明
hazelcast.health.monitoring.level SILENT string Health monitoring log level. When SILENT, logs are printed only when values exceed some predefined threshold. When NOISY, logs are always printed periodically. Set OFF to turn off completely.
hazelcast.health.monitoring.delay.seconds 30 int Health monitoring logging interval in seconds.
hazelcast.version.check.enabled true bool Enable Hazelcast new version check on startup.
hazelcast.prefer.ipv4.stack true bool Prefer Ipv4 network interface when picking a local address.
hazelcast.io.thread.count 3 int Number of input and output threads.
hazelcast.operation.thread.count -1 int Number of partition based operation handler threads. -1 means CPU core count x 2.
hazelcast.operation.generic.thread.count -1 int Number of generic operation handler threads. -1 means CPU core count x 2.
hazelcast.event.thread.count 5 int Number of event handler threads.
hazelcast.event.queue.capacity 1000000 int Capacity of internal event queue.
hazelcast.event.queue.timeout.millis 250 int Timeout to enqueue events to event queue.
hazelcast.connect.all.wait.seconds 120 int Timeout to connect all other cluster members when a member is joining to a cluster.
hazelcast.memcache.enabled true bool Enable ​​Memcache​​ client request listener service.
hazelcast.rest.enabled true bool Enable ​​REST​​ client request listener service.
hazelcast.map.load.chunk.size 1000 int Chunk size for ​​MapLoader​​ 's map initialization process (MapLoder.loadAllKeys()).
hazelcast.merge.first.run.delay.seconds 300 int Initial run delay of ​​split brain/merge process​​ in seconds.
hazelcast.merge.next.run.delay.seconds 120 int Run interval of ​​split brain/merge process​​ in seconds.
hazelcast.operation.call.timeout.millis 60000 int Timeout to wait for a response when a remote call is sent, in milliseconds.
hazelcast.socket.bind.any true bool Bind both server-socket and client-sockets to any local interface.
hazelcast.socket.server.bind.any true bool Bind server-socket to any local interface. If not set, hazelcast.socket.bind.any will be used as default.
hazelcast.socket.client.bind.any true bool Bind client-sockets to any local interface. If not set, hazelcast.socket.bind.any will be used as default.
hazelcast.socket.client.bind true bool Bind client socket to an interface when connecting to a remote server socket. When set to false, client socket is not bound to any interface.
hazelcast.socket.receive.buffer.size 32 int Socket receive buffer (SO_RCVBUF) size in KB.
hazelcast.socket.send.buffer.size 32 int Socket send buffer (SO_SNDBUF) size in KB.
hazelcast.socket.linger.seconds int Set socket SO_LINGER option.
hazelcast.socket.keep.alive true bool Socket set keep alive (SO_KEEPALIVE).
hazelcast.socket.no.delay true bool Socket set TCP no delay.
hazelcast.shutdownhook.enabled true bool Enable Hazelcast shutdownhook thread.
hazelcast.wait.seconds.before.join 5 int Wait time before join operation.
hazelcast.max.join.seconds 300 int Join timeout, maximum time to try to join before giving.
hazelcast.max.join.merge.target.seconds 20 int Split-brain merge timeout for a specific target.
hazelcast.max.wait.seconds.before.join 20 int Maximum wait time before join operation.
hazelcast.heartbeat.interval.seconds 1 int Heartbeat send interval in seconds.
hazelcast.max.no.heartbeat.seconds 500 int Max timeout of heartbeat in seconds for a node to assume it is dead.
hazelcast.max.no.master.confirmation.seconds 450 int Max timeout of master confirmation from other nodes.
hazelcast.master.confirmation.interval.seconds 30 int Interval at which nodes send master confirmation.
hazelcast.member.list.publish.interval.seconds 600 int Interval at which master node publishes a member list.
hazelcast.icmp.enabled false bool Enable ICMP ping.
hazelcast.icmp.timeout 1000 int ICMP timeout in ms.
hazelcast.icmp.ttl int ICMP TTL (maximum numbers of hops to try).
hazelcast.initial.min.cluster.size int Initial expected cluster size to wait before node to start completely.
hazelcast.initial.wait.seconds int Initial time in seconds to wait before node to start completely.
hazelcast.map.replica.wait.seconds.for.scheduled.tasks 10 int Scheduler delay for map tasks those will be executed on backup members.
hazelcast.partition.count 271 int Total partition count.
hazelcast.logging.type jdk enum Name of ​​logging​​ framework type to send logging events.
hazelcast.jmx false bool Enable ​​JMX​​ agent.
hazelcast.jmx.detailed false bool Enable detailed views on ​​JMX​​.
hazelcast.mc.max.visible.instance.count 100 int Management Center maximum visible instance count.
hazelcast.mc.url.change.enabled true bool Management Center changing server url is enabled.
hazelcast.connection.monitor.interval 100 int Minimum interval to consider a connection error as critical in milliseconds.
hazelcast.connection.monitor.max.faults 3 int Maximum IO error count before disconnecting from a node.
hazelcast.partition.migration.interval int Interval to run partition migration tasks in seconds.
hazelcast.partition.migration.timeout 300 int Timeout for partition migration tasks in seconds.
hazelcast.partition.migration.zip.enabled true bool Enable compression during partition migration.
hazelcast.partition.table.send.interval 15 int Interval for publishing partition table periodically to all cluster members.
hazelcast.partition.backup.sync.interval 30 int Interval for syncing backup replicas.
hazelcast.partitioning.strategy.class null string Class name implementing com.hazelcast.core.PartitioningStrategy, which defines key to partition mapping.
hazelcast.migration.min.delay.on.member.removed.seconds 5 int Minimum delay (in seconds) between detection of a member that has left and start of the rebalancing process.
hazelcast.graceful.shutdown.max.wait 600 int Maximum wait seconds during graceful shutdown.
hazelcast.system.log.enabled true bool Enable system logs.
hazelcast.elastic.memory.enabled false bool Enable ​​Hazelcast Elastic Memory​​ off-heap storage.
hazelcast.elastic.memory.total.size 128 int ​​Hazelcast Elastic Memory​​ storage total size in MB.
hazelcast.elastic.memory.chunk.size 1 int ​​Hazelcast Elastic Memory​​ storage chunk size in KB.
hazelcast.elastic.memory.shared.storage false bool Enable ​​Hazelcast Elastic Memory​​ shared storage.
hazelcast.elastic.memory.unsafe.enabled false bool Enable usage of sun.misc.Unsafe when allocating, reading and modifying off-heap storage.
hazelcast.enterprise.license.key null string ​​Hazelcast Enterprise​​ license key.
hazelcast.client.heartbeat.timeout 300000 string Timeout for the heartbeat messages sent by the client to members. If there is no any message passing between client and member within the given time via this property in milliseconds the connection will be closed.
hazelcast.client.heartbeat.interval 10000 string The frequency of heartbeat messages sent by the clients to members.
hazelcast.client.max.failed.heartbeat.count 3 string When the count of failed heartbeats sent to members reaches this value, the cluster is deemed as dead by the client.
hazelcast.client.request.retry.count 20 string The retry count of the connection requests by the client to the members.
hazelcast.client.request.retry.wait.time 250 string The frequency of the connection retries.
hazelcast.client.event.thread.count 5 string Thread count for handling incoming event packets.
hazelcast.client.event.queue.capacity 1000000 string Default value of the capacity of executor that handles incoming event packets.

網絡分區

想象你有10台機器的叢集,由于某些原因,網絡被分為兩份,共4台機器,其他6台機器看不見了。結果,你隻有兩個叢集。4台機器的和6台機器的叢集。這種情況下,每個叢集的機器都在想,其他的節點都死了甚至是不存在的。這種情況就叫做網絡分區(a.k.a. Split-Brain Syndrome)。

然而,就像包括主機和備份機在内的一樣,并不是所有的271個分區都在小叢集中。是以,從每個小叢集的角度來看,就像分區不存在一樣,資料已經丢失了(它們在其他的分區裡)。

如果使用Map存儲的話,這些丢失的資料會從資料庫重新加載,使得每個小叢集保持完整。每個小叢集的機器會重新建立丢失的主要分區,然後存儲起來。也包括在其他節點的備份資料。

當主分區存在并且沒有備份的話,一個關于備份版本的問題就會出現了,緊接着備份分區就會被建立。當備份分區存在而主分區不存在的話,這個備份分區就會更新為主分區,然後重新建立個合适的版本的備份分區。這時候,兩個叢集都已經修複好了,并且有271個分區和備份分區。然後在彼此沒有知曉的情況下繼續處理事務。想象它們都有足夠的剩餘記憶體,生産力較低。

如果使用Map存儲,并且網絡通路資料庫可用的話,而現在叢集中的一個在進行寫/更新操作,這就産生了一個潛在的問題-如果在兩個叢集都做修改的話,這就重寫了同一個緩存記錄。這種重寫情況會導緻潛在的資料丢失。是以,資料庫的設計應該在讀的時候考慮到插入和結合問題,或者是版本問題,而不是更新資料。

如果網絡通路資料庫不可用,那麼基于配置的和編碼的事務、緩存中的條目更新都會被拒絕(保持一緻性和同步性)。在緩存中的資料,更新操作的資料将會被認為是髒資料,當更新可用的時候,重寫到資料庫。叢集成員可以在管理中心的web控制台看到髒條目資料(請參考 ​​Map Monitoring​​)。

當網絡不可用的時候,就沒有辦法避免以程式設計式的方式情況下你的叢集會以兩個獨立的叢集運作。但是,我們應該可以回答下面的問題:”當網絡修複好并且連接配接恢複了,程式又會怎樣呢?這兩個叢集會再一次融合為一個嗎?如果是這樣,那資料又是怎樣解決的呢?你将Map中相同的key的值删除?”

當網絡恢複了,你應該保證所有271個分區在每個叢集中都是活着的,并且進行合并。一旦所有的主分區合并了,所有的備份分區将會重新寫入,這時候它們的版本也就對了。也許你想通過MapMergePolicy接口寫個合并政策,從資料庫中将條目重建,而不是從緩存中。

從EntryView接口的觀點來看,隻有中繼資料(包括對象大小,點選次數,最後一次更新/存儲資料,從0開始的随條目更新而增加的版本号)才可以起到合并的功能。你還可以建立你自己的版本控制計劃,或者捕捉重建條目的時間序列。

下面例子,通過一步一步的告訴你,Hazelcast是怎麼實作合并的:

1.  叢集中時間最長的機器檢查在網絡中是否有另台帶有相同組名或組密碼的機器。

2.  如果發現了這樣的機器,那這個探測主機将會判斷它和哪個叢集進行合并。

3.  進行合并的叢集中每台機器将會做下面的事情:

o   暫停

o   取出本地所有map條目

o   關閉所有網絡連接配接

o   加入新的叢集

o   給本地所有map條目發送合并資訊請求

o   重新啟動

是以合并叢集中的每個機器,事實上重新加入了新的叢集,然後發送合并資訊請求給每個map條目。

兩點重要提示:

  • 較小的叢集将會合并成更大的叢集。如果它們有相同的叢集量,那麼就通過哈新雜湊演算法來決定負責合并的叢集。

· 每個叢集在同一個map中具有相同的key值的也許也會有不同的版本。目的叢集會基于合并政策(MergePolicy)為那個map決定怎麼合并條目。因為有内置的合并政策就像PassThroughMergePolicy,PutIfAbsentMapMergePolicy,HigherHitsMapMergePolicy 和 LatestUpdateMapMergePolicy.但是,你也可以設計你自己的合并政策通過實作com.hazelcast.map.merge.MapMergePolicy.你應該設定你的實作的完整類名到merge-policy配置。

public interface MergePolicy {

  /**

  *合并條目之後傳回具有相同key值的條目的value值

  *你應該考慮到條目是null的情況

  * @param mapName       name of the map

  * @param mergingEntry  條目合并到目的叢集

  * @param existingEntry 在叢集中存在的叢集

  * @return final value of the entry. 如果傳回null,條目會被删除

  */

  Object merge( String mapName, EntryViewmergingEntry, EntryView existingEntry );

}

在這裡告訴你 合并政策是怎麼被每個map識别的

<hazelcast>

  ...

  <map name="default">

    <backup-count>1</backup-count>

   <eviction-policy>NONE</eviction-policy>

    <max-size>0</max-size>

   <eviction-percentage>25</eviction-percentage>

    <!--

      當從網絡分區恢複過來的時候,

      基于在這裡配置的政策,小叢集的map條目将會合并到大叢集中。當一個條目合并到叢集中時,也許會出現相同key值的條目。

      具有相同的key值的條目也許value值不同.

     出現沖突了,預設政策是hz.ADD_NEW_ENTRY

    有内置的政策 如:

     com.hazelcast.map.merge.PassThroughMergePolicy; entry will be added if

         這個key沒有已存在的條目.

     com.hazelcast.map.merge.PutIfAbsentMapMergePolicy ; entry will be

          如果在叢集中沒有這個條目,就增加這個條目.

     com.hazelcast.map.merge.HigherHitsMapMergePolicy ;

                點選最多的條目有效.

     com.hazelcast.map.merge.LatestUpdateMapMergePolicy ; entry with the

                最近更新的有效.

    -->

   <merge-policy>MY_MERGE_POLICY_CLASS</merge-policy>

  </map>

  ...