系统设计 System Design -2-2-数据分区、索引、代理、冗余和复制、SQL 与 NoSQL、CAP定理、PACELC定理、一致性哈希

53 阅读7分钟

数据分区

将大型数据库分区。提高性能和可扩展性

1. 分区方法

a. 水平分区:分量 (例如:根据地理位置)

b. 垂直分区:分结构 (例如:历史记录和付款信息)

c. 混合分区:分量+分结构(都有)

2. 划分标准

a. 基于键或哈希的分区:使用“一致性哈希”解决添加新服务器的问题

b. 列表分区:每个分区都分配一个值列表

c. 循环分区:n 个分区,第 i 个元组会被分配给 (i mod n) 个分区,感觉像是最简单的哈希分区

d. 复合分区:列表(结构) + 哈希(效率)

3. 数据分区的常见问题

原因:跨多个表 、跨服务器

a. 连接和非规范化

  • 为了避免跨分馆查询(Join)的低效,我们选择在每本书上都多写点作者信息(非规范化),但这大大增加了保持所有信息同步更新的难度。

b. 参照完整性:

  • 数据库放弃了跨分馆执行“作者必须存在”的规则(外键),这个责任转嫁给了你的程序,但程序可能会犯错,导致你需要定期去清理烂摊子。

c. 重新平衡:

  • 当数据或访问压力不均时,需要重新划分分区(搬家),这是一个非常复杂且高风险的操作。使用中央咨询台可以简化这个过程,但这个咨询台本身又成了一个致命的弱点。


索引

索引就像一本书的目录,它的本质是用“预先排序好的额外空间”,来换取“查找时不用遍历全文”的极速时间。

需要在那些经常被用作“查询条件”、“排序依据”的字段上建立索引,但也要避免在“写密集型”、“小型表”或“低选择性”的字段上滥用索引,以免得不偿事故。


代理

代理服务器

  • 位于客户端和服务器之间的中间软件或硬件

正向代理

正向代理可以代表客户端发送请求,从而向服务器隐藏客户端的身份。

  • 用于缓存数据、过滤请求、记录请求或转换请求(通过添加/删除标头、加密/解密或压缩资源)。
  • 折叠转发:可以将相同的数据访问请求合并为一个请求

反向代理

反向代理隐藏了服务器的身份。

  • 可用于缓存、负载平衡或将请求路由到适当的服务器


冗余和复制

冗余是指对系统关键组件或功能进行复制,以提高系统的可靠性(通常以备份或故障保护的形式),或提升系统的实际性能

主服务器 + 副本服务器

数据库复制策略

  • 同步复制:主数据库会等待副本数据库确认已接收并处理更改,然后才会确认写入操作

  • 异步复制:主数据库上的写入操作与副本数据库上的更新之间存在延迟,写入操作无需等待副本数据库的确认

  • 半同步复制:对主数据库所做的更改会立即复制到至少一个副本数据库,其他副本数据库异步更新


SQL 与 NoSQL

SQL

关系数据库以行和列的形式存储数据

  • MySQL、Oracle、MS SQL Server、SQLite、Postgres 和 MariaDB

NoSQL

键值存储: Redis、Voldemort 和 Dynamo

文档数据库: CouchDB 和 MongoDB

宽列数据库: 列式数据库不使用“表”,而是使用列族,即行的容器;Cassandra 和 HBase

图形数据库: 包含节点(实体)、属性(实体信息)和线(实体之间的连接);Neo4J 和 InfiniteGraph。

SQL 和 NoSQL 之间的高级差异

  • 模式: SQL的模式是静态的,NoSQL的模式是静态的

  • 查询: SQL(结构化查询语言) / UnQL(非结构化查询语言)

  • 可扩展性:

    • SQL 数据库天生适合垂直扩展,但也可以通过更复杂的方式(分片)来实现水平扩展
    • 🐂🍺NoSQL 数据库可水平扩展,可轻松添加更多服务器来处理大量流量。任何廉价的商用硬件或云实例都可以托管 NoSQL 数据库,因此比垂直扩展更具成本效益。许多 NoSQL 技术还能自动在服务器之间分发数据。
  • 可靠性或 ACID 合规性(原子性、一致性、隔离性、持久性) :SQL 数据库好

