ignite学习笔记
1、一个Ignite节点可以从命令行启动,可以用默认的配置也可以传递一个配置文件。可以启动很多很多的节点然后他们会自动地发现对方。
2、Ignite只需要一个ignite-core强依赖,通常你还需要添加ignite-spring,来做基于spring的XML配置,还有ignite-indexing,来做SQL查询。
3、由于Ignite的零部署特性,当从IDE运行上面的程序时,远程节点没有经过显示的部署,就获得了计算作业。
4、导入独立模块。
ignite-spring:基于Spring的配置支持
ignite-indexing:SQL查询和索引
ignite-geospatial:地理位置索引
ignite-hibernate:Hibernate集成
ignite-web:Web Session集群化
ignite-schedule:基于Cron的计划任务
ignite-log4j:Log4j日志
ignite-jcl:Apache Commons logging日志
ignite-jta:XA集成
ignite-hadoop2-integration:HDFS2.0集成
ignite-rest-http:HTTP REST请求
ignite-scalar:Ignite Scalar API
ignite-slf4j:SLF4J日志
ignite-ssh;SSH支持,远程机器上启动网格节点
ignite-urideploy:基于URI的部署
ignite-aws:AWS S3上的无缝集群发现
ignite-aop:网格支持AOP
ignite-visor-console:开源的命令行管理和监控工具
5、有时可能希望在Ignite节点启动和停止的之前和之后执行特定的操作,这个可以通过实现LifecycleBean接口实现,然后在spring的配置文件中通过指定IgniteConfiguration的lifecycleBeans属性实现。
6、支持的事件(这些事件也是可以被监听的)
BEFORE_NODE_START:Ignite节点的启动程序初始化之前调用
AFTER_NODE_START:Ignite节点启动之后调用
BEFORE_NODE_STOP:Ignite节点的停止程序初始化之前调用
AFTER_NODE_STOP:Ignite节点停止之后调用
7、Ignite API中的所有分布式方法都既可以同步执行也可以异步执行。
8、IgniteAsyncSupport接口为很多Ignite API提供了异步模型,比如,IgniteCompute,IgniteServices,IgniteCache以及IgniteTransactions,都实现了IgniteAsyncSupport接口。
要启用异步模式,需要调用withAsync()方法,他会返回同样API的实例,这样的话,异步功能就启用了。
如果异步功能启用了,实际的同步方法的返回值就被忽略了,异步操作中获得返回值的唯一方式是通过future()方法。
9、Ignite有一个可选的概念,就是客户端节点和服务器端节点,服务器节点参与缓存,计算,流式处理等等,而原生的客户端节点提供了远程连接服务器的能力。
10、当在Ignite中创建缓存时,不管是通过XML方式,还是通过Ignite.createCache(...)或者Ignite.getOrCreateCache(...)方法,Ignite会自动地在所有的服务端节点中部署分布式缓存。
11、IgniteCompute默认会在所有的服务端节点上执行作业,然而,也可以通过创建相应的集群组来选择是只在服务端节点还是只在客户端节点上执行作业。
12、要管理这些状况(客户端卡慢),可以配置允许向客户端节点输出消息的最大值,如果输出队列的大小超过此值,该客户端节点会从集群断开以防止拖慢整个集群。
13、Ignite的唯一特点是所有节点都是平等的。没有master节点或者server节点,也没有worker节点或者client节点,按照Ignite的观点所有节点都是平等的。但是,开发者可以将节点配置成master,worker,或者client以及data节点。
所有集群节点启动时都会自动将所有的环境和系统属性注册为节点的属性,开发者也可以通过配置自定义节点属性。
14、可以基于一些谓词定义动态集群组,这个集群组只会包含符合该谓词的节点。
下面是一个例子,一个集群组只会包括CPU利用率小于50%的节点,注意这个组里面的节点会随着CPU负载的变化而改变。
15、很多系统选举领导者通常要处理数据一致性,然后通常是通过收集集群成员的选票处理的。而在Ignite中,数据一致性是通过数据网格的类似功能处理的(Rendezvous Hashing或者HRW哈希),选择领导者在传统意义上的数据一致性,在数据网格以外就不是真的需要了。
然而,可能还是希望有一个协调员节点来处理某些任务,为了这个,Ignite允许在集群中自动地选择最老的或者最新的节点。
16、Ignite中,通过DiscoverySpi节点可以彼此发现对方,Ignite提供了TcpDiscoverySpi作为DiscoverySpi的默认实现,它使用TCP/IP来作为节点发现的实现,可以配置成基于多播的或者基于静态IP的。
17、Docker允许将Ignite应用及其所有的依赖打包进一个标准的容器,Docker会自动下载Ignite发布版,将代码部署进Ignite以及配置节点,他还可以自动启动配置好的Ignite节点,这样的集成使只需要简单地重启Ignite Docker容器就可以部署新的节点。
18、Ignite数据网格支持本地、复制的、分区化的数据集,允许使用标准SQL语法方便地进行跨数据集查询,同时还支持在内存数据中进行分布式SQL关联。
19、Ignite实现了JCache(JSR107)规范(持久化存储)。
20、Ignite提供了三种不同的缓存操作模式,分区、复制和本地。(三种各有优劣)
21、CacheWriteSynchronizationMode枚举可以用来配置主节点和备份部分的同步和异步更新。
21、对于SQL查询,Ignite提供了内存内的索引,因此所有的数据检索都是非常快的,如果是在堆外内存中缓存数据的,那么查询索引也会缓存在堆外内存中。
22、Ignite对SQL查询的支持几乎没有任何限制,语法兼容于ANSI-99,可以使用任何SQL函数,聚合以及分组,Ignite会找出从哪里获得查询结果。(可以跨缓存查询)
23、持续查询对于当执行一个查询之后希望持续地获得该查询结果数据更新的通知时,是很有用的。 持续查询是通过ContinuousQuery类实现的
24、鉴于分区缓存是最常见的缓存数据的方式,那么数据和计算以及数据和数据的并置就可以显著地提升性能和应用的可扩展性。
在许多情况下,如果不同的缓存键被同时访问的话那么将他们并置在一起是很有利的。通常来说业务逻辑需要访问不止一个的缓存键,通过将他们并置在一起可以确保所有的键具有缓存在同一个处理节点上的同一个affinityKey,从而避免从远程节点获取数据的昂贵网络开销。
例如,有一个Person和Company对象,然后希望将Person对象和其工作的Company对象并置在一起。对于一个键类型有两种声明关系键的方式。
25、虽然Ignite可以单独地配置CacheRLoader和CacheWriter,但是在两个单独的类中实现事务化存储是非常尴尬的,因为多个load和put操作需要在同一个事务中的同一个连接中共享状态。为了缓解这个问题,Ignite提供了·org.apacche.ignite.cache.store.CacheStore·接口,他同时扩展了CacheLoader和CacheWriter。当希望通读和通写时,提供一个正常的缓存存储的实现是很重要的。通读意味着当缓存无效时会从持久化存储中读取,通写意味着当缓存更新时会自动地进行持久化。所有的通读和通写都会参与整体的缓存事务以及作为一个整体提交或者回滚。
要配置通读和通写,需要实现CacheStore接口以及设置CacheConfiguration中cacheStoreFactory的readThrough和writeThrough属性,下面的例子会有说明。
26、数据加载通常用于启动时初始化缓存数据,用标准的缓存put(...)和putAll(...)操作通常加载大量的数据是比较低效的。数据流处理器是通过IgniteDataStreamerAPI定义的,他可以将大量的连续数据注入Ignite缓存。数据流处理器以可扩展和容错的方式在数据被发送到集群节点之前通过把定量数据放在一起以获得高性能。
数据流处理器可以用于任何时候将大量数据载入缓存,包括启动时的预加载。
将大量数据载入缓存的另一个方法是通过CacheStore.loadCache()方法,他可以在不传入要加载的所有键的情况下进行缓存的数据加载。
27、数据流处理器是通过IgniteDataStreamerAPI定义的,他可以往Ignite数据流缓存中注入大量的持续不断的数据流,数据流处理器对于所有流入Ignite的数据以可扩展和容错的方式提供了至少一次保证。
28、滑动窗口可以和任何其他Ignite缓存以同样的方式进行查询,可以使用基于谓词的,基于SQL的和基于文本的查询。
29、Ignite除了提供了标准的键-值的类似于Map的存储以外,也提供了一个快速的分布式阻塞队列和分布式集合的实现。
IgniteQueue和IgniteSet分别是java.util.concurrent.BlockingQueue和java.util.Set接口的实现,也支持java.util.Collection接口的所有功能,这两个实现既可以以并置模式也可以以非并置模式创建。
30、分布式计算是通过以并行的方式执行来获得高性能、低延迟和线性可扩展。Ignite计算网格提供了一套简单的API,使得可以在集群内的多台计算机上执行分布式计算和数据处理。分布式并行处理是基于在任何集群节点集合上进行计算和执行然后将结果返回的能力实现的。
31、Ignite计算网格可以对集群或者集群组内的任何闭包进行广播和负载平衡,包括纯Java的runnables和callables。
32、ComputeTask是Ignite对于简化内存内MapReduce的抽象,这个也非常接近于ForkJoin范式,纯粹的MapReduce从来不是为了性能而设计,只适用于处理离线的批量业务处理(比如Hadoop MapReduce)。然而,当对内存内的数据进行计算时,实时性低延迟和高吞吐量通常具有更高的优先级。同样,简化API也变得非常重要。考虑到这一点,Ignite推出了ComputeTask API,它是一个轻量级的MapReduce(或ForkJoin)实现。
ComputeTask定义了要在集群内执行的作业以及这些作业到节点的映射,他还定义了如何处理作业的返回值(Reduce)。所有的IgniteCompute.execute(...)方法都会在集群上执行给定的任务,应用只需要实现ComputeTask接口的map(...)和reduce(...)方法即可。
33、每个任务执行时都会创建分布式任务会话,他是由ComputeTaskSession接口定义的。任务会话对于任务和其产生的所有作业都是可见的,因此一个作业或者一个任务设置的属性也可以被其他的作业访问。任务会话也可以在属性设置或者等待属性设置时接收通知。
34、通常来说在不同的计算作业或者不同的部署服务之间共享状态是很有用的,为此Ignite在每个节点上提供了一个共享并发node-local-map。
IgniteCluster cluster = ignite.cluster();
ConcurrentMap<String, Integer> nodeLocalMap = cluster.nodeLocalMap():
35、Ignite支持作业的自动故障转移,当一个节点崩溃时,作业会被转移到其他可用节点再次执行。然而在Ignite中也可以将任何作业的结果认为是失败的。工作的节点可以仍然是存活的,但是他运行在一个很低的CPU,I/O,磁盘空间等资源上,在很多情况下会导致应用的故障然后触发一个故障的转移。此外,也有选择一个作业故障转移到那个节点的功能,因为同一个应用内部不同的程序或者不同的计算也会是不同的。
36、负载平衡组件将作业在集群节点之间平衡分配。Ignite中负载平衡是通过LoadBalancingSpi获得的。它控制所有节点的负载以及确保集群中的每个节点负载水平均衡。对于同质化环境中的同质化的任务,负载平衡采用的是随机或者循环的策略。然而在很多其他场景中,特别是在一些不均匀的负载下,就需要更复杂的自适应负载平衡策略。
37、服务网格可以在集群上部署任意用户定义的服务,比如自定义计数器,ID生成器,分层映射等。
Ignite可以控制每个集群节点应该部署多少个服务的实例,可以自动地确保所有的服务正确地部署和容错。
所有的服务网格功能都是通过IgniteServices接口实现的。
38、Ignite分布式消息可以在集群内的所有节点间进行基于主题的通信,带有特定消息主题的消息可以分布到订阅了该主题的所有节点或者节点的子集。
Ignite消息基于发布-订阅范式,发布者和订阅者通过一个通用的主题连接在一起。当一个节点针对主题T发布了一个消息A,他会被分布到所有订阅了主题T的节点。
39、gnite分布式事件功能使得在分布式集群环境下发生各种各样事件时应用可以接收到通知。可以自动获得比如任务执行、发生在本地或者远程节点上的读写或者查询操作的通知。
分布式事件功能是通过IgniteEvents接口提供的,可以通过如下方式从Ignite中获得IgniteEvents的实例
40、Ignite会自动地对集群内发生的,作为缓存事件的结果生成的事件通知进行分组或者分批处理。
缓存内的每个事件都会导致一个事件通知被生成以及发送,对于缓存活动频繁的系统,获取每个事件的通知都将是网络密集的,可能导致集群内缓存操作的性能下降。
Ignite中,事件通知可以被分组然后分批地或者定时地发送
41、Ignite提供了一个HTTP REST客户端,可以以REST的方式通过HTTP或者HTTPS协议与集群进行通信。REST API可以用于执行不同的操作,比如从/对缓存的读/写,执行任务,获取各种指标等等。
42、Ignite有一个独特的功能,叫做Ignite文件系统(IGFS),就是一个分布式的内存文件系统,IGFS提供了和Hadoop HDFS类似的功能,但是只在内存中。事实上,除了他自己的API,IGFS还实现了Hadoop的文件系统API,可以透明地加入Hadoop或者Spark的运行环境。
43、Ignite Hadoop加速器提供了一个叫做IgniteHadoopFileSystem的Hadoop兼容IGFS实现,Hadoop可以以即插即用的形式运行在这个文件系统上,然后显著地减少了I/O和改善了延迟和吞吐量。
优化:
1、Ignite有丰富的事件系统来向用户通知各种各样的事件,包括缓存的修改,退出,压缩,拓扑的变化以及很多其他的。因为每秒钟可能产生上千的事件,他会对系统产生额外的负载,这会导致显著地性能下降。因此,强烈建议只有应用逻辑必要时才启用这些事件。默认的话,事件通知是禁用的。
2、就大小和容量而言,Ignite的内部缓存映射行为非常像正常的Java HashMap。他有一些初始的容量(默认都非常小),是持有数据的两倍,内部缓存映射的大小调整过程是CPU密集以及费时的,如果往缓存中加载大量的数据集(这是正常的使用场景),这个映射就会频繁地调整大小。要避免这个问题,可以比对预期的数据集大小指定初始的缓存映射容量,这会在加载期间节约大量的CPU资源,因为映射不需要重新调整大小了。比如如果希望在缓存中加载一亿的数据,可以用如下的配置:
3、如果使用了分区缓存,而且数据丢失并不是关键(比如,当有一个备份缓存存储时),可以考虑禁用分区缓存的备份。当备份启用时,缓存引擎会为每个条目维护一个远程拷贝,这需要网络交换和而且是耗时的。要禁用备份,可以使用如下的配置:
4、如果打算为了缓存数据为JVM分配大量的内存(通常大于10G的内存),那么应用很可能会遭遇长时间的GC暂停,他会显著地增加延时。要避免GC暂停可以使用堆外内存来缓存数据-实际上数据仍然换存在内存中,但是JVM并不知道他而且GC也不起作用。要启用不限大小的堆外存储,可以使用如下的配置:
5、如果需要往缓存中加载大量的数据,可以使用IgniteDataStreamer来实现,数据流处理器在将数据发送到远程节点之前会将数据正确地形成批次然后会正确地控制发生在每个节点的并发操作的数量来避免颠簸。通常他会比一堆单线程的操作有十倍的性能提升
6、如果能发送10个比较大的作业代替100个小些的作业,那么应该选择发送大些的作业,这会降低网络上传输作业的数量以及显著地提升性能。对于缓存的条目也是同样的问题-应该一直使用API方法,他会使用键和值的集合,而不是一个一个地传递。