第十九节:深入理解 RDBMS | 青训营笔记
这是我参与「第三届青训营 -后端场」笔记创作活动的的第17篇笔记
一、经典案例
事务(Transaction) :是由一组SQL语句组成的一一个程序执行单元(Unit) ,它需要满足ACID特性。
通过抖音红包雨的案例,介绍 RDBMS 中 ACID 的概念:
- 原子性(Atomicity):事务是一个不可再分割的工作单元,事务中的操作要么都发生,要么都不发生。
- 一致性(Consistency):数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。
- 隔离性(Isolation):多个事务并发访问时,事务之间是隔离的,一个事务不应该影响其它事务运行效果。
- 持久性(Durability):在事务完成以后,该事务所对数据库所做的更改便持久的保存在数据库之中,并不会被回滚。
高并发(Concurrency)
高可靠(High Reliability/Availability)
二、发展历史
2.1 前DBMS时代
-
人工管理
- 结绳记事
- 清代钱庄账本
- 1890年人口欧普查的霍列瑞斯式到打孔机
-
文件系统
- 1950s,现代计算机的雏形基本出现。1956年IBM发布了第一个的磁盘驱动器 – Model 305 RAMAC ,从此数据存储进入磁盘时代。在这个阶段,数据管理直接通过文件系统来实现。
2.2 DBMS时代
-
1960s ,传统的文件系统已经不能满足人们的需要,数据库管理系统( DBMS )应运而生。
-
DBMS :按照某种数据模型来组织、存储和管理数据的仓库。
-
所以通常按照数据模型的特点将传统数据库系统分成网状数据库、层次数据库和关系数据库三类。
-
数据库发展最初过程中,诞生过3种数据模型,最终关系型模型成为了应用最为广泛的数据库模型。
- 网状模型:用有向图表示实体和实体之间的联系的数据结构模型称为网状数据模型。
- 层次模型:层次数据模型是用树状<层次>结构来组织数据的数据模型。
- 关系模型:使用表格表示实体和实体之间关系的数据模型称之为关系数据模型。
| 网状模型 | 层次模型 | 关系模型 | |
|---|---|---|---|
| 优势 | 能直接描述现实世界 存取效率较高 | 结构简单 查询效率高 可以提供较好的完整性支持 | 实体及实体间的的联系都通过二维表结构表示 可以方便的表示 M:N 关系 数据访问路径对用户透明 |
| 劣势 | 结构复杂 用户不易使用 访问程序设计复杂 | 无法表示 M:N 的关系 插入、删除限制多 遍历子节点必须经过父节点 访问程序设计复杂 | 关联查询效率不够高 关系必须规范化 |
2.3 SQL语言
1974年IBM的Ray Boyce和Don Chamberlin将Codd关系数据库的12条准则的数学定义以简单的关键字语法表现出来,里程碑式地提出了SQL(Structured Query Language)语言。
- 语法风格接近自然语言;
- 高度非过程化;
- 面向集合的操作方式;
- 语言简洁,易学易用。
三、关键技术
01 SQL 执行流程
在 SQL 执行过程中,需要经历 SQL 引擎、存储引擎、以及事务引擎等模块。而其中 SQL 引擎又分为Parser、Optimizer、Executor 几个部分:
02 SQL 引擎
SQL 引擎包括了:
-
Paser:解析器(Parser)- 般分为词法分析( Lexical analysis )、语法分析( Syntax analysis)、语义分析( Semantic analyzer )等步骤。经过词法分析、语法分析生成语法树,然后对语法树进行合法性校验。
-
Optimizer:根据 Parser 产生的语法树,根据规则或者代价产生执行计划树。
-
条件化简
-
表连接优化
- 总是小表先进行连接
-
Scan优化
-
唯一索引
-
普通索引
-
全表扫描
数据库索引:是数据库管理系统中辅助数据结构,以协助快速查询、更新数据库表中数据。目前数据库中最常用的索引是通过B +树实现的。
-
-
-
Executor:根据计划树进行执行,常见的执行方式是火山模型。
-
每个Operator调用Next操作,访问下层Operator ,获得下层Operator返回的一行数据,经过计算之后1将这行数据返回给上层。
- 优点:每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
- 缺点:每计算一条数据有多次函数调用开销 ,导致CPU效率不高。
-
向量化:
-
每个Operator每次操作计算的不再是一行数据,而是一批数据(Batch N行数据) ,计算完成后向上层算子返回-一个Batch。
-
优点:
- 函数调用次数降低为1/N ;
- CPU cache命中率更高;
- 可以利用CPU提供的SIMD(Single Instruction Multi Data)机制。
-
-
编译执行
- 将所有的操作封装到一个函数里面,函数调用的代价也能大幅度降低。
-
03 存储引擎
存储引擎负责了数据的底层存储、管理和访问工作。各大 RDBMS 存储引擎的设计都有不少的差异,这里选择 MySQL 的 InnoDB 存储引擎来向大家做一个介绍:
- Buffer Pool:存储引擎位于内存中的重要结构,用于缓存数据,减少磁盘 IO 的开销。
- Page:数据存储的最基本单位,一般为 16KB。
- B+u Tree:InnoDB 中最常用的索引结构。
04 事务引擎
事务引擎实现了数据库的 ACID 能力,这里还是以 MySQL 的 InnoDB 为例来介绍数据库内部是通过哪些技术来实现 ACID:
-
Atomicity:InnoDB 中通过 undo 日志实现了数据库的原子性,通过 Undo Log,数据库可以回滚到事务开始的状态;
-
Isolation:通过 Undo Log 实现 MVCC(多版本并发控制),降低读写冲突。
-
MVCC的意义:
- 读写互不阻塞;
- 降低死锁概率;
- 实现一致性读。
-
Undo Log在MVCC的作用:
- 每个事务有一个单增的事务ID ;
- 数据页的行记录中包含了DB_ROW_ID , DB_TRX_ID,DB_ROLL_PTR;
- DB_ROLL_PTR将数据行的所有快照记录都通过链表的结构串联了起来。
-
-
Durability:通过 Redo Log(一种 WAL 实现方式)来保证事务在提交后一定能持久化到磁盘中。
- redo log是物理日志,记录的是页面的变化,它的作用是保证事务持久化。如果数据写入磁盘前发生故障,重启MySQL后会根据redo log重做。
-
Consistency:一致性本质上是一种业务层的限制。
Undo Log 是逻辑日志,记录的是数据的增量变化。利用Undo Log可以进行事务回滚,从而保证事务的原子性。同 时也实现了多版本并发控制( MVCC )解决读写冲突和一致性读的问题。
四、企业实践
字节中是国内数据规模最大的互联网公司之一,公司内部有成千上万套 RDBMS 系统。这一章节还是以红包雨为案例,展示了字节是如何解决大流量、流量突增、高可靠等问题的。
4.1 红包雨挑战
- 流量大
- 流量突增
- 稳定性
4.2 大流量 Sharding
问题背景:
- 单节点写容易成为瓶颈
- 单机数据容量上限
解决方案:
- 业务数据进行水平拆分
- 代理层进行分片路由
实施效果:
- 数据库写入性能线性扩展
- 数据库容量线性扩展
4.3 扩容
问题背景
- 活动流量上涨
- 集群性能不满足要求
解决方案
- 扩容DB物理节点数量
- 利用影子表进行压测
实施效果
- 数据库集群提供更高的吞吐
- 保证集群可以承担预期流量
4.4 流量突增 - 代理连接池
问题背景
- 突增流量导致大量建联
- 大量建联导致负载变大,延时上升
解决方案
- 业务侧预热连接池
- 代理侧预热连接池
- 代理侧支持连接队列
实施效果
- 避免DB被突增流量打死
- 避免代理和DB被大量建联打死
4.5 稳定性 & 可靠性
-
3AZ高可用
-
三机房部署
- 机房级别容灾
- 机房级别容量调度
-
proxy
- 读写分离,分库分表
- 限流,流量调度
-
监控报警
- 试试监控集群运行状态
- 提前上报集群风险
-
-
HA管理
-
问题背景
- db所在机器异常宕机
- db节点异常宕机
-
解决方案
- ha服务监管、切换宕机节点
- 代理支持配置热加载
- 代理自动屏蔽宕机读节点
-
五、课程总结

\