Apache Ignite 學習筆記(三): Ignite Server和Client節點介紹


在前兩篇文章中,我們把Ignite集群當做一個黑盒子,用二進制包自帶的腳本啟動Ignite節點后,我們用不同的客戶端連接上Ignite進行操作,展示了Ignite作為一個分布式內存緩存,內存數據庫的基本功能。從這篇文章開始,讓我們打開這個黑盒子,逐步的深入到Ignite內部了解更多的特性。

Ignite集群沒有采用master/slave架構設計。在集群里,每個節點都是平等的,並且可以互相通訊,這樣的架構保證Ignite集群可以添加,移除節點,對集群的內存容量進行不間斷的擴容/減容。也使得Ignite集群有很強的容錯能力,可以快速的檢測到一個或多個失效節點並恢復。 但在前面的文章中,我們提到過在Ignite集群里有client和server節點,還有thin client。剛開始我也不理解為什么要引入這么多不同角色的節點,但Ignite作為一個數據網格,計算網格以及服務網格,不同角色的節點在不同的場景下都有其作用。 這篇文章里,我們先比較一下client和server節點有什么不同;然后介紹下不同場景下,應該采用什么樣的節點來搭建集群;最后我們看看如何在你自己的Java程序里啟動一個server或者client節點。

Client和Server節點比較


  • Serve節點:存儲數據,參與緩存,執行計算和流處理,部署服務網格。換句話說,server節點是功能最全的節點。默認情況下,啟動一個Ignite節點都是以server節點的角色啟動。
  • Client節點:不存儲數據,但是可以通過Ignite APIs連接到server節點上,進行緩存的讀寫,參與計算任務,流處理,事務和服務網格。和server節點不同,如果需要把一個節點作為client節點,需要修改默認的配置。Client節點和server節點同時組成了Ignite集群,所以它們可以相互發現,相互連接。
  • Thin client:上一篇文章我們做過介紹,thin client不會加入Ignite的集群拓撲,它也不存儲數據,也不參與執行計算和流處理。和Ignite原生的client節點不同,它並不感知集群的拓撲結構變化(增加/刪除節點后,thin client並不知道),而且一次只能和Ignite集群中的一個節點連接通訊,當該節點失效后,它會從事先配置好節點列表中挑選一個新的節點,重新連接。

下圖就展示了不同節點能提供的能力,以及它們互相之間的連接關系:

Thin client是跑在Ignite集群外的,它只能連接集群中某些節點,所有的操作和數據傳輸都需要通過這些節點。Client和server節點組成了Ignite集群的拓撲,它們之間是可以互相發現以及互相通訊的,可以充分利用不同節點間的帶寬進行數據傳輸。除了不能存儲數據,client和server節點基本一樣。那為什么Ignite還需要引入client和server不同的節點呢?Ignite同時提供了數據網格,計算網格和服務網格服務,通過client和server節點,可以很方便的實現存儲和計算分離的架構。設想一下,如果所有服務都部署在同一組節點來提供,如果計算任務需要消耗大量系統資源,或者需要升級計算/服務網格,勢必要影響要影響數據服務。反之,對數據網格的減容,擴容也會影響計算和服務網格。因此,我們可以將計算網格和服務網格部署在client節點上,而數據網格部署在server節點上,這樣保證了計算和數據服務不會互相競爭資源,而且可以獨立的對計算和數據網格進行減容/擴容。當然,這么做的一個缺點client節點都需要通過server節點獲取數據,對一些追求高性能的計算任務來說,網絡延時和帶寬就有可能成為瓶頸。對於這種場景,我們可以將client節點和server節點部署在同一台主機上,減少一部分的網絡傳輸。

在應用程序中啟動Ignite server/client節點


前兩篇文章,我們通過二級制安裝包中的腳本啟動幾個server節點,組成Ignite集群,現在讓我們來看看怎么在自己的代碼里啟動一個server節點或者是client節點。

啟動server節點代碼

我們先來看看啟動server節點的代碼:

