关于memcache和redis数据并发问题

memchaced

CAS协议是什么

Memcached于1.2.4版本新增CAS(Check and Set)协议原子操作,处理同一item被多个线程更改过程的并发问题。

在Memcached中,每个key关联有一个64-bit长度的long型惟一数值,表示该key对应value的版本号。这个数值由Memcached server产生,从1开始,且同一Memcached server不会重复。在两种情况下这个版本数值会加1:1、新增一个key-value对;2、对某已有key对应的value值更新成功。删除item版本值不会减小。

下文来自手册
Memcached::cas()执行一个“检查并设置”的操作,因此,它仅在当前客户端最后一次取值后,该key 对应的值没有被其他客户端修改的情况下, 才能够将值写入。检查是通过cas_token参数进行的, 这个参数是Memcach指定给已经存在的元素的一个唯一的64位值, 怎样获取这个值请查看 Memcached::get*() 系列方法的文档。注意:这个值作为double类型是因为PHP的整型空间限制。

译注:这是Memcached扩展比Memcache扩展一个非常重要的优势, 在这样一个系统级(Memcache自身提供)的冲突检测机制(乐观锁)下, 我们才能保证高并发下的数据安全。

cas下的场景
A取出key1,值为value1,cas标记值为cas1.
B取出key1,值为value1,cas标记值为cas1.
B修改key1,在进行写入操作时,检查cas标记值是否与缓存中的cas标记值一致,如果一致插入成功,否则插入失败,这里一致插入成功.
A修改key1,在进行写入操作时,同样检查cas标记值是否与缓存中的cas标记值一致,这里不一致,插入失败.

<?php
$m = new Memcached();
$m->addServer('localhost', 11211);

do {
    /* 获取ip列表以及它的标记 */
    $ips = $m->get('ip_block', null, $cas);
    /* 如果列表不存在, 创建并进行一个原子添加(如果其他客户端已经添加, 这里就返回false)*/
    if ($m->getResultCode() == Memcached::RES_NOTFOUND) {
        $ips = array($_SERVER['REMOTE_ADDR']);
        $m->add('ip_block', $ips);
    /* 其他情况下,添加ip到列表中, 并以cas方式去存储, 这样当其他客户端修改过, 则返回false */
    } else { 
        $ips[] = $_SERVER['REMOTE_ADDR'];
        $m->cas($cas, 'ip_block', $ips);
    }   
} while ($m->getResultCode() != Memcached::RES_SUCCESS);

?> 

redis

现在有一个场景情况如:
mysql
a b c
101 102 103
下列同时三个连接a更改某个字段为101 b为102 c为103
当mysql更改成功后,更改redis的那个key的值.
发现那个Key的值为102,如何更改保证redis的那个值和mysql一致?
这里我们在更改redis的时候,后面可以跟一个标识符,如时间戳.
在插入的时候比较时间戳即可.

欢迎各位纠正.

猜你喜欢

转载自blog.csdn.net/hejinshan12/article/details/88738128