@liyuj
2016-08-28T13:17:34.000000Z
字数 41818
阅读 9072
Apache-Ignite-1.7.0-中文开发手册
Ignite具有非常先进的集群能力,包括逻辑集群组和自动发现。
Ignite节点之间会自动发现对方,这有助于必要时扩展集群,而不需要重启整个集群。开发者可以利用Ignite的混合云支持,允许公有云(比如AWS)和私有云之间建立连接,向他们提供两者的好处。
集群的功能是通过IgniteCluster
接口提供的,可以像下面这样从Ignite
中获得一个IgniteCluster
的实例:
Ignite ignite = Ignition.ignite();
IgniteCluster cluster = ignite.cluster();
通过IgniteCluster
接口可以:
集群组
;ClusterNode
接口具有非常简洁的API,他只处理集群中的几点,把他视为网络中的逻辑端点,他有一个唯一的ID,节点的元数据信息,静态属性集以及一些其他的参数。
所有的集群节点在启动时都会自动地注册环境和系统的参数,把他们作为节点的属性,也可以通过配置添加自定义的节点属性。
<bean class="org.apache.ignite.IgniteConfiguration">
...
<property name="userAttributes">
<map>
<entry key="ROLE" value="worker"/>
</map>
</property>
...
</bean>
下面的代码显示了如何获得设置了“worker”属性的节点:
ClusterGroup workers = ignite.cluster().forAttribute("ROLE", "worker");
Collection<ClusterNode> nodes = workers.nodes();
所有的节点属性都是通过
ClusterNode.attribute("propertyName")
方法获得的。
Ignite自动收集所有集群节点的指标数据,指标数据是在后台收集的并且被集群节点之间的每一次心跳消息交换所更新。
节点的指标数据是通过ClusterMetrics
接口体现的,他包括至少50种指标(注意,同样的指标也可以用于集群组)。
下面的例子显示了获取一些元数据信息,包括本地节点的平均CPU负载,已用堆大小:
// Local Ignite node.
ClusterNode localNode = cluster.localNode();
// Node metrics.
ClusterMetrics metrics = localNode.metrics();
// Get some metric values.
double cpuLoad = metrics.getCurrentCpuLoad();
long usedHeap = metrics.getHeapMemoryUsed();
int numberOfCores = metrics.getTotalCpus();
int activeJobs = metrics.getCurrentActiveJobs();
本地集群节点是ClusterNode
的一个实例,表示当前的Ignite节点。
下面的例子显示如何获得本地节点:
ClusterNode localNode = ignite.cluster().localNode();
ClusterGroup
表示集群内节点的一个逻辑组。
从设计上讲,所有集群节点都是平等的,所以没有必要以一个特定的顺序启动任何节点,或者给他们赋予特定的规则。然而,Ignite可以因为一些应用的特殊需求而创建集群节点的逻辑组,比如,可能希望只在远程节点上部署一个服务,或者给部分worker节点赋予一个叫做‘worker’的规则来做作业的执行。
IgniteCluster
接口也是一个集群组,只不过包括集群内的所有节点。
可以限制作业执行、服务部署、消息、事件以及其他任务只在部分集群组内执行,比如,下面这个例子只把作业广播到远程节点(除了本地节点):
Java8:
final Ignite ignite = Ignition.ignite();
IgniteCluster cluster = ignite.cluster();
// Get compute instance which will only execute
// over remote nodes, i.e. not this node.
IgniteCompute compute = ignite.compute(cluster.forRemotes());
// Broadcast to all remote nodes and print the ID of the node
// on which this closure is executing.
compute.broadcast(() -> System.out.println("Hello Node: " + ignite.cluster().localNode().id());
Java7:
final Ignite ignite = Ignition.ignite();
IgniteCluster cluster = ignite.cluster();
// Get compute instance which will only execute
// over remote nodes, i.e. not this node.
IgniteCompute compute = ignite.compute(cluster.forRemotes());
// Broadcast closure only to remote nodes.
compute.broadcast(new IgniteRunnable() {
@Override public void run() {
// Print ID of the node on which this runnable is executing.
System.out.println(">>> Hello Node: " + ignite.cluster().localNode().id());
}
});
可以基于任何谓词创建集群组,为了方便Ignite也提供了一些预定义的集群组。
下面的例子显示了ClusterGroup
接口中定义的部分集群组:
IgniteCluster cluster = ignite.cluster();
// Cluster group with remote nodes, i.e. other than this node.
ClusterGroup remoteGroup = cluster.forRemotes();
Ignite的唯一特点是所有节点都是平等的。没有master节点或者server节点,也没有worker节点或者client节点,按照Ignite的观点所有节点都是平等的。但是,可以将节点配置成master,worker,或者client以及data节点。
所有集群节点启动时都会自动将所有的环境和系统属性注册为节点的属性,但是也可以通过配置自定义节点属性。
XML:
<bean class="org.apache.ignite.IgniteConfiguration">
...
<property name="userAttributes">
<map>
<entry key="ROLE" value="worker"/>
</map>
</property>
...
</bean>
Java:
IgniteConfiguration cfg = new IgniteConfiguration();
Map<String, String> attrs = Collections.singletonMap("ROLE", "worker");
cfg.setUserAttributes(attrs);
// Start Ignite node.
Ignite ignite = Ignition.start(cfg);
启动时,所有的环境变量和系统属性都会自动地注册为节点属性。
节点属性是通过ClusterNode.attribute("propertyName")
属性获得的。
下面的例子显示了如何获得赋予了‘worker’属性值的节点:
IgniteCluster cluster = ignite.cluster();
ClusterGroup workerGroup = cluster.forAttribute("ROLE", "worker");
Collection<GridNode> workerNodes = workerGroup.nodes();
可以基于一些谓词定义动态集群组,这个集群组只会包含符合该谓词的节点。
下面是一个例子,一个集群组只会包括CPU利用率小于50%的节点,注意这个组里面的节点会随着CPU负载的变化而改变。
IgniteCluster cluster = ignite.cluster();
// Nodes with less than 50% CPU load.
ClusterGroup readyNodes = cluster.forPredicate((node) -> node.metrics().getCurrentCpuLoad() < 0.5);
可以通过彼此之间的嵌套来组合集群组,比如,下面的代码片段显示了如何通过组合最老组和远程组来获得最老的远程节点:
// Group containing oldest node out of remote nodes.
ClusterGroup oldestGroup = cluster.forRemotes().forOldest();
ClusterNode oldestNode = oldestGroup.node();
可以像下面这样获得各种集群组的节点:
ClusterGroup remoteGroup = cluster.forRemotes();
// All cluster nodes in the group.
Collection<ClusterNode> grpNodes = remoteGroup.nodes();
// First node in the group (useful for groups with one node).
ClusterNode node = remoteGroup.node();
// And if you know a node ID, get node by ID.
UUID myID = ...;
node = remoteGroup.node(myId);
Ignite自动收集所有集群节点的元数据,很酷的事是集群组会自动地收集组内所有节点的元数据,然后提供组内正确的平均值,最小值,最大值等信息。
集群组元数据是通过ClusterMetrics
接口体现的,他包括了超过50个指标(注意,同样的指标单独的集群节点也有)。
下面的例子是获取一些元数据,包括所有远程节点的平均CPU利用率以及可用堆大小:
// Cluster group with remote nodes, i.e. other than this node.
ClusterGroup remoteGroup = ignite.cluster().forRemotes();
// Cluster group metrics.
ClusterMetrics metrics = remoteGroup.metrics();
// Get some metric values.
double cpuLoad = metrics.getCurrentCpuLoad();
long usedHeap = metrics.getHeapMemoryUsed();
int numberOfCores = metrics.getTotalCpus();
int activeJobs = metrics.getCurrentActiveJobs();
当工作在分布式环境中时,有时需要确保有这么一个节点,不管网络是否发生变化,这个节点通常被叫做leader(领导者)
。
很多系统选举领导者通常要处理数据一致性,然后通常是通过收集集群成员的选票处理的。而在Ignite中,数据一致性是通过数据网格的类似功能处理的(Rendezvous Hashing或者HRW哈希),选择领导者在传统意义上的数据一致性,在数据网格以外就不是真的需要了。
然而,可能还是希望有一个协调员
节点来处理某些任务,为了这个,Ignite允许在集群中自动地选择最老的或者最新的节点。
使用服务网格
注意对于大多数领导者
或者类单例
用例中,建议使用服务网格
功能,他可以自动地部署各个集群单例服务
,而且更易于使用。
每当新节点加入时,最老的节点都有一个保持不变的属性,集群中的最老节点唯一发生变化的时间点就是它从集群中退出或者该节点故障。
下面的例子显示了如何选择一个集群组,他只包含了最老的节点。
IgniteCluster cluster = ignite.cluster();
// Dynamic cluster group representing the oldest cluster node.
// Will automatically shift to the next oldest, if the oldest
// node crashes.
ClusterGroup oldestNode = cluster.forOldest();
最新的节点,与最老的节点不同,每当新节点加入集群时都会不断发生变化,然而,有时他也会变得很灵活,尤其是如果希望只在最新的节点上执行一些任务时。
下面的例子显示了如何选择一个集群组,他只包含了最新的节点。
IgniteCluster cluster = ignite.cluster();
// Dynamic cluster group representing the youngest cluster node.
// Will automatically shift to the next youngest, if the youngest
// node crashes.
ClusterGroup youngestNode = cluster.forYoungest();
一旦获得了集群组,就可以用它执行任务、部署服务、发送消息等。
Ignite中,通过DiscoverySpi
节点可以彼此发现对方,Ignite提供了TcpDiscoverySpi
作为DiscoverySpi
的默认实现,它使用TCP/IP来作为节点发现的实现,可以配置成基于组播的或者基于静态IP的。
TcpDiscoveryMulticastIpFinder
使用组播来发现网格内的每个节点。他也是默认的IP搜索器。除非打算覆盖默认的设置否则不需要指定他。
下面的例子显示了如何通过Spring XML配置文件或者通过Java代码编程式地进行配置:
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
ipFinder.setMulticastGroup("228.10.10.157");
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
XML:
<bean 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="228.10.10.157"/>
</bean>
</property>
</bean>
</property>
</bean>
对于组播被禁用的情况,TcpDiscoveryVmIpFinder
会使用预配置的IP地址列表。
唯一需要提供的就是至少一个远程节点的IP地址,但是为了保证冗余一个比较好的做法是在未来的某些时间点提供2-3个计划启动的网格节点的IP地址。只要建立了与任何一个已提供的IP地址的连接,Ignite就会自动地发现其他的所有节点。
TcpDiscoveryVmIpFinder
默认用的是非共享
模式,如果希望启动一个服务端节点,那么在该模式中的IP地址列表同时也要包含本地节点的一个IP地址。当其他节点加入集群过程中时,他会使该节点不用等待而是成为集群的第一个节点,并且正常运行。
下面的例子显示了如何通过Spring XML配置文件或者通过Java代码编程式地进行配置:
XML:
<bean 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.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<!--
Explicitly specifying address of a local node to let it start
and operate normally even if there is no more nodes in the cluster.
You can also optionally specify an individual port or port range.
-->
<value>1.2.3.4</value>
<!--
IP Address and optional port range of a remote node.
You can also optionally specify an individual port and don't set
the port range at all.
-->
<value>1.2.3.5:47500..47509</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();
// Set initial IP addresses.
// Note that you can optionally specify a port or a port range.
ipFinder.setAddresses(Arrays.asList("1.2.3.4", "1.2.3.5:47500..47509"));
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
可以同时使用基于组播和静态IP的发现,这种情况下,除了通过组播接受地址以外,如果有的话,TcpDiscoveryMulticastIpFinder
也可以与预配置的静态IP地址列表一起工作,就像上面描述的基于静态IP的发现一样。
下面的例子显示了如何配置使用了静态IP地址的组播IP搜索器。
XML:
<bean 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="228.10.10.157"/>
<!-- list of static IP addresses-->
<property name="addresses">
<list>
<value>1.2.3.4</value>
<!--
IP Address and optional port range.
You can also optionally specify an individual port.
-->
<value>1.2.3.5:47500..47509</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();
// Set Multicast group.
ipFinder.setMulticastGroup("228.10.10.157");
// Set initial IP addresses.
// Note that you can optionally specify a port or a port range.
ipFinder.setAddresses(Arrays.asList("1.2.3.4", "1.2.3.5:47500..47509"));
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
为了测试或者其他的一些原因,需要在同一个机器组中启动两个互相隔离的集群,这个是可以作为一个场景的。
对于TcpDiscoverySpi
和TcpCommunicationSpi
,不同集群的节点使用不交叉的本地端口范围,在Ignite中这个任务是可以做到的。
为了测试,假设需要在一个单个机器上启动两个互相隔离的集群,那么对于第一个集群的节点,需要使用如下的TcpDiscoverySpi
和TcpCommunicationSpi
配置:
XML:
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
...
<!--
Explicitly configure TCP discovery SPI to provide list of
initial nodes from the first cluster.
-->
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<!-- Initial local port to listen to. -->
<property name="localPort" value="48500"/>
<!-- Changing local port range. This is an optional action. -->
<property name="localPortRange" value="20"/>
<!-- Setting up IP finder for this cluster -->
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<!--
Addresses and port range of the nodes from the first
cluster.
127.0.0.1 can be replaced with actual IP addresses or
host names. Port range is optional.
-->
<value>127.0.0.1:48500..48520</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
<!--
Explicitly configure TCP communication SPI changing local
port number for the nodes from the first cluster.
-->
<property name="communicationSpi">
<bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
<property name="localPort" value="48100"/>
</bean>
</property>
</bean>
Java:
IgniteConfiguration cfg=new IgniteConfiguration();
// Explicitly configure TCP discovery SPI to provide list of initial nodes
// from the first cluster.
TcpDiscoverySpi discoverySpi=new TcpDiscoverySpi();
// Initial local port to listen to.
discoverySpi.setLocalPort(48500);
// Changing local port range. This is an optional action.
discoverySpi.setLocalPortRange(20);
TcpDiscoveryVmIpFinder ipFinder=new TcpDiscoveryVmIpFinder();
// Addresses and port range of the nodes from the first cluster.
// 127.0.0.1 can be replaced with actual IP addresses or host names.
// The port range is optional.
ipFinder.setAddresses(Arrays.asList("127.0.0.1:48500..48520"));
// Overriding IP finder.
discoverySpi.setIpFinder(ipFinder);
// Explicitly configure TCP communication SPI by changing local port number for
// the nodes from the first cluster.
TcpCommunicationSpi commSpi=new TcpCommunicationSpi();
commSpi.setLocalPort(48100);
// Overriding discovery SPI.
cfg.setDiscoverySpi(discoverySpi);
// Overriding communication SPI.
cfg.setCommunicationSpi(commSpi);
// Starting a node.
Ignition.start(cfg);
而对于第二个集群的节点,配置看起来是这样的:
XML:
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<!--
Explicitly configure TCP discovery SPI to provide list of initial
nodes from the second cluster.
-->
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<!-- Initial local port to listen to. -->
<property name="localPort" value="49500"/>
<!-- Changing local port range. This is an optional action. -->
<property name="localPortRange" value="20"/>
<!-- Setting up IP finder for this cluster -->
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">
<property name="addresses">
<list>
<!--
Addresses and port range of the nodes from the second
cluster.
127.0.0.1 can be replaced with actual IP addresses or
host names. Port range is optional.
-->
<value>127.0.0.1:49500..49520</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
<!--
Explicitly configure TCP communication SPI changing local port number
for the nodes from the second cluster.
-->
<property name="communicationSpi">
<bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
<property name="localPort" value="49100"/>
</bean>
</property>
</bean>
Java:
IgniteConfiguration cfg=new IgniteConfiguration();
// Explicitly configure TCP discovery SPI to provide list of initial nodes
// from the second cluster.
TcpDiscoverySpi discoverySpi=new TcpDiscoverySpi();
// Initial local port to listen to.
discoverySpi.setLocalPort(49500);
// Changing local port range. This is an optional action.
discoverySpi.setLocalPortRange(20);
TcpDiscoveryVmIpFinder ipFinder=new TcpDiscoveryVmIpFinder();
// Addresses and port range of the nodes from the second cluster.
// 127.0.0.1 can be replaced with actual IP addresses or host names.
// The port range is optional.
ipFinder.setAddresses(Arrays.asList("127.0.0.1:49500..49520"));
// Overriding IP finder.
discoverySpi.setIpFinder(ipFinder);
// Explicitly configure TCP communication SPI by changing local port number for
// the nodes from the second cluster.
TcpCommunicationSpi commSpi=new TcpCommunicationSpi();
commSpi.setLocalPort(49100);
// Overriding discovery SPI.
cfg.setDiscoverySpi(discoverySpi);
// Overriding communication SPI.
cfg.setCommunicationSpi(commSpi);
// Starting a node.
Ignition.start(cfg);
从配置中可以看到,他们的差别是很小的 - 只是SPI的端口号和IP搜索器不同。
如果希望不同集群的节点之间可以互相检索到,可以使用组播协议然后将
TcpDiscoveryVmIpFinder
替换为TcpDiscoveryMulticastIpFinder
并且在上面的每个配置中设置唯一的TcpDiscoveryMulticastIpFinder.multicastGroups
。
参照2.9.JCoud集成
章节
参照2.7.Amazon AWS集成
章节
参照2.8.Google云集成
章节
可以用数据库作为通用共享存储来保存初始的IP地址,这些节点会在启动时将IP地址写入数据库,这是通过TcpDiscoveryJdbcIpFinder
实现的。
XML:
<bean 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.jdbc.TcpDiscoveryJdbcIpFinder">
<property name="dataSource" ref="ds"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- Configured data source instance. -->
<bean id="ds" class="some.Datasource">
...
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
// Configure your DataSource.
DataSource someDs = MySampleDataSource(...);
TcpDiscoveryJdbcIpFinder ipFinder = new TcpDiscoveryJdbcIpFinder();
ipFinder.setDataSource(someDs);
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
如果使用ZooKeeper 来整合分布式环境,也可以利用它进行Ignite节点的发现,这是通过TcpDiscoveryZookeeperIpFinder
实现的(注意需要启用ignite-zookeeper
模块)。
XML:
<bean 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.zk.TcpDiscoveryZookeeperIpFinder">
<property name="zkConnectionString" value="127.0.0.1:2181"/>
</bean>
</property>
</bean>
</property>
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryZookeeperIpFinder ipFinder = new TcpDiscoveryZookeeperIpFinder();
// Specify ZooKeeper connection string.
ipFinder.setZkConnectionString("127.0.0.1:2181");
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
故障检测超时用于确定一个集群节点在与远程节点连接失败时可以等待多长时间,根据集群的硬件和网络条件,这个超时时间是调整发现SPI的故障检测功能的最简单的方式。
这些
TcpDiscoverySpi
的超时配置参数是自动控制的,比如套接字超时,消息确认超时以及其他的,如果显式地设置了这些参数中的任意一个,故障超时设置都会被忽略掉。
故障检测超时是通过IgniteConfiguration.setFailureDetectionTimeout(long failureDetectionTimeout)
方法来配置的,默认值是10秒,这个时间可以使发现SPI在大多数的硬件和虚拟环境下可靠地工作,但是这已经使故障检测很糟糕了。然而,对于一个稳定低延迟网络来说,这个参数设置成大约200毫秒会更有助于快速地进行故障的检测和响应。
下面的配置参数可以对TcpDiscoverySpi
进行可选的配置:
setter方法 | 描述 | 默认值 |
---|---|---|
setIpFinder(TcpDiscoveryIpFinder) |
用于节点IP地址信息共享的IP搜索器 | TcpDiscoveryMulticastIpFinder ,有如下的实现可以使用:TcpDiscoverySharedFsIpFinder ,TcpDiscoveryS3IpFinder ,TcpDiscoveryJdbcIpFinder ,TcpDiscoveryVmIpFinder |
setLocalAddress(String) |
设置发现SPI使用的本地主机IP地址 | 如果未提供,默认会使用发现的第一个非loopback地址,如果没有可用的非loopback地址,那么会使用java.net.InetAddress.getLocalHost() |
setLocalPort(int) |
SPI监听端口 | 47500 |
setLocalPortRange(int) |
本地端口范围,本地节点会试图绑定从localPort开始的第一个可用的端口,直到localPort+localPortRange | 100 |
setHeartbeatFrequency(long) |
发送的心跳消息之间的时间间隔(毫秒),SPI会在配置好的时间间隔内向其他节点发送消息,以向他们通知自己的状态 | 2000 |
setMaxMissedHeartbeats(int) |
本地节点初始状态检查之前允许丢失的心跳请求的数量 | 1 |
setReconnectCount(int) |
节点与其他节点试图(重新)建立连接的次数 | 2 |
setNetworkTimeout(long) |
用于网络操作的最大超时时间 | 5000 |
setSocketTimeout(long) |
设置Socket操作超时时间,这个超时时间用于限制连接时间以及写Socket时间 | 2000 |
setAckTimeout(long) |
设置收到发送消息的确认的超时时间,如果在这个时间段内未收到确认,发送会被认为失败然后SPI会试图重新发送消息 | 2000 |
setJoinTimeout(long) |
设置加入超时时间,如果使用了非共享的IP搜索器然后节点通过IP搜索器无法与任何地址建立连接,节点会在这个时间段内仍然试图加入集群。如果所有地址仍然无响应,会抛出异常然后节点启动失败,0意味着一直等待 | 0 |
setThreadPriority(int) |
SPI启动的线程的线程优先级 | 0 |
setStatisticsPrintFrequency(int) |
统计输出的频率(毫秒),0意味着不需要输出。如果值大于0那么日志就会激活,然后每隔一段时间就会以INFO级别输出一个状态,这对于跟踪网络拓扑的问题非常有用。 | 0 |
计算所需的闭包和任务可能是任意自定义的类,也包括匿名类。Ignite中,远程节点会自动感知这些类,不需要显式地将任何jar文件部署或者移动到任何远程节点上。
这个行为是通过对等类加载(P2P类加载)实现的,他是Ignite中的一个特别的分布式类加载器,实现了节点间的字节码交换。当对等类加载启用时,不需要在网格内的每个节点上手工地部署Java或者Scala代码,也不需要每次在发生变化时重新部署。
下面的代码由于对等类加载会在所有的远程节点上运行,不需要任何的显式部署步骤:
IgniteCluster cluster = ignite.cluster();
// Compute instance over remote nodes.
IgniteCompute compute = ignite.compute(cluster.forRemotes());
// Print hello message on all remote nodes.
compute.broadcast(() -> System.out.println("Hello node: " + cluster.localNode().id()));
下面是对等类加载如何配置:
XML:
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
...
<!-- Explicitly enable peer class loading. -->
<property name="peerClassLoadingEnabled" value="true"/>
...
</bean>
Java:
IgniteConfiguration cfg = new IgniteConfiguration();
cfg.setPeerClassLoadingEnabled(true);
// Start Ignite node.
Ignite ignite = Ignition.start(cfg);
对等类加载的工作步骤如下:
热部署自动缓存清理
:
BinaryMarshaller(默认)是支持热部署的,如果不使用默认的BinaryMarshaller,那么每当改变了存储在缓存中的类定义时,Ignite会在对等部署新数据之前自动清理缓存中之前的类定义,以避免类加载冲突。
第三方库
:
当使用对等类加载时,会发现可能从对等节点加载库,还可能本地类路径就已经存在库。建议在每个节点的类路径里包含所有的第三方库,这可以通过将jar文件复制到Ignite的libs
文件夹实现,这样就可以避免每次只改变了一行代码然后还需要向远程节点上传输若干M的第三方库文件。
要在Ignite中显式地部署jar文件,可以将他们拷贝进每个集群节点的libs
文件夹,Ignite会在启动时自动加载所有的libs
文件夹中的jar文件。
AWS云上的节点发现通常认为很有挑战性。Amazon EC2,和其他大部分的虚拟环境一样,有如下的限制:
虽然在没有组播时可以使用基于TCP的发现,但是不得不处理不断变换的IP地址以及不断更新配置。这产生了一个主要的不便之处以至于在这种环境下基于静态IP的配置实质上变得不可用。
为了减轻不断变化的IP地址的问题,Ignite支持通过使用基于TcpDiscoveryS3IpFinder
的S3存储来实现节点的自动发现。在启动时节点在Amazon S3存储上注册他们的IP地址,这样其他节点会试图连接任意存储在S3上的IP地址然后初始化网格节点的自动发现。
这个方法可以只配置一次就可以在所有的EC2实例上复用。
下面的例子显示了如何配置基于Amazon S3的IP搜索器:
XML:
<bean 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.s3.TcpDiscoveryS3IpFinder">
<property name="awsCredentials" ref="aws.creds"/>
<property name="bucketName" value="YOUR_BUCKET_NAME"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- AWS credentials. Provide your access key ID and secret access key. -->
<bean id="aws.creds" class="com.amazonaws.auth.BasicAWSCredentials">
<constructor-arg value="YOUR_ACCESS_KEY_ID" />
<constructor-arg value="YOUR_SECRET_ACCESS_KEY" />
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
BasicAWSCredentials creds = new BasicAWSCredentials("yourAccessKey", "yourSecreteKey");
TcpDiscoveryS3IpFinder ipFinder = new TcpDiscoveryS3IpFinder();
ipFinder.setAwsCredentials(creds);
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
GCE上的节点发现通常认为很有挑战性。Google云,和其他大部分的虚拟环境一样,有如下的限制:
虽然在没有组播时可以使用基于TCP的发现,但是不得不处理不断变换的IP地址以及不断更新配置。这产生了一个主要的不便之处以至于在这种环境下基于静态IP的配置实质上变得不可用。
为了减轻不断变化的IP地址的问题,Ignite支持通过使用基于TcpDiscoveryGoogleStorageIpFinder
的Google云存储来实现节点的自动发现。在启动时节点在存储上注册他们的IP地址,这样其他节点会试图连接任意保存在存储上的IP地址然后初始化网格节点的自动发现。
这个方法可以只配置一次就可以在所有的EC2实例上复用。
下面的例子显示了如何配置基于Google云存储的IP搜索器:
XML:
<bean 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.gce.TcpDiscoveryGoogleStorageIpFinder">
<property name="projectName" ref="YOUR_GOOGLE_PLATFORM_PROJECT_NAME"/>
<property name="bucketName" value="YOUR_BUCKET_NAME"/>
<property name="serviceAccountId" value="YOUR_SERVICE_ACCOUNT_ID"/>
<property name="serviceAccountP12FilePath" value="PATH_TO_YOUR_PKCS12_KEY"/>
</bean>
</property>
</bean>
</property>
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryGoogleStorageIpFinder ipFinder = new TcpDiscoveryGoogleStorageIpFinder();
ipFinder.setServiceAccountId(yourServiceAccountId);
ipFinder.setServiceAccountP12FilePath(pathToYourP12Key);
ipFinder.setProjectName(yourGoogleClourPlatformProjectName);
// Bucket name must be unique across the whole Google Cloud Platform.
ipFinder.setBucketName("your_bucket_name");
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
云平台上的节点发现通常认为很有挑战性。Google云,和其他大部分的虚拟环境一样,有如下的限制:
虽然在没有组播时可以使用基于TCP的发现,但是不得不处理不断变换的IP地址以及不断更新配置。这产生了一个主要的不便之处以至于在这种环境下基于静态IP的配置实质上变得不可用。
为了减轻不断变化的IP地址的问题,Ignite支持通过使用基于TcpDiscoveryCloudIpFinder
的Apache jclouds工具包来实现节点的自动发现。要了解有关Apache JCloud的信息,请参照jclouds.apache.org。
该IP搜索器形成节点地址,通过获取云上所有虚拟机的私有和共有IP地址以及给他们增加一个端口号使Ignite可以运行,该端口可以通过TcpDiscoverySpi.setLocalPort(int)
或者TcpDiscoverySpi.DFLT_PORT
进行设置,这样所有节点会连接任何生成的的IP地址然后初始化网格节点的自动发现。
可以参考Apache jclouds providers section来获取他支持的云平台的列表。
所有虚拟机都要使用同一个端口启动Ignite实例,否则他们无法通过IP搜索器发现对方。
下面的例子显示了如何配置基于Apache JCloud的IP搜索器:
XML:
<bean 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.cloud.TcpDiscoveryCloudIpFinder">
<!-- Configuration for Google Compute Engine. -->
<property name="provider" value="google-compute-engine"/>
<property name="identity" value="YOUR_SERVICE_ACCOUNT_EMAIL"/>
<property name="credentialPath" value="PATH_YOUR_PEM_FILE"/>
<property name="zones">
<list>
<value>us-central1-a</value>
<value>asia-east1-a</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>
Java:
TcpDiscoverySpi spi = new TcpDiscoverySpi();
TcpDiscoveryCloudIpFinder ipFinder = new TcpDiscoveryCloudIpFinder();
// Configuration for AWS EC2.
ipFinder.setProvider("aws-ec2");
ipFinder.setIdentity(yourAccountId);
ipFinder.setCredential(yourAccountKey);
ipFinder.setRegions(Collections.<String>emptyList().add("us-east-1"));
ipFinder.setZones(Arrays.asList("us-east-1b", "us-east-1e"));
spi.setIpFinder(ipFinder);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default discovery SPI.
cfg.setDiscoverySpi(spi);
// Start Ignite node.
Ignition.start(cfg);
CommunicationSpi
为发送和接收网格消息提供了基本的管道,他也被用于所有的分布式网格操作,比如执行任务,监控数据交换,分布式事件查询以及其他的。Ignite提供了TcpCommunicationSpi
作为CommunicationSpi
的默认实现,它使用TCP/IP协议来进行节点间的通信。
要启用节点间的通信,TcpCommunicationSpi
增加了TcpCommuncationSpi.ATTR_ADDRS
和TcpCommuncationSpi.ATTR_PORT
本地节点属性。启动时,这个SPI会监听由TcpCommuncationSpi.setLocalPort(int)
方法设置的本地端口。如果端口被占用,SPI会自动增加端口号直到成功绑定监听。
TcpCommuncationSpi.setLocalPortRange(int)
配置参数控制了SPI可以尝试的最大端口数量。
本地端口范围
当在一台机器上甚至是在同一个JVM上启动多个网格节点时,端口范围会非常方便,这样的话所有的节点都会启动而不用一个个地进行单独的配置。
下面的例子显示了如何调整TcpCommuncationSpi
的参数:
XML:
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
...
<property name="communicationSpi">
<bean class="org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi">
<!-- Override local port. -->
<property name="localPort" value="4321"/>
</bean>
</property>
...
</bean>
Java:
TcpCommunicationSpi commSpi = new TcpCommunicationSpi();
// Override local port.
commSpi.setLocalPort(4321);
IgniteConfiguration cfg = new IgniteConfiguration();
// Override default communication SPI.
cfg.setCommunicationSpi(commSpi);
// Start grid.
Ignition.start(cfg);
Docker可以将Ignite应用及其所有的依赖打包进一个标准的容器,Docker会自动下载Ignite发布版,将代码部署进Ignite以及配置节点,他还可以自动启动配置好的Ignite节点,这样的集成方式,使得通过简单地重启Ignite的Docker容器就可以部署新的代码。
如果配置了GIT_REPO
参数,Ignite的docker容器会以这个模式启动。这时,容器会构建Git仓库指定的项目并且启动部署有代码的Ignite,这样的集成可以通过简单地重启Ignite的docker容器就可以部署新的代码。
可以使用如下的命令来拉取Ignite的docker容器:
sudo docker pull apacheignite/ignite-docker
可以使用docker run
来运行Ignite的docker容器:
sudo docker run -it --net=host
-e "GIT_REPO=$GIT_REPO"
[-e "GIT_BRANCH=$GIT_BRANCH"]
[-e "BUILD_CMD=$BUILD_CMD"]
...
apacheignite/ignite-docker
配置参数可以通过docker容器的环境变量进行传递,可用的配置参数如下:
名称 | 描述 | 可选 | 默认 | 示例 |
---|---|---|---|---|
GIT_REPO |
Git仓库的URL | 否 | 无 | https://github.com/bob/ignite-pojo |
GIT_BRANCH |
构建的Git分支 | 是 | master |
sprint-1 |
BUILD_CMD |
用于构建Git项目的命令 | 是 | `mvn clean package | mvn clean package -DskipTests=true` |
IGNITE_CONFIG |
Ignite配置文件的URL(也可以是相对于类路径中META-INF文件夹的相对路径),下载的配置文件会保存于./ignite-config.xml | 是 | 无 | https://raw.githubusercontent.com/bob/master/ignite-cfg.xml |
LIB_PATTERN |
如果设置,那么Ignite docker容器只会拷贝匹配这个正则表达式的文件。 | 是 | 从目标文件夹中拷贝所有jar文件 | libs/.* |
OPTION_LIBS |
会被包含在类路径中的可选库 | 是 | ignite-log4j,ignite-spring, ignite-indexing | ignite-aws,ignite-aop |
要从Git仓库运行Ignite docker容器,可以执行如下的命令:
sudo docker run -it --net=host
-e "GIT_REPO=https://github.com/TikhonovNikolay/docker-example.git"
apacheignite/ignite-docker
之后应该看到如下的输出日志:
如果未配置GIT_REPO
参数,那么Ignite docker容器会下载指定的或者最新的Ignite发布版,默认会下载最新的版本。
可以使用如下的命令拉取Ignite docker容器:
sudo docker pull apacheignite/ignite-docker
可以使用docker run
来运行Ignite docker容器:
sudo docker run -it --net=host
-e "IGNITE_VERSION=$IGNITE_VERSION"
[-e "IGNITE_CONFIG=$IGNITE_CONFIG"]
[-e "OPTION_LIBS=$OPTION_LIBS"]
...
apacheignite/ignite-docker
配置参数可以通过docker容器的环境变量进行传递,可用的配置参数如下:
名称 | 描述 | 默认 | 示例 |
---|---|---|---|
IGNITE_URL |
Ignite发布版的URL | 无 | http://apache-mirror.rbc.ru/pub/apache/incubator/ignite/1.1.0/apache-ignite-fabric-1.1.0-incubating-bin.zip |
IGNITE_VERSION |
Ignite的版本号 | latest | 1.6.0 |
IGNITE_SOURCE |
要下载的Ignite版本,如果设置了IGNITE_VERSION属性,这个属性会被忽略。 | COMMUNITY |
APACHE |
IGNITE_CONFIG |
Ignite配置文件的URL(也可以是相对于类路径中META-INF文件夹的相对路径),下载的配置文件会保存于./ignite-config.xml | 无 | https://raw.githubusercontent.com/bob/master/ignite-cfg.xml |
OPTION_LIBS |
会被包含在类路径中的可选库 | ignite-log4j, ignite-spring,ignite-indexing |
ignite-aws,ignite-aop |
要用干净的Ignite节点启动Ignite的docker容器,可以使用如下的命令:
sudo docker run -it --net=host -e "IGNITE_VERSION=1.7.0" apacheignite/ignite-docker
之后应该看到如下的输出日志:
要导入Ignite映像,可以执行如下命令:
gcloud compute images
create <IMAGE_NAME>
--source-uri gs://ignite-media/ignite-google-image-1.0.0.tar.gz
要了解更多信息请参照[cloud.google.com](https://cloud.google.com/compute/docs/images#import_an_image
Google Compute Console
;Compute->Compute Engine->VM instances
然后点击New instance
;Boot disk
部分点击Change
按钮;Your image
然后选择导入的映像,在映像的快照中就能看到ignite-name
名字;Management, disk, networking, access & security options
,就可以为Ignite Docker容器添加任何配置参数;容器id
,下面的命令会显示容器id
:sudo docker ps
;sudo docker logs -f CONTAINER_ID
sudo docker exec -it container_id /bin/bash
区域 | 映像 |
US-WEST | ami-5b53a41f |
US-EAST | ami-3fa45e54 |
EU-CENTRAL | ami-9c5f6481 |
Instance Type
;Configure Instance
然后展开Advanced Details
标签;name
项目赋值,比如ignite-node
;容器的id
,可以用如下的命令获得:sudo docker ps
sudo docker logs -f CONTAINER_ID
sudo docker exec -it container_id /bin/bash
Apache Ignite支持在Mesos集群上调度和运行Ignite节点。
Apache Mesos是一个集群管理器,他提供了一个通用运行环境以及所有的必要资源来部署、运行和管理分布式应用。他对资源的管理和隔离有助于充分利用服务器资源。
要了解Apache Mesos的更多信息,请参照:http://mesos.apache.org/
典型的部署Apache Ignite集群需要下载Apache Ignite发行版,修改配置参数以及启动节点。Apache Ignite Mesos框架由调度器
和任务
组成,可以极大地简化集群的部署。
调度器
:调度器启动时将自己注册成Mesos主节点,一旦注册成功调度器就会开始处理从Mesos主节点到使用资源的Ignite节点的资源请求,调度器会维护Ignite集群所需的所有资源水平(CPU,内存等);任务
:从节点运行Ignite节点的实体。要运行Ignite Mesos框架需要配置好的正在运行的Apache Mesos集群,如果需要如何Apache Mesos集群的信息,请参照:https://docs.mesosphere.com/getting-started/datacenter/install/。
确保主节点和从节点监听正确的IP地址,否则无法保证Mesos集群能正常工作。
通过Marathon运行框架
当前建议的做法是通过Marathon运行框架。
libs\optional\ignite-mesos\ignite-mesos-<ignite-version>-jar-with-dependencies.jar
上传到任意一个云存储(比如Amazon S3yun);marathon.json
文件,然后对参数做必要的修改,如果未对集群进行限制那么框架会试图占用Mesos集群的所有资源,可以看下面的配置
章节;
{
"id": "ignition",
"instances": 1,
"cpus": 2,
"mem": 2048,
"ports": [0],
"uris": [
"http://host/ignite-mesos-<ignite-version>-jar-with-dependencies.jar"
],
"env": {
"IGNITE_NODE_COUNT": "4",
"MESOS_MASTER_URL": "zk://localhost:2181/mesos",
"IGNITE_RUN_CPU_PER_NODE": "2",
"IGNITE_MEMORY_PER_NODE": "2048",
"IGNITE_VERSION": "1.0.5"
},
"cmd": "java -jar ignite-mesos-<ignite-version>-jar-with-dependencies.jar"
}
curl -X POST -H "Content-type: application/json" --data-binary @marathon.json http://<marathon-ip>:8080/v2/apps/
http://<marathon-ip>:8080
,确保已有的应用名字为ignition
而且状态是Running
; http://<master-ip>:5050
,如果一切正常那么任务的名字类似Ignite node N
,状态是RUNNING
。在本示例中,N=4,可以看示例中的marathon.json
文件-"IGNITE_NODE_COUNT": "4"; Active Tasks
表格中的Sandbox
; stdout
获取标准输出日志,stderr
获取标准错误日志; libs\optional\ignite-mesos\
文件夹;properties.prop
是一个配置文件,如果不提供配置文件那么框架会试图占用Mesos集群的所有资源,下面是一个例子:
# The number of nodes in the cluster.
IGNITE_NODE_COUNT=1
# Mesos ZooKeeper URL to locate leading master.
MESOS_MASTER_URL=zk://localhost:2181/mesos
# The number of CPU Cores for each Apache Ignite node.
IGNITE_RUN_CPU_PER_NODE=4
# The number of Megabytes of RAM for each Apache Ignite node.
IGNITE_MEMORY_PER_NODE=4096
# The version ignite which will be run on nodes.
IGNITE_VERSION=1.7.0
http://<marathon-ip>:5050
,确保已有的应用名字为ignition
而且状态是Running
。在本示例中N=1,可以看示例中的properties.prop
文件-"IGNITE_NODE_COUNT": "1"; Active Tasks
表格中的Sandbox
; stdout
获取标准输出日志,stderr
获取标准错误日志; 所有配置都是通过环境变量或者配置文件处理的(这非常适用于简化marathon的配置以运行框架),下面的配置参数可以根据需要进行配置:
名称 | 描述 | 默认值 | 示例 |
---|---|---|---|
IGNITE_RUN_CPU_PER_NODE |
每个Ignite节点的CPU核数 | 没有限制 | 2 |
IGNITE_MEMORY_PER_NODE |
每个节点的内存数量(M) | 没有限制 | 1024 |
IGNITE_DISK_SPACE_PER_NODE |
每个节点占用的磁盘容量(M) | 1024 | 2048 |
IGNITE_NODE_COUNT |
集群内的节点数量 | 5 | 10 |
IGNITE_TOTAL_CPU |
Ignite集群的CPU核数 | 没有限制 | 5 |
IGNITE_TOTAL_MEMORY |
Ignite集群占用的内存(M) | 没有限制 | |
IGNITE_TOTAL_DISK_SPACE |
Ignite集群占用的磁盘空间(M) | 没有限制 | 5120 |
IGNITE_MIN_CPU_PER_NODE |
要运行Ignite节点所需的CPU核数的最小值 | 1 | 4 |
IGNITE_MIN_MEMORY_PER_NODE |
要运行Ignite节点所需的内存的最小值(M) | 256 | 1024 |
IGNITE_VERSION |
节点要运行的Ignite的版本 | latest | 1.6.0 |
IGNITE_WORK_DIR |
保存Ignite发行版的 | ignite-release | /opt/ignite/ |
IGNITE_XML_CONFIG |
Apache Ignite配置文件的路径 | 无 | /opt/ignite/ignite-config.xml |
IGNITE_CONFIG_XML_URL |
Apache Ignite配置文件的URL | 无 | https://example.com/default-config.xml |
IGNITE_USERS_LIBS |
要添加到类路径的库文件的路径 | 无 | /opt/libs/ |
IGNITE_USERS_LIBS_URL |
要添加到类路径的库文件的URL列表,逗号分割 | 无 | https://example.com/lib.zip,https://example.com/lib1.zip |
MESOS_MASTER_URL |
要定位主节点的Mesos Zookeeper的URL | zk://localhost:2181/mesos | zk://176.0.1.45:2181/mesos or 176.0.1.45:2181 |
IGNITE_PACKAGE_PATH |
Ignite的压缩包路径,这个参数在访问因特网受限时是有用的。 | 无 | /opt/ignite/apache-ignite-fabric-1.6.0-bin.zip |
与Yarn的集成可以支持在Yarn集群上调度和运行Apache Ignite节点。
Yarn是一个资源管理器,他提供了一个包括所有必要资源的通用的运行环境来进行分布式应用的部署,运行和管理,他对资源的管理和隔离有助于充分利用服务器资源。
要了解Yarn的信息,请参照http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html。
部署Apache Ignite集群的典型步骤是下载Ignite的发行版,修改配置文件以及启动节点。与Yarn的集成可以避免这些操作,Ignite Yarn应用可以极大的简化集群的部署,它由如下组件组成:
Application master
进程;Application master
:一旦注册成功组件就会开始处理从资源管理器到使用资源的Ignite节点的资源请求,Application master
会维护Ignite集群所需的所有资源水平(CPU,内存等);Container
:在从节点上运行Ignite节点的实体;要运行Ignite应用,需要配置和运行Yarn和Hadoop集群,要了解如何配置集群的信息,可以参照: http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/ClusterSetup.html.
配置
章节:
# The number of nodes in the cluster.
IGNITE_NODE_COUNT=2
# The number of CPU Cores for each Apache Ignite node.
IGNITE_RUN_CPU_PER_NODE=1
# The number of Megabytes of RAM for each Apache Ignite node.
IGNITE_MEMORY_PER_NODE=2048
# The version ignite which will be run on nodes.
IGNITE_VERSION=1.0.6
hadoop java jar ignite-yarn-<ignite-version>.jar ./ignite-yarn-<ignite-version>.jar cluster.properties
Ignition
的应用是否工作正常; Logs
; stdout
获取标准输出日志,stderr
获取标准错误日志; 所有的配置都是通过环境变量和属性文件进行的,下面的配置参数可以根据需要进行配置:
名称 | 描述 | 默认值 |
---|---|---|
IGNITE_XML_CONFIG | 指向Apache Ignite配置文件的HDFS路径 | 无 |
IGNITE_WORK_DIR | 用于保存Ignition发行版的目录 | ./ignite-release |
IGNITE_RELEASES_DIR | 保存Ignite发行版的HDFS路径 | /ignite/releases/ |
IGNITE_USERS_LIBS | 要添加到CLASSPATH的库文件的HDFS路径 | 无 |
IGNITE_MEMORY_PER_NODE | 每个Ignite节点占用的内存的大小(M),这个是Java堆的大小。 | 2048 |
IGNITE_MEMORY_OVERHEAD_PER_NODE | 分配用于处理JVM原生日常管理、内部字符串等的内存量,但是如果用的话也包括堆外内存。YARN用于容器运行Ignite节点的必要内存量是IGNITE_MEMORY_PER_NODE和IGNITE_MEMORY_OVERHEAD_PER_NODE之和。 | IGNITE_MEMORY_PER_NODE * 0.10,最小值 |
IGNITE_HOSTNAME_CONSTRAINT | 从节点约束 | 无 |
IGNITE_NODE_COUNT | 集群节点的数量 | 3 |
IGNITE_RUN_CPU_PER_NODE | 每个Ignite节点的CPU核数 | 2 |
IGNITE_VERSION | 节点上运行的Ignite版本 | latest |
IGNITE_PATH | 到Ignite构建的hdfs路径,当yarn集群运行在内网无法访问互联网时,这个属性很有用。 | 无 |
Ignite允许在所有节点之间使用SSL Socket进行通信。要使用SSL,需要设置Factory<SSLContext>
以及配置Ignite配置文件的SSL
段落,Ignite提供了一个默认的SSL上下文工厂,org.apache.ignite.ssl.SslContextFactory
,他用一个配置好的keystore来初始化SSL上下文。
XML:
<bean id="cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="sslContextFactory">
<bean class="org.apache.ignite.ssl.SslContextFactory">
<property name="keyStoreFilePath" value="keystore/server.jks"/>
<property name="keyStorePassword" value="123456"/>
<property name="trustStoreFilePath" value="keystore/trust.jks"/>
<property name="trustStorePassword" value="123456"/>
</bean>
</property>
</bean>
Java:
IgniteConfiguration igniteCfg = new IgniteConfiguration();
SslContextFactory factory = new SslContextFactory();
factory.setKeyStoreFilePath("keystore/server.jks");
factory.setKeyStorePassword("123456".toCharArray());
factory.setTrustStoreFilePath("keystore/trust.jks");
factory.setTrustStorePassword("123456".toCharArray());
igniteCfg.setSslContextFactory(factory);
某些情况下需要禁用客户端侧的证书认证(比如连接到一个自签名的服务器时),这可以通过给上述工厂设置禁用信任管理器实现,他可以通过getDisabledTrustManager
获得。
XML:
<bean id="cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="sslContextFactory">
<bean class="org.apache.ignite.ssl.SslContextFactory">
<property name="keyStoreFilePath" value="keystore/server.jks"/>
<property name="keyStorePassword" value="123456"/>
<property name="trustManagers">
<bean class="org.apache.ignite.ssl.SslContextFactory" factory-method="getDisabledTrustManager"/>
</property>
</bean>
</property>
</bean>
Java:
IgniteConfiguration igniteCfg = new IgniteConfiguration();
SslContextFactory factory = new SslContextFactory();
factory.setKeyStoreFilePath("keystore/server.jks");
factory.setKeyStorePassword("123456".toCharArray());
factory.setTrustManagers(SslContextFactory.getDisabledTrustManager());
igniteCfg.setSslContextFactory(factory);
如果配置了安全,那么日志就会包括:communication encrypted=on
INFO: Security status [authentication=off, communication encrypted=on]
Ignite允许使用不同的加密类型,支持的加密算法可以参照:http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext,可以通过setProtocol()
方法进行设置,默认值是TLS
。
XML:
<bean id="cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="sslContextFactory">
<bean class="org.apache.ignite.ssl.SslContextFactory">
<property name="protocol" value="SSL"/>
...
</bean>
</property>
...
</bean>
Java:
IgniteConfiguration igniteCfg = new IgniteConfiguration();
SslContextFactory factory = new SslContextFactory();
...
factory.setProtocol("TLS");
igniteCfg.setSslContextFactory(factory);
下面的配置参数可以通过SslContextFactory
进行配置:
setter方法 | 描述 | 默认值 |
---|---|---|
setKeyAlgorithm | 设置key管理器算法,用于创建key管理器。注意,大多数情况下默认值即可,但是在Android平台需要设置成X509 . |
SunX509 |
setKeyStoreFilePath | keystore文件路径,该参数为必须参数,否则SSL上下文无法初始化 | 无 |
setKeyStorePassword | keystore密码 | 无 |
setKeyStoreType | 用于上下文初始化的keystore类型 | JKS |
setProtocol | 安全传输协议 | TLS |
setTrustStoreFilePath | truststore文件路径 | 无 |
setTrustStorePassword | truststore密码 | 无 |
setTrustStoreType | 用于上下文初始化的truststore类型 | JKS |
setTrustManagers | 设置配置好的信任管理器 | 无 |
Ignite中,预定义的资源都是可以进行依赖注入的,同时支持基于属性和基于方法的注入。任何加注正确注解的资源都会在初始化之前注入相对应的任务、作业、闭包或者SPI。
可以通过在一个属性或者方法上加注注解来注入资源。当加注在属性上时,Ignite只是在注入阶段简单地设置属性的值(不会理会该属性的访问修饰符)。如果在一个方法上加注了资源注解,他会访问一个与注入资源相对应的输入参数的类型,如果匹配,那么在注入阶段,就会将适当的资源作为输入参数,然后调用该方法。
基于属性:
Ignite ignite = Ignition.ignite();
Collection<String> res = ignite.compute().broadcast(new IgniteCallable<String>() {
// Inject Ignite instance.
@IgniteInstanceResource
private Ignite ignite;
@Override
public String call() throws Exception {
IgniteCache<Object, Object> cache = ignite.getOrCreateCache(CACHE_NAME);
// Do some stuff with cache.
...
}
});
基于方法:
public class MyClusterJob implements ComputeJob {
...
private Ignite ignite;
...
// Inject Ignite instance.
@IgniteInstanceResource
public void setIgnite(Ignite ignite) {
this.ignite = ignite;
}
...
}
有很多的预定义资源可供注入:
资源 | 描述 |
---|---|
CacheNameResource |
由CacheConfiguration.getName() 提供,注入网格缓存名 |
CacheStoreSessionResource |
注入当前的CacheStoreSession 实例 |
IgniteInstanceResource |
注入当前的Ignite实例 |
JobContextResource |
注入ComputeJobContext 的实例。作业的上下文持有关于一个作业执行的有用的信息。比如,可以获得包含与作业并置的条目的缓存的名字。 |
LoadBalancerResource |
注入ComputeLoadBalancer 的实例,注入以后,可以用于明确的负载平衡。 |
LoggerResource |
注入IgniteLogger 的实例,他可以用于向本地节点的日志写消息。 |
ServiceResource |
通过指定服务名注入Ignite的服务。 |
SpringApplicationContextResource |
注入Spring的ApplicationContext 资源。 |
SpringResource |
从Spring的ApplicationContext 注入资源,当希望访问在Spring的ApplicationContext XML配置中指定的一个Bean时,可以用它。 |
TaskContinuousMapperResource |
注入一个ComputeTaskContinuousMapper 的实例,持续映射可以在任何时点从任务中发布作业,即使过了map的初始化阶段。 |
TaskSessionResource |
注入ComputeTaskSession 资源的实例,它为一个特定的任务执行定义了一个分布式的会话。 |
对等类加载行为的特性是由不同的部署模式控制的。特别地,当发起节点离开网格时的卸载行为也会依赖于部署模式。另一方面,由部署模式,是用户资源管理和类版本管理。在下面的章节中会更详细地描述每个部署模式。
PRIVATE和ISOLATED
在主节点,同一个类加载器部署的类,还会在worker节点远程共享同一个类加载器。然而,从不同主节点部署的任务不会在worker节点共享同一个类加载器,这对于开发很有用,这时不同的开发者可以工作于同一个类的不同版本上。
自从@UserResource
注解删除后,PRIVATE和ISOLATED部署模式就没有不同了。这两个常量都因为后向兼容的原因保留了,并且这两个之一可能在未来的大版本中被删除。
这个模式中,当主节点离开集群时,类会卸载。
SHARED
这是默认的部署模式。这个模式中,来自不同主节点的、用户版本相同的类会在worker节点上共享同一个类加载器。当所有主节点离开网格或者用户版本发生变化时,类会卸载。这个模式可以使来自不同主节点的类在远程节点上共享用户资源的同一个实例(见下面)。这个模式对于产品环境特别有用,与ISOLATED
模式相比,它在单一主节点上有一个单一类加载器的作用域,SHARED
模式会向所有主节点扩展部署作用域。
这个模式中,当所有的主节点离开集群时,类会卸载。
CONTINUOUS
在CONTINUOUS
模式中,当主节点离开网格时类不会卸载。卸载只会发生于类的用户版本发生变化时。这个方式的优势是可以使来自不同主节点的任务在worker节点共享同一个用户资源的实例(参见资源注入),这使得在worker节点上执行的所有任务可以复用,比如,连接池或者缓存的同一个实例。当用这个模式时,可以启动多个独立的worker节点,在主节点定义用户资源并且在worker节点上初始化一次,不管他们来自那个主节点。与ISOLATED
部署模式相比,它在单一主节点上有一个单一类加载器的作用域,CONTINUOUS
模式会向所有主节点扩展部署作用域,这对于产品模式非常有用。
这个模式中,即使所有的主节点离开集群,类都不会卸载。
通过对等类加载获得的类定义,有他们自己的生命周期。在特定的事件中(当主节点离开或者用户版本变化,依赖于部署模式),类信息会从网格中卸载,类定义会从网格中的所有节点和用户资源抹掉,与该类链接的,也会有选择地抹掉(还是依赖于部署模式)。对于内存数据网格,还意味着一个卸载的类的所有缓存条目都会从缓存删除。然而,如果使用了二进制编组器,后者并不适用,它允许以二进制的形式存储缓存数据来避免从一个主节点加载条目的必要性。
当部署于SHARED
和CONTINUOUS
模式时,如果想重新部署类,用户版本来了。Ignite默认会自动检测类加载器是否改变或者一个节点是否重新启动。然而,如果希望在节点的一个子集上改变或者重新部署代码,或者在CONTINUOUS
模式中,杀掉所有的现存部署,那么需要修改用户版本。
用户版本是在类路径的META-INF/ignite.xml
中指定的,像下面这样:
<!-- User version. -->
<bean id="userVersion" class="java.lang.String">
<constructor-arg value="0"/>
</bean>
所有的Ignite启动脚本(ignite.sh或者ignite.bat)默认都会从IGNITE_HOME/config/userversion
文件夹获取用户版本。通常,在这个文件夹中更新用户版本就够了,然而,当使用GAR或者JAR部署时,需要记得提供一个META-INF/ignite.xml
文件,里面有期望的用户版本。
下面的对于对等类加载的配置参数可以在IgniteConfiguration
中进行可选的配置:
setter方法 | 描述 | 默认值 |
---|---|---|
setPeerClassLoadingEnabled(boolean) |
启用/禁用对等类加载 | false |
setPeerClassLoadingExecutorService(ExecutorService) |
配置对等类加载使用的线程池,如果未配置,会使用一个默认的。 | null |
setPeerClassLoadingExecutorServiceShutdown(boolean) |
对等类加载ExecutorService关闭标志,如果该标志设置为true,对等类加载线程池当节点停止时会强制关闭。 | true |
setPeerClassLoadingLocalClassPathExclude(String...) |
系统类路径的包列表,即使他们在本地存在,P2P也不会加载。 | null |
setPeerClassLoadingMissedResourcesCacheSize(int) |
错过的资源缓存的大小,设为0会避免错过的资源缓存。 | 100 |
setDeploymentMode(DeploymentMode) |
为部署的类和任务设置部署模式。 | SHARED |
XML:
<bean class="org.apache.ignite.configuration.IgniteConfiguration">
<!--
Explicitly enable peer class loading. Set to false
to disable the feature.
-->
<property name="peerClassLoadingEnabled" value="true"/>
<!-- Set deployment mode. -->
<property name="deploymentMode" value="CONTINUOUS"/>
<!-- Disable missed resources caching. -->
<property name="peerClassLoadingMissedResourcesCacheSize" value="0"/>
<!--
Exclude force peer class loading of a class,
even if exists locally.
-->
<property name="peerClassLoadingLocalClassPathExclude">
<list>
<value>com.mycompany.MyChangingClass</value>
</list>
</property>
</bean>
Java:
IgniteConfiguration cfg=new IgniteConfiguration();
// Explicitly enable peer class loading.
cfg.setPeerClassLoadingEnabled(true);
// Set deployment mode.
cfg.setDeploymentMode(DeploymentMode.CONTINUOUS);
// Disable missed resource caching.
cfg.setPeerClassLoadingMissedResourcesCacheSize(0);
// Exclude force peer class loading of a class,
// even if it exists locally.
cfg.setPeerClassLoadingLocalClassPathExclude("com.mcompany.MyChangingClass");
// Start a node.
Ignition.start(cfg);