一.写在开头
1. 系统采用了Apache Ignite 2.3.0版本,JDK1.8,主要用到功能:分布式,堆外内存,SQL语法,持久化,数据过期,可内嵌。功能多,方便后期扩展。
2. Ignite基础学习,请参看https://www.zybuluo.com/liyuj/note/230739,
或者官网https://ignite.apache.org/
3. 本文列出一些使用上遇到的问题与总结。
4. 我们使用了Ignite的如下特性:
1) 使用off-heap缓存:避免gc停顿。
2) 固化内存可设置堆外内存使用阈值,随着历史地址的增多,系统内存被耗尽时,因持久化特性,固化内存会在内存中保留热数据,自动地将冷数据移出内存到磁盘
3) 使用持久化:宕机无须担心历史数据丢失,重启无须初始化。
4) 使用集群:可自动同步节点中的数据,可自动发现新机器,方便扩展,提升性能。
5) 使用固化内存的“复制”模式,只查询本机,占用内存大,但是性能好。
6) H2内置数据库,以标准SQL语法存储和查询数据,且能自定义SQL函数,便于应付不同规则,还可通过外部工具查询内置数据库。
7) 对于客户环境,程序能自检出建议调优的系统配置项
二.分布式
SQL表ID自增
分布式如何做到id的自增?
IgniteCacheAtomicSequence接口提供的分布式原子性序列类似于分布式原子性的long类型,但是它的值只能增长。他也支持预留一定范围的序列值,来避免每次一个序列必须提供下一个值时导致的昂贵的网络消耗以及缓存更新。
2.2版本测试时,发现IgniteCacheAtomicSequence会出现数据不同步的问题,2.3版本未测试出来,已经解决。请注意它在close时会删除缓存的。springboot中可设置这个bean的destroyMethod = ""
通讯队列
Message queue limit is set to 0 which may lead to potential OOMEs
when running cache operations in FULL_ASYNC or PRIMARY_SYNC modes
due to message queues growth on sender and receiver sides.
我的理解:可以不管这个警告,如果运维中发现负载高,导致队列大,占用内存多,应该考虑分流出去,而不是去限制队列大小,来牺牲接口延时或者负载能力。现实情况是,客户可能提供内存刚刚够用的机器,那么如果要保证系统稳定运维,必须设置这个参数,来避免突然的访问洪流导致系统的奔溃。
看了源码,可设置如下,其值使用时需要32*128=4096,这是最小队列值。先做下测试观察下
ipCom.setMessageQueueLimit(32);//same as DFLT_ACK_SND_THRESHOLD
slowClientQueueLimit
慢节点的数据同步队列阈值,如果配置了该值,且待发送数据大于该值,则会丢弃远端节点。
默认不开启该功能
静态IP查找和组播查找
TcpDiscoveryMulticastIpFinder();//组播查找
TcpDiscoveryVmIpFinder();//静态ip查找
使用细节说明:
1) 组播查找:是会自动发现并连接上网络可达的Ignite节点。Ignite的默认IP搜索器。服务器网络有可能组播被禁用的情况,这时候只能使用静态ip查找。对应想隔离的Ignite集群,也需要使用静态ip查找。
2) 静态ip查找:只需知道节点ip和port就能连接组成集群了。
3) 对于本地端口侦听LocalPortRange,建议设置0,默认是20,它会从setLocalPort开启尝试绑定端口,那么每次启动服务可能用于连接的port会不同,并且原生持久化的文件夹会不同,导致无法重用之前的持久化数据。
三.固化内存
过期策略
过期策略可以在CacheConfiguration
中进行设置,这个策略可以用于缓存内的所有条目。
cfg.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.ZERO));
也可以在对缓存进行单独操作时对过期策略进行设置或者修改。
1. IgniteCache<Object, Object> cache = cache.withExpiryPolicy(
2. new CreatedExpiryPolicy(new Duration(TimeUnit.SECONDS, 5)));
注意:过期策略,如果开启了持久化,那么第二种方式在重启系统后,会把之前过期退出内存的数据,但是在磁盘的数据重新load到缓存,并且不会退出。而第一种方式,在重启后是不会load这部分过期数据的。
设置固化内存大小(堆外内存)
当没有开启持久化时,内存不足时会抛出异常。
Not enough memory allocated (consider increasing memory policy size or enabling evictions) [policyName=default, size=100.0 MB]
解决方案:1.调大固化内存;2.设置setPageEvictionMode;3.开启持久化。
当开启原生持久化时,多出的数据会被写入磁盘,出现如下信息,说明堆外内存已经存不下:
WARN 10996 --- [io-17103-exec-1] o.a.i.i.p.c.p.pagemem.PageMemor