mysql高并发时候投票问题 如何优化

比如一万人给一个人投票
我的做法是先是读取票数然后在票数+1
但是一万人同时投票的话 获取票数和更新肯定获取的不对

代码如下 用的是phpcms 请问大神该怎么优化 代码就这么点 结构简单的 就是投票人比较多

//根据ID获取票数
$r = $db->get_one(array('id' => intval($_GET['id'])));
//票数累计并更新票数
$num = $r['num'] + 1;
$sql = array('num' => $num);
$db->update($sql, array('id' => intval($_GET['id'])));
阅读 2.2k
评论
    8 个回答

    诚邀。

    如果你不想或者不愿意将redis引入到phpcms中。
    我没有对phpcms进行过二次开发,但是你可以在sql中直接进行相加,并非使用代码去实现相加

    update student set score=score+1 where id = 1

    这样就避免了投票不准确
    如果有时间可以使用redis或者队列去实现这个功能。

      • 246

      针对于这个需求,我有两步方案

      1.将用户点击投票或者取消投票的总数放到缓存中,redis,memcache都可以,建议redis;

      2.将某个用户是否投票,放入缓存,同上;

      3.用户展示的以及判断的数据逻辑,直接走缓存,然后再通过定时脚本同步数据到mysql服务器上;

      4.如果为了保险起见可以在更新或者写入的时候加锁,保证数据的一致性,前提条件要根据逻辑来,不会出现死锁。

        如果只是保证数据正常, 那可以事务加排它锁来搞.

        按理说会先存到redis里面, 投票结束了才写入数据库

          简单点就直接MySQL上锁,但是这样性能会低很多。
          可以利用redis,读也从redis读,更新也是更新redis里(incr操作),
          开个任务等到投票结束,把缓存中投票数写入到MySQL中。

            • 1k

            这个投票我建议你用redis投票 然后定时更新到mysql 因为update可能造成锁表,你还要select读取票数,在并发量很大的情况下可能直接会因为sql阻塞导致mysql gone away

              这其实是涉及到队列控制,锁的一个应用。即,当一个用户写的时候,将其先锁起来,不给其它人控制数据,直到一个修改完成,然后才到下一个人进行修改。
              可以对 数据锁 或者 数据队列 查找下相关文章进行了解。具体实现可以通过临时表进行队列排序,逐个处理。当然,如果处理高并发数据,一般都会用牛刀诸如 redis 等数据库进行主从数据处理会比较好。

                • 130

                看你的并发有多高、服务器性能有多好了。
                简单来讲,有几点可以处理你的问题。

                1. 使用redis列表记录每个人的投票,异步去处理数据库。
                2. 数据库加锁,不过在高并发(如只有一台低档服务器+一万个人3s内同时访问)时能不能扛得住要看信仰。
                3. 优化你的表设计,这张表尽量简单一些,选择适当的事务隔离级别。
                4. 服务器物理机换成硬盘读写性能更优的。

                  只要不对表造成死锁,控制好高并发,基本上没有问题,不用非得把表锁死。做好异步处理

                    撰写回答

                    登录后参与交流、获取后续更新提醒

                    相似问题
                    推荐文章