使用不同的存储引擎了解 MYSQL 集群中的分片

Understand Sharding in MYSQL cluster with different storage engines

在MySQL学习后,我了解到流行的集群有两种类型,即InnoDB和NDB。我想讨论的是 sharding.

InnoDB集群并没有真正通过分区的方式将数据分布到各个节点上。它只是在本地对数据进行分区(每个节点通过复制具有相同的复制数据),而 NDB 集群则这样做。此外,InnoDB 集群的缺点是应用程序级分区,这意味着必须决定要使用哪个分区。 例如SELECT * 来自 table 分区 (p1)。

我理解的对吗?

您似乎认为必须在查询中指定分区:

SELECT * FROM table PARTITION (p1);

这不是必需的。分区的一个特点是,如果它可以从您的查询逻辑中推断出要读取哪个分区,它会自动执行。

假设您的 table 被 created_at 列分区。引用该列中特定日期的查询将知道要访问哪个分区,而无需在 table 提示语法中指定它。

SELECT * FROM table WHERE created_at = '2020-11-28'; 

它访问哪个分区取决于您在创建 table 时定义分区的方式。但它是确定性的,只要您的搜索条件引用用作分区键的列。请参阅 https://dev.mysql.com/doc/refman/8.0/en/partitioning-pruning.html 了解更多相关信息。

如果您 运行 查询 引用分区键列,则它无法进行此推断。假设您按 created_at 分区,但您 运行 此查询:

SELECT * FROM table WHERE user_id = 12345;

user_id 的行可能出现在任何甚至所有分区中。分区引擎无法在不读取分区的情况下猜测哪些分区包含匹配的行。这就是它的作用——它读取 所有 个分区。

但是,如果您不知何故知道您只对分区 p1 中的行感兴趣,那么您将在查询中指定它,如您所示。


你说得对,InnoDB Cluster 没有为你做分片。所有节点都有所有数据的副本。它是一种冗余解决方案,而不是可扩展性。

NDB Cluster 也不用于分片。所有数据都存储在同一个集群中,但集群中可能有多个数据节点。但是 NDB 具有多个数据节点的目的不是可伸缩性,它主要是为了高可用性 (HA)。作为次要好处,它为您提供了一种通过添加更多节点来扩展存储的方法。

但是如果您在设计数据库 table 和查询时不小心,您可能会 运行 查询 比您 慢 将所有数据存储在同一个物理节点上。

我以前见过这种情况:一个 MySQL 用户将他们的数据库设计为 运行 在单个节点上,然后一些销售人员告诉他们 NDB Cluster 更快,所以用户移动了他们的数据库到 NDB Cluster,而不考虑将它们的 tables 和查询匹配到分布式架构。结果是他们的查询必须从每个存储节点收集数据,并且他们的性能下降。

这是每个分布式数据库架构的特征。

有时它被称为“跨分片查询”或“扇出查询”。但基本原则是,只有当您的查询可以通过仅访问一个(或至少一小部分)分片来获得结果时,您才能获得可伸缩性。如果它必须“扇出”,那么您就失去了任何可扩展性优势。

因此,它要求您非常仔细地设计 table,牢记您要对数据进行 运行 的查询。

简答:InnoDB Cluster 不提供分片。 (也就是说,将 table(s) 拆分到多个服务器。)NDB 会。

长答案:

对于任何“普通”数据库,只需使用 InnoDB。也许只有 1% 的 MySQL 用户“需要”NDB。在与熟悉 NDB 和 InnoDB 的人讨论过您的应用程序之前,甚至不要考虑它。

也许只有 1% 的 InnoDB 用户曾经“需要”PARTITIONing。当我在这个论坛上遇到这种情况时,我通常会花时间解释为什么 没有 分区实际上会更好。再一次,让我们听听您的申请是什么。

“分区”经常与“分片”相混淆。对于 MySQL,分片,而不是分区,涉及将不同的行放在不同的物理服务器上。分片也是 1% 的特性。再一次,让我们讨论一下它是否相关。

我很乐意更详细地讨论上述任何内容,但只是在更集中的背景下。

一般来说,最好在 InnoDB 中制作原型,增加数据集,直到您看到对 NDB/分区/分片的真正需求。到那时,您将更好地了解您需要什么以及如何做(服务器拓扑、分区/分片键等)