Shared Cache Performance

Topics: Developer Forum
Feb 3, 2009 at 7:36 PM
Hi,

I have evaluating the Shared Cahce Performance

I have return simple problem that put the data in the cache and gets from the cache. But get call for 1000 keys its taking 300 ms it is every expensive.
Please let me know if i am doing some thing wrong here.

 

for (int i = 0; i < 6000; i++){

 

 

IndexusDistributionCache.SharedCache.Add(i + "", i+"");
}

 

 

for (int j = 0; j < 1000; j++)

 

{

 

string gotten = (String)IndexusDistributionCache.SharedCache.Get(j + "");

 

}

 

 

Coordinator
Feb 3, 2009 at 9:50 PM
hi, thanks for your post. did you try to run the test client? maybe you can mail me your result's then we able to compare between. it would be good if you could send me also the system details (OS, RAM, Shared Cache single instance, dist / rep)

regards, roni
Feb 4, 2009 at 2:21 AM
Please try code from ron that is posted here http://www.codeplex.com/SharedCache/Thread/View.aspx?ThreadId=44779
Feb 4, 2009 at 5:10 AM
unable to download from this link

http://uploading.com/files/L4WI2TII/ConsoleTest%20-%20Sc_3.0.5.0.zip.html
Coordinator
Feb 4, 2009 at 6:43 AM
please try this one: http://www.ronischuetz.com/code/ConsoleTest_-_Sc_3.0.5.0.zip

Feb 4, 2009 at 10:55 AM
Thanks for the sample.

Here are the results from the sample

Time taken to insert 1000 entries into the cache 657 ms
Time taken to get 1000 entries from cache 312 ms

What we are looking is 1000 less than 0 to 15 ms (JBoss Cache is giving this for java)

Please help me in getting this numbers using SharedCache.

Tesing on the below config system
OS - Windows XP
3.00 GB of RAM

thanks
Anil
Feb 4, 2009 at 11:47 AM
Just to Add for the above mail. What i observed is GetAllKeys taking less time.

Get and Put is taking time because of the serializationa and deserialization. 

Please let me know your thoughts on this.
Coordinator
Feb 4, 2009 at 5:19 PM
can you post please your Program.cs file?  i would like to run and compare the same code base from your measurement.

thanks, roni
Feb 4, 2009 at 5:32 PM
Edited Feb 4, 2009 at 5:34 PM

Its the same code that i have download from the site

using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;

using CACHE = SharedCache.WinServiceCommon.Provider.Cache.IndexusDistributionCache;
using System.Windows.Forms;

namespace Sc_3._0._5._0
{
 class Program
 {
  static void Main(string[] args)
  {
   Console.WriteLine("Start Test");
   Console.WriteLine("Clear Cache");
   CACHE.SharedCache.Clear();
            long s = CurrentTimeMillis();
   for (int i = 0; i < 1000; i++)
   {
    //Console.Write("Add Data " + i.ToString() + ": ");
    string dataToAdd = string.Format("some numers to add, {0}, {1}, {2}", i, i*4, i*5);
                CACHE.SharedCache.Add("Cache-" + i, dataToAdd);
                //Console.Write(recievedData);
                //Console.WriteLine();
   }

            Console.WriteLine("Time taken to insert 1000 keys " + (CurrentTimeMillis() - s));
            long s1 = CurrentTimeMillis();
            List<string> keys = CACHE.SharedCache.GetAllKeys();
            //Console.WriteLine("Receiving all Keys from Cache {0}", keys.Count);

   foreach (string item in keys)
   {
                string value = CACHE.SharedCache.Get<string>(item);
            }
            Console.WriteLine("Time taken to get 1000 keys " + (CurrentTimeMillis() - s1));

   CACHE.SharedCache.Clear();
   Console.WriteLine("Clear Cache");
   Console.WriteLine("End Test");
   Console.ReadLine();
  }

        private static long CurrentTimeMillis()
        {
            DateTime UTCBmgreTine = new DateTime(1970, 1, 1, 0, 0, 0, 0, new System.Globalization.GregorianCalendar(), DateTimeKind.Utc);
            long dt = (DateTime.UtcNow.Ticks - UTCBmgreTine.Ticks) / TimeSpan.TicksPerMillisecond;
            return dt;
        }

 }
}

Coordinator
Feb 4, 2009 at 8:24 PM
this are the results i get when i run the program.cs
you posted above and the default configuration from the download.

Start Test
Clear Cache
Time taken to insert 1000 keys 625
Time taken to get 1000 keys 610
Clear Cache
End Test

how your numbers are looking like?
Coordinator
Feb 4, 2009 at 8:34 PM
p.s. about your statement in previous post: "What we are looking is 1000 less than 0 to 15 ms (JBoss Cache is giving this for java)"

it's hard for me to compare this to JBoss since i do not know the how you done the test and how you configured JBoss. It has a reach possibility to cache data also in process and stuff like this so it would be helpful to know more details for your test cases.

regards, roni

Feb 5, 2009 at 1:17 AM
There are some things I don't like about this test. One is that there is a String.Format command inside the "timer" area. The other is that there is math going on inside the "timer" area as well. Third is that there is a string + occuring inside the "timer" area.