public class IgniteServerNodeExample {
    public static void main(String[] args) {
        Ignite ignite;

        if(args.length == 1 && !args[0].isEmpty())
        {
            //如果啟動時指定了xml配置文件,則用指定的配置文件
            System.out.println("Use " + args[0] + " to start.");
            ignite = Ignition.start(args[0]);
        }
        else
        {
            //如果啟動時沒指定配置文件,則生成一個配置文件
            System.out.println("Create an IgniteConfiguration to start.");
            TcpDiscoverySpi spi = new TcpDiscoverySpi();
            TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
            ipFinder.setMulticastGroup("224.0.0.251");
            spi.setIpFinder(ipFinder);
            IgniteConfiguration cfg = new IgniteConfiguration();
            cfg.setDiscoverySpi(spi);
            ignite = Ignition.start(cfg);
        }

        // 創建一個TEST緩存並寫入一些數據, key是城市的名字,value是省的名字
        IgniteCache<String, String> cityProvinceCache = ignite.getOrCreateCache("TEST");
        cityProvinceCache.put("Edmonton", "Alberta");
        cityProvinceCache.put("Markham", "Ontario");
        cityProvinceCache.put("Montreal", "Quebec");
    }
}

在啟動Ignite節點時,我們需要傳入節點的配置信息。代碼里我們用了兩種方式:1)如果啟動時傳入一個xml配置文件路徑,我們就用該配置文件啟動節點;2)如果沒指定配置文件,我們就在代碼里生成一個IgniteConfiguration對象,並配置Ignite節點用multicast的方式發現局域網內的其他節點並組成集群(除了multicast,Ignite還支持指定靜態ip地址或者用zookeeper進行節點探測發現,具體的配置方式會有一篇文章專門來介紹)。xml配置文件中的每個配置項都可以通過IgniteConfiguration對象用代碼進行配置,所以二者是等效的。和代碼里IgniteConfiguration對象等效的xml配置如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                        <property name="multicastGroup" value="224.0.0.251"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>
</beans>

在用Ignite.start()啟動節點后,我們在server節點上創建了一個名字叫“TEST”的緩存,緩存的key是城市的名字(String),value是城市所在省份的名字(String)。 然后往緩存里插入三條數據。

啟動Client節點的代碼

下面是啟動client節點的代碼:

public class IgniteClientNodeExample {
    public static void main(String[] args) {
        Ignite ignite;
        if(args.length == 1 && !args[0].isEmpty())
        {
            //如果啟動時指定了配置文件,則用指定的配置文件
            System.out.println("Use " + args[0] + " to start.");
            ignite = Ignition.start(args[0]);
        }
        else
        {
            //如果啟動時沒指定配置文件,則生成一個配置文件
            System.out.println("Create an IgniteConfiguration to start.");
            TcpDiscoverySpi spi = new TcpDiscoverySpi();
            TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
            ipFinder.setMulticastGroup("224.0.0.251");
            spi.setIpFinder(ipFinder);
            IgniteConfiguration cfg = new IgniteConfiguration();
            cfg.setDiscoverySpi(spi);
            //顯式配置client模式啟動該節點.
            cfg.setClientMode(true);
            ignite = Ignition.start(cfg);
        }
        //從ignite中讀取緩存,並讀取數據
        IgniteCache<String, String> cityProvinceCache = ignite.getOrCreateCache("TEST");
        System.out.println("Montreal is in " + cityProvinceCache.get("Montreal"));
        System.out.println("Edmonton is in " + cityProvinceCache.get("Edmonton"));
        System.out.println("Markham is in " + cityProvinceCache.get("Markham"));
        System.out.println("Toronto is in " + cityProvinceCache.get("Toronto"));
    }
}

和server節點的代碼類似,啟動client節點時我們同樣可以傳入一個xml配置文件,或者在代碼中生成一個IgniteConfiguration對象,然后進行配置。和server節點不同的是,如果需要啟動一個client節點,需要顯式的配置client modetrue(對應代碼為cfg.setClientMode(true))。和代碼里等效的xml配置文件如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="discoverySpi">
            <bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
                <property name="ipFinder">
                    <bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
                        <property name="multicastGroup" value="224.0.0.251"/>
                    </bean>
                </property>
            </bean>
        </property>
        <property name="clientMode" value="true"/>
    </bean>
