【问题标题】:Hazelcast eviction is not working with FREE_HEAP_PERCENTAGE policyHazelcast 驱逐不适用于 FREE_HEAP_PERCENTAGE 政策
【发布时间】:2020-03-16 10:27:45
【问题描述】:

我正在使用 hazelcast 3.12.2 版本。下面是我使用的代码sn-p;

package com;

import com.hazelcast.config.Config;
import com.hazelcast.config.EvictionPolicy;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.MaxSizeConfig;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.map.listener.EntryEvictedListener;

public class HazelcastMaxSizeTest {

    private static final String GROUP_NAME = "TEST";

    private static final String MAP_NAME = "test";

    private static final String MAP_NAME1 = "test1";

    private static final String MAP_NAME2 = "test2";

    private static MaxSizeConfig POLICY_THAT_DOES_NOT_WORK = new MaxSizeConfig(
            20,
            MaxSizeConfig.MaxSizePolicy.FREE_HEAP_PERCENTAGE);

    public static void main(String[] args) throws Exception {

        HazelcastInstance instance = startHazelcast("hazelcast1", POLICY_THAT_DOES_NOT_WORK);
        System.out.println("started " + instance.getName());

        IMap<Long, byte[]> map = createMap(instance, MAP_NAME, 10000000);
        System.out.println("map size: " + map.size());

        IMap<Long, byte[]> map1 = createMap(instance, MAP_NAME1, 15000000);
        System.out.println("map1 size: " + map1.size());

        IMap<Long, byte[]> map2 = createMap(instance, MAP_NAME2, 20000000);
        System.out.println("map2 size: " + map2.size());

        instance.shutdown();
    }

    private static IMap<Long, byte[]> createMap(HazelcastInstance instance, String mapname, int bytes) {

        IMap<Long, byte[]> map = instance.getMap(mapname);

        map.addEntryListener(new EntryEvictedListener<Long, byte[]>() {

            @Override
            public void entryEvicted(EntryEvent<Long, byte[]> event) {
                System.out.println("evicted " + event.getName() + ": " + event.getKey());
            }

        }, false);

        for (long i = 1; i <= 10; i++) {
            map.set(i, new byte[bytes]);
        }

        return map;
    }

    private static HazelcastInstance startHazelcast(String instanceName, MaxSizeConfig maxSizeConfig) {

        MapConfig mapConfig = new MapConfig(MAP_NAME);
        mapConfig.setMaxSizeConfig(maxSizeConfig);
        mapConfig.setStatisticsEnabled(false);
        mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
        mapConfig.setMinEvictionCheckMillis(0L);
        mapConfig.setBackupCount(1);

        MapConfig mapConfig1 = new MapConfig(MAP_NAME1);
        mapConfig.setMaxSizeConfig(maxSizeConfig);
        mapConfig.setStatisticsEnabled(false);
        mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
        mapConfig.setMinEvictionCheckMillis(0L);
        mapConfig.setBackupCount(1);

        MapConfig mapConfig2 = new MapConfig(MAP_NAME2);
        mapConfig.setMaxSizeConfig(maxSizeConfig);
        mapConfig.setStatisticsEnabled(false);
        mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
        mapConfig.setMinEvictionCheckMillis(0L);
        mapConfig.setBackupCount(1);

        Config config = new Config(instanceName);
        config.addMapConfig(mapConfig);
        config.addMapConfig(mapConfig1);
        config.addMapConfig(mapConfig2);
        config.getGroupConfig().setName(GROUP_NAME).setPassword(GROUP_NAME);
        return Hazelcast.getOrCreateHazelcastInstance(config);
    }

}

当我尝试使用 450mb 堆空间运行上述代码时,最终会出现“内存不足”错误。经过调试,我知道即使使用的堆空间为 80%,驱逐也不起作用。如果我配置不正确,请告诉我。任何建议都会真正有帮助。

【问题讨论】:

    标签: heap-memory hazelcast hazelcast-imap


    【解决方案1】:

    此代码存在剪切和粘贴错误

            MapConfig mapConfig1 = new MapConfig(MAP_NAME1);
            mapConfig.setMaxSizeConfig(maxSizeConfig);
            mapConfig.setStatisticsEnabled(false);
            mapConfig.setEvictionPolicy(EvictionPolicy.LRU);
            mapConfig.setMinEvictionCheckMillis(0L);
            mapConfig.setBackupCount(1);
    

    应该是

            MapConfig mapConfig1 = new MapConfig(MAP_NAME1);
            mapConfig1.setMaxSizeConfig(maxSizeConfig);
            mapConfig1.setStatisticsEnabled(false);
            mapConfig1.setEvictionPolicy(EvictionPolicy.LRU);
            mapConfig1.setMinEvictionCheckMillis(0L);
            mapConfig1.setBackupCount(1);
    

    mapConfig2 也一样。

    虽然这不会阻止三张地图中的第一张需要驱逐。

    更新 1: 我可以让驱逐工作。您需要在创建 Hazelcast 实例之前设置它以容纳少量键:

            config.setProperty("hazelcast.partition.count", "1");
    

    然后试试这段代码,如果你将factor 设置为 2,它会起作用并且会发生驱逐,将其设置为 1,它不会。

            int factor = 2;
            byte[] value = new byte[bytes / factor];
            for (long i = 1; i <= 10 * factor; i++) {
                System.out.println("Write " + i + " size " + value.length + " to " + mapname + " free memory " +
                       (Runtime.getRuntime().freeMemory() / (1024 * 1024)) + "MB");
                map.set(i, value);
            }
    

    但是,当因子设置为 1 和 -Xmx512m -Xms512m 时,我会在 139MB 可用时获得 OOME。这超过了 20% 的可用堆空间,因此不适用驱逐。

    更新 2 我已经记录了这个问题https://github.com/hazelcast/hazelcast/issues/16760 您可以获得剩余内存充足的 OOME。这就是发生的事情 在这里,没有触发驱逐,因为可用内存高于 20% 配置好了。

    更新 3 这是一个 G1 问题,请参阅 Github 问题,空间很大。 您可以尝试调整、更改 GC 或轻松创建 10 倍大小的对象,这些对象的大小只有 1/10,然后问题就消失了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-13
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多