高容量更新计数器Mysql

时间:2015-03-03 11:07:27

标签: mysql ajax database performance

我有一个包含很多计数器表的网站:

favoritefollowupvotedownvote等。

现在每次点击我都会在这些表格中更新/插入一行。

我的结构

最喜欢的表格

user_id|obj_id|time

关注表格

user_id|obj_id|time

每次点击我都要做更新/插入,即 1次点击= 1 ajax请求到服务器= 1更新/插入这会导致大量调用数据库。

根据数学(据我所知)并且计算次数最少:

1 click = 1 request
1 million click = 1 million request
100 million click/day 

= 100 million request/day
= 416k request/hour
= 6830 request/min
= 115 request/sec

有没有更好的方法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

您是否已将客户端拆分为与服务器不同的计算机?这是缩放的第一步,次要步骤。

您是否有发送给Slaves的复制和只读查询?这可以允许无限制的读取缩放。 (但这并没有解决UPDATE问题,除了减轻主人的负担。)

单个旋转磁盘上的115个IOP几乎会使其饱和。 innodb_flush_log_at_trx_commit默认为1,这导致每个事务至少1个IOP。一些临时解决方案(直到你的流量再增加10倍)......

SSD - 可能是1000 IOP。

批量更新(例如@N.B.提到的)。这减少了“刷新”数量的100倍。

innodb_flush_log_at_trx_commit = 2 - 几乎消除了冲洗(在某种程度上失去了安全性)。

但是 - 即使你能够足够快地完成UPDATE,你也不需要读取值吗?也就是说,会有争用。您正在做相同的表上有多少个SELECT? 100 /秒可能没问题; 1000 /秒可能会造成太大的干扰而无法正常工作。

桌子有多大?要使其中任何一个工作,它需要足够小,以便始终缓存。

Reddit是另一种方法 - 在那里捕获更新。然后不断提取累积的计数并进行所需的更新。

分片 - 这是您在多台计算机上分割数据的地方。在用户标识的散列或查找(或两者的组合)上拆分很常见。然后UPDATE需要找出要更新的机器,然后在那里执行操作。如果你有10个分片(机器),你可以维持近10倍的更新速率。最终,这是所有重型打击者每天可以处理100M +用户和数十亿次查询的唯一方式。

分区不太可能有所帮助。分区修剪代码还不够高效,无法为这么小的查询避免过多的开销。