RDBMS | 青训营笔记(二)

20 阅读5分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天。

📜📜📜今天学习的是RDBMS(关系型数据库)——第二部分。

三、关键技术✍

3.2存储引擎——以InnoDB为例

image.png

  • buffer pool(缓冲池)——数据库具有缓冲池(buffer pool)机制,以避免每次查询数据都进行磁盘IO。

MySQL中每个页面大小是16k,每个chunk的大小一般为128M,每个block对应一个page,一个chunk下面有8192个block。这样可以避免内存碎片化。分成多个instance,可以有效避免并发冲突。

Page id % instance num得到它属于哪个instance

image.png buffer pool有两个重要的结构,一个是hashmap(根据page_id计算block在哪个哈希桶里面),另一个是LRU(当buffer pool里的页面都被使用之后,再需要换存其他页面怎么办?淘汰已有的页面基于什么规则淘汰:淘汰那个最近一段时间最少被访问过的缓存页了)。

普通的LRU算法存在缺陷,考虑我们需要扫描10G的表,而我们的bufferpool只有1GB,这样就会因为全表扫描的数据量大,需要淘汰的缓存页多,导致在淘汰的过程中,极有可能将需要频繁使用到的缓存页给淘汰了,而放进来的新数据却是使用频率很低的数据。

MySQL确实没有直接使用LRU算法,而是在LRU算法上进行了优化。 ✨MSQL的优化思路——对数据进行冷热分离,将LRU链表分成两部分,一部分用来存放冷数据,也就是刚从磁盘读进来的数据,另一部分用来存放热点数据,也就是经常被访问到数据。当从磁盘该取数据页后,会先将数据页存故到LRU链表冷数据区的头部,如果这些缓存页在1秒之后被访问,那么就将缓存页移动到热数据区的头部,如果是1秒之内被访问,则不会移动,缓存页仍然处于冷数据区中。淘汰时,首先淘汰冷数据区。

  • page(InnoDB存储引擎磁盘管理最小单位,默认大小为16k。 image.png Page还分类,在缓冲池里常见的类型有:索引页、数据页、Undo页、系统页等。page有7个部分,下面是它的结构图:

image.png

  • B+tree(InnoDB存储引擎的存储数据结构是B+树 在百度上找到一个简单的b+树

image.png

页面内:页目录中使用二分法快速定位到对应的槽,然后再遍历该槽对应分组中的记录即可快速找到指定的记录。

从根到叶:中间节点存储

使用b+树,叶子结点之间通过双链表进行关联,这样找到一个叶子结点,就可以查询其他叶子结点,在内存中进程查找即可,不用再进行磁盘操作,减少IO次数,提高查询性能

3.3事务引擎

Undo Log—— 抖音扣除一亿之后,服务器挂了,没给老师加。这时,我们需要将数据库回退带修改前的状态。

  • 如何将数据库回退到修改之前的状态? 使用Undo Log——Undo Log是逻辑日志,记录的是数据的增量变化。利用Undo Log可以进行事务回滚,从而保证事务的原子性。同时也实现了多版本并发控制(MVCC) ,解决读写冲突和一致性读的问题。

Isolation与锁——在抖音抢了一个亿,在另一个也抢了一个亿,同时向一个账户转账,发生冲突了怎么办? image.png Isolation与MVCC(数据的多版本)—— MVCC的意义:读写互不阻塞 | 降低死锁概率 | 实现一致性读。

Undo Log在MVCC的作用:每个事务有一个单增的事务ID | 数据页的行记录中包含了DB_ROW_ID,DB_TRX_ID,DB_ROLL_PTR | DB_ROLL_PTR将数据行的所有快照记录都通过链表的结构串联了起来。

Durability 与 Redo Log——如何保证事务结束后,对数据的修改永久的保存。

方案一:事务提交前页面写盘,随机IO(对某些磁盘可能会导致效率较低),写放大。

方案二:WAL(Write-ahead logging)—— redo log是物理日志,记录的是页面的变化,它的作用是保证事务持久化。如果数据写入磁盘前发生故障,重启MySQL后会根据redo log重做。

四、关键技术

  1. 大流量——sharding

问题背景:单节点写容易成为瓶颈 | 单机数据容量上限

解决方案:业务数据进行水平拆分 | 代理层进行分片路由

实施效果: 数据库写入性能线性扩展 | 数据库容量线性扩展

  1. 流量突增——扩容

问题背景:活动流量上涨 | 集群性能不满足要求

解决方案:扩容DB物理节点数量 | 利用影子表进行压测

实施效果: 数据库集群提供更高的吞吐 | 保证集群可以承担预期流星

  1. 流量突增——代理连接池

问题背景: 突增流星导致大量建联 | 大是建联导致负载变大,延时上升

解决方案:业务侧预热连接池 | 代理侧预热连接池 | 代理侧支持连接队列

实施效果:避免DB被突增流量打死 | 避免代理和DB被大量建联打死

  1. 稳定性&可靠性——3AZ高可用

三机房部署:机房级别客容 | 机房级别流量调度

proxy: 读写分离,分库分表 | 限流,流量调度

监控报警: 实时监控集群运行状态 | 提前上报集群风险

HA(高可用)—— High Availability实时监控DB运行状态 | 宕机快速切换

  1. 稳定性&可靠性——HA管理

问题背景: db所在机器异常宕机 | db节点异常宕机

解决方案: ha服务监管、切换宕机节点 | 代理支持配置热加载 | 代理自动屏蔽宕机读节点

实施效果 :读节点宕机秒级恢复 | 写节点宕机30s内恢复服务