大容量更新计数器Mysql



我有一个网站,里面有很多计数器表:

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

有什么比这更好的方法吗?

您是否将客户端与服务器分离到一台单独的机器中?这是缩放的第一步,也是次要的一步。

是否将复制和只读查询发送到从属服务器?这可以允许无限制的读取缩放。(但这并没有解决UPDATE问题,只是为了减轻Master的负载。)

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

固态硬盘——可能1000 IOP。

批处理更新(例如@N.B.提到的)这将"刷新"次数减少100倍。

innodb_flush_log_at_trx_commit=2——实际上消除了刷新(在某些安全性损失的情况下)。

但是——即使你可以足够快地进行更新,难道你不需要读取值吗?也就是说,会有争论。您在同一表上执行了多少个SELECT?100/秒可能还可以;1000/秒可能会造成太多干扰,以至于无法工作。

这张桌子有多大?为了使这些功能发挥作用,它需要足够小,以便一直缓存。

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

Sharding--这是在多台机器上分割数据的地方。对userid的散列或查找(或两者的组合)进行拆分是很常见的。然后UPDATE需要确定更新哪台机器,然后在那里执行操作。如果你有10个碎片(机器),你可以维持近10倍的更新率。最终,这是所有重量级人物每天处理1亿以上用户和数十亿次查询的唯一方法。

分区可能没有帮助。分区修剪代码的效率还不够高,无法避免如此微小的查询产生过多的开销。

最新更新