这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记.
RDBMS(Relational DataBse Management System)
关系型数据库
数据库:就是RDBMS中的DB,全拼为DataBase,我们常常接触仓库的概念,如maven中的私服,其实就是本地仓库。写这些东西的人,他们也是从生活中来的,为了让大家能明白他们所表达的意思,把存储数据信息的仓库就叫数据库了。
既然是仓库,总得有个摆放位置和摆放内容吧,要不然管仓库的还不得疯了。你们以为规则是怎么来的?就是在定义时候约定的,仓库的这个位置放高粱,那个位置放大米。都是聪明人哪。
对应的,我们数据库的基本概念也就来了: ①表:我们常见的table,表是什么?就是一类数据的集合,大家应该见过纸质的各种表格,其实我们说的数据表就是把纸质表电子化了,这也就是后来为啥有了持久化的概念--因为网络存放总比你人为纸质存放的长久哪。那数据库是什么?就是放各种数据表的地方。 ②记录:数据表中的每一行就是一条记录。。 ③列项:记录中包含了多列,每一列就是一个列项。也就是我们的数据表每一行记录都至少包含一个以上的列项(估计没人傻到一个表我就放一列)。
管理系统:就是RDBMS中的MS。一说系统,就是软件层面的东西。前面限定两字:管理。
管理系统就是负责对外提供:检索、查询功能;插入功能;修改功能;删除功能
关系型:就是RDBMS中的R。专业术语中他们说的关系型,就是将各种表之间的数据关系定义了关系模型R(U,D,Dom,F)
R的本质就在于各种表之间的数据关系,关系型数据库能够通过不同表之间的关系,把不同表之间的相关信息查询检索出来,这也正是关系型数据库的强大之处。
存储系统
- 块存储
- 文件存储
- 对象存储
- k-v存储
数据库系统
- 关系型数据库
- 非关系型数据库
分布式架构
- 数据分布策略
- 数据复制协议
- 分布式事务算法
从经典案例---抖音红包雨讲关系数据库
RDBMS 事务的ACID特性以及高可用和高可靠
事务: 一组sql语句组成的一个程序执行单元,需要满足ACID
从1970年论文的发表到如今讲关系数据库的发展历程
万变归宗,关系数据库的关键技术
一条sql的生命历程
- 手机发送请求到后端router
- 请求的本质是向数据库请求数据的sql语句
- parser解析sql语句
- 生成一个语法树AST,到达优化树Optimizer,生成Plan(树状结构,到达执行器Executor
- Executor从文件中读取数据,并生成日志文件,executor把结果返回给用户
其中,**parser,parser、executor、optimizer是sql引擎,datafile logfile是存储引擎,事务引擎没有显式的表示
sql引擎
parser
解析用户目的
- 词法分析
类似于自然语言解析,抓取关键词(保留字,如关键词运算符表列名等),分成不同类型
- 语法分析
将关键词生成语法树
- 语义分析
合法性校验,检查列名表明是否存在常量是否合法等。
optimizer
选择性能最好的路径 select * from A,B,C WHERE A.a1=B.b1 and A.a1 = C.b1
以sql的连接为例,优化器就是找到最好的连接方式。
- 基于规则的优化 Rule Base Optimizer
如表连接优化: 小表优先连接
如Scan优化: 使用索引(唯一索引/普通索引/全表扫描
- 基于代价的优化 Cost Base Optimizer
代价:可以指时间
Executor
- 火山模型
Projection(c1)->Filter(c2>1)->Table Scan(c1,c2)->Storage Engine
每个Operator调用next操作,访问下层Operator,获得下层Operator返回的一行数据,逐层调用,逐层返回
优点: 算子独立实现,相互没有耦合,逻辑简单
缺点: 计算一条数据涉及多层函数调用,cpu效率低-->>向量化、编译执行
向量化的优化在于每次Operator计算和返回的不是一行数据,而是一批数据(Batch,可以降低调用次数,cpu cache命中率更高,利用cpu提供的SMD(Single Instruction Multi Data)机制
编译执行是把所有的计算代码写到一个函数中。但是用户需求千变万化,很难实现,使用了 动态编译技术,动态生成执行的代码路径。LLVM动态执行编译技术。
存储引擎
-InnoDB为例
解决日志和数据的存储部分。
-
IN-MEMORY
-
buffer pool
- hashmap<page_id,block>
- LRU
-
change buffer
-
adaptive hash index
-
log buffer
-
-
on-disk
- System tablespace(元数据
- general tablesoace
- undo tablespace
- temporary tablespace
- redo log
B+Tree
页面内二分法快速对应到对应的槽,从根到叶遍历快速查找指定记录。
事务引擎
Atomicity 与Undo Log
通过undolog实现事务状态回退。记录的是逻辑日志,记录数据增量变化。
Isolation与锁
-
读-读 share lock
-
写-写 exclusive lock
-
读-写 mvcc解决读写冲突和一致性读的问题。
- 每个事务都有一个递增的事务id
- 数据页的行记录中包含db_row_id,db_trx_id,db_roll_ptr
- db_roll_ptr将数据行中所有快照记录都通过链表结构串联
- 读写互不阻塞,降低死锁概率,实现一致性读。
durability与redolog
事务结束后保证对事务修改的永久保存。
- 事务提交前页面写入磁盘。但是随机访问io的代价会很大,也会造成写放大,即很少字节却要重写页面。×
- WAL redolog是物理日志,记录了页面变化,保证事务持久化。如果数据写入磁盘前故障,会根据redolog重做。
关系数据库在字节中的实践
使用sharding解决大流量
单节点写容易成为瓶颈,单机数据容量存在上限。
- 数据在业务层进行水平拆分(分库分表),按照某种规则(hash)拆分到多个服务器。
- 使用代理层实现数据的分片路由。用户的单点服务到多点服务使用代理解决。
数据库写入性能、容量线性扩展。
流量突增
使用扩容解决流量突增
- 扩容DB物理节点数量
- 利用影子表进行压测
- copy现有物理节点,使用日志实时同步信息,更改代理拓扑信息,使用户正常访问新增服务器。将老的服务器和新的服务器各删除一半,一台服务器扩展成为两台,提供更好的吞吐和数据容量,可以承担预期流量。
使用代理连接池解决流量突增问题
使用预热,业务侧、代理侧预热连接池,预先缓存建立好的连接,无需重新建立。代理侧支持连接队列。避免代理和db被突增流量打死。
稳定性&可靠性
- 3AZ
多个不同城市建立多个独立的机房。不同AZ之间通过日志同步,代理也会分发请求到不同az,代理也可以实现读写限流,进行监控报警,实时关注运行状态,上报集群风险,进行自我保护。
- HA管理
机器宕机后,HA快速识别出宕机节点,快速监控,快速应对,将宕机节点下线,将请求分发到剩下的服务器