数据库水平扩展和垂直扩展

 原地址:https://www.cnblogs.com/blfshiye/p/5059748.html

        https://www.2cto.com/database/201607/524821.html

    数据库经常是我们存储和訪问数据的经常使用介质。随着负载的增大,对数据库读写性能的要求往往成为非常大的挑战。在这种情况下我们能够考虑数据库相关的replication机制提高读写的性能。因为一般採用一写多读的replication机制(写master同步到多个slaves),导致这种机制往往会有缺陷。首先它依赖于读写的比例,假设写的操作过多,导致master往往成为性能的瓶颈所在,从而使得slaves的数据同步延迟也变大,进而大大消耗CPU的资源,而且导致数据的不一致从而影响到用户的体验。

       这个时候我们就要考虑使用数据库的sharding(分片)机制,这里面我们所说sharding机制并非一个数据库软件的附属功能,而是一种相对简朴的软件理念。

一般我们把sharding机制分成水平扩展(横向扩展,或者向外扩展)和垂直扩展两种方式。

详细什么是数据库的水平扩展和垂直扩展呢?我们以以下的样例来说明。

       比方我们如今有两个表:用户信息表 产品订单表

       水平的拆分的方案,即不改动数据库表结构。通过对表中数据的拆分而达到分片的目的:

1)使用用户id做hash,分解数据库,在訪问数据库的使用用户id做路由。

2)将产品订单表依照已下单和未下单区分成两个表。

       一般水平拆分在查询数据库的时候可能会用到union操作。

 

垂直拆分的方案:将表和表分离,或者改动表结构,依照訪问的差异将某些列拆分出去。

         1)将用户信息表放到一个数据库server,将产品订单表放到一个数据库server。

         2)将用户信息表中主码(通常是user id)和一些经常使用的信息放到一个表,将主码和不经常使用的信息放到另外的表。这导致一般查询数据的时候可能会用到join操作。

在数据库的设计中,我们更关注数据库的水平扩展的能力。

一、数据库水平扩展

数据库的横向扩展支持三种方法,即主从复制,集群和分片(sharding)。

主从复制

主从复制(Master-slave replication),最易配置,对应用改动最小,并可以减轻主库的负担。

主数据库可以读写,从数据库只读。最常用的场景就是实现读写分离,或业务分离,即运行报表,备份,数据仓库等应用。

这种方法的问题是主与从之间数据非完全同步,可能会读到两个不同的版本。另一个问题是,如果只有主库接受读写,那么主库迟早会过载,因此不算是真正的scale out。

不过主从库数据的延迟,有的业务是可以接受的。另外,利用一些实时复制的工具如GoldenGate,从库也是可以写的,这时可以利用从库做其它的业务,从而达到横向扩展的目的。这也算是主从复制的一个新趋势。

集群(Clustering)

集群也称为shared everything或shared disk架构。最知名的就是Oracle RAC。

1个数据库可以有多个实例,来访问共享存储上的数据库。

每一个节点都可以读写,从应用角度来看,代码无需改变。负载均衡也是自动的。

集群存在的问题包括:

* 写数据时需要内存中数据的同步,数据加速带来竞争,影响扩展性

* 难以设置和管理

* 由于存储是共享的,读操作也不能无限扩展

集群适合于读密集的应用,如数据仓库和BI。

分片(Sharding)

分区(Partition)是库内的,分片(Sharding)是库外的,也叫分表分库, 是shared nothing的架构。

Sharding即将一个大的库拆分成很多小库。如何拆和业务规则有关,可以按用户ID拆,按业务拆。如果需要Join,相关的表需要放到一个库里,避免数据库间的通讯。

Sharding也可以有两种方法,即垂直分区和水平分区。

垂直分区是按业务分,简称为分库,即不同的业务使用不同的库,互不相干。垂直分区到一定程度,也无法扩展,这时需要水平分区。

水平分区则是将一个大表拆分为小表,每个小表位于不同的库。每一个建立相同的schema。如根据主键的hash值来分区。

sharding的不足在于:

* 加大了应用代码的复杂性,需要路由到正确的shard。

* 后期增加shard需要修改应用逻辑,并需要迁移数据

* 查询和聚集(aggregation)不再简单,需要跨库联合操作