If I may make a suggestion:

Fill a collection with the proposed data ahead of time. Iterate that collection. Something like:

long addTime;
Dictionary<string,string> data .... fill with data

foreach (string key in data.Keys)
{
long start = CurrentTimeMillis();
CACHE.Add(key, data[key]);
long end = CurrentTimeMilis();
addTime += end - start;
}

Since we are talking about milliseconds and ticks, every operation is important for the overall time impact.



Feb 5, 2009 at 5:42 AM
JBoss supports inmemory(i.e jvm heap memory) as well as secondary memory like disk and database.
We have tested with inmemory and we have seen its given less than 0 ms to 15 ms for 1000 entries.
One more important thing we can set syncronization level for different cache instances(lock acquizations on instance) to differet levels.
We are using "NONE" means no locks(i.e no syncronization).
 
thanks
Anil
Coordinator
Feb 5, 2009 at 11:12 AM
based on our msn discussion i understand we cannot compare beteween the jboss cache which support in-process caching and shared cache which supports and were created for out-of-process caching. as we discussed - I gone provide you a small POC which can simpulate local / distributed caching behaviours.

regards, roni
Coordinator
Feb 5, 2009 at 8:36 PM
Edited Feb 5, 2009 at 8:41 PM
hi anil,

as promissed today you can download a small POC from the following url: http://www.ronischuetz.com/code/SharedCacheWrapper.zip (this wrapper code is based on release 3.0.5.0 which were releases on jan 18th)

i'm not really sure if this is the right way to combine between local & remote (distributed) caching because in case data get updated all your local cache entries are not up to date but this depends on your usecase.

the output of this program looks like this:

**************************************************************************************

This test program presents a combination between in-process caching and out-of-process caching.
Please consolidate your needs if you really want to use this approach
Creating 1000 strings
Time (ms) to add Data to local cache: 31
Press enter to read data from local cache

Time (ms) to read Data from local cache: 0
Press enter to add data to shared cache

Time (ms) to add Data to shared cache: 625
Press enter to read data from shared cache

Time (ms) to read Data from shared cache: 531
Press enter to combine between local and shared cache

Time (ms) to add Data to local + shared cache: 531
Press enter to remove mod 2 key's from local cache, so 50% of the keys will be readed from local cache and 50% from shared cache

Mod 2 key's removed from local cache

Time (ms) to read Data from local + shared cache: 265
End of Test - press enter to exit.

**************************************************************************************

if you have questions / suggestions / inputs about it let me know.

i hope this helps you to make your evaluations for shared cache. if you need further assistance or you have an inquiry then feel free to post it or to contact me direclty.

regards,
roni

Feb 6, 2009 at 1:38 AM
I did some performance testing today and got an average of 1.2ms get, 1.8ms put in a 2 server cluster on average hardware with a 32K object over 100 iterations. I might add that this was faster than both nCache and Microsoft Velocity.

On Thu, Feb 5, 2009 at 1:42 AM, akandach <notifications@codeplex.com> wrote:

From: akandach

JBoss supports inmemory(i.e jvm heap memory) as well as secondary memory like disk and database.
We have tested with inmemory and we have seen its given less than 0 ms to 15 ms for 1000 entries.
One more important thing we can set syncronization level for different cache instances(lock acquizations on instance) to differet levels.
We are using "NONE" means no locks(i.e no syncronization).
thanks
Anil

Read the full discussion online.

To add a post to this discussion, reply to this email (SharedCache@discussions.codeplex.com)

To start a new discussion for this project, email SharedCache@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com




--
"Maybe Jesus was right when he said that the meek shall inherit the earth—but they inherit very small plots, about six feet by three." --Robert A. Heinlein
Feb 6, 2009 at 2:47 AM
Mike

Can you send me your code and config file. so that i can test the same from side.
100 iterations and average of 1.2ms get, 1.8ms put in a 2 server cluster is good number.
Can you test the same with 1000 and 10000 iterations also and tell me the number.

Send me the same test code that you used. What the version of SharedCache you are using.

thanks
Anil
Feb 6, 2009 at 3:35 AM
CACHE.SharedCache.RegexGet this API is faster compared to single Get or MultiGet.

But even MultiAdd is slow. If we can get other APIs also like RegexGet then it will be great.
Feb 10, 2009 at 1:29 PM
This is pretty much what my (larger) test application is doing:

using System;
using System.Text;
using MergeSystem.Indexus.WinServiceCommon.Provider.Cache;

