1

我们每天都在构建从推文用户 ID 到该用户发布的推文的推文 ID 列表的映射。我们使用的存储引擎是 Percona xtraDB "5.1.63-rel13.4 Percona Server (GPL), 13.4, Revision 443"

我们对每秒行插入的最大吞吐量不满意。我们使用 xtraDB 处理推文的最大吞吐量约为每秒 6000 到 8000 条推文。(例如,如果我们必须从头开始重建数据,我们将不得不等待将近一天)

在大多数情况下,我们能够利用全部 twitter 数据(大约每秒 4000 到 5000 条推文)实时完成这项工作。

我们已将应用程序的瓶颈缩小到 MySQL InnoDB 插入。在我们的应用程序中,我们从磁盘读取提要并使用 jackson 解析它(每秒大约 30,000 条推文)。然后,我们的应用程序分批发送推文。对于生成这些推文的作者集,我们将它们划分为 8 个组(使用用户 id 模 8 进行简单划分)。为每个组分配一个表,并分配 1 个线程将数据写入该表。每天大约有 2600 万唯一用户生成这些推文,因此每个表大约有 400 万行。对于一组用户,我们只使用一个事务进行读取和更新。组大小是运行时可调的。我们尝试了从 8 ~ 64000 的各种大小,我们确定 256 是一个很好的批量大小。

我们表的模式是

CREATE TABLE `2012_07_12_g0` (  `userid` bigint(20) NOT NULL,  `tweetId` longblob,  PRIMARY KEY (`userid`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

其中 tweetId 是推文 ID 长整数的压缩列表,使用 Google snappy 压缩

每个线程使用

Select userid,tweetId from <tablename> where userid IN (....)

解析用户标识以回读数据,线程使用

INSERT INTO <tablename> (userid,tweetId) VALUES (...) ON DUPLICATE KEY UPDATE tweetId=VALUES(tweetId)

用新的 tweetid 更新行。

我们尝试过设置各种 XtraDB 参数

innodb_log_buffer_size = 4M
innodb_flush_log_at_trx_commit = 2
innodb_max_dirty_pages_pct = 80
innodb_flush_method = O_DIRECT
innodb_doublewrite = 0
innodb_use_purge_thread = 1
innodb_thread_concurrency = 32
innodb_write_io_threads = 8
innodb_read_io_threads = 8 
#innodb_io_capacity = 20000 
#innodb_adaptive_flushing = 1
#innodb_flush_neighbor_pages= 0"

所有表每天的表大小约为 8G,InnoDB 有 24GB 可供使用。

我们正在使用:

  • 6 磁盘(关键 m4 SSD,512 GB,000F 固件)软件 RAID5。
  • Mysql innodb数据,SSD分区上的表空间
  • ext4 挂载 noatime,nodiratime,commit=60
  • centos 6.2
  • 太阳jdk 1.6.30

任何使我们的插入速度更快的提示将不胜感激,谢谢。

4

2 回答 2

0

InnoDB 提供 24GB

你的意思是这是innodb_buffer_pool_size?你没有说你有多少内存,也没有说你正在使用什么 CPU。如果是这样,那么您可能应该使用更大的 innodb_log_buffer_size。你对 innodb_log_file_size 的设置是什么?它可能应该在 96Mb 左右。

innodb_write_io_threads = 8

ISTR 认为 ext3 与多个写入器存在一些并发问题 - 但我不知道 ext4

您是否尝试过更改 innodb_flush_method?

您正在使用哪个 I/O 调度程序(在没有智能磁盘控制器的情况下,通常截止日期是最快的,有时是 CFQ)?

关闭 ext4 屏障将有助于提高吞吐量——它有点风险——确保你在 JBD2 中启用了校验和。同样设置 innodb_flush_log_at_trx_commit=0 应该会显着增加,但风险更大。

由于您显然不关心以关系格式维护数据,因此您可以考虑使用 noSQL 数据库。

于 2012-07-13T09:46:29.510 回答
0

我最初的建议是:

  1. 由于您没有带内存的 RAID 卡,您可能需要注释掉innodb_flush_method = O_DIRECT行以让系统缓存写入
  2. 当您禁用双写缓冲区时,您还可以将innodb_flush_log_at_trx_commit设置为 0,这将比 2 快
  3. 设置innodb_log_buffer_size以覆盖至少一秒的写入(30K 推文大约 12Mb)
  4. 如果你使用二进制日志 - 确保你有sync_binlog = 0

在硬件方面,我强烈建议尝试使用至少 256Mb RAM 和电池单元 (BBU) 的 RAID 卡来提高写入速度。市场上有支持 SSD 的 RAID 卡。

希望这可以帮助。请让我知道情况如何。

于 2012-07-13T07:12:06.123 回答