mysql中列值的增量更新。并发问题?

时间:2015-06-28 12:04:46

标签: mysql rabbitmq innodb scalability

我有一个像

这样的查询
update pageviews set count = count + 1 where pageid = $pageid

每次查看网页时都会执行此语句。因此,每次查看页面时列数都会增加。

我的表是InnoDB类型。

假设每秒有数千次网页浏览,这是不可扩展的?我可以遇到并发问题吗?像查询锁定等?

有人告诉我,我应该将队列用于这样的目的。为什么我需要使用队列?在什么样的情况下我的数据可能会被破坏或可扩展性成为一个问题?

2 个答案:

答案 0 :(得分:1)

开箱即用,在商用硬件上,InnoDB每秒处理大约100个这样的语句。没有并发或锁定问题,只有性能问题。

    为了安全起见,
  • innodb_flush_log_at_trx_commit默认为1。但这需要每个事务的日志磁盘I / O. 2更快,合理妥协。 (崩溃可能会导致一秒钟的交易损失。)

  • 您的UPDATE可能是autocommited?或者在交易中自己?可以以任何方式批量生产吗?如果是这样,那将减少开销。

  • 网页浏览器是由网页服务器处理的,对吗?它可以在实际写入表之前收集一些pageid吗?即使它收集了一秒钟,这可能是一个显着的加速。如果您这样做,请务必对IN中的update pageviews set count = count + 1 where pageid IN (...)列表进行排序。这将减少死锁的可能性。

  • 处理UPDATE的错误。 (否则,您的数据将“错误”或“已损坏”。)

答案 1 :(得分:1)

除了@Rick的回答:我不知道队列如何帮助你,我唯一的想法是将所有页面事件发送到你有多个消费者的队列,每个他们更新了自己的数据库,稍后会汇总结果。队列允许您在短时间内有大量负载时处理一些峰值负载 - 在这种情况下,您不会阻止数据库更新,而是将事件放入内存中,稍后将处理它们,但它无济于事如果你不能在常规负载下处理事件流。

还有一个建议 - 如果您每秒有数千次综合浏览量,可能您不需要预先跟踪它们(如果它不是计费),那么如果您有一个代码,您可以拥有这样的代码有状态服务器:

onPageView() {
    cnt += 1
    if (cnt == 1000) {update table set views = views + 1000; counter = 0;}
}

(不要忘记线程安全)

甚至

onPageView() {
   value = random(0, 1000);
   if (value == 0) {
       update table set views = views + 1000
   }    
}

并且您不需要关心状态,并且您可以减少1000次写入次数