【问题标题】:Limit before sharding or partitioning a table分表或分区前限制
【发布时间】:2022-12-10 13:45:13
【问题描述】:
我是数据库系统设计的新手。在阅读了很多文章之后,我真的很困惑我们应该有 1 个表而不是进行分片或分区的限制是多少。我知道提供通用答案真的很难,事情取决于诸如
- 行的大小
- 数据类型(字符串、blob 等)
- 活跃查询数
- 什么样的查询
- 索引
- 读重/写重
- 预期的延迟
但是当有人这样问
- 如果每天有 10 亿条数据和 100 万行数据被添加,您会怎么做。对于如此大的数据库等,4 次读取、1 次写入和 2 次更新查询的延迟需要小于 5 毫秒。
- 如果您只有 1000 万行但更新和读取很高,您会如何选择。添加的新行数并不重要。高一致性和低延迟是需求。
如果行数少于一百万,而行大小增加了数千,那么选择很简单。 But it gets trickier when the choice involves for million or billion of rows.
注意:我没有在我的问题中提到延迟数。请
根据你能接受的潜伏期数来回答。此外,我们正在谈论结构化数据。
我不确定,但我可以添加 3 个具体问题:
- 假设您为亚马逊或任何电子商务订单管理系统选择 sql 数据库。订单数量每天都在增加百万。已经有10亿条记录。现在,假设没有数据归档。每秒有超过一千个查询的高读取查询。还有写入。读写比为 100:1
- 让我们举个例子,现在这个数字较小。假设您为 abc 或任何电子商务订单管理系统选择了一个 sql 数据库。订单数量每天都在增加数千。已经有1000万条记录。现在,假设没有数据归档。每秒有超过一万个查询的高读取查询。还有写入。读写比为 10:1
- 第三个例子:免费赠品分发。我们有 1000 万件好东西要分发。每个用户 1 个好东西。高一致性和低延迟是目标。让我们假设 2000 万用户已经在等待这个免费分发,并且一旦时间开始,他们都会尝试获得免费的好东西。
注意:在整个问题中,假设我们将与
SQL 解决方案。另外,如果提供的用例在逻辑上没有意义,请忽略。目的是获得数字方面的知识。
有人可以帮助确定基准是什么吗?您当前工作的项目中的任何实际数字都可以告诉您,对于具有如此多查询的如此庞大的数据库,这是观察到的延迟。任何可以帮助我证明针对特定延迟的一定数量的查询选择表数量的合理性的任何东西。
【问题讨论】:
标签:
mysql
sql
database
database-design
architecture
【解决方案1】:
MySQL 的一些答案。由于所有数据库都受到磁盘空间、网络延迟等因素的限制,其他引擎可能类似。
- 无论行数多少,“点查询”(使用合适的索引获取一行)都需要几毫秒。
- 可以编写一个
SELECT,它需要几个小时,甚至几天才能运行。所以你需要了解查询是否像这样病态。 (我认为这是高“延迟”的一个例子。)
- 当您无法维持单个服务器上所需的写入数量时,需要“分片”。
- 通过使用复制并将读取发送到副本,可以“无限”扩展大量读取。
-
PARTITIONing(尤其是在 MySQL 中)用处很少。更多详情:Partition
-
INDEXes 对性能非常重要。
- 对于数据仓库应用程序,构建和维护“汇总表”对于大规模性能至关重要。 (其他一些引擎为此内置了一些工具。)
-
INSERTing每天一百万行不是问题。 (当然,有些模式设计可能会导致这个问题。)经验法则:100/秒可能不是问题; 1000/秒可能是可能的;之后会变得更难。更多关于high speed ingestion
- 网络延迟主要取决于客户端和服务器的距离。到达地球的另一端需要200多毫秒。另一方面,如果客户端和服务器位于同一建筑物中,则延迟低于 1 毫秒。另一方面,如果您指的是运行查询需要多长时间,那么这里有一些经验法则:10ms 用于需要命中 HDD 磁盘的简单查询; SSD 为 1 毫秒。
- 如果数据太大而无法缓存在 RAM 中,UUID 和散列对性能非常不利。
- 我没有说任何关于读写比率的事情,因为我更喜欢独立判断读写。
- “每秒万读”很难实现;我建议很少有应用程序真正需要这样。或者他们可以找到更好的方法来实现相同的目标。一个用户发出查询的速度有多快?也许每秒一个?可以同时连接和激活多少用户?数百个。
- (我的意见)大多数基准测试都是无用的。一些基准测试可以表明一个系统的速度是另一个系统的两倍。所以呢?一些基准测试说当你有超过几百积极的连接,吞吐量停滞不前,延迟趋于无穷大。所以呢。应用程序运行一段时间后,捕获实际的查询也许是最好的基准。但它的用途仍然有限。
- 几乎总是单个表比拆分表(多个表;分区;分片)更好。如果你有一个具体的例子,我们可以讨论表设计的优缺点。
- 行的大小和数据的种类——大列(TEXT/BLOB/JSON)被存储为“非记录”,从而导致 [潜在] 额外的磁盘命中。磁盘命中是任何查询中成本最高的部分。
- 活动查询 -- 几十次后,查询会相互干扰。 (想想一家有很多购物者推着手推车的杂货店——“太多”的购物者,每个人都需要很长时间才能完成。)
当您进入大型数据库时,它们分为几种不同的类型;每个都有一些不同的特征。
- 数据仓库(传感器、日志等)——附加到表的“末尾”;高效“报告”的汇总表;巨大的“事实”表(可选地以块的形式存档);某些“维度表”。
- 搜索(产品、网页等)——EAV 有问题; FULLTEXT 通常很有用。
- 银行业务、订单处理——这对 ACID 功能和制作交易的需求很重要。
- 媒体(图像和视频)——如何存储庞大的对象,同时使搜索(等)相当快。
- “查找最近”——需要二维索引,
SPATIAL或一些技术here