Question

I want to store serialized objects (or whatever) in a key/value cache.

Now I do something like this :

public string getValue(int param1, string param2, etc )
{
    string key = param1+"_"+param2+"_"+etc;

    string tmp = getFromCache();
    if (tmp == null)
    {
       tmp = getFromAnotherPlace();
       addToCache( key, tmp);
    }
    return tmp;
}

I think it can be awkward. How can I design the key?

Était-ce utile?

La solution

if i understood the question, i think the simplest and smartest way to make a key is to use an unidirectional hash function as MD5, SHA1 ecc...

At least two reason for doing this:

  1. The resulting key is unique for sure!(actually both MD5 and SHA1 have been cracked (= )
  2. The resulting key has a fixed lenght!

You have to give your object as argument of the function and you have your unique key. I don t know very much c# but i am quite sure you can find an unidirectional hash function builted-in.

Autres conseils

First of all your key seems to be composed out of a lot of characters. Keep in mind that the key name also occupies memory (1byte / char) so try to keep it as short as possible. I've seen situations where the key name was larger than the value, which can happen if you have cases where you store an empty array or an empty value.

The key structure. I guess from your example that the object you want to store is identified by the params (one being the item id maybe, or maybe filters for a search [...]). Start with a prefix. The prefix should be the name of the object class (or a simplified name depicting the object in general).

Most of the time, keys will have a prefix + identifier. In your example you have multiple identifiers. If one of them is a unique id, go with only prefix + id and it should be enough.

If the object is large and you don't always use all of it then change your strategy to a multiple key storage. Use one main key for storing the most common values, or for storing the components of the object, values of which are stored in separate keys. Make use of pipes and get the whole object in one connection using one "multiple" query :

 mainKey = prefix + objectId;
 object = getFromCache(mainKey);

 startCachePipeline();
 foreach (object[properties] as property) {
      object->property = getFromCache(prefix + objectId + property);
 }
 endCachePipeline();

The structure for an example "Person" object would then be something like :

 person_33 = array(
      properties => array(age, height, weight)
 );
 person_33_age = 28;
 person_33_height = 6;
 person_33_weight = 150;

Memcached uses memory most efficient when objects stored inside are of similar sizes. The bigger the size difference between objects (not talking about 1 lost big object or singular cases, although memory gets wasted then as well) the more wasted memory.

Hope it helps!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top