【问题标题】:Order by across multiple database in sharding在分片中跨多个数据库排序
【发布时间】:2020-08-17 12:03:38
【问题描述】:

假设我们正在开发一个拥有数十亿用户的 Instagram。我们在多个数据库中(在不同的分片实例/服务器/设备中)对照片表进行分片,并且在照片表中我们有一个createdAt 列。现在用户在应用中打开主页选项卡,应用应该在多个数据库中的照片表中全局(非本地)显示最近的 20 张照片(order by createdAt desc)。 SQL查询应该是怎样的?

我们必须对照片表进行分片,因为数十亿用户会制作数千亿张照片。我们无法在一台服务器的一个数据库中的一张表中存储和提供数千亿张照片。

假设我们有 100 台数据库服务器,一种可能的解决方案是在超过 100 台数据库服务器的照片表上查询 select id from photo order by createdAt desc limit 20。然后在我们的后端,我们得到 20*100 = 2000 张照片行,并在后端(Node.js、Java、Python 等)中按 createdAt 对它们进行排序,只返回前 20 行。

【问题讨论】:

  • 也许你不应该抢先分裂。为什么您认为同一服务器上的多个数据库更好?你是如何分片照片表的?因为如果它按用户,它只有一个数据库查询,而且是一个非常基本的查询。你选择 MySQL/Postgres 了吗?
  • @danblack 我并不是说多个数据库在同一台服务器上。 MySQL/Postgres 或其他 RDMS 都很好。请看我的编辑。谢谢!

标签: mysql database postgresql database-design


【解决方案1】:

从每个数据库中获取前 20 行并在应用程序内存中排序的简单方法。 有更好的解决方案可以避免使用数据库游标将所有 20*100=2000 的数据一起加载到内存中。由于来自每个数据库的所有数据都是有序的,我们可以只比较当前游标的数据,将最小(或最大,ASC 或 DESC 的依赖)数据保存到获取的数据中,然后用游标调用 next。每个next 只需要调用真正的下一次。它被称为流顺序。

有点复杂,幸运的是Apache ShardingSphere实现了数据分片功能,并使用智能合并排序来处理上述算法。

FIY:https://shardingsphere.apache.org/document/current/en/features/sharding/principle/merge/#order-by-merger

【讨论】:

    【解决方案2】:

    现在谈论分片还为时过早。在您的数据集中有数百万个条目之前不要考虑它。

    到那时,您将至少重新设计一次架构。只有在第二次或第三次重新设计之后,您才应该担心分片。比如……

    当你到达那里时,这里有一些提示:

    • 一个表(或一小组密切相关的表)将在多台机器上拆分(“分片”)。
    • 其他表需要跨分片复制,或者保存在不同的机器上。维护这些表成为一项单独的管理任务。
    • 它将被一些“id”分片。您选择的 id 可能需要更改;但不要纠结于此。 UUID 有性能问题,但是让多个客户端独立构造唯一的 id。有更好的方法;稍后再打。
    • 您将需要多层机器——用于数据库、Web 服务器、路由器等。
    • 需要查看所有分片的查询编写起来很复杂并且运行缓慢。所以尽量避免这种情况。
    • 可以通过散列或字典或两者的混合来完成分片。
    • 编写一个工具来将用户从一个分片迁移到另一个分片。该工具是简化许多任务的关键——硬件升级、软件升级、崩溃修复、负载平衡等。
    • 将照片放在不同的服务器上;仅在数据库中保留 URL。这可以简化事情,更有效地利用硬件等。
    • 100B 张照片,每张 1MB -- 这将需要 许多 标准机器或一些巨大的 SAN。保持它独立于数据库可以让您单独扩展它。
    • “所有分片中的 20 张最近的照片”——建议您使用具有 API 的非分片服务器,其主要目的是接收 URL 并维护该列表;加上提供清单。这可能是一台服务器可以处理的全部。并且一直触及所有碎片可能会使整个系统陷入瘫痪。
    • 您将需要数百台服务器来满足您的描述;你的预算是多少?您的 HA 要求是什么?数百台机器==每隔几天就会崩溃一次。而且您需要每隔几天添加另一台服务器以增加容量。您将招聘多少 SA/DBA IT 专家?

    Flickr 是多年前在分片 MySQL 服务器上构建的。所以,这是可能的。他们有一个“小组”,其唯一目标是上传一百万张照片。那条“鲸鱼”给了他们一些挑战。

    【讨论】:

      【解决方案3】:

      如果按用户拆分数据库服务器是此表的逻辑映射,则在应用程序中应用映射(最好是不需要数据库查找的映射),然后直接使用SELECT .. FROM photos ORDER BY createdAt DESC的数据库服务器@

      【讨论】:

        【解决方案4】:

        听起来您正在寻找的是Spider storage engine from MariaDB。 这将让您在不同的服务器上拥有每个分区。您应该意识到,像这样的架构从来都不是完全透明的——要从中获得最佳(甚至是好的)性能,您必须围绕底层数据存储的性能副作用来设计整个应用程序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多