php 高并发下数据同步的问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php 高并发下数据同步的问题相关的知识,希望对你有一定的参考价值。


1.加锁
缺点:降低性能
优点:减少代码逻辑复杂度(题主现在这样超过1w条就删数据的逻辑,感觉看起来就点糟糕啊,如果整个系统一复杂,这样的来回写数据,你确定你的逻辑还维护得下去?建议题主梳理一下代码的逻辑流)


2.队列(redis/各类mq等)
缺点:引入其他组件,增加系统复杂度,降低稳定性。
优点:能够将web的并行逻辑串行,其实和加锁差不多,不过更优雅,并且性能上面也更可控。如果题主的系统的逻辑复杂,推荐采用这种。

建议:php写多你会发现,它的逻辑就是一波流的。在它的逻辑层实现过多的重试,等待,以及回写,会导致php很臃肿。建议要么在数据库层上锁,要么引入队列等待,要么就直接报错,让用户F5重试,如果用ajax重试,几乎没有用户体验上的问题。那么来说一下直接报错的方案。

3.建一个计数器表
举例:
create table store_count (total int(11) NOT NULL) ENGINE=InnoDB
抢计数器:
如果我查出来现在总数是2,那么我 update store_count set total = 3 where total = 2
如果更新成功,说明现在的总行数是3,可以去插表,如果未更新,说明这时已经有其他用户插入了,直接给用户报错,让他下次请求再来过。

缺点:这种方式其实比前两个更粗暴,前2种方式还是等待的,这种方式直接丢弃了部分用户流量,带来的是一个有缓存特性的计数器来实现题主提的逻辑。
这个计数器在内存中效果更佳。

建议题主根据自身的系统状况,和代码逻辑,进行性能、开发效率、逻辑成本、维护成本上的取舍。
 
 
===================================================================================
 
用一个计数器
我最近在做一个项目 高并发选课系统
每次insert之前先计数器+1然后判断他的值是否大于max
如果大于max计数器自减1 类似回滚
如果小于max 执行insert语句

ps:计数器自增和自减需要保证其原子性
推荐Redis来做计数器 max也可以用redis来存.
 
====================================================================================
用队列
====================================================================================
加锁就行,要么锁表,要么锁程序,加了锁就相当于变成队列执行,一次只能一个人拿到锁,只能一个人通过,去插入数据。
php里可以使用文件锁,或memcached锁也行,文件锁会导致阻塞。
可以搜索:php锁,php文件锁

以上是关于php 高并发下数据同步的问题的主要内容,如果未能解决你的问题,请参考以下文章

高并发下的web异步处理方案

高并发下减少锁竞争

php结合redis实现高并发下的抢购秒杀功能

php结合redis实现高并发下的抢购秒杀功能

php结合redis实现高并发下的抢购秒杀功能

php结合redis实现高并发下的抢购秒杀功能