* 主数据和参照数据需要复制到所有shard,以避免跨库操作。主数据和参照数据虽然偏静态,但一旦修改,可能会有数据一致性问题。

* 跨库修改需要分布式交易处理,会限制可扩展性。因此应尽量避免。

* 单个shard的失效可能会使整个系统不可用(其实也不一定)。因此通常需要为每个shard再配置HA方案,如主从复制。





主从复制

主从复制(Master-slave replication),最易配置,对应用改动最小,并可以减轻主库的负担。

主数据库可以读写,从数据库只读。最常用的场景就是实现读写分离,或业务分离,即运行报表,备份,数据仓库等应用。

这种方法的问题是主与从之间数据非完全同步,可能会读到两个不同的版本。另一个问题是,如果只有主库接受读写,那么主库迟早会过载,因此不算是真正的scale out。

不过主从库数据的延迟,有的业务是可以接受的。另外,利用一些实时复制的工具如GoldenGate,从库也是可以写的,这时可以利用从库做其它的业务,从而达到横向扩展的目的。这也算是主从复制的一个新趋势。

集群(Clustering)

集群也称为shared everything或shared disk架构。最知名的就是Oracle RAC。

1个数据库可以有多个实例,来访问共享存储上的数据库。

每一个节点都可以读写,从应用角度来看,代码无需改变。负载均衡也是自动的。

集群存在的问题包括:

* 写数据时需要内存中数据的同步,数据加速带来竞争,影响扩展性

* 难以设置和管理

* 由于存储是共享的,读操作也不能无限扩展

集群适合于读密集的应用,如数据仓库和BI。

分片(Sharding)

分区(Partition)是库内的,分片(Sharding)是库外的,也叫分表分库, 是shared nothing的架构。

Sharding即将一个大的库拆分成很多小库。如何拆和业务规则有关,可以按用户ID拆,按业务拆。如果需要Join,相关的表需要放到一个库里,避免数据库间的通讯。

Sharding也可以有两种方法,即垂直分区和水平分区。

垂直分区是按业务分,简称为分库,即不同的业务使用不同的库,互不相干。垂直分区到一定程度,也无法扩展,这时需要水平分区。

水平分区则是将一个大表拆分为小表,每个小表位于不同的库。每一个建立相同的schema。如根据主键的hash值来分区。

sharding的不足在于:

* 加大了应用代码的复杂性,需要路由到正确的shard。

* 后期增加shard需要修改应用逻辑,并需要迁移数据

* 查询和聚集(aggregation)不再简单,需要跨库联合操作

* 主数据和参照数据需要复制到所有shard,以避免跨库操作。主数据和参照数据虽然偏静态,但一旦修改,可能会有数据一致性问题。

* 跨库修改需要分布式交易处理,会限制可扩展性。因此应尽量避免。

* 单个shard的失效可能会使整个系统不可用(其实也不一定)。因此通常需要为每个shard再配置HA方案,如主从复制。


