码迷,mamicode.com
首页 > 其他好文 > 详细

redis下并发问题解决方案

时间:2017-07-31 12:31:41      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:一段   就会   消息   问题   更改   ble   line   code   space   

http://effective.blog.51cto.com/8296150/1671743

 

现在的计算机大都是多核的cpu,意味着可以并行执行多个进程.如果这多个运行的进程对同一份数据进行读写操作,那么就有可能出现两个或者多个进程读到的都是老的数据,这种情况下,再进行写入操作之后就会有一些进程写入的数据被覆盖掉,就导致最终的结果错误.这份数据对于这些进程来说就是临界区.

 

redis下处理并发问题.

1.通过使用setnx进行加锁,在操作系统以及数据库中处理并发都会用到锁机制,虽然加锁可以解决并发问题,但是会降低并发量,所以它们都会通过读写锁来降低锁的粒度.

  加锁实际上就是把并行读写改成串行读写的方式来避免资源竞争

1
2
3
4
5
6
7
8
9
10
11
$redis new Redis();
$redis->connect(‘127.0.0.1‘, 6370);
if(!$redis->setnx(‘lock‘,1)){
    usleep(500000); //等待一段时间
    if(!$redis->setnx(‘lock‘,1)){
exit();
    }
}
redis->EXPIREAT(‘lock‘, 2); //设置一个过期时间,避免进程挂掉导致锁不能释放
//业务处理
$redis->del(‘lock‘);

 

2.watch + 事物,redis的事物不能自动回滚,所以在失败的情况下要处理回滚操作.如果事物中更新多个,那么回滚操作会比较麻烦,

1
2
3
4
5
6
7
8
$redis new Redis();
        $redis->connect(‘127.0.0.1‘, 6370);
        $redis->watch(‘test‘); //必须在读之前进行watch
$redis->hGetAll(‘test‘)
       //业务处理
        $result $redis->multi()
                        ->hset()
                        ->exec();

 

3.减少写数据的粒度或者修改数据结构来避免并发,我们的业务中使用的是hset方式,把用户的数据都放到了一个filed中,这就导致一次更改要写入用户所有的数据,通过修改

使用hmset,更新数据的时候只更新需要更新的数据,降低写入的粒度来降低各个接口对临界区的读写访问.这种方式或许能避免部分接口对临界区的访问,不能避免的接口还需要另外

处理.

 

4.在并发量过大的情况下,可以通过消息中间件进行处理,把并行读写进行串行化.这种方式在一些高并发的场景中算是一种通用的解决方案,简单的方式可以通过redis的list实现,

在大规模的软件中就需要引入专门的消息中间层来处理了.

redis下并发问题解决方案

标签:一段   就会   消息   问题   更改   ble   line   code   space   

原文地址:http://www.cnblogs.com/joshsung/p/7262335.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!