经典案例
小明下载了一个APP,并进行账号注册。
{
"user_name": "小明",
"password": "vjaow89_ek:jfD",
"timestamp": 1692970484081
}
一条数据在前端被创造出来,随后通过网络链路被送到后端服务器(的内存)上,最后被存储到数据库中。之后可能也有其他系统来获取这条被持久化的数据。几乎所有计算机系统的最后一环,都是关于数据库的,没有持久化,系统就是无状态的,这样的系统是几乎不可用的。
当数据到达了数据库,在被完全持久化(以寿命和性能友好的方式写入磁盘)之前,还会经过数据校验(例如是否符合表的约束)、内存修改(利用数据结构来高效地组织数据)的过程。
存储 & 数据库简介
存储系统概览
存储系统就是一个提供了读写、控制类接口,能够安全有效地把数据持久化的软件。它需要和用户、存储介质、内存和网络打交道。
存储系统特点
-
性能敏感
-
架构易受硬件影响
针对硬件变化,架构可能也需要变化。
-
其代码,“简单”又“复杂”
处理IO,代码需简单,保证性能;非IO,代码复杂,保证可靠
存储器层级结构
从上到下依次为:
从上到下,尺寸和容量从小变大,速度从快到慢。
第三和第四层之间可能存在的可持久化内存。
单机存储栈
-
缓存很重要,贯穿整个存储体系
不同层次之间的读写粒度不同,使用缓存来缓和差异,使得对软/硬件友好。
-
拷贝很昂贵,尽量减少
拷贝需要CPU来进行,拷贝多了使得CPU利用率下降,性能降低。使用零拷贝的方法来减少拷贝。
-
抽象硬件接入层
RAID技术
单机存储系统怎么做到高性能 / 高性价比 / 高可靠性?
使用 R(edundant) A(rray) of I(nexpensive) D(isks)
背景:
- 单块大容量嵫盘的价格 > 多块小容量磁盘
- 单块磁盘的写入性能 < 多块磁盘的并发写入性能
- 单块磁盘的容错能力有限,不够安全
组合
- RAID 0
- 多块磁盘简单组合
- 数据条带化存储,提高磁盘带宽
- 没有额外的容错设计
- RAID 1
- 一块磁盘对应一块额外镜像盘
- 真实空间利用率仅50%
- 容错能力强
- RAID 0 + 1
- 结合了 RAID 0 和 RAID 1
- 真实空间利用率仅50%
- 容错能力强,写入带宽好
数据库系统概览
关系型数据库特点
基于关系代数的存储系统,对于结构化数据友好,同时支持事务(具有ACID特性)以及复杂的查询语言(SQL)。关系就是集合,这个集合上有一些关系运算。
非关系型数据库特点
也是存储系统,但是一般不要求严格的结构化。对半结构化数据友好,可能支持事务,可能支持复杂的SQL。
数据库 vs 经典存储
结构化
使用数据库,将使用表的形式来管理数据,方便开发;
使用经典存储(文件系统),需要自行定义数据存储结构,对开发者不友好。
事务
数据库支持事务,具有ACID特性。
事务保证了事务内操作的原子性、一致性、隔离性以及持久性。
经典存储很难做到,做到了也不如直接使用数据库。
复杂查询
使用经典存储,需要手动编写大量逻辑,并且逻辑可能不易复用,也不灵活。
使用数据库SQL,编写几行代码即可实现复杂查询。
数据库使用方式
Data Definition Language
用于定义数据库的三级结构,包括外模式、概念模式、内模式及其相互之间的映像,定义数据的完整性、安全控制等约束
Data Manipulation Language
由数据库系统提供,用于让用户使用,实现对数据库中数据增删改查。
Data Control Language
用于权限管理、角色控制。
Transaction Control Language
用于事务控制。
主流产品剖析
单机存储产品
单个计算机节点上的存储软件系统,一般不涉及网络交互。
单机文件系统
Linux设计哲学:一切皆文件
管理单元:文件
文件系统接口:VFS
两大数据结构
-
Index Node
记录文件元数据,如 id、大小、权限、磁盘位置等。
inode 是一个文件的唯一标识,会被存储到磁盘上。
inode 的总数在格式化文件系统时就固定了。 -
Directory Entry
记录文件名、inode 指针,层级关系(parent)等。
dentry 是内存结构,与 inode 的关系是 N:1(hardlink 的实现),多个 dentry 对应一个 inode。
单机key-value存储
常见使用方式:Put(k, v)
Get(k)
数据结构:LSM树,牺牲读性能,追求写入性能
产品:RocksDB、LevelDB
分布式存储产品
在单机存储基础上实现了分布式协议,涉及大量网络交互。
HDFS
大数据时代的基石。
特点:
- 支持海量数据存储
- 高容错性
- 弱 POSIX 语义
- 使用普通 x86 服务器,性价比高
Ceph
特点:
- 一套系统支持对象接口、块接口、文件接口,一切皆对象
- 数据写入采用主备复制模型
- 数据分布模型采用 CRUSH 算法(HASH + 权重 + 随机标签)
单机数据库产品
单个计算机节点上的数据库系统。
事务在单机内执行,也可能通过网络交互实现分布式事务。
关系型数据库 —— Oracle、PG、MySQL
通用组件:
Query Engine
:负责解析 query,生成查询计划Txn Manager
:负责事务并发管理Lock Manager
:负责锁相关的策略Storage Engine
:负责组织内存 / 磁盘数据结构Replication
:负责主备同步
内存数据结构:B树、B+树、LRU List等
磁盘数据结构:WriteAheadLog(RedoLog)、Page
非关系型数据库 —— ES、MongoDB、Redis
这些非关系型数据库交互方式各不相同,schema相对灵活,都尝试支持SQL(子集)和事务。
ES
- 面向文档存储
- 文档可序列化成 JSON,支持嵌套
- 存在 index,index就是文档的集合
- 存储和构建索引能力依赖 Lucene 引擎
- 实现了大搜索数据结构和算法
- 支持 RESTful API,也支持弱 SQL 交互
MongoDB
- 面向文档存储
- 文档可序列化成JSON,支持嵌套
- 存在collection,也就是文档的集合
- 存储和构建索引能力依赖 wiredTiger 引擎
- 4.0 后开始支持事务(多文档、跨分片多文档等)
- 常用 client/SDK 交互,可通过插件转译支持弱 SQL
Redis
- 数据结构丰富(hash 表、set、zset、list)
- C 语言实现,超高性能
- 主要基于内存,但支持 AOF/RDB 持久化
- 常用 redis-cli / 多语言 SDK 交互
分布式数据库产品
- 单机容量有限,受硬件限制。
- 弹性,服务器配置变更时间长,同时需要解决配置变更带来的一系列问题。
- 性价比,容量和计算之间的权衡。
解决方案:使用分布式系统,将物理存储节点池化、虚拟化,动态扩缩容。
问题与挑战
- 突破单写:同一时间同一数据,只有一个用户写入,实现多写。
- 内存池化
- 分布式事务优化
新技术演进
方向:
- 软件架构变更:绕过操作系统内核
- AI增强:智能存储格式转换
- 新硬件革命:
- 存储介质
- 计算单元
- 网络硬件
SPDK(Storage Performance Development Kit)
- 内核态到用户态:避免syscall带来的性能损耗,直接从用户态访问磁盘。
- 中断到轮询:硬盘性能提高后,中断次数增多,不利于IO。
SPDK poller可以绑定特定CPU进行轮询,减少上下文切换,提高性能。 - 无锁数据结构:使用无锁队列,降低并发的同步开销。
人工智能
行列混存,使用AI决策数据是行存还是列存。
新硬件加速
RDMA网络
传统的网络协议栈,需要基于多层网络协议处理数据包,存在用户态和内核态之间的切换,足够通用但性能不是最佳。
RDMA 是 kernel bypass 的流派,不经过传统的网络协议栈,可以把用户态虚拟内存映射给网卡,减少拷贝开销,减少 cpu 开销。
Persistent Memory
在 NVMe SSD 和 Main Memory 间有一种全新的存储产品——Persistent Memory
- IO 时延介于 SSD 和 Memory 之间,约百纳秒量级
- 可以用作易失性内存(memory mode),也可以用作持久化介质(app-direct)
可编程交换机
P4 Switch,配有编译器、计算单元、DRAM,可以在交换机层对网络包做计算逻辑。在数据库场景下,可以实现缓存一致性协议等。
CPU/GPU/DPU
- CPU:从 multi-core 走到 many-core
- GPU:强大的算力,越来越大的显存空间
- DPU:异构计算,减轻 CPU 的 workload
参考资料
The Google File System
The Linux Programming Interface(第13章 FILE I/O BUFFERING)