深入理解RDBMS | 青训营笔记

76 阅读7分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第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年论文的发表到如今讲关系数据库的发展历程

www.youtube.com/watch?v=PA3…

万变归宗,关系数据库的关键技术

一条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

事务结束后保证对事务修改的永久保存。

  1. 事务提交前页面写入磁盘。但是随机访问io的代价会很大,也会造成写放大,即很少字节却要重写页面。×
  2. WAL redolog是物理日志,记录了页面变化,保证事务持久化。如果数据写入磁盘前故障,会根据redolog重做。

关系数据库在字节中的实践

使用sharding解决大流量

单节点写容易成为瓶颈,单机数据容量存在上限。

  • 数据在业务层进行水平拆分(分库分表),按照某种规则(hash)拆分到多个服务器。
  • 使用代理层实现数据的分片路由。用户的单点服务到多点服务使用代理解决。

数据库写入性能、容量线性扩展。

流量突增

使用扩容解决流量突增

  • 扩容DB物理节点数量
  • 利用影子表进行压测
  • copy现有物理节点,使用日志实时同步信息,更改代理拓扑信息,使用户正常访问新增服务器。将老的服务器和新的服务器各删除一半,一台服务器扩展成为两台,提供更好的吞吐和数据容量,可以承担预期流量。

使用代理连接池解决流量突增问题

使用预热,业务侧、代理侧预热连接池,预先缓存建立好的连接,无需重新建立。代理侧支持连接队列。避免代理和db被突增流量打死。

稳定性&可靠性

  • 3AZ

多个不同城市建立多个独立的机房。不同AZ之间通过日志同步,代理也会分发请求到不同az,代理也可以实现读写限流,进行监控报警,实时关注运行状态,上报集群风险,进行自我保护。

  • HA管理

机器宕机后,HA快速识别出宕机节点,快速监控,快速应对,将宕机节点下线,将请求分发到剩下的服务器