Mysql:处理 192 万亿条记录......(是的,192 万亿条)

Sar*_*rah 39 mysql database

这是问题...

考虑到 192 万亿条记录,我应该考虑什么?

我主要关心的是速度。

这是桌子...

    CREATE TABLE `ref` (
  `id` INTEGER(13) AUTO_INCREMENT DEFAULT NOT NULL,
  `rel_id` INTEGER(13) NOT NULL,
  `p1` INTEGER(13) NOT NULL,
  `p2` INTEGER(13) DEFAULT NULL,
  `p3` INTEGER(13) DEFAULT NULL,
  `s` INTEGER(13) NOT NULL,
  `p4` INTEGER(13) DEFAULT NULL,
  `p5` INTEGER(13) DEFAULT NULL,
  `p6` INTEGER(13) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY (`s`),
  KEY (`rel_id`),
  KEY (`p3`),
  KEY (`p4`)
    );
Run Code Online (Sandbox Code Playgroud)

这是查询...

SELECT id, s FROM ref WHERE red_id="$rel_id" AND p3="$p3" AND p4="$p4"

SELECT rel_id, p1, p2, p3, p4, p5, p6 FROM ref WHERE id="$id"

INSERT INTO rel (rel_id, p1, p2, p3, s, p4, p5, p6)
VALUES ("$rel_id", "$p1", "$p2", "$p3", "$s", "$p4", "$p5", "$p6")
Run Code Online (Sandbox Code Playgroud)

这里有一些注意事项...

  • SELECT 将比 INSERT 更频繁地完成。但是,有时我想一次添加几百条记录。
  • 负载方面,几个小时内什么都没有,然后可能一次有几千个查询。
  • 不要认为我可以再规范化(需要组合使用 p 值)
  • 整个数据库是非常相关的。
  • 这将是迄今为止最大的表(第二大大约 900k)

更新 (08/11/2010)

有趣的是,我得到了第二个选择......

我可以存储2.6*10^16(15 个零,意味着 26 Quadrillion)而不是 192 万亿...

但是在第二个选项中,我只需要存储一个 bigint(18) 作为表中的索引。就是这样 - 只有一列。所以我只会检查值是否存在。偶尔添加记录,从不删除它们。

所以这让我觉得必须有一个比 mysql 更好的解决方案来简单地存储数字......

鉴于这第二个选择,我应该接受还是坚持第一个......

[编辑]刚刚得到一些已经完成测试的消息 - 使用此设置的 1 亿行在 0.0004 秒内返回查询[/edit]

Con*_*lls 30

pQd 对 7PB 的估计似乎是合理的,这对于 RDBMS 来说是很多数据。我不确定我是否听说过有人用任何共享磁盘系统做 7PB,更不用说 MySQL。使用任何共享磁盘系统查询此数据量的速度将非常缓慢。即使针对大型流查询进行了优化,最快的 SAN 硬件也能达到 20GB/秒。如果你能负担得起这个规格的 SAN 硬件,你可以努力使用比 MySQL 更适合这项工作的东西。

事实上,我正在努力设想一个场景,您可以为该规范的磁盘子系统提供预算,但不能为更好的 DBMS 平台提供预算。即使使用 600GB 磁盘(目前市场上最大的 15K“企业”驱动器),您也需要使用 12,000 个物理磁盘驱动器来存储 7PB。SATA 磁盘会更便宜(如果使用 2TB 磁盘,您将需要大约 1/3 的数量),但速度要慢一些。

来自像 EMC 或 Hitachi 这样的主要供应商的这种规格的 SAN 将花费数百万美元。上次我使用一家主要供应商的 SAN 设备时,IBM DS8000 上的空间转移成本超过 10,000 英镑/TB,不包括控制器的任何资本津贴。

对于这么多数据,您确实需要一个像 Teradata 或 Netezza 这样的无共享系统。分片 MySQL 数据库可能可行,但我建议使用专门构建的 VLDB 平台。无共享系统还允许您在节点上使用便宜得多的直接附加磁盘 - 看看 Sun 的 X4550 (thumper) 平台的一种可能性。

您还需要考虑您的性能要求。

  • 查询的可接受运行时间是多少?
  • 您多久查询一次数据集?
  • 是否可以使用索引解决大多数查询(即它们是否会查看一小部分 - 例如:少于 1% - 的数据),或者它们是否需要进行全表扫描?
  • 数据加载到数据库的速度有多快?
  • 您的查询是否需要最新数据,或者您是否可以接受定期刷新的报告表?

简而言之,反对 MySQL 的最有力的论点是,如果可能的话,您将进行后空翻以获得超过 7PB 数据的不错查询性能。如此庞大的数据量确实让您进入了无共享领域,以便快速查询它,并且您可能需要一个从一开始就为无共享操作而设计的平台。仅磁盘本身就将使任何合理的 DBMS 平台的成本相形见绌。

注意:如果您确实拆分了操作数据库和报告数据库,则不必为两者使用相同的 DBMS 平台。从同一个 7PB 表中获取快速插入和亚秒级报告至少将是一项技术挑战。

根据您的评论,您可以忍受报告中的一些延迟,您可能会考虑单独的捕获和报告系统,并且您可能不需要将所有 7PB 的数据保留在您的操作捕获系统中。考虑一个操作平台,比如 Oracle(MySQL 可以用 InnoDB 做到这一点)用于数据捕获(同样,除非你有很多用户,否则单独的磁盘成本将使 DBMS 的成本相形见绌)和一个 VLDB 平台,如Teradata、 Sybase IQ、 RedBrick、 Netezza(注:专有硬件)或Greenplum用于报告


pQd*_*pQd 16

切碎它。在这种规模下,拥有一个大型实例是一种自杀——想想可能的备份恢复、表空间损坏、添加新列或任何其他“内务管理”过程——在这种规模下,所有这些都不可能在合理的时间内完成。

简单的信封计算 - 假设除 64 位 id 之外的所有列都是 32 位整数;不包括指数:

8*4B+8B = 每行 40B [这是非常乐观的]

192 万亿行 40B 每行给我们几乎 7 PB

也许您可以重新考虑整个事情,汇总信息以进行快速报告,并在有人需要深入了解更深层次的细节时在给定的时间间隔内存储压缩记录。

要回答的问题:

  • 如果系统崩溃/重新启动,什么是可接受的停机时间?
  • 当您需要恢复备份或将服务器退出生产以进行计划维护时,什么是可访问的停机时间。
  • 您要备份的频率和位置?

随机链接 - 插入速度:

  • @Sarah - 我不仅建议拆分成表格,还建议拆分成机器。您可以并行运行查询以获得性能 [我以较小的规模进行]。服务器重启后文件系统损坏甚至例行检查怎么​​办?我不确定找到特定组合是什么意思……也许简单的键值存储会有所帮助?表大小 - 不超过几十 GB;单个服务器上的数据 - 不超过几 TB。查看 http://stackoverflow.com/questions/654594/ 以了解在更小规模的情况下会出现什么样的头痛;使用 innodb_file_per_table (5认同)