如何设计/创建密钥/值存储密钥?

时间:2012-01-19 16:02:37

标签: dictionary memcached key outputcache voldemort

我想将序列化对象(或其他)存储在键/值缓存中。

现在我做这样的事情:

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;
}

我认为这可能很尴尬。我该如何设计密钥?

2 个答案:

答案 0 :(得分:1)

如果我理解了这个问题,我认为制作密钥的最简单,最智能的方法是使用单向哈希函数作为MD5,SHA1 ecc ......

这样做至少有两个原因:

  1. 结果密钥肯定是唯一的!(实际上MD5和SHA1都已被破解(=)
  2. 生成的密钥有一个固定的长度!
  3. 您必须将对象作为函数的参数,并且您拥有唯一的密钥。 我不太了解c#,但我很确定你可以找到一个单向哈希函数。

答案 1 :(得分:0)

首先,你的密钥似乎是由很多角色组成的。请记住,密钥名称也占用内存(1byte / char),因此请尽量缩短内存。我已经看到了键名大于值的情况,如果你有存储空数组或空值的情况,就会发生这种情况。

关键结构。我想从你的例子中你想要存储的对象是由params标识的(一个是项目ID,或者可能是搜索的过滤器[...])。以前缀开头。前缀应该是对象类的名称(或者通常描述对象的简化名称)。

大多数情况下,密钥会有前缀+标识符。在您的示例中,您有多个标识符。如果其中一个是唯一ID,请仅使用prefix + id,这应该足够了。

如果对象很大并且您并不总是使用所有对象,则将策略更改为多键存储。使用一个主键存储最常用的值,或者存储对象的组件,其值存储在单独的键中。利用管道并使用一个“多个”查询在一个连接中获取整个对象:

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

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

示例“Person”对象的结构将类似于:

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

当内存中的对象具有相似的大小时,Memcached使用内存最有效。对象之间的大小差异越大(不是谈论丢失的大对象或单个案例,尽管内存也被浪费掉了),内存浪费得越多。

希望它有所帮助!