分库分表
业界普遍认为,MySQL 单表容量在 1 千万以下是一种最佳状态,一旦超过这个量级,就需要考虑采用其他方案了。
为了解决由于数据量过大而导致的数据库性能降低的问题,将原来独立的数据库拆分成若干数据库,把原来数据量大的表拆分成若干数据表,使得单一数据库、单一数据表的数据量变得足够小,从而达到提升数据库性能的效果。
表现形式
- 垂直拆分
- 垂直分表:将一个表按照字段分成多张表,每个表存储其中一部分字段。访问频次低的放一个表中,访问频次高的放一个表中。
- 数据毕竟仍然位于同一个数据库中,也就是把操作范围限制在一台服务器上,每个表还是会竞争同一台服务器中的 CPU、内存、网络 IO 等资源。基于这个考虑,在有了垂直分表之后,就可以进一步引入垂直分库。
- 垂直分库:指按照业务将表进行分类,然后分布到不同的数据库上
- 分表之后的用户信息同样还是跟其他的商品、订单信息存放在同一台服务器中。基于垂直分库思想,可以把用户相关的数据表单独拆分出来,放在一个独立的数据库中。
- 核心理念:专库专用。每个库可以位于不同的服务器上。垂直分库很大程度上取决于业务的规划和系统边界的划分
- 垂直拆分尽管实现起来比较简单,但并不能解决单表数据量过大这一核心问题。所以,现实中往往需要在垂直拆分的基础上添加水平拆分机制
- 垂直分表:将一个表按照字段分成多张表,每个表存储其中一部分字段。访问频次低的放一个表中,访问频次高的放一个表中。
- 水平拆分
- 水平分库:同一个表的数据按一定规则拆分到不同的数据库中,每个库同样可以位于不同的服务器上
- 规则:
- 取模算法,取模的方式有很多,比如按照用户 ID 进行取模,通过表的一列或多列字段进行 hash 求值来取模;
- 范围限定算法,比如可以采用按年份、按时间等策略路由到目标数据库或表;
- 预定义算法,是指事先规划好具体库或表的数量,然后直接路由到指定库或表中。
- 规则:
- **水平分表:**是在同一个数据库内,把同一个表的数据按一定规则拆到多个表中。
- 水平分库:同一个表的数据按一定规则拆分到不同的数据库中,每个库同样可以位于不同的服务器上
分库分表与读写分离
- 读写分离,主要解决的就是高并发下的数据库访问
- 解决方案:
- 分片:把数据划分成不同的数据片,并存储在不同的目标对象中
- 客户端分片:在数据库的客户端就实现了分片规则,这种方式将分片处理的工作进行前置,客户端管理和维护着所有的分片逻辑,并决定每次 SQL 执行所对应的目标数据库和数据表。
- 应用层分片,在应用程序中直接维护着分片规则和分片逻辑
- 客户端分片在实现上会进一步抽象,把分片规则的管理工作从业务代码中剥离出来,形成单独演进的一套体系。设计思路是重写 JDBC 协议,在 JDBC 协议层面嵌入分片规则。优势在于,分片操作对于业务而言是完全透明的。
- 代理服务器分片:采用了代理机制,在应用层和数据库层之间添加一个代理层。把分片规则集中维护在这个代理层中,并对外提供与 JDBC 兼容的 API 给到应用层
- 分布式数据库
- 客户端分片:在数据库的客户端就实现了分片规则,这种方式将分片处理的工作进行前置,客户端管理和维护着所有的分片逻辑,并决定每次 SQL 执行所对应的目标数据库和数据表。
- 分片:把数据划分成不同的数据片,并存储在不同的目标对象中
ShardingSphere
ShardingSphere 由 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar 这三款相互独立的产品组成,
ShardingSphere 的前身是 Sharding-JDBC,所以这是整个框架中最为成熟的组件
Sharding-JDBC
Sharding-JDBC 以 JAR 包的形式提供服务。开发人员可以使用这个 JAR 包直连数据库,无需额外的部署和依赖管理。在应用 Sharding-JDBC 时,需要注意到 Sharding-JDBC 背后依赖的是一套完整而强大的分片引擎
Sharding-Proxy:
定位为一个透明化的数据库代理端。它是代理服务器分片方案的一种具体实现方式。
用 Sharding-JDBC 的方式是在应用程序中直接嵌入 JAR 包,这种方式适合于业务开发人员。
Sharding-Proxy 提供静态入口以及异构语言的支持,适用于需要对分片数据库进行管理的中间件开发和运维人员。基于底层共通的分片引擎,以及数据库治理功能,可以混合使用 Sharding-JDBC 和 Sharding-Proxy,以便应对不同的应用场景和不同的开发人员:
Sharding-Sidecar:
目标是把系统中各种异构的服务组件串联起来,并进行高效的服务治理。
ShardingSphere 的核心功能:从数据分片到编排治理
基础设施
- 微内核架构:确保系统具有高度可扩展性。只要用新插件替换旧插件而不需要改变整个系统架构
- 内核系统
- 插件
- 分布式主键
- 分片场景下,需要考虑主键在各个数据库中的全局唯一性。默认采用的是 SnowFlake(雪花)算法。
分片引擎
- 数据分片:常规的,基于垂直拆分和水平拆分的分库分表操作它都支持,预留了分片扩展点可以基于需要实现分片策略的定制化开发。
- 读写分离:
分布式事务
- 标准化事务处理接口
- 强一致性事务与柔性事务
治理与集成
- 数据脱敏:确保数据访问安全的常见需求,通常做法是对原始的 SQL 进行改写,从而实现对原文数据进行加密。
- 配置中心:基于 YAML 格式或 XML 格式的配置文件完成配置信息的维护。还提供了配置信息动态化的管理机制,可以支持数据源、表与分片及读写分离策略的动态切换。
- 注册中心:提供了基于 Nacos 和 ZooKeeper 的两种实现方式。而在应用场景上,基于注册中心完成数据库实例管理、数据库熔断禁用等治理功能。
- 链路跟踪:使用 OpenTracing API 发送性能追踪数据。SQL 解析与 SQL 执行是数据分片的最核心步骤,ShardingSphere 在完成这两个步骤的同时,也会将运行时的数据通过标准协议提交到链路跟踪系统。
- 系统集成:ShardingSphere 和 Spring 系列框架的集成。ShardingSphere 实现了两种系统的集成机制
- 命名空间机制,通过扩展 Spring Schema 来实现与 Spring 框架的集成;
- 通过编写自定义的 starter 组件来完成与 Spring Boot 的集成。