database-design - 高可用性和数据库设计

标签 database-design high-availability

这是我很长一段时间以来一直在思考的问题之一。
拥有超过一亿用户的Facebook或任何此类网站/应用程序如何维护该数据库?

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

可以使数据库架构具有关系性吗?

5亿以上的用户,并且在不断增长,如果平均每个用户有10个文本更新,则至少有50亿行,这应该是Facebook实际处理的数据的10%。

我读到某个地方,Facebook有1800多个sql实例,其中有800多个被内存缓存。这些数据库实例是否应该相同?这些将如何设计?

最佳答案

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

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

  • 水平分区(也称为 sharding )提高了总体读取/写入性能

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

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

    这种分区方法有很多优点。每个表中的总行数减少了。这样可以减小索引大小,从而通常可以提高搜索性能。可以将数据库分片放置在单独的硬件上,并且可以将多个分片放置在多台计算机上。这样可以在大量计算机上分布数据库,这意味着数据库性能可以分布在多台计算机上,从而大大提高了性能。另外,如果数据库分片是基于数据的某些真实世界的细分(例如,欧洲客户对美国客户),则可以轻松,自动地推断出适当的分片成员身份,并且仅查询相关分片。

    实际上,分片要比这困难得多。尽管已经通过手工编码完成了很长时间(特别是在行具有明显分组的地方,如上面的示例所示),但这通常是不灵活的。希望自动地支持分片,既增加对代码的支持,又识别要分开分片的候选者。

    如果使用分布式计算来分隔多个服务器之间的负载(出于性能或可靠性的原因),则分片方法也可能有用。

    与水平分区相比的碎片

    水平分区通常在模式和数据库服务器的单个实例中按行拆分一个或多个表。如果存在某种明显的,健壮的,隐式的方式来标识将在哪个表中找到特定行而无需首先搜索索引(例如,索引),则可以通过减小索引大小(从而减少搜索工作量)来提供优势。 “CustomersEast”和“CustomersWest”表的经典示例,其邮政编码已经指示了将在何处找到它们。

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

    在多个隔离的实例之间拆分碎片不仅需要简单的水平分区。如果查询数据库需要查询两个实例,而只是检索一个简单的维表,则效率的期望提高将丢失。因此,除了分区之外,分片还可以在服务器之间拆分大型可分区表,而较小的表则可以批量复制到它们中。

    这也是为什么分片与无共享架构相关的原因-分片后,每个分片都可以生活在完全独立的逻辑架构实例/物理数据库服务器/数据中心/大洲中。不再需要保留对其他分片中其他未分区表的共享访问(从分片之间)。

    这使得跨多个服务器的复制变得容易(简单的水平分区无法实现)。这对于在世界范围内分发应用程序也很有用,否则,数据中心之间的通信链接将成为瓶颈。

    显然,在模式实例之间还需要某种通知和复制机制,以便未分区的表保持与应用程序所需的紧密同步。这在分片系统的体系结构中是一个复杂的选择:方法包括使这些分片有效地只读(很少进行更新和批量更新),动态复制表(以减少分片的一些分发好处为代价)和许多选择。在两者之间。
  • 垂直分区可改善对数据的访问

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

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

    对关系数据库架构的影响

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

    关系数据库是数十年来数据存储的首选工具。但是它们不仅仅存储数据。甚至读取操作也可以分为几个功能。至少有三种数据库读取查询:
  • 数据图构建查询:通过这些查询,您可以从数据库,客户以及地址等中获取数据。
  • 聚集查询:八月已存储了多少订单,按产品类别
  • 聚集
  • 搜索查询:给我所有住在纽约的客户

  • 分片现在消除了第二和第三个查询,并将数据库缩减为数据存储。由于分片是不同系统上的不同数据库,因此,如果没有跨系统的自定义代码,就无法汇总查询(与集群相比),并且无法使用一个查询(每个数据库只有几个查询)进行搜索。数据库导致了这样一个概念,即搜索和检索链接在一起,应该一起处理。大多数人认为检索和搜索是同一件事。这阻碍了技术的发展。 Sharding,S3,Dynamo,Memcached最近改变了这一观念。来自Qi4j知名度的Rickard这样说:

    Entities are really cool. We have decided to split the storage from the indexing/querying, sort of like how the internet works with websites vs Google, which makes it possible to implement really simple storages. Not having to deal with queries makes things a whole lot easier.



    因此,存储和搜索是两回事,任何与网络相关的公司都对它们的处理方式不同。

    人们现在谈论拆分存储和搜索一段时间。诸如Lucene之类的搜索引擎已开始搜索数据库。但是主要是存储和搜索的概念很普遍。分片作为一种提高性能和降低风险的机制将进入许多Web公司,并减少数据库到存储机制的数量,并减少聚集(数据仓库和报告)和搜索部分。可以使用诸如Mondrian这样的真实数据仓库服务器以及基于Lucene或Sesame这样的语义工程的搜索服务来更好地填充这些数据。存储可能会从关系数据库转移到简单存储,例如Amazon Simple DBJDBM或NoSQL。

    关于database-design - 高可用性和数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5854124/

    相关文章:

    locking - 动物园管理员的替代品? (集群协调服务)

    apache-zookeeper - 领导选举与 : Etcd vs Zookeeper vs Hazelcast

    sql - 为什么将表关系存储在不同的表中?

    mysql - 在验证第三范式的数据库逻辑模式时需要一些帮助

    php - 跟踪点 : insert or update?

    high-availability - HA gearman 作业服务器的最佳实践是什么

    MongoDB——跨数据中心初选DRP/地理分布式副本集

    elasticsearch - Elasticsearch 7.3 Rest客户端是否发现新节点?

    mysql - 数据库连接-数据库设计-父级-子级-子级的子级

    MySQL 数据库设计建议 - 使用连接