memcached中的原子获取和删除?

时间:2014-04-02 22:04:36

标签: memcached

有没有办法在memcached中进行原子获取和删除?

换句话说,我想获取密钥的值(如果存在)并立即删除它,因此该值只能读取一次。

我认为这个伪代码可能有用,但请注意警告后记:

# When setting:
SET key-0 value
SET key-ns 0

# When getting:
ns = INCR key-ns
GET key-{ns - 1}

约束:我有数以百万计的密钥可以访问数百万次,只有一小部分密钥会在任何给定时间设置一个值。如上所述,我不想为每个获取访问请求更新每个密钥的原子计数器。

3 个答案:

答案 0 :(得分:0)

对你的问题的规范但但是通用的答案是:使用宽松的内存模型锁定自由哈希表。

你的内存模型越放松,你就越能获得无锁设计,这是一种从同一芯片组中获得更多性能的方法。

Here is a talk about that,我认为用哈希表和锁定免费编程的单个帖子回答你的问题是不可能的,我甚至都不想这样做。

答案 1 :(得分:0)

你不能在单个命令中使用memcached来执行此操作,因为没有api支持你所要求的内容。我要做的是让你想要的行为是实现某种标记行为,以表示另一个客户已经或没有读取数据。例如,您可以按如下方式创建JSON文档:

{ "data": "value", "used": false }

当您通过检查已使用的字段检查项目是否已被其他客户端使用时。如果尚未使用,则使用从GET命令获得的cas设置值,并确保更新文档以反映客户端已访问此密钥的事实。

如果设置操作失败,因为cas无效,那么这意味着另一个客户端已获取此项并已在memcached中更新它以表示它已被使用。在这种情况下,您只需取消对项目所做的任何操作,然后继续。

如果设置操作成功,则表示您的客户端是此数据的唯一所有者。您现在可以从memcached中删除它并对其进行任何处理。

请注意,在执行该设置时,我还会添加约5秒的到期时间。这样,如果您的应用程序崩溃,如果您没有完成删除它们的整个过程,您的文档将自行清理。

答案 2 :(得分:0)

要将一些代码放到@mikewied的答案中,我认为基本要点是......(使用Node.js):

var Memcached = require('memcached');
var memcache = new Memcached('localhost:11211');

var getOnce = function(key, callback) {
  // gets is the check-and-set get (vs regular get)
  memcache.gets(key, function(err, data) {
    if (!data) {
      // Cache miss, nothing to see here.
      callback(null);
    } else {
      var yourData = data[key];
      // Do a check-and-set to remove the data from the cache.
      // This sets the value to null *only* if no one else already did.
      memcache.cas(key, null /* new data */, data.cas, 10, function(err) {
        if (err) {
          // Check-and-set failed! (Here we'll treat it like a cache miss)
          yourData = null;
        }
        callback(yourData);
      });
    }
  });
};