![MySQL:具有高更新频率的超大集合的表组织](https://linux22.com/image/508995/MySQL%EF%BC%9A%E5%85%B7%E6%9C%89%E9%AB%98%E6%9B%B4%E6%96%B0%E9%A2%91%E7%8E%87%E7%9A%84%E8%B6%85%E5%A4%A7%E9%9B%86%E5%90%88%E7%9A%84%E8%A1%A8%E7%BB%84%E7%BB%87.png)
我在选择 MySQL 模式应用程序时面临困境。因此,在我开始之前,这里有一张极其简化的数据库图片:
架构如下:http://i43.tinypic.com/2wp5lxz.png
一句话:对于每个客户,应用程序都会收集文本数据并为收集到的每个数据附加标签。
作为对每个表的使用情况的近似估计,我期望如下:
- 客户:约 5000 人,增长速度不会很快
- 数据:每个客户 500 万,大客户的数据可能增加一倍或三倍。
- 标签:~1000,相当固定的大小
- data_tag : 每个客户动辄数亿个。每个数据都可以被标记很多。
收集过程是永久性的,这意味着大约每隔 15 分钟就会有新的数据到来并被标记,这需要非常持续的索引刷新。
我的许多查询都是在特定日期之间选择数据计数,并用特定客户的特定标签进行标记(很少涉及多个客户)。
情况就是这样,你可以想象,面对如此大量的数据,我在数据组织和索引方面面临着挑战。同样,这是我的结构的一个非常简约和简化的版本。我的问题是,这样是否更好:
- 坚持使用这个模型并管理疯狂的索引优化?(这涉及 data_tag 表中可能包含数十亿行)
- 更改架构并为每个客户使用一个数据表和一个 data_tag 表?(这涉及在我的数据库中拥有 5000 个表)
我在一台 MySQL 5.0 专用服务器(四核,8G 内存)上复制运行所有这些。我只使用 InnoDB,我还有另一台运行 Sphinx 的服务器。了解了所有这些之后,我迫不及待地想听听你对此的看法。
谢谢。
编辑
感谢您的回答,我意识到这些数字有多疯狂。因此,以下是更新后的表格更实际的用法(基于实际服务器,它只是一个基本的机架空间箱)。
- 客户:2000(固定)
- 数据:每个客户 100 万(固定,存档旧数据。非常不公平:一些客户只有几千个,最大的有 500 万)
- 标签:1000(固定)
- data_tag:每个客户约 3 或 5 百万(取决于数据,因此也不公平)。
谢谢。
答案1
根据我多年使用 MySQL 的经验,我的看法是,后一种选择听起来更合乎逻辑、更现实。
与当前架构相比,每个客户使用一个数据和一个 data_tag 具有更简单的整体可管理性。第二个选项的编码也将更简单。
您可以询问更多 MySQL 专家;您的第二个选择是最好的。
如果你愿意的话我可以详细地讲,这是针对一个大问题的一个简化问题的简单答案。它是双向的。
答案2
除了您在此处提供的内容之外,如果不了解您的应用程序的很多信息,那么很难说。您的数据模型非常简单,这对您有利,因为您预计会有数十亿行。我会避免创建超过 5k 个表,因为如果您尝试这样做,您可能会遇到文件描述符问题和缓存限制。
当然,您可能可以通过 ulimit/configure 将它们移除,但这仍然不是最佳配置。
您是否也在非关键数据上创建索引?例如,这些名称列?这可能会降低您的写入性能,从而导致 15 分钟的批处理作业被备份。
老实说,如果这是我的应用程序,我会考虑两种潜在的解决方案:
如果性能成为问题,请按照您现有的方案,将客户分散到多个 MySQL 服务器。除非您拥有这些数据并安排好这些客户,否则目前还不是问题。不要花太多时间设计“如果”。坚持使用简单的模式,将第一批用户引入第一台服务器。当您开始达到容量上限时,引入第二台服务器,并将这些新用户隔离到该数据库。可以称之为分片。使用资源监控和良好的管理技术进行支持,这样您就知道何时接近“容量上限”。
Cassandra 或 MongoDB 之类的东西能行吗?我对您的查询了解不够多,无法建议或排除它。MongoDB 可能是一个选择。值得一试。
所以,简而言之,让 MySQL 做它擅长的事情,多运行一些就行。或者,如果可能的话,看看 Mongo 之类的东西。
答案3
嗯,根据我的经验,你确定 MySQL 是最好的数据库吗?试过看看 Oracle 或 SQL Server(尽管 Oracle 集群在这里可能有优势)?
如果您认为许可成本会让您吃不消,我只能说您还不知道运行它需要什么硬件。一旦您获得所需的 SAN 的第一批报价 - 您可能会嘲笑相应软件的价格。
只是一个想法。
- 客户——假设是 10,000,正如您所指出的,它将快速增长。
- 数据 - 假设平均每个客户有 700 万。数据表已经有 700 亿行了。是的,抱歉,4 个零确实加起来了。
- 如果每个数据有 10 个标签(您未指定任何内容),我们谈论的 data_tag 字段接近 7000 亿行。
变得更加疯狂。
- 如果 DataTag 没有索引且没有开销(它有),data:tag 是每个条目 10 个字节 - tag_id 为 2 个字节(65536 就足够了),遗憾的是 data_id 为 8 个字节 - 您无法用 4 个字节来处理 7000 亿个条目。这总共是大约 7800 GB 的原始数据(700.000.000.000 * 12 / 1024 / 1024 / 1024)。索引可能会使这个数字翻倍。
为了高效处理这些数据,这是一个高端 SAN。我们这里说的不是“10 个磁盘”,而是高端 SAN,可能有 400 个以上的磁盘来处理所有这些数据 - 别忘了到目前为止我们实际上还没有任何索引。
我正在一个 MySQL 5.0 专用服务器(四核,8Go RAM)上复制运行所有这些。
不错的尝试。这到底有什么用?不好意思,但 8GB RAM 真的没什么用(这里没有印象),买一台 256GB 的机器吧……这可能需要 AMD 和那些非常昂贵的 Opteron 8000。但你需要 RAM。
无论如何,这将是(我怀疑您是否正确陈述了事实)世界上最大的数据库安装之一。
您肯定想要某种可以处理这种情况的东西 - 如果您确实需要这样做,Oracle 群集或 SQL Server 群集可能会加快速度。在我看来,这远远超出了免费数据库所能处理的范围。真的。
而且您需要适当的备份程序(MySQL 缺乏此程序)。您还可能喜欢 SQL Serve 2008 数据页压缩,它可能会将磁盘上的数据大小减少约 50%。这不仅因为节省了磁盘成本,还因为它意味着更少的 IO - 这直接转化为更高的性能(因为您无法将表缓存在内存中)。
虽然我不愿意这么说,但您可能还想考虑在一台不错的大型机上使用 IBM DB2 - 我不是说在它上面运行 Linux VM。由于硬件架构,VMS 在处理超大规模数据库方面具有极大的优势。不要问价格 ;)