2

这是我长久以来的疑问之一。Facebook或任何拥有超过一亿用户的网站/应用程序如何维护那里的数据库?

我相信不能把所有东西都放在一个数据库中。如果是这种情况,是否应该有多个数据库处理不同的部分?不同的部分,例如:一个数据库用于状态,一个用于照片,一个用于用户......</p>

可以使数据库模式成为关系型吗?

超过 5 亿用户并且还在增长,如果平均一个用户有 10 条文本更新,至少 50 亿行,这应该是 Facebook 实际处理的数据的 10%。

我在某处读到 Facebook 有 1800 多个 sql 实例,其中 800 多个是 memcached。这些数据库实例应该相同吗?这些应该如何设计?

4

1 回答 1

10

Facebook 和其他拥有庞大数据库的大公司使用数据库分区

分区是将表分布在多个子表上,这些子表可能驻留在不同的数据库或服务器上,以提高读/写性能。SQL Server 分区通常在表级别完成,当相关表组已分布时,数据库被视为已分区。表通常水平垂直分区。

  1. 水平分区(也称为分片)提高了整体读/写性能

    水平分区涉及将不同的行放入不同的表中。可能邮政编码小于 50000 的客户存储在 CustomersEast,而邮政编码大于或等于 50000 的客户存储在 CustomersWest。这两个分区表是CustomersEast 和CustomersWest,而可以在这两个分区表上创建一个具有联合的视图,以提供所有客户的完整视图。

    水平分区是一种数据库设计原则,其中数据库表的行是分开保存的,而不是按列拆分(如规范化)。每个分区构成分片的一部分,分片又可以位于单独的数据库服务器或物理位置上。

    这种分区方法有许多优点。每个表中的总行数减少。这减少了索引大小,这通常会提高搜索性能。一个数据库分片可以放在单独的硬件上,多个分片可以放在多台机器上。这使得数据库可以分布在大量机器上,这意味着数据库性能可以分散到多台机器上,大大提高了性能。此外,如果数据库分片是基于数据的一些真实世界分段(例如欧洲客户与美国客户),那么可能可以轻松自动地推断出适当的分片成员资格,并仅查询相关分片。

    分片在实践中远比这困难得多。尽管它已经通过手动编码完成了很长时间(尤其是在行有明显分组的情况下,如上例所示),但这通常是不灵活的。人们希望自动支持分片,无论是在为其添加代码支持方面,还是在识别要单独分片的候选者方面。

    在分布式计算用于分离多个服务器之间的负载(出于性能或可靠性原因)的情况下,分片方法也可能有用。

    分片与水平分区的比较

    水平分区通常在模式和数据库服务器的单个实例中按行拆分一个或多个表。它可以通过减少索引大小(从而减少搜索工作量)来提供优势,前提是有一些明显的、健壮的、隐式的方法来识别将在哪个表中找到特定行,而无需首先搜索索引,例如经典示例'CustomersEast' 和 'CustomersWest' 表中,他们的邮政编码已经表明他们将在哪里找到。

    分片超越了这一点:它以相同的方式对有问题的表进行分区,但它在可能的多个模式实例中执行此操作。明显的优势是大型分区表的搜索负载现在可以跨多个服务器(逻辑或物理)拆分,而不仅仅是同一逻辑服务器上的多个索引。

    跨多个隔离实例拆分分片需要的不仅仅是简单的水平分区。如果查询数据库需要查询两个实例,而只是为了检索一个简单的维度表,那么希望获得的效率收益将会丢失。除了分区之外,分片因此在服务器之间拆分大型可分区表,而较小的表则被大量复制到其中。

    这也是分片与无共享架构相关的原因——一旦分片,每个分片都可以存在于完全独立的逻辑模式实例/物理数据库服务器/数据中心/大陆中。没有持续需要保留对其他分片中其他未分区表的共享访问(从分片之间)。

    这使得跨多个服务器的复制变得容易(简单的水平分区不能)。它对于应用程序的全球分布也很有用,否则数据中心之间的通信链接将成为瓶颈。

    显然,模式实例之间还需要一些通知和复制机制,以便未分区的表保持与应用程序所需的密切同步。这是分片系统架构中的一个复杂选择:方法的范围从使这些有效地只读(更新很少且成批)到动态复制表(以减少分片的一些分布优势为代价)和许多选项介于两者之间。

  2. 垂直分区改进了对数据的访问

    在垂直分区表中,列从主表中删除,并通过称为非规范化的过程放置在子表中。这种类型的分区允许您在数据库页面上容纳更多行,从而使表更窄以提高数据访问性能。因此,单个 I/O 操作将返回更多行。通过对数据进行垂直分区,您可能不得不求助于连接来返回非规范化的列。

除了分区,当然还有复制,使数据的多个副本可用。


对关系数据库模式的影响

分片确实会破坏您的关系数据库——这是一件好事。分片背后的想法是根据某些标准将数据分发到多个数据库。例如,这可能是主键。键以 1 开头的所有实体进入一个数据库,以 2 进入另一个数据库,依此类推(通常使用键上的模函数,或基于客户位置或函数等业务数据的组)。分片存在几个原因,主要的两个是更好的性能和更低的崩溃数据库的影响——只有名字以 S 开头的人才会受到数据库崩溃的影响。

几十年来,关系数据库一直是数据存储的首选工具。但他们做的不仅仅是存储数据。甚至读取操作也可以拆分为几个函数。至少有三种数据库读取查询:

  1. 数据图构建查询:通过这些,您可以从数据库、客户以及地址等中获取数据。

  2. 聚合查询:8月份有多少订单,按产品类别聚合

  3. 搜索查询:给我所有住在纽约的客户

分片现在取消了第二个和第三个查询,并将数据库减少到数据存储。因为分片是不同系统上的不同数据库,如果没有跨系统的自定义代码,您无法聚合查询(与集群相比),并且您无法使用一个查询进行搜索(只有几个查询 - 每个数据库一个)。数据库导致了这样一种观念,即搜索和检索是联系在一起的,应该一起处理。大多数人认为检索和搜索是一回事。这阻碍了技术的发展。Sharding、S3、Dynamo、Memcached 最近改变了这种观念。来自 Qi4j 的 Rickard 是这么说的:

实体真的很酷。我们决定将存储与索引/查询分开,有点像互联网与网站与谷歌的工作方式,这使得实现非常简单的存储成为可能。不必处理查询使事情变得容易得多。

因此,存储和搜索是两个不同的东西,任何大型网络相关公司处理它们的方式都不同。

人们谈论拆分存储和搜索已经有一段时间了。像 Lucene 这样的搜索引擎已经将搜索排除在数据库之外。但主要是商店和搜索的概念很流行。分片作为一种提高性能和降低风险的机制将进入许多网络公司,并将数据库简化为存储机制,并放弃聚合(数据仓库和报告)和搜索部分。这些可以更好地填充真正的数据仓库服务器,如 Mondrian 和基于 Lucene 的搜索服务或 Sesame 等语义引擎。存储可能会从关系数据库转移到Amazon Simple DBJDBM或 NoSQL 等简单存储。

于 2011-05-10T08:23:42.270 回答