在前两篇文章中,咱们把Ignite集群当作一个黑盒子,用二进制包自带的脚本启动Ignite节点后,咱们用不一样的客户端链接上Ignite进行操做,展现了Ignite做为一个分布式内存缓存,内存数据库的基本功能。从这篇文章开始,让咱们打开这个黑盒子,逐步的深刻到Ignite内部了解更多的特性。java
Ignite集群没有采用master/slave架构设计。在集群里,每一个节点都是平等的,而且能够互相通信,这样的架构保证Ignite集群能够添加,移除节点,对集群的内存容量进行不间断的扩容/减容。也使得Ignite集群有很强的容错能力,能够快速的检测到一个或多个失效节点并恢复。 但在前面的文章中,咱们提到过在Ignite集群里有client和server节点,还有thin client。刚开始我也不理解为何要引入这么多不一样角色的节点,但Ignite做为一个数据网格,计算网格以及服务网格,不一样角色的节点在不一样的场景下都有其做用。 这篇文章里,咱们先比较一下client和server节点有什么不一样;而后介绍下不一样场景下,应该采用什么样的节点来搭建集群;最后咱们看看如何在你本身的Java程序里启动一个server或者client节点。node
下图就展现了不一样节点能提供的能力,以及它们互相之间的链接关系:
git
Thin client是跑在Ignite集群外的,它只能链接集群中某些节点,全部的操做和数据传输都须要经过这些节点。Client和server节点组成了Ignite集群的拓扑,它们之间是能够互相发现以及互相通信的,能够充分利用不一样节点间的带宽进行数据传输。除了不能存储数据,client和server节点基本同样。那为何Ignite还须要引入client和server不一样的节点呢?Ignite同时提供了数据网格,计算网格和服务网格服务,经过client和server节点,能够很方便的实现存储和计算分离的架构。设想一下,若是全部服务都部署在同一组节点来提供,若是计算任务须要消耗大量系统资源,或者须要升级计算/服务网格,势必要影响要影响数据服务。反之,对数据网格的减容,扩容也会影响计算和服务网格。所以,咱们能够将计算网格和服务网格部署在client节点上,而数据网格部署在server节点上,这样保证了计算和数据服务不会互相竞争资源,并且能够独立的对计算和数据网格进行减容/扩容。固然,这么作的一个缺点client节点都须要经过server节点获取数据,对一些追求高性能的计算任务来讲,网络延时和带宽就有可能成为瓶颈。对于这种场景,咱们能够将client节点和server节点部署在同一台主机上,减小一部分的网络传输。spring
前两篇文章,咱们经过二级制安装包中的脚本启动几个server节点,组成Ignite集群,如今让咱们来看看怎么在本身的代码里启动一个server节点或者是client节点。数据库
咱们先来看看启动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节点的代码:架构
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 mode为true(对应代码为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时有两点须要注意的:
$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提供了哪些不同的能力。