</beans>

在用Ignite.start()啟動節點后,client節點從Ignite集群中獲取名為“TEST”的緩存,然后試着從緩存里讀取不同城市對應的省份名字。

Server和client節點的啟動

啟動server和client時有兩點需要注意的:

  • Client節點啟動時必須有可用的server節點在Ignite集群中,所以啟動的順序是先server節點后client節點。當然,在某些情況下,如果需要client節點不管是否有可用的server節點都必須要成功啟動,則需要在client節點上配置強制服務端發現模式
  • 如果通過傳入xml配置文件的方式啟動節點,則需要在CLASS_PATH中包含ignite-spring模塊的jar文件(如果你通過二級制包安裝了Ignite,ignite-spring模塊就在IGNITE_HOME/lib/ignite-spring目錄下)。在maven成功編譯代碼后,我用下面的命令啟動server節點:
$cd ignite-client-server-node-example/target
$java -cp ./ignite-client-server-node-example-1.0-SNAPSHOT.jar:$IGNITE_HOME/libs/*:$IGNITE_HOME/libs/ignite-spring/* IgniteServerNodeExample ../src/main/resources/ignite-server-config.xml

同理,用下面的命令啟動client節點:

$cd ignite-client-server-node-example/target
$java -cp ./ignite-client-server-node-example-1.0-SNAPSHOT.jar:$IGNITE_HOME/libs/*:$IGNITE_HOME/libs/ignite-spring/* IgniteClientNodeExample ../src/main/resources/ignite-client-config.xml

在啟動client節點前后,我們可以稍微留意下server節點關於Ignite集群拓撲結構的相關日志,在啟動client節點前:

[00:55:52] Ignite node started OK (id=42996817)
[00:55:52] Topology snapshot [ver=1, servers=1, clients=0, CPUs=2, offheap=1.6GB, heap=1.7GB]
[00:55:52]   ^-- Node [id=42996817-925A-4FF5-8B5D-4B80D4774905, clusterState=ACTIVE]
[00:55:52] Data Regions Configured:
[00:55:52]   ^-- default [initSize=256.0 MiB, maxSize=1.6 GiB, persistenceEnabled=false]

集群的拓撲版本為1,集群內有1個server節點,0個client節點。 在啟動client節點后:

[00:59:06] Topology snapshot [ver=2, servers=1, clients=1, CPUs=2, offheap=1.6GB, heap=3.5GB]
[00:59:06]   ^-- Node [id=42996817-925A-4FF5-8B5D-4B80D4774905, clusterState=ACTIVE]
[00:59:06] Data Regions Configured:
[00:59:06]   ^-- default [initSize=256.0 MiB, maxSize=1.6 GiB, persistenceEnabled=false]

集群的拓撲版本為2,集群內有1個server節點,1個client節點,這代表我們成功的啟動了一個server節點和client節點。

在client節點啟動后,它會試着讀取server節點寫入“TEST”緩存的數據,所以我們應該可以在client節點日志中看到以下的輸出:

Montreal is in Quebec
Edmonton is in Alberta
Markham is in Ontario
Toronto is in null

除了Toronto以外,其他的城市都能讀到對應的省份信息。這也驗證了client節點讀取的就是server節點寫入的那份緩存。

總結


我們介紹了Ignite集群節點中兩個不同的角色--server和client,並比較了它們之間的不同。我們還展示了如何在java程序中啟動server和client節點。 完整的代碼和maven工程可以在這里找到。 Server和client對應的xml配置文件在src/main/resources目錄下。

Ignite集群的配置,節點發現以及集群管理,感興趣的同學可以參考下官方文檔。在后面會有專門的文章介紹細節和例子。從下一篇文章開始,讓我們先聚焦在Ignite的數據網格服務上,看看和其他key/value緩存系統相比,Ignite提供了哪些不一樣的能力。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM