刚看了memcached处理抢购问题的队列的一些代码,我理解到的思路有两种
1.使用 $mem->set(LOCK_key,1) 来加锁,入队结束后 $mem->delete(LOCK_key) 解锁
2.使用memcached 的 increment(key,1) 来获得队列位置
我的问题是:
1.第一种方法可行吗?
2.$memcached->increment(key,1) 这个函数能处理并发访问吗?也就是多个进程同时调用 increment函数,会不会发生并发覆盖问题?
我今年大四了,在不断找工作中,由于之前学习的不够系统的PHP,被 YY 和 4399 都复试的时候刷了。
心很凉,找工作不易,且行且珍惜,我要好好加油,谢谢各位大牛拉我一把
回复讨论(解决方案)
会发生冲突
你自己测试一下就知道
只用memcached你这样会冲突的,对于高并发冲突,可使用memcacheQ来解决。
memcacheq 是专为门为解决高并发问题所开发的中间件,以队列的方式存取数据。
参考: http://blog.csdn.net/fdipzone/article/details/17933673
1.第一种方法是可以的,只不过这个锁效率太低了,多个客户端访问都在等待解锁,速度超级慢(根据我的测试,800个客户端,每个客户端访问10次,填满一个200的队列,需要用时32秒)。
这种队列的实现方法github上面已经有大神贴代码了
https://github.com/meetrajesh/php-memqueue/blob/master/memqueue.php
只不过第95行 while ($this->memc->add($this->lock_key, '1', 0, 2)) while里面要加上! 才能正确加锁。
2.memcached的所有操作都是原子性的(get/set/increment, 参见 http://blog.csdn.net/jarfield/article/details/4336035#what's the big benefit for all this),也就是说无论多少个操作,你丢到memcached服务器里,都是顺序执行的,所以方法2是可行的。我同样用800个客户端,每个客户端访问10次,最后查看increment的值,正好是8000,所以不会覆盖。
无独有偶,我也是今年大四连续被4399,YY等公司刷掉了。
痛定思痛,从工作中慢慢重新学习吧
忘了说了,队列服务,建议用 redis 吧,他自带队列的各种操作,性能比memcached的在服务端加锁要好很多。
http://redis.io/