2011-05-02 105 views
2

这是我脑海中长久以来的问题之一。 Facebook或拥有超过一亿用户的任何此类网站/应用如何维护数据库?高可用性和数据库设计

我相信一切都不能放到一个单一的数据库中。 如果是这种情况,应该有多个数据库处理不同的部分?不同的部分,如:一个数据库的状态,一个用于照片和一个用户...

数据库模式可以关系吗?

如果平均一个用户有10个文本更新,至少50亿行(至少)应该是Facebook实际处理的数据的10%

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

回答

9

Facebook和其他拥有庞大数据库的大公司采用database partitioning

分区是为了提高读写性能而可能位于不同数据库或服务器上的多个子表的分布。 SQL Server分区通常在表级完成,并且在分发相关表组时分配数据库。表格通常被水平划分为垂直

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

    水平分区涉及将不同的行为不同的表。也许邮政编码小于50000的客户存储在CustomersEast中,而邮政编码大于或等于50000的客户存储在CustomersWest中。然后这两个分区表就是CustomersEast和CustomersWest,同时可以创建一个包含union的视图,以提供所有客户的完整视图。

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

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

    分片在实践中远比这更困难。尽管手工编码已经进行了很长一段时间(特别是在行数有明显分组的情况下(如上例),但这通常是不灵活的。希望自动支持分片,无论是为其添加代码支持还是用于确定分开分片的候选者。

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

    碎片相比水平分区

    水平分区由行分裂一个或多个表,通常在一个模式的单个实例和数据库服务器。它可以通过减少索引大小(以及因此搜索努力)来提供优点,前提是存在一些明显的,可靠的,隐含的方式来识别在哪个表中找到特定的行,而不首先需要搜索索引,例如, “CustomersEast”和“CustomersWest”表的典型例子,其中邮政编码已经指明了它们的位置。

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

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

    这也是为什么分片与无共享体系结构有关 - 一旦分片,每个分片可以存在于完全独立的逻辑模式实例/物理数据库服务器/数据中心/大陆中。没有持续的需要保持共享访问(从碎片之间)到其他碎片中未分区的表。

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

    很显然,在模式实例之间还需要一些通知和复制机制,以便未分区的表保持与应用程序所需的同步性。在分片系统的体系结构中,这是一个复杂的选择:从有效地只读(更新很少并且批量更新)到动态复制表(以降低分片的一些分发益处为代价)以及许多选项在之间。

  2. 垂直分区提高对数据的访问

    在垂直分区表,列从主台移出并通过一个称为非规范化处理放置在子表。这种类型的分区允许您在数据库页面上放置更多行,从而缩小表格以提高数据访问性能。因此,单个I/O操作将返回更多行。通过垂直分区您的数据,您可能不得不求助于返回非规格化的列。

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


在关系数据库模式

拆分的影响不破坏你的关系型数据库 - 这是一件好事。分片背后的想法是根据某些标准将数据分发到多个数据库。这可能是例如主键。所有以1开头的实体转到一个数据库,2到另一个数据库,等等(通常使用关键的模函数,或基于业务数据的组,例如客户位置或功能)。分片有几个原因,主要有两个原因是性能更好,崩溃数据库的影响更小 - 只有名称以S开头的人才会受数据库崩溃的影响。

当谈到数据存储时,关系数据库是几十年来首选的工具。但他们不仅仅是存储数据。即使阅读操作可以分成几个功能。至少有3种读取数据库查询:

  1. 数据图建立查询:有了这些你不会忽略等

  2. 聚集查询得到你的数据从数据库中,客户一起:有多少订单已经存储在8月,按产品类别汇总

  3. 搜索查询:给我谁住在纽约

所有客户

Sharding现在消除了第二个和第三个查询并将数据库减少到数据存储。因为碎片是不同系统上的不同数据库,所以无法跨系统聚合查询(与群集相比)而无需自定义代码,并且无法使用一个查询(只有几个 - 每个数据库一个)进行搜索。数据库已经导致了搜索和检索连接在一起的概念,应该一起处理。大多数人认为检索和搜索是一回事。这阻碍了技术的发展。 Sharding,S3,Dynamo,Memcached最近改变了这个预言。来自Qi4j的Rickard声名曰:

实体真的很酷。我们有 决定分割存储从 索引/查询,有点像 互联网与网站的工作与 谷歌,这使得它可能到 实现真正简单的存储。不是 必须处理查询使得 事情变得更容易。

因此,存储和搜索是两个不同的事情,任何大规模的网络相关公司处理它们的方式都不同。人们谈论了拆分存储和搜索一段时间的时间。像Lucene这样的搜索引擎已经推动了数据库的搜索。但主要是商店&搜索的概念是普遍的。作为更多性能和更低风险的机制,分拆将转移到许多网络公司,并将数据库减少到存储机制,并减少聚合(数据仓库和报告)和搜索部分。这些可以更好地填充像Mondrian这样的真正的数据仓库服务器,以及基于Lucene的搜索服务或者像Sesame这样的语义enginse。存储可能会从关系数据库转移到简单存储,如Amazon Simple DBJDBM或NoSQL。