我有一个像
这样的查询update pageviews set count = count + 1 where pageid = $pageid
每次查看网页时都会执行此语句。因此,每次查看页面时列数都会增加。
我的表是InnoDB类型。
假设每秒有数千次网页浏览,这是不可扩展的?我可以遇到并发问题吗?像查询锁定等?
有人告诉我,我应该将队列用于这样的目的。为什么我需要使用队列?在什么样的情况下我的数据可能会被破坏或可扩展性成为一个问题?
答案 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次写入次数