设为首页 收藏本站
查看: 2429|回复: 0

[经验分享] redis下并发问题解决方案

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-7-8 08:35:31 | 显示全部楼层 |阅读模式
最近做的功能需求中,使用了redis作为数据库,上线之后个别玩家出现了莫名其妙的错误,该插入的数据没有插入,莫名其妙丢失了.最后通过分析用户的错误数据才想明白原来是并发问题导致的.第一次接触并发是在看操作系统原理的时候,之后再看数据库原理的时候也看到过并发,对与并发的原理还是比较清楚的,只是一直没遇到过.这次在用reids的过程中算是踩坑了.

现在的计算机大都是多核的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实现,
在大规模的软件中就需要引入专门的消息中间层来处理了.



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-84312-1-1.html 上篇帖子: Redis 安装与使用 下篇帖子: redis通配符 解决方案
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表