@aloxc
2017-12-05T06:34:40.000000Z
字数 2827
阅读 505
一起学
ignite
源码分析
这几天在学习ignite的内存管理,其中有说明为了减少jvm gc对缓存的影响,可以把缓存数据放到堆外内存中,具体配置如下相关的几项
<property name="memoryMode" value="OFFHEAP_TIERED"/>
<property name="offHeapMaxMemory" value="#{512 * 1000 * 1000}" />
<property name="swapEnabled" value="false"/>
<property name="expiryPolicy"></property>
<property name="evictionPolicy">
<bean class="org.apache.ignite.cache.eviction.lru.LruEvictionPolicy">
<property name="maxSize" value="100001"/>
</bean>
</property>
1、memoryMode设置缓存使用什么内存模式,有三个选项:ONHEAP_TIERED保存在堆内,逐出到堆外以及可选的存储在交换空间;OFFHEAP_TIERED保存在堆外,避开堆内以及可选的逐出到交换空间;OFFHEAP_VALUES将键存储在堆内,将值存储在堆外。
2、offHeapMaxMemory(单位字节)设置为-1时SQL索引会保存在堆上,否则会一直使用堆外索引。要注意这是打开和关闭堆外索引的唯一属性,默认值-1保存到堆上。当打开堆外功能时要提高SQL查询的性能,可以试着增加CacheConfiguration.setSqlOnheapRowCacheSize()属性的值,他的默认值是10000.
3、swapEnabled是否允许使用交换存储,默认值false不允许,记住使用交换存储会显著影响性能。所以一般不建议设置为true
4、evictionPolicy逐出策略,默认是禁止不做逐出处理,如果确实需要使用退出来确保缓存的数据不会增长到超过允许的内存限额,可以考虑选择正确的逐出策略。可以设置这几种LruEvictionPolicy最近最少使用;FifoEvictionPolicy先进先出;SortedEvictionPolicy有序;RandomEvictionPolicy随机,我们也可以设置自己定义的逐出策略(需要实现EvictionPolicy接口),
5、expiryPolicy过期策略。
测试过程中发现一些问题,可能是我配置不对,我还在测试中,
<property name="cacheMode" value="PARTITIONED"/>
<property name="name" value="benchmark4"/>
<property name="offHeapMaxMemory" value="#{524 * 1000 * 1000}" />
<property name="backups" value="0"/>
<property name="memoryMode" value="OFFHEAP_TIERED"/>
<property name="swapEnabled" value="false"/>
<property name="startSize" value="#{3 * 1000 * 1000}"/>
<property name="evictionPolicy">
<bean class="org.apache.ignite.cache.eviction.lru.LruEvictionPolicy">
<property name="maxSize" value="100001"/>
</bean>
</property>
ignite启动脚本中设置了xmx1g,启动后进程信息为
root 31919 100 88.5 6941836 3475148 pts/0 Sl+ 14:42 29:02 /usr/java/jdk1.8.0_111/bin/java -Xms1g -Xmx1g -server -XX:+AggressiveOpts -XX:MaxMetaspaceSize=256m -DIGNITE_QUIET=true -DIGNITE_SUCCESS_FILE=/usr/java/ignite/work/ignite_success_67ba90ea-10b7-40dd-8fa4-57aa4da90427 -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=9988 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.16.69 -DIGNITE_HOME=/usr/java/ignite -DIGNITE_PROG_NAME=/usr/java/ignite/bin/ignite.sh -cp /usr/java/ignite/libs/:/usr/java/ignite/libs/ignite-indexing/:/usr/java/ignite/libs/ignite-spring/:/usr/java/ignite/libs/licenses/ org.apache.ignite.startup.cmdline.CommandLineStartup config/default-config.xml
我启动了一个数据写入程序,往ignite一直插入数据,当程序运行一段时间后ignite进程会被os killed掉,查询os的/var/log/message
发现如下日志
Dec 26 14:54:46 bbs_192 kernel: Out of memory: Kill process 31919 (java) score 796 or sacrifice child
Dec 26 14:54:46 bbs_192 kernel: Killed process 31919, UID 0, (java) total-vm:7064264kB, anon-rss:3480232kB, file-rss:1372kB
提示的很明显了,内存溢出。再次重启ignite服务,并且重启插入数据的程序,观察ignite服务的jvm情况,的确堆内存没有超过1g,但是通过top查看os的进程信息,发现java所占res内存远远超过1g,当res达到最大可用内存的时候os就又把ignite的服务进程杀掉了,这是为什么?我都设置了使用堆外内存并且设置最大ignite允许最大堆外内存约为520兆,为什么通过top查看os中所有进程的时候发现java的res远远大于520兆