【问题标题】:Apache Ignite goes OOM while using Eviction PolicyApache Ignite 在使用驱逐策略时出现 OOM
【发布时间】:2016-06-20 15:45:45
【问题描述】:

我正在尝试使用 LruEvictionPolicy 使用 Apache Ignite 1.6 缓存数据。我编写了一些测试代码来观察缓存行为(用于进程缓存中的 Apache Ignite / Redis / Memcached / .NET)。我正在使用 Win10 / VS2015。

static void Main(string[] args)
    {

        // 64Bit -> size in memory for an atring = 26 + length * 2
        // using 512KB string
        StringBuilder builder = new StringBuilder(262131);
        for (int i = 0; i < 262131; i++)
        {
            builder.Append('G');
        }

        ICache cache;
        IList<bool> cacheMemTest;

        cache = new IgniteCache();
        cacheMemTest = TestCache(cache, builder.ToString(), 10);
        DrawResult(GetFilestreamForName("IgniteCache"), cacheMemTest);
    }

    private static IList<bool> TestCache(ICache cache, string testValue, int delay)
    {
        int numOfElements = 10000;
        for (int i = 0; i < numOfElements; i++)
        {
            var currentString = String.Copy(testValue);
            cache.AddValue(i.ToString(), currentString);
            currentString = null;
            GC.Collect();
        }

        IList<bool> boolList = new List<bool>(numOfElements);
        for (int i = 0; i < numOfElements; i++)
        {
            boolList.Add(cache.HasElement(i.ToString()));
        }

        return boolList;
    }

IgniteCach 类如下所示:

class IgniteCache : ICache, IDisposable
{

    private IIgnite _ignite;
    private Apache.Ignite.Core.Cache.ICache<string, string> _cache;

    public IgniteCache()
    {
        var conf = new IgniteConfiguration();
        //conf.JvmInitialMemoryMb = 512;
        //conf.JvmMaxMemoryMb = 1024;

        conf.JvmOptions = new string[] { "-XX:+UseParNewGC",
    "-XX:+UseConcMarkSweepGC",
    "-XX:+UseTLAB",
    "-XX:NewSize=128m",
    "-XX:MaxNewSize=128m",
    "-XX:MaxTenuringThreshold=0",
    "-XX:SurvivorRatio=1024",
    "-XX:+UseCMSInitiatingOccupancyOnly",
    "-XX:CMSInitiatingOccupancyFraction=60" };

        var cacheConf = new CacheConfiguration();
        cacheConf.CopyOnRead = false;
        cacheConf.EagerTtl = false;
        cacheConf.AtomicityMode = CacheAtomicityMode.Atomic;
        cacheConf.WriteBehindEnabled = false;
        cacheConf.EvictionPolicy = new Apache.Ignite.Core.Cache.Eviction.LruEvictionPolicy()
        {
            MaxMemorySize = 1073741824
        };

        cacheConf.Name = "cache";
        cacheConf.CacheMode = CacheMode.Local;
        cacheConf.Backups = 0;
        cacheConf.OffHeapMaxMemory = -1;
        cacheConf.EnableSwap = false;
        conf.CacheConfiguration = new List<CacheConfiguration>() { cacheConf };
        conf.DiscoverySpi = new TcpDiscoverySpi
        {
            IpFinder = new TcpDiscoveryStaticIpFinder
            {
                Endpoints = new[] { "127.0.0.1:47500" }
            },
            SocketTimeout = TimeSpan.FromSeconds(0.3)
        };

        _ignite = Ignition.Start(conf);
        TimeSpan timeSpan = new TimeSpan(6, 0, 0);
        _cache = _ignite.GetCache<string, string>("cache").WithExpiryPolicy(new Apache.Ignite.Core.Cache.Expiry.ExpiryPolicy(timeSpan, timeSpan, timeSpan));
    }

    public void AddValue(string key, string values)
    {
        _cache.Put(key, values);
    }

    public void Dispose()
    {
        _ignite.Dispose();
    }

    public string GetValue(string key)
    {
        if (HasElement(key))
        {
            return _cache.Get(key);
        }
        return null;
    }

    public bool HasElement(string key)
    {
        return _cache.ContainsKey(key);
    }
}

使用时和“conf.JvmMaxMemoryMb = 1024;”我会用完内存, LruEvictionPolicy 似乎什么都不做。删除 JVM 最大值。内存限制程序将在分配 ~5GB 时运行到最后。现在我正在检查结果:大约 2/5 的缓存数据仍在缓存中。这是我想要/预期的行为,但使用了太多内存。

有没有办法减少使用的内存?

【问题讨论】:

    标签: c# .net ignite


    【解决方案1】:

    简答:不要将CopyOnRead 设置为false。默认为true。


    更长的解释:

    将CopyOnRead 设置为false 会导致序列化和反序列化值都在内部存储。在某些情况下,这可能会提高性能,但会增加内存使用量。

    另外,当 CopyOnRead 为 false (https://issues.apache.org/jira/browse/IGNITE-3347) 时,EvictionPolicy 会错误地计算内存大小。

    此外,不要期望将 JvmMaxMemoryMb 和 EvictionPolicy.MaxMemorySize 设置为相同的值会起作用:Ignite 需要备用内存用于内部用途和 JVM GC 高效工作。

    【讨论】:

    • 我在运行 oom 时使用了不同的值作为最大堆大小(最大 5gb)。将 CopyOnRead 设置为 true 可以解决问题。谢谢。
    猜你喜欢
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 2020-02-08
    • 2020-07-10
    • 2020-07-03
    相关资源
    最近更新 更多