存储与数据库
存储 & 数据库
存储系统
- 一个提供了读写、控制类接口,能够安全有效地把数据库持久化的软件,可以成为存储系统
系统特点
- 作为后端软件的底座,性能敏感
- 存储系统软件架构,容易受硬件影响
- 存储系统代码,即简单又复杂
RAID 技术
-
出现背景
- 单块大容量磁盘的价格 > 多块小容量磁盘
- 单块磁盘的写入性能 < 多块磁盘的并发写入性能
- 单块磁盘的容错能力有限,不够安全
-
RAID 0
- 多块磁盘简单组合
- 数据调带化存储,提高磁盘带宽
- 没有额外的容错设计
-
RAID 1
- 一块磁盘对应一块额外外镜像盘
- 真是空间利用率仅50%
- 容错能力强
-
RAID 0 + 1
- 结合了 RAID 0 和 RAID 1
- 真是空间利用率仅50%
- 容错能力强,写入带宽好
数据库
概览
- 关系 = 集合 = 任意元素组成的若干有序偶对反映了事务间的关系
- 关系代数 = 对关系做运算的抽象查询语言
- SQL = 一种 DSL = 方便人类阅读的关系代数表达形式
特点
-
关系型数据库时存储系统,但是在存储之外,有发展出其他能力
- 结构数据友好
- 支持事务
- 支持复杂查询语言
-
非关系型数据库也是存储系统,但是一般不要求严格的结构化
- 半结构化数据友好
- 可能支持事务
- 可能支持复杂查询语言
主流产品
单机存储
- 单机存储 = 单个计算机节点上的存储软件系统,一般不涉及网络交互
本地文件系统
-
Linux:一切皆文件
-
文件系统的管理单元:文件
-
文件文件接口:文件系统繁多,如 Ext2/3/4,sysfs,rootfs 等,但是都遵循 VFS 的统一抽象接口
-
Linux 文件系统的两大数据结构:Index Node & Directory Entry
-
Index Node
- 记录文件元数据,如 id、大小、权限、磁盘位置等
- inode 是一个文件的唯一标识,会被存储到磁盘上的 inode 的总数在格式化文件系统时就固定了
-
Directory Entry
- 记录文件名、inode 指针、底层关系(parent)等
- dentry 是内存结构,与 inode 的关系是 N : 1(hardlink 的实现)
-
key-value存储
- 常见使用方法:put(k, v) & get(k)
- 常见数据结构:LSM-Tree,某种程度上牺牲读性能,追求写入性能
- 拳头产品:RocksDB
分布式存储
- 分布式存储 = 在单机存储基础上实现了分布式协议,涉及大量网络交互
HDFS
-
大数据时代的基石
-
专用的高级硬件很贵,同时数据存量很大,要求超高吞吐
-
核心特点
- 支持海量数据存储
- 高容错性
- 弱 POSIX 语义
- 使用普通 x86 服务器,性价比高
Ceph
-
开源分布式存储系统的万金油
-
核心特点
-
一套系统支持对象接口、块接口、文件接口,但是一切皆对象
-
数据写入采用主备复制模型
-
数据分布模型采用 CRUSH 算法
- CRUSH = HASH + 权重 + 随机抽签
-
单机数据库
- 单机数据库 = 单个计算机节点上的数据库系统
- 事务在单机内执行,也可能通过网络交互实现分布式事务
关系型数据库
-
商业产品 Oracle 称王,开源产品 MySQL & PostgreSQL 称霸
-
关系型数据库的通用组件
- Query Engine - 负责解析 query、生成查询计划
- Txn Manager - 负责事务并发管理
- Lock Manager - 负责锁相关的策略
- Storage Engine - 负责组织内存 / 磁盘数据结构
- Replication - 负责主备同步
-
关键内存数据结构:B-Tree、B+-Tree、LRU List 等
-
关键磁盘数据结构:WeiteAheadLog(Redo log)、Page
非关系型数据库
-
ES
- 面向文档存储
- 文档可序列化为 JSON、支持嵌套
- 存在 index、index = 文档的集合
- 存储和构建索引依赖 Lucene 引擎
- 实现了大量搜索数据结构 & 算法
- 支持 RESTFUL API,也支持弱 SQL 交互
-
mongoDB
- 面向文档存储
- 文件可序列化为 JSON、BSON,支持嵌套
- 存在 collection,collection = 文档的集合
- 存储和构建索引能力依赖的 wiredTiger 引擎
- 4.0 后开始支持事务(多文档、跨分片多文档等)
- 常用 client / SDK 交互,可通过插件转移支持弱 SQL
-
Redis
- 数据结构丰富(hash 表、set、zset、list)
- C语言实现、超高性能
- 主要基于内存,但支持 AOF / RDB 持久化
- 常用 redis-cli / 多语言 SDK 交互
小总结
存储系统
- 块存储:存储软件栈里的底层系统,接口过于朴素
- 文件存储:日常使用最广泛的存储系统,接口十分友好,实现五花八门
- 对象存储:公有云上的王牌产品,immutable 语义加持
- key-value 存储:形式最灵活,存在大量的开源 / 黑盒产品
数据库系统
-
关系型数据库
- 基于关系和关系代数构建的,一般支持事务和 SQL 访问,使用体验友好的存储产品
-
非关系型数据库
- 结构灵活,访问方式灵活,针对不同场景有不同的针对性产品
深入理解 RDBMS
DBMS 数据模型
| 网状模型 | 层次模型 | 关系模型 | |
|---|---|---|---|
| 优势 | - 能够直接描述现实世界 - 存储效率较高 | - 结构简单 - 查询效率高 - 可以提供较好的完整性支持 | - 实体及实体间的联系都通过二维表结构表示 - 可以方便的表示 M : N 关系 - 数据访问路径对用户透明 |
| 劣势 | - 结构复杂 - 用户不易访问 - 访问程序设计复杂 | - 无法表示 M : N 的关系 - 插入、删除限制多 - 遍历子节点必须经过父节点 - 访问程序设计复杂 | - 关联查询效率不够高 - 关系必须规范化 |
SQL 语言
- 语法风格接近自然语言
- 高度非过程化
- 面向集合的操作方式
- 语言简洁,易学易用
SQL 引擎
Parser
- 解析器一般分为词法分析、语法分析、语义分析等步骤
Optimizer
-
基于规则的优化
-
条件化简
-
表连接优化
-
总是小表先进行连接
-
Scan 优化
- 唯一索引
- 普通索引
- 全表扫描
-
数据库索引:是数据库管理系统中的数据结构,以协助快速查询、更新数据库表中的数据,目前数据库中常见的索引是通过 B+ 树实现的
-
Executor
-
每个 Operator 调用 Next 操作,访问下层 Operator,获得下层 Operator 返回的一行数据,经过计算之后,将这行数据返回给上层
-
优点
- 每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
-
缺点
- 每计算一条数据有多次函数调用开销,导致 CPU 效率不高
事务引擎
-
Undo Log 是逻辑日志,记录的是数据的增量变化,利用 Undo Log 可以进行事务回滚,从而保证事务的原子性,同时也实现了多版本并发控制(MVCC),解决读写冲突和一致性的问题
-
MVCC 的意义
- 读写互不阻塞
- 降低死锁概率
- 实现一致性读
-
Undo Log 在 MVCC 的作用
- 每个事务有一个单增的事务 ID
- 数据库的行记录中包含了 DB_ROW_ID,DB_TRX_ID,DB_ROLL_PTR
- DB_ROLL_PTR 将数据行的所有快照记录都通过链表的结构串联了起来
-
如何保证事务结束后,对数据的修改永久的保存
-
方案一
- 事务提交前页面写盘
-
方案二(WAL)
- redo log 是物理日志,记录的是页面的变化,它的作用是保证事务持久化,如果数据写入磁盘前发生故障,重启 MySQL 后会根据 redo log 重做
-
实战
大流量 - Sharding
-
问题背景
- 单节点容易成为瓶颈
- 单机数量容易上限
-
解决方案
- 业务数据进行水平拆分
- 代理层进行分配路由
-
实施效果
- 数据库写入性能线程扩展
- 数据库容量线性扩展
流量徒增 - 扩容
-
问题背景
- 活动流量上涨
- 集群性能不满足要求
-
解决方案
- 扩容 DB 物理节点数量
- 利用影子表进行压测
-
实施效果
- 数据库集群提供更高的吞吐
- 保证集群可以承担预期流量
流量徒增 - 代理连接池
-
问题背景
- 突增流量导致大量建联
- 大量建联导致负载变大,延时上升
-
解决方案
- 业务侧预热连接池
- 代理侧预热连接池
- 代理侧支持连接队列
-
实施效果
- 避免 DB 被突增流量打死
- 避免代理和 DB 被大量建联打死
稳定性 & 可靠性
3AZ 高可用
-
三机房部署
- 机房级别容灾
- 机房级别流量调度
-
proxy
- 读写分离,分库分类
- 限流,流量调度
-
监控报警
- 实施监控集群运行状态
- 提前上报集群风险
-
HA
- High Availability
- 实施监控 DB 运行状态
- 宕机快速切换
HA 管理
-
问题背景
- db 所在机器异常宕机
- db 节点异常宕机
-
解决方案
- ha 服务监管、切换宕机节点
- 代理支持配置热加载
- 代理自动屏蔽宕机读节点
-
实施效果
- 读节点宕机妙计恢复
- 写节点宕机 30s 内恢复服务
TOS 对象存储
对象存储 vs 分布式文件系统
| 海量 | 易用 | 便宜 | |
|---|---|---|---|
| 分布式文件系统 HDFS | - 支持PB -> EB海量存储 - 文件数量收到Name Node 限制 | - 伪 Posix 文件接口,开发略复杂 - 非云原生,搭载维护较麻烦 视频 / 图片相关生态接入略复杂 | - 使用普通 x86 服务器,成本低 |
| 对象存储 TOS | - 支持 > EB 海量存储 - 对象数量无限制 | - Restful HTTP 接口,开发极其简单 - 云原生,按需申请使用 - 视频 / 图片相关生态丰富 | - 使用普通 x86 服务器 - 具备冷热数据分级存储能力,成本更低 |