zoukankan      html  css  js  c++  java
  • 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提供了哪些不一样的能力。

  • 相关阅读:
    Linux Core Dump
    ODP.NET Managed正式推出
    获取EditText的光标位置
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
  • 原文地址:https://www.cnblogs.com/peppapigdaddy/p/9951694.html
Copyright © 2011-2022 走看看