3

我在 MySQL 中遇到高频插入问题。我在互联网上搜索了很多,但没有找到一个很好的答案来解决我的问题。

我需要以非常高的频率记录很多事件(每天约 3000 次插入/秒 => 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 问题

你对这类问题有什么想法吗?

谢谢

弗朗索瓦

4

2 回答 2

1

你那张桌子上有外键吗?如果是这样,我会考虑删除它们并仅在用于读取的列上添加索引。这应该会改善写入。

第二个想法是使用一些内存数据库(例如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 的外观。

我的其他问题是:

  • 你能显示整个表的定义吗?
  • 哪些字段用于读取?你能告诉他们吗?
  • 您需要读取所有数据还是仅需要最近的数据?如果是这样,数据必须是最近多久?(例如,仅从最后一天/周/月/年开始)
  • id_event 是一个事件类型,对吧?可能事件的数量是静态的还是将来会发生变化?
于 2013-04-24T14:28:33.053 回答
1

事件由成千上万的访问者发送,我们无法批量插入

您需要批量插入或分片数据。我很想先尝试批量插入路线。

你认为你不能暗示这些事件是由自治进程创建的——你只需要通过中介而不是直接到数据库来引导它们。并且最容易将该漏斗实现为基于事件的服务器(而不是线程或分叉服务器)。

您没有说明事件是什么,也没有说明它们的来源——这对实施解决方案的细节有一些影响。

rsyslog 和 syslogng 都将与 MySQL 后端通信——因此您可以消除为每条消息建立新连接的开销——但我不知道它们是否实现了缓冲/批量插入。当然可以使用单个进程跟踪他们生成的文件并从那里创建批量插入。

使用这个基于事件的服务器这个缓冲工具以及一些代码来实现异步 mysqli 调用和看门狗来编写一个漏斗相对简单。或者您可以将node.js 与 async mysql lib 一起使用。还有像statsd之类的工具(同样使用 node.js),它也可以对数据上的数据执行一些聚合。

或者你可以从头开始写一些东西。

不过,只写数据库是一个无用的硬件。您尚未提供有关如何使用此数据的任何详细信息 - 这与设计解决方案有些相关。此外,由于理想情况下数据馈送将是单个进程/数据库会话,因此使用 MyISAM 而不是 InnoDB 可能是一个更好的主意(我在您后来的评论中看到您说您在使用 MyISAM 时遇到问题 - 大概这是与多个客户端有关)。

于 2013-04-24T15:01:17.673 回答