Apache Ignite 学习笔记(三): Ignite Server和Client节点介绍

在前两篇文章中,咱们把Ignite集群当作一个黑盒子,用二进制包自带的脚本启动Ignite节点后,咱们用不一样的客户端链接上Ignite进行操做,展现了Ignite做为一个分布式内存缓存,内存数据库的基本功能。从这篇文章开始,让咱们打开这个黑盒子,逐步的深刻到Ignite内部了解更多的特性。java

Ignite集群没有采用master/slave架构设计。在集群里,每一个节点都是平等的,而且能够互相通信,这样的架构保证Ignite集群能够添加,移除节点,对集群的内存容量进行不间断的扩容/减容。也使得Ignite集群有很强的容错能力,能够快速的检测到一个或多个失效节点并恢复。 但在前面的文章中,咱们提到过在Ignite集群里有client和server节点,还有thin client。刚开始我也不理解为何要引入这么多不一样角色的节点,但Ignite做为一个数据网格,计算网格以及服务网格,不一样角色的节点在不一样的场景下都有其做用。 这篇文章里,咱们先比较一下client和server节点有什么不一样;而后介绍下不一样场景下,应该采用什么样的节点来搭建集群;最后咱们看看如何在你本身的Java程序里启动一个server或者client节点。node

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集群中的一个节点链接通信,当该节点失效后,它会从事先配置好节点列表中挑选一个新的节点,从新链接。

下图就展现了不一样节点能提供的能力,以及它们互相之间的链接关系:
git

Thin client是跑在Ignite集群外的,它只能链接集群中某些节点,全部的操做和数据传输都须要经过这些节点。Client和server节点组成了Ignite集群的拓扑,它们之间是能够互相发现以及互相通信的,能够充分利用不一样节点间的带宽进行数据传输。除了不能存储数据,client和server节点基本同样。那为何Ignite还须要引入client和server不一样的节点呢?Ignite同时提供了数据网格,计算网格和服务网格服务,经过client和server节点,能够很方便的实现存储和计算分离的架构。设想一下,若是全部服务都部署在同一组节点来提供,若是计算任务须要消耗大量系统资源,或者须要升级计算/服务网格,势必要影响要影响数据服务。反之,对数据网格的减容,扩容也会影响计算和服务网格。所以,咱们能够将计算网格和服务网格部署在client节点上,而数据网格部署在server节点上,这样保证了计算和数据服务不会互相竞争资源,并且能够独立的对计算和数据网格进行减容/扩容。固然,这么作的一个缺点client节点都须要经过server节点获取数据,对一些追求高性能的计算任务来讲,网络延时和带宽就有可能成为瓶颈。对于这种场景,咱们能够将client节点和server节点部署在同一台主机上,减小一部分的网络传输。spring

在应用程序中启动Ignite server/client节点


前两篇文章,咱们经过二级制安装包中的脚本启动几个server节点,组成Ignite集群,如今让咱们来看看怎么在本身的代码里启动一个server节点或者是client节点。数据库

启动server节点代码

咱们先来看看启动server节点的代码:apache

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配置文件以下:maven

<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提供了哪些不同的能力。

相关文章
相关标签/搜索