我在MySQL中遇到高频插入问题。我在互联网上搜索了很多,但没有找到解决问题的好方法。
我需要以非常高的频率记录大量事件(每天约3000个插入/ s => 2.6亿行),这些事件存储在InnoDB表中,如下所示:
log_events :
- id_user : BIGINT
- id_event : SMALLINT
- date : INT
- data : BIGINT (data associated to this event)
我的问题是:
- 如何加速插入?活动由数千名访客发送,我们无法批量插入
- 如何限制IO写入?我们使用的是6 * 600 GB SSD驱动器,并且存在写入IO问题
你对这类问题有什么想法吗?
由于
弗朗索瓦
答案 0 :(得分:1)
那张桌子上有外键吗?如果是这样,我会考虑删除它们,并仅在用于读取的cols上添加索引。这应该改善写入。
第二个想法是使用一些内存数据库(例如redis,memcache)作为队列,一些工作者可以从中获取数据并以批量形式(例如每2秒)插入到mysql存储中。
如果您不需要频繁阅读,另一个选项是使用archive
存储而不是innodb:http://dev.mysql.com/doc/refman/5.5/en/archive-storage-engine.html。但看起来它不是你的选择,只要它根本没有索引(这意味着完整的扫描表读取)。
另一个选项是重组你的数据库结构,例如。使用分区(http://dev.mysql.com/doc/refman/5.5/en/partitioning.html)。但这取决于SELECTS的样子。
我的其他问题是:
答案 1 :(得分:1)
活动由数千名访问者发送,我们无法批量插入
您需要批量插入或分片数据。我很想先尝试批量插入路线。
您认为您无法建议这些事件是由自主流程创建的 - 您只需要通过中介将其汇总,而不是直接发送到数据库。将该漏斗实现为基于事件的服务器(而不是线程或分支服务器)是最容易的。
您不会说明事件是什么以及它们来自何处 - 这对实施解决方案的细节有一些影响。
rsyslog和syslogng都会与MySQL后端通信 - 因此您可以消除每条消息建立新连接的开销 - 但我不知道是否实现了缓冲/批量插入。当然可以使用单个进程拖放它们生成的文件,并从那里创建批量插入。
使用此event based server,this buffer tool以及一些代码实现asynch mysqli调用和监视程序来编写漏斗相对简单。或者您可以使用node.js with an async mysql lib。还有像statsd这样的工具(再次使用node.js),它们也可以对数据上的数据执行一些聚合。
或者你可以从头开始写点东西。
只写数据库是一个无用的硬件。您尚未提供有关如何使用此数据的任何详细信息 - 这与设计解决方案有关。此外,理想情况下,数据馈送将是单个进程/数据库会话,使用MyISAM而不是InnoDB可能是一个更好的想法(我在后面的评论中看到你说你有MyISAM的问题 - 可能这是多个客户端)。