使用 SQL 数据库的原因

ACID合规、结构化、不可变、不需要大规模增长

使用 NoSQL 数据库的原因

存储大量通常缺乏结构的数据、充分利用云计算和存储(开箱即用扩展)、快速开发


CAP定理

image.png 分布式系统的问题:服务器崩溃或永久故障,磁盘损坏导致数据丢失,或者网络连接中断导致系统部分功能无法访问

一致性 ( C ): 所有节点同时看到相同的数据。

可用性 ( A ): 系统中非故障节点收到的每个请求都必须得到响应。

分区容忍性 ( P ) :即使系统中存在分区(网络故障),分区容忍系统也能继续运行。凭借数据的充分复制。

  • 选择一:为了保证数据绝对正确,我选择停止服务。
  • 选择二:为了保证服务一直在线,我接受数据暂时不一致。

总结:在存在网络分区的情况下,分布式系统必须在一致性或可用性之间做出选择


PACELC定理

image.png 在复制数据的系统中:

  • 如果存在分区(“P”),分布式系统可以在可用性和一致性之间进行权衡(即“A”和“C”);
  • 否则(“E”),当系统在没有分区的情况下正常运行时,系统可以在延迟(“L”)和一致性(“C”)之间进行权衡。

示例:

  • Dynamo 和 CassandraPA/EL系统:当发生分区时,它们选择可用性而不是一致性;否则,它们选择较低的延迟。

  • BigTable 和 HBasePC/EC系统:它们总是会选择一致性,而放弃可用性和更低的延迟。

  • MongoDB可视为PA/EC(默认配置):MongoDB 采用主/从配置。在默认配置中,所有写入和读取操作均在主服务器上执行。由于所有复制都是异步完成的(从主服务器到从服务器),因此,当发生网络分区,导致主服务器丢失数据或在少数副本侧被隔离时,可能会丢失未复制到从服务器的数据,从而导致分区期间一致性丧失。因此,可以得出结论:在发生网络分区的情况下,MongoDB 会选择可用性,但在其他情况下会保证一致性。或者,当 MongoDB 配置为在多数副本上写入并从主服务器读取时,可以将其归类为 PC/EC。


一致性哈希

image.png

一致性哈希算法将数据映射到物理节点,并确保在添加或移除服务器时,只有一小部分键会移动。

读取或写入数据:对密钥应用MD5 哈希算法,输出决定了数据所在的范围,从而决定了存储节点。

虚拟节点(Vnode)

解决添加和删除节点导致的数据和负载分布不均匀

手动固定划分范围的一些潜在问题:

  • 添加或删除节点:由于数据连续分布,迁移量巨大
  • 热点:由于数据连续分布,某些节点可能会成为热点
  • 节点重建:给副本节点带来很大压力,可能导致雪崩效应

虚拟节点

  • 不再将单个令牌分配给每个节点,而是将哈希范围划分为多个较小的范围,每个物理节点分配多个较小的范围。每个服务器负责的小块是分散在整个蛋糕环上的,而不是连续的一大块

虚拟节点的优势

  1. 添加新节点:数据迁移的工作被平均分摊给了集群里的所有老成员
  2. 节点重建:重建的压力被整个集群分担了
  3. 热点被天然地分散到了多台不同的物理服务器上。

使用一致性哈希进行数据复制

一致性哈希将每个数据项复制到系统中的多个 N 个节点上,其中 N 的值等于复制因子。

一致性哈希的使用场景

  • 存储服务器系统的扩大或缩小
  • 根据流量负载通过添加或删除缓存服务器来动态调整其缓存使用情况
  • 通过数据复制:防止单点故障