1

我有一个应用程序,我想将某些信息汇总到 membase 中,以避免昂贵的 group by 查询。例如,一次点击转换将记录在 MySQL 中,我想在 memcache 键中为某个用户保留按小时分组的运行总点击次数。在那里我可以用我需要的值取消/序列化一个数组。我还有很多其他的需求,比如收入、点赞等。

创建某种“事务”以确保 MC 和 Mysql 保持同步的最佳方法是什么?我总是可以基于底层的 MySQL 存储重建密钥存储,但我想在两个产品之间保持良好的并发性。

4

1 回答 1

0

概括地说,要使用 membase / memcache / etc 作为 mysql 的缓存,您需要执行以下操作:

public Object readMethod(String key) {
    value = membaseDriver->get(key);
    if(value != null) {
        return value;
    }
    value = getFromMysql(key);
    membaseDriver->put(key, value, TTL);
}

public Object writeMethod(String key, String value) {
    writeToMysql(key, value);
    membaseDriver->delete(key); 
    //next call to get will get the value that we just wrote to db
}

这可确保您的数据库仍然是数据的主要来源,并确保 membase 和 mysql几乎保持同步。(它在进程执行 write 方法时同步,在它写入 mysql 之后并且在它从 membase 中删除密钥之前)。

如果您希望它们真正同步,您必须确保在任何进程执行 writeMethod 时,没有进程可以执行 readMethod。您可以使用 add 方法在 memcache / membase 中进行简单的全局锁定。基本上,您添加一个以您的锁命名的唯一键(例如:“MY_LOCK”),如果添加成功,您就拥有了锁,发生这种情况后,其他人都无法获得锁。完成写入后,您可以通过使用锁的键名调用 delete 来释放锁。通过使用该“锁定”启动这两种方法,并使用“解锁”结束这两种方法,您可以确保一次只有一个进程正在执行其中一个。您还可以在此之上构建单独的读写锁,但我不这样做

在每小时点击次数的情况下,您可以避免在每次计算另一次点击时重新运行查询,方法是将当前时间(即:唯一会更改的时间)与之前所有时间的数组(可能会永远不会改变,对吧?)。

每次添加点击时,只需在当前小时计数器上使用 memcache 增量。然后,当您收到读取请求时,查找之前所有小时的数组,然后是当前小时,以及所有之前的小时,并将当前小时附加到末尾。作为一个免费的奖励,增量是原子的事实为您提供了实际同步的值,因此您可以跳过锁定。

于 2012-05-10T19:45:54.047 回答