namespace AopCacheTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // Test iterations
            int iterations = 1000;

            // Object size in bytes
            int testObjectByteSize = 32768;

            if (args.Length > 0)
            {
                int tmp;
                if (int.TryParse(args[0], out tmp))
                {
                    iterations = tmp;
                }
                if (args.Length == 2)
                {
                    int tmpSize;
                    if (int.TryParse(args[1], out tmpSize))
                    {
                        testObjectByteSize = tmpSize;
                    }
                }
            }
            const string cacheKey = "CACHEKEY";
            double getsTotalTime = 0;
            double setsTotalTime = 0;

            // Test Object
            
            StringBuilder sb = new StringBuilder();
            do
            {
                sb.Append("F");
            } while (sb.Length < testObjectByteSize); // mostly correct
            string testObject = sb.ToString();

            


            // Get test
            IndexusDistributionCache.SharedCache.Clear();
            IndexusDistributionCache.SharedCache.Add(cacheKey, testObject);
            for (int i = 0; i < iterations; i++)
            {
                DateTime startTime = DateTime.Now;
                string temp = (string)IndexusDistributionCache.SharedCache.Get(cacheKey);
                DateTime endTime = DateTime.Now;
                TimeSpan runTime = endTime - startTime;
                getsTotalTime += runTime.Milliseconds;
            }

            // Set test
            IndexusDistributionCache.SharedCache.Clear();
            for (int i = 0; i < iterations; i++)
            {
                DateTime startTime = DateTime.Now;
                IndexusDistributionCache.SharedCache.Add(cacheKey, testObject);
                DateTime endTime = DateTime.Now;
                TimeSpan runTime = endTime - startTime;
                setsTotalTime += runTime.Milliseconds;
                IndexusDistributionCache.SharedCache.Remove(cacheKey);
            }
            IndexusDistributionCache.SharedCache.Clear();

            Console.WriteLine("Test Results\n\nIterations: {0}\nObject Size: {1}kb\nTotal GET Time: " +
                               "{2}\nTotal SET Time: {3}\nAverage GET Time: {4}\nAverage SET Time: {5}",
                               iterations, testObjectByteSize / 1024, getsTotalTime,
                               setsTotalTime, getsTotalTime / iterations,
                               setsTotalTime / iterations);

            Console.WriteLine("\n\nPress any key to exit...");
            Console.ReadKey();
        }
    }
}

Config file:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog"/>
    <section name="indexusNetSharedCache" type="MergeSystem.Indexus.WinServiceCommon.Configuration.Client.IndexusProviderSection, MergeSystem.Indexus.WinServiceCommon"/>  
  </configSections>
  <indexusNetSharedCache defaultProvider="IndexusSharedCacheProvider">
    <clientSetting
                SharedCacheVersionNumber="2.0.4.276"
                LoggingEnable="1"
                CompressionEnabled="0"
                CompressionMinSize="1024000"
                SocketPoolMinAvailableSize="5"
                HashingAlgorithm="Ketama" />
    <!--
            Hashing (default - is useless if your envrionment is using different versions of CLR's)
            Ketama
            FvnHash32
            FvnHash64
            -->
    <servers>
      <add key="localhost"    ipaddress="127.0.0.1" port="48888"/>
    </servers>
    <replicatedServers>
      <!-- only use this node in case you are using replication mode on server -->
      <add key="MNDESKTOP"        ipaddress="172.16.20.15" port="48888" />
      <!--<add key="SrvZh02"        ipaddress="192.168.212.37" port="48888" />-->
    </replicatedServers>
    <providers>
      <add
                name="IndexusSharedCacheProvider"
                type="MergeSystem.Indexus.WinServiceCommon.Provider.Cache.IndexusSharedCacheProvider, MergeSystem.Indexus.WinServiceCommon"
           >
      </add>
    </providers>
  </indexusNetSharedCache>
  <nlog autoReload="true" throwExceptions="true">
    <targets async="true">
      <target name="shared_cache_general"        type="File" layout="${longdate}|${level:uppercase=true}|${aspnet-request:item=logSession}|${message}" filename="C:\temp\logs\client\${date:format=yyyy-MM-dd}_shared_cache_general_log.txt"/>
      <target name="shared_cache_traffic"        type="File" layout="${longdate}|${level:uppercase=true}|${aspnet-request:item=logSession}|${message}" filename="C:\temp\logs\client\${date:format=yyyy-MM-dd}_shared_cache_traffic_log.txt"/>
      <target name="shared_cache_tracking"    type="File" layout="${longdate}|${level:uppercase=true}|${aspnet-request:item=logSession}|${message}" filename="C:\temp\logs\client\${date:format=yyyy-MM-dd}_shared_cache_tracking_log.txt"/>
      <target name="shared_cache_sync"            type="File" layout="${longdate}|${level:uppercase=true}|${aspnet-request:item=logSession}|${message}" filename="C:\temp\logs\client\${date:format=yyyy-MM-dd}_shared_cache_sync_log.txt"/>
    </targets>
    <rules>
      <logger name="General" minlevel="Debug" writeTo="shared_cache_general" final="true"/>
      <logger name="Traffic" minlevel="Debug" writeTo="shared_cache_traffic" final="true"/>
      <logger name="Tracking" minlevel="Debug" writeTo="shared_cache_tracking" final="true"/>
      <logger name="Sync" minlevel="Debug" writeTo="shared_cache_sync" final="true"/>
      <logger name="*" minlevel="Debug" writeTo="shared_cache_general"/>
      <logger name="*" minlevel="Info" writeTo="shared_cache_general"/>
    </rules>
  </nlog>
 </configuration>