这是我参与「第五届青训营」笔记创作活动的第16天。
一、本堂课重点知识
今天主要的学习内容是RDBMS的相关知识。
二、详细知识点介绍
1. 经典案例
- case 1: 抖音的账户上扣了一个亿之后,假设服务器挂了,还没来得及给羊老师账户上加一个亿
- case 2:假设抖音的账户上只有0.5个亿,但是扣一个亿的操作成功了
- case 3:羊老师从抖音和头条都抢了一个亿,假设他们都以为是从零开始更新羊老师的账户余额,羊老师最后得到一个亿
- case 4:抖音账户扣了一个亿,羊老师账户加一个亿,但都还没写到磁盘上。这时如果服务器挂了。
上述为关系型数据库事务的ACID特性,即原子性,一致性,隔离性,持久性。在昨天的学习中也提到了这部分内容,更多详细的解释可以查看这篇文章。
同时还有如下问题:
- case 5:全国14亿人,假设有10亿人同时开抢红包,每秒处理一个请求,那需要31年才能完成。春节完了,抖音可能也被大家嫌弃了--高并发 Concurrency
- case 6:假设除夕晚上大家正在愉快的从抖音身上“薅羊毛”,这时候服务器挂了,程序员花了一个小时,头发都掉光了,终于修好了。这时候发现李谷一老师《难忘今宵》都唱完了。“抖音宕机”秒上热搜--高可靠、高可用 High Reliability/Availability
2. 发展历史
2.1 前DBMS时代
- 人工管理
- 文件系统
2.2 DBMS数据模式
- 网状模型
- 层次模型
- 关系模型
2.3 SQL语言
- 语法风格接近自然语言
- 高度非过程化
- 面向集合的操作方式
- 语言简洁,易学易用
2.4 历史回顾
3. 关键技术
3.1 一条SQL的一生
3.2 SQL引擎
- Parser
- 解析器(Parser)一般分为词法分析(Lexical analysis)、语法分析(Syntax analysis)、语义分析(Semantic analyzer)等步骤。
- Optimizer
- 为什么需要一个优化器(Optimizer)?
- 基于规则的优化(RBO Rule Base Optimizer)
- 条件化简
- 表连接优化
- 总是小表先进行连接
- Scan优化
- 唯一索引
- 普通索引
- 全表扫描
- 数据库索引:是数据库管理系统中辅助数据结构,以协助快速查询、更新数据库表中数据。目前数据库中最常用的索引是通过B+树实现的。
- 基于代价的优化(CBO Cost Optimizer)
- 时间
- IO
- CPU
- NET
- MEM
- 基于规则的优化(RBO Rule Base Optimizer)
- 为什么需要一个优化器(Optimizer)?
- Executor
- 火山模型:每个Operator调用Next操作,访问下层Operator,获得下层Operator返回的一行数据,经过计算之后,将这行数据返回给上层。
- 优点:
- 每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
- 缺点:
- 每计算一条数据有多次函数调用开销,导致CPU效率不高。
- 优点:
- 向量化:每个Operator每次操作计算的不再是一行数据,而是一批数据(Batch N行数据),计算完成后向上层算子返回一个Batch。
- 优点:
- 函数调用次数降低为1/N:
- CPU cachei命中率更高;
- 可以利用CPU提供的SIMD(Single Instruction Multi Data)机制。
- 优点:
- 编译执行:将所有的操作封装到一个函数里面,函数调用的代价也能大幅度降低
- 火山模型:每个Operator调用Next操作,访问下层Operator,获得下层Operator返回的一行数据,经过计算之后,将这行数据返回给上层。
3.3 存储引擎
- InnoDB
- Page
- B+ Tree
3.4 事务引擎
- Atomicity与Undo Log
- Undo Log是逻辑日志,记录的是数据的增量变化。利用Undo Log可以进行事务回滚,从而保证事务的原子性。同时也实现了多版本并发控制(MVCC)解决读写冲突和一致性读的问题。
- Isolation与锁
- Isolation与MVCC
- MVCC的意义
- 读写互不阻塞
- 降低死锁概率
- 实现一致性读
- MVCC的意义
- Durability与Redo Log
- 事务提交前页面写盘
- WAL(Write-ahead logging)
- redo log是物理日志,记录的是页面的变化,它的作用是保证事务持久化。如果数据写入磁盘前发生故障,重启MySQL后会根据redo log重做,
4. 企业实践
-
红包雨挑战
-
大流量
- Sharding
- 问题背景
- 单节点写容易成为瓶颈
- 单机数据容量上限
- 解决方案
- 业务数据进行水平拆分
- 代理层进行分片路由
- 实施效果
- 数据库写入性能线性扩展
- 数据库容量线性扩展
- 问题背景
- Sharding
-
流量突增
- 扩容
- 问题背景
- 活动流量上涨
- 集群性能不满足要求
- 解决方案
- 扩容DB物理节点数量
- 利用影子表进行压测
- 实施效果
- 数据库集群提供更高的吞吐
- 保证集群可以承担预期流量
- 问题背景
- 代理连接池
- 问题背景
- 突增流量导致大量建联
- 大量建联导致负载变大,延时上升
- 解决方案
- 业务侧预热连接池
- 代理侧预热连接池
- 代理侧支持连接队列
- 实施效果
- 避免DB被突增流量打死
- 避免代理和DB被大量建联打死
- 问题背景
- 扩容
-
高可用&高可靠
- 3AZ高可用
- 三机房部署
- 机房级别容灾
- 机房级别流量调度
- proxy
- 读写分离,分库分表
- 限流,流量调度
- 监控报警
- 实时监控集群运行状态
- 提前上报集群风险
- 三机房部署
- HA管理
- 问题背景
- db所在机器异常宕机
- db节点异常宕机
- 解决方案
- ha服务监管、切换宕机节点
- 代理支持配置热加载
- 代理自动屏蔽宕机读节点
- 问题背景
- 3AZ高可用
三、实践练习例子
- WAL 日志到底是如何保证数据的持久化,宕机后数据不丢失的?相比于其他方案,WAL 日志都有什么优势?
- 除了 Undo Log 之外,是否还有其他方案可以实现 MVCC?
- 基于代价的优化器一般需要考虑哪些代价?
- 执行器的执行模型,除了本课中提到的火山模型是否还有其他模型?相比于火山模型有什么优劣势?
- InnoDB 的 B+ Tree 是怎么实现的?
- InnoDB 的 buffer pool 是怎么实现页面管理和淘汰的?
四、课后个人总结
深入了解了更多RDBMS相关知识。
五、引用参考
A Relational Model of Data for Large Shared Data Banks.pdf - 飞书云文档 (feishu.cn)
Readings in Database Systems-5th-edition.pdf - 飞书云文档 (feishu.cn)