<think>嗯,用户现在问的是如何理解水平扩展垂直扩展。我需要先回忆这两个概念的基本定义,然后考虑如何用简单易懂的中文解释清楚。用户可能是在学习系统设计或者数据库相关的知识,之前的问题是关于MongoDBMySQL在打车场景中的对比,现在转向扩展性,可能是想深入理解系统架构。 首先,垂直扩展(Vertical Scaling)通常指的是通过增加单个服务器的资源,比如CPU、内存、存储来提升性能。而水平扩展(Horizontal Scaling)则是通过增加更多的服务器节点,把负载分散到这些节点上。这两个概念在系统设计中非常重要,尤其是在处理高并发大数据量的时候。 用户可能已经有一定的技术背景,但需要更清晰的对比实际例子来理解两者的区别适用场景。我需要避免使用过于专业的术语,尽量用生活中的比喻来辅助说明。比如垂直扩展就像给一台电脑升级硬件,而水平扩展就像增加更多的电脑一起工作。 然后,我需要考虑用户可能的深层需求。他们可能想知道在什么情况下选择哪种扩展方式,或者两者如何结合使用。比如,垂直扩展简单但有限,而水平扩展更灵活但复杂度高。实际应用中,很多系统会同时使用两种方式,比如先垂直扩展到一定极限,再水平扩展。 还要注意之前的对话中提到了MongoDB的水平扩展能力,用户可能对数据库扩展策略感兴趣,可以结合之前的例子来说明。比如MongoDB的分片功能就是水平扩展的典型应用,而MySQL的垂直扩展可能涉及到更强大的服务器或者读写分离。 需要确保回答结构清晰,分点说明两者的定义、优缺点、使用场景,可能的话加上实际案例或者图示。这样用户能够逐步理解,并应用到实际场景中。同时,要检查是否有技术错误,比如垂直扩展的成本物理限制,水平扩展的复杂性如数据分片一致性等问题。 最后,总结两者的对比,帮助用户做出合适的选择。可能用户需要的是如何在自己的项目中决定扩展策略,所以提供决策因素会很有帮助,比如业务增长预期、预算、技术能力等。</think>在系统架构设计中,水平扩展(Horizontal Scaling)垂直扩展(Vertical Scaling)是两种核心的扩容策略,可通过以下维度深入理解: --- ### **💡 核心概念对比** ```mermaid graph TD A[扩展策略] --> B[垂直扩展/Scale-Up] A --> C[水平扩展/Scale-Out] B --> D["提升单节点能力(CPU/RAM/磁盘)"] C --> E["增加节点数量"] ``` --- ### **🖥️ 技术实现差异** #### **垂直扩展示例(MySQL场景)** ```sql -- 初始配置 AWS RDS db.m5.large (2vCPU, 8GB RAM) -- 垂直扩展后 AWS RDS db.m5.24xlarge (96vCPU, 384GB RAM) ``` **代价**:成本呈指数增长($0.38/hr → $32.77/hr) #### **水平扩展示例(MongoDB分片)** ```javascript sh.addShard("shard001/replicaSet1:27017") sh.addShard("shard002/replicaSet2:27017") sh.enableSharding("ride_orders") sh.shardCollection("ride_orders.trips", { "geo_hash": 1 }) ``` **效果**:数据自动分布到多个分片 --- ### **📊 关键指标对比** | 维度 | 垂直扩展 | 水平扩展 | |-----------------|-----------------------------------|-----------------------------------| | 扩容上限 | 受物理硬件限制(最大单机规格) | 理论无上限(可无限加节点) | | 成本曲线 | 非线性增长(高端硬件溢价) | 线性增长 | | 停机时间 | 需要重启(硬件更换/配置变更) | 在线扩容 | | 故障域 | 单点故障风险高 | 分布式容错 | | 典型应用 | Oracle RAC, MySQL主从 | Cassandra, MongoDB分片集群 | --- ### **🔧 混合架构实践** ```mermaid graph LR subgraph 支付系统 MySQL_Master[MySQL主库] -->|同步复制| MySQL_Replica[从库] end subgraph 订单系统 MongoDB_Router[路由节点] --> Shard1[分片1] MongoDB_Router --> Shard2[分片2] MongoDB_Router --> Shard3[分片3] end API_Gateway --> MySQL_Master API_Gateway --> MongoDB_Router ``` *某出行平台架构示例:支付系统采用垂直扩展(主从复制),订单系统采用水平扩展(MongoDB分片)* --- ### **⚖️ 选择策略决策树** ```plaintext 是否需要扩容? ├── 是 → 当前负载类型? │ ├── 计算密集型 → 垂直扩展(升级CPU) │ ├── 存储密集型 → 水平扩展(添加存储节点) │ └── 混合型 → 混合扩展 └── 否 → 维持当前架构 ``` --- ### **⚠️ 典型误区警示** 1. **盲目水平扩展**:某社交平台初期将MySQL强行分库分表,导致开发效率下降50% 2. **过度垂直扩展**:某电商花费$2M购买高端服务器,3年后硬件过时导致迁移困难 3. **忽视瓶颈转移**:扩容数据库后未同步扩展应用服务器,引发新的性能瓶颈 --- ### **🚀 现代演进趋势** 1. **云原生自动伸缩**:AWS Aurora支持分钟级存储扩容(1GB→64TB) 2. **Serverless数据库**:FaunaDB根据请求量自动扩展计算资源 3. **智能分片技术**:CockroachDB实现跨云自动数据分布 掌握扩展策略的组合运用,才能构建弹性可扩展的系统架构。建议初期采用垂直扩展快速验证业务,当TPS超过5,000时开始规划水平扩展方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值