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


39

这是问题...

考虑到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`)
    );

这是查询...

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")

这里有一些笔记...

  • 与INSERT相比,SELECT的执行频率要高得多。但是,有时我想一次添加几百条记录。
  • 负载方面,数小时之内什么都没有,那么一次可能有数千个查询。
  • 不要以为我可以再规范化了(需要结合使用p值)
  • 整个数据库是非常相关的。
  • 这将是迄今为止最大的表(下一个最大的表是约90万)

更新(08/11/2010)

有趣的是,我还有第二种选择...

而不是192万亿,我可以存储2.6 * 10 ^ 16(15个零,表示26 个万亿次)...

但是在第二种选择中,我只需要在表中存储一个bigint(18)作为索引。就这样-仅一栏。因此,我只是要检查值的存在。偶尔添加记录,从不删除它们。

所以这让我认为必须有一个比mysql更简单的存储数字的解决方案...

有了第二种选择,我应该还是选择第一种呢?

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


7
您如何为此使用MySQL?如果有人提供可靠的论据,可以说服您切换到其他dbms吗?
WheresAlice10年

3
万亿,例如10 ^ 12还是10 ^ 18?
andol 2010年

15
在192万亿条记录中,您应该有一个预算,该预算可以让您向MySQL提交者而不是某些讨论论坛提问。
雷木斯·鲁萨努

5
对于这么大的数据库(显然是不错的预算),为什么不使用经过证明可以轻松处理大型DB的oracle或sql serer解决方案呢?
Jim B

5
在执行此操作时,请确保及时更新。我当然会感兴趣。您可能还想为highscalability.com
O'Connor

Answers:


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上的空间转移成本超过1万英镑/ TB,这不包括控制器的任何资本补贴。

您真的需要像Teradata或Netezza这样的无共享系统来处理大量数据。分片MySQL数据库可能有效,但我建议使用专用的VLDB平台。无共享系统也使您可以在节点上使用便宜得多的直接连接磁盘-看看Sun的X4550(thumper)平台是否可行。

您还需要考虑性能要求。

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

简而言之,针对MySQL的最强论据是,如果有可能,您将进行反向翻转以在7PB的数据上获得不错的查询性能。如此大量的数据确实使您进入了无共享领域,可以进行一些合理的查询,并且从一开始就可能需要一个专为无共享操作而设计的平台。单凭磁盘将使任何合理的DBMS平台的成本相形见war。

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

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


1
@ConcernedOfTunbridgeW-他们总是可以这样走:blog.backblaze.com/2009/09/01/…-比SAN有趣得多,只需要约 120-130 4U盒子...但是我不确定'业务”将很高兴....
pQd

本质上是预算上的Sun Thumper,实际上是无共享系统中节点选项的示例。我敢肯定,我也看到了其他选择,但我想不出where。问题不是什么硬件,而是什么数据库平台。
ConcernedOfTunbridgeWells,2010年

但是,敏锐的观察者会注意到,与基于SAN的任何产品相比,此类基于直接连接的产品每TB的价格都要便宜得多,这至少是一个重要论点,赞成设计用于无共享平台的产品。
ConcernedOfTunbridgeWells,2010年

@ConcernedOfTunbridgeWells,您可以在多个[否则耗电]框上并行运行所有这些查询/维护和其他任何内容。
pQd 2010年

1
@ConcernedOfTunbridgeWells-回答您的问题...如果可能,我需要大约500个查询才能在一秒钟内返回。我一天只会做几百次。但是,当查询运行时,确实需要扫描整个表。另外,INSERT的优先级低于SELECT的优先级,因此它不必在即时范围内。我可以等待几个小时,以使“新”数据进入数据库。
萨拉

16

分片。在这种规模的情况下,只有一个大实例很容易自杀-考虑可能的备份还原,表空间损坏,添加新列或任何其他“内部整理”过程-所有这些都不可能在此规模的合理时间内完成。

简单的回溯计算-假设除64位ID以外的所有列均使用32位整数;不包括索引:

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

192万亿行40B每个给我们近7 PB

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

要回答的问题:

  • 如果系统崩溃/重新启动,可接受的停机时间是多少?
  • 当您需要恢复备份或将服务器退出生产以进行计划维护时,可访问的停机时间是多少?
  • 您要多久备份一次?在哪里备份?

随机链接-插入速度:


我同意-7PB很重。我希望重新考虑它,并找到一个更简单的解决方案,但是我需要找到p字段的特定组合的存在(或不存在)。拆分表让我很想念-这更明智,但这仅意味着我已依次查询了每个表。出于兴趣,您建议将几个表格拆分到此处?
莎拉(Sarah)2010年

5
@Sarah-我不仅建议拆分成表格,还要拆分成机器。您可以并行运行查询以提高性能[我以较小的规模进行]。服务器重启后文件系统损坏甚至例行检查怎么​​办?我不确定通过找到特定组合意味着什么...也许简单的键值存储会有所帮助?表格大小-不超过几十GB;单个服务器上的数据-不超过几TB。查看stackoverflow.com/questions/654594以了解在较小的规模下会发生什么头痛;使用innodb_file_per_table
pQd 2010年


2

可能还有另一种方法,而不是存储四千万个数字,如果您要做的就是查看它们是否在集合中。 布隆过滤器是通过多种方式进行哈希处理的一种概率方法。同样,误报是可能的,但误报是不可能的。(因此,它可能会说数字在集合中-并错了,但是如果确实存在,它不会说它不存在)。仍然存在大量项目要存储的问题,但是至少它可以使工作数据集的大小有所减小。


听起来很有趣,尽管我可以忍受错误的否定-但不能接受错误的肯定:)
Sarah 2010年

2

编辑:实际上,如果它只是X位置的“记录”在整数范围内的存在或不存在,则可以消除数据存储而仅使用位图...因此,大约10台具有100 TB磁盘空间的计算机(因此,您有10个位图副本用于性能和备份),并且如果每个服务器都具有128GB的RAM,则可以在内存中容纳高分辨率顶级块组索引来进行第一次检查,然后再将磁盘击中26 Quadrillion的X位。

如果您采取以下措施,我会选择方案2:

375台具有64TB(32个2TB驱动器)的计算机(实际上是400台发生故障的计算机),然后将记录映射到每个2TB的ZVOL。然后在一个或多个索引服务器上,存储在Judy数组或critbit数组中或仅在普通位图中,存储是否映射到26个Quadrillion位置中的1个的映射。索引将在50到100TB之间,如果有记录写入到某个特定的64k地址块中,而该记录可以容纳小于64 GB的RAM,并且可以提供快速的初始检查级别,则您甚至可以拥有第二级索引是否某个“邻居”为空。

然后,要读取该记录,您首先需要通过查看索引来检查是否有要查找的记录。如果存在,则根据简单索引计算,转到该机器上的机器#(X)/ ZOL#(Y)/该2TB Blob内的记录位置#(Z)。单记录查找将非常快,您可以测试将数据存储的某些部分加载到不同的数据库中(当您使用数据存储进行实际工作时),并进行性能测试以查看它们是否能够支持整个数据库-只是以这种方式使用数据存储。

ZOL是ZFS事物,可以认为是其他文件系统中的稀疏文件,因此适用类似的事物。或者,您可以仅索引到磁盘上的某个字节数,但是如果磁盘的大小不同,如果您不将每个磁盘使用的字节数限制在适用于所有磁盘的水平上,即每2TB磁盘1.75TB,这将变得棘手。或创建固定大小的元设备,等等。


嗨,莎拉(Sarah)-不知道您是否仍在进行此工作,但是如果您需要帮助,我可以在100TB的计算机上为您制作想法的原型,并且愿意(在美国主要的数据中心)托管和管理完整的生产集群。根据需要400-500台计算机。顺便说一句,您曾经在SF的CNET工作吗?

1

除了疯狂调整数据库参数(使用mysqltuner来帮助)以尽量保持人为缓存之外,您可能要研究的一件事是在插入几百条记录时避免启动事务/ CoMMIT(假设InnoDB),以避免逐行锁定开销,并大大减少了插入时间。我还将表创建为MyISAM和InnoDB并在其上运行测试,以查看一旦加强缓存后,哪个表真正更快—并不总是MyISAM会更快地进行读取—请检查以下内容:

http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

在测试过程中,并发线程的数量也应上下变化,直到您发现服务器上可以提供多少RAM专门用于调整缓存的最佳内存为止。您可能会发现虽然可以通过数学方法支持更多的线程,但是如果线程数过多,则数据库本身实际上可能会表现得更差。

另外,如果您使用MyISAM和/或InnoDB每张表文件,则可以研究为/ var / lib / mysql创建一个不同的文件系统挂载点,该挂载点已调整为较小的块大小并调整了fs类型的参数-即ext3 / ext4 / resiserfs可以将data = writeback用于日志,并禁用I / O速度来更新文件系统上的访问时间。


1
由于交易要求,myisam似乎毫无疑问。
PQD

0

对于第二种选择,实际上可能放置多少个数字?

如果只有千分之一,或者10K,100K等,那么存储使用(或未使用)数字的范围可以节省数万亿的条目。例如:存储('free',0,100000),('taken',100000,100003),('free',100004,584234)-根据需要将行分为两行或三行,并在第一个数字上建立索引,搜索x <= {needle},以查看包含搜索数字的范围是被占用还是免费。

您甚至可能不需要这两种状态。只需存储最不可能的状态。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.