2016-06-20 69 views
1

我使用LruEvictionPolicy嘗試使用Apache Ignite 1.6緩存數據。我編寫了一些測試代碼來觀察緩存行爲(對於進程緩存中的Apache Ignite/Redis/Memcached/.NET)。我正在使用Win10/VS2015。Apache Ignite在使用驅逐策略時使用OOM

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的緩存數據仍在緩存中。這就是我想要的/預期的行爲,但使用太多的內存。

有沒有減少使用內存的方法?

回答

1

簡答:請勿將CopyOnRead設置爲false。默認爲true


更詳細的解釋:

設置CopyOnReadfalse導致了兩個序列化和反序列化值存儲在內部。這可能會在某些情況下提高性能,但會增加內存使用量。

另外,當CopyOnRead爲falsehttps://issues.apache.org/jira/browse/IGNITE-3347)時,存在EvictionPolicy錯誤地計算內存大小的錯誤。

此外,不要期望將JvmMaxMemoryMbEvictionPolicy.MaxMemorySize設置爲相同的值將起作用:Ignite需要備用內存用於內部目的,並且JVM GC可以高效工作。

+0

我在運行oom時使用了不同的值作爲最大堆大小(高達5GB)。將CopyOnRead設置爲true解決了問題。謝謝。 –

相關問題