认识基本存储与数据库|青训营笔记

88 阅读13分钟

经典案例

某天,小明同学下载了一个新的APP。因为第一次登陆,所以进入APP后需要注册一个新的账号。小明同学三下五除二地填好了注册资料,按下了「注册」按钮。就这样,数据就从无到有地产生了,并且在数十/数百毫秒内向APP的后端服务器飞奔而去……

小明的个人信息数据开启了一场冒险,在下图中各个不同的介质中疯狂流动:

image.png

小明的数据一般会经历以下的持久化过程

image.png

在APP使用的过程中,会不会有以下潜在的问题?

  • 数据库怎么保证数据不丢?
  • 数据库怎么处理多人同时修改的问题?
  • 为什么用数据库,除了数据库还能存到别的存储系统吗?
  • 数据库只能处理结构化数据吗?
  • 有哪些操作数据库的方式,要用什么编程语言?

存储&数据库

存储系统

什么是存储系统?

一个提供了读写、控制类接口,能够安全有效地把数据持久化的软件,就可以称为存储系统

存储系统有哪些特点?

  • 作为后端软件的底座,性能敏感
  • 存储系统软件架构,容易受硬件影响
  • 存储系统代码,既“简单”又“复杂”

存储器层次结构如下图,来自Memory hierarchy

数据从应用到存储介质,需要经过以下流程:

  1. 用户数据需要调用标准库函数,标准库函数拥有其自身的缓冲
  2. 用户调用刷新函数执行输入输出的系统调用
  3. 系统调用将用户空间数据拷贝到内核空间缓存
  4. 调用执行函数将内核数据刷新到硬盘上

在这个过程中,缓存很重要,贯穿整个存储体系,拷贝很昂贵,应该尽量减少。

单机存储系统怎么做到高性能、高性价比、高可靠性?

使用R(edundant) A(rray) of l(nexpensive) D(isks)技术,独立磁盘冗余阵列,通俗的讲就是把多块硬盘组成一个独立的磁盘阵列进行管理。

RAID出现的背景:

  • 单块大容量磁盘的价格>多块小容量磁盘
  • 单块磁盘的写入性能<多块磁盘的并发写入性能
  • 单块磁盘的容错能力有限,不够安全

RAID 0:

将数据条带化,最少需要两块硬盘(每块硬盘的容量一样,实际生产环境中建议使用同品牌同型号同批次同容量的硬盘组成 RAID 0),即将所有组成 RAID 0 的硬盘的可用容量组合在一起,形成计算机上的一个逻辑卷。通俗的讲就是至少使用两块硬盘来存储数据,但是我要存储的数据不是全部存在某一块硬盘上,而是把我要存储的数据分成均等的多部分,然后平均分散存储在组成 RAID 0 的磁盘阵列上。

下图是用四块硬盘组成 RAID 0 的示意图,其中每块硬盘都被分成 ABCD 四个条带,然后我要存数据就先存把数据均分成四部分,如果 A1 能存下其中一份,那就直接将四部分分别存入 A1A4,如果存不下就先存满 A1A4,剩下的按同样的方式存 B1~B4,以此类推。

image.png

  • 优点:

    • 处理大文件很快。
    • 提高读写速度,对硬盘的总容量没有损失。
  • 缺点:

    • 一旦阵列中某块硬盘损坏了,所有数据将不可恢复。

RAID 1:

镜像存储,RAID 1 至少需要两块硬盘组成,两块硬盘互为备份,存储的内容完全相同。建议硬盘容量大小也要一样,如果不一样,那实际可用容量不超过较小的那块硬盘的容量。

image.png

  • 优点:

    • 读取性能翻倍。
    • 提供数据冗余,如果其中一块数据丢失,可以通过另一块还原。
  • 缺点:

    • 磁盘的利用率低,成本高。

RAID 2:

RAID 2 本质上是 RAID 0,只是加入了汉明码来做数据的纠错。以此来优化 RAID 0。汉明码(Hamming Code)是广泛用于内存和磁盘纠错的编码。汉明码不仅可以用来检测转移数据时发生的错误,还可以用来修正错误。要注意的是,汉明码只能发现和修正一位错误,对于两位或者两位以上的错误无法正确和发现。

  • 优点:

    • 加入了数据纠错机制
  • 缺点:

    • 成本增高,需要额外的盘做汉明码纠错

RAID 3:

RAID 3 使用字节级别的条带化技术,并采用专用的奇偶校验磁盘。RAID 3 阵列能在一个磁盘出现故障的情况下确保数据不丢失。如果一个物理磁盘出现故障,该磁盘上的数据可以重建到更换磁盘上。如果数据尚未重建到更换驱动器上,而此时又有一个磁盘出现故障,那么阵列中的所有数据都将丢失。本质上和 RAID 0 相同,与 RAID 2 相似,作为 RAID 0 的优化版本。

image.png

  • 优点:

    • 加入了数据纠错机制。
  • 缺点:

    • 做奇偶校验会消耗系统性能,容易导致系统出现性能瓶颈。

数据库系统

数据库分为关系型数据库和非关系型数据库。

关系型数据库在提供存储的基础功能之外,还具有以下增强功能:

  1. 结构化数据友好
  2. 支持事务(ACID)
  3. 支持复杂查询语句

非关系型数据库也是存储系统,但是一般不要求严格的结构化:

  1. 半结构化数据友好
  2. 可能支持事务(ACID)
  3. 可能支持复杂查询语言

关系型数据库相较于存储系统的优点:

  1. 帮助我们存储并管理数据
  2. 支持事务,即ACID
  3. 支持复杂查询的能力

以SQL为例,数据库支持以下操作:

  • 操作数据

    • Insert
    • Update
    • Select
    • Delete
    • Where
    • GroupBy
    • OrderBy
    • ……
  • 操作定义

    • Create user
    • Create table
    • Create database
    • Alter table
    • ……

主流产品剖析

单机存储

单机存储指单个计算机节点上的存储软件系统,一般不涉及网络交互。单机存储一般有两种方式,本地文件系统和key-value存储。

本地文件系统:

Linux经典哲学:一切皆文件。文件系统的管理单元是文件,文件系统繁多,如Ext2/3/4,sysfs,rootfs等,但都遵循VFS的统一抽象接口。Linux文件系统有两大数据结构,Index Node 和 Directory Entry。

lndex Node记录文件元数据,如id、大小、权限、磁盘位置等,inode是一个文件的唯一标识,会被存储到磁盘上,inode的总数在格式化文件系统时就固定了。

Directory Entry记录文件名、inode指针,层级关系(parent)等,dentry是内存结构,与inode的关系是N:1(hardlink的实现)。

key-value存储:

世间一切皆key-value——key是你身份证,value是你的内涵。

常见使用方式::put(k,v) 或 get(k)

常见数据结构:LSM-Tree,某种程度上牺牲读性能,追求写入性能。

拳头产品:RocksDB

image.png

分布式存储

分布式存储在单机存储基础上实现了分布式协议,涉及大量网络交互。分布式存储一般有两类,分布式文件系统和分布式对象存储。

分布式文件系统——HDFS:

HDFS堪称大数据时代的基石,出现背景为专用高级硬件很贵,同时数据存量很大,且要求超高吞吐。

HDFS核心特点:

  • 支持海量数据存储
  • 高容错性
  • 弱POSIX语义
  • 使用普通x86服务器,性价比高

image.png

分布式存储—Ceph:

Ceph是开源分布式存储系统里的万金油。

Ceph的核心特点:

  • 一套系统支持对象接口、块接口、文件接口,但是一切皆对象
  • 数据写入采用主备复制模型
  • 数据分布模型采用CRUSH(HASH+权重+随机抽签)算法

单机数据库

单机数据库指单个计算机节点上的数据库系统,事务在单机内执行,也可能通过网络交互实现分布式事务。

关系型数据库

商业产品Oracle称王,开源产品MySQL & PostgresQL称霸。

关系型数据库的通用组件:

  • Query Engine: 负责解析query,生成查询计划
  • Txn Manager: 负责事务并发管理
  • Lock Manager: 负责锁相关的策略
  • Storage Engine: 负责组织内存/磁盘数据结构
  • Replication: 负责主备同步

关键内存数据结构:B-Tree、B+-Tree、LRU List等

关键磁盘数据结构:WriteAheadLog(RedoLog)、Page

image.png

非关系型数据库

非关系型数据库中,MongoDB、Redis、Elasticsearch三足鼎立。关系型数据库一般直接使用SQL交互,而非关系型数据库交互方式各不相同。非关系型数据库的数据结构千奇百怪,没有关系约束后,schema相对灵活。不管是否关系型数据库,大家都在尝试支持SQL(子集)和“事务”。

Elasticsearch特点:

  • 面向文档存储
  • 文档可序列化成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交互

分布式数据库

单机数据库遇到了哪些问题&挑战,需要我们引入分布式架构来解决?

单机数据库容量有限,需要多机扩容;单机数据库不能支持弹性扩缩容;维护单机数据库性价比低

解决容量问题:

image.png

解决弹性问题:

解决性价比问题:

分布式数据库还有更多的事情可以做,例如:

  1. 单写和多写
  2. 从磁盘弹性到内存弹性
  3. 分布式事务优化

新技术演进

软件架构

Kernel Bypass(内核旁路)是绕过Linux内核(TCPIP协议栈)的技术,不使用Linux内核子系统的功能,采用自己实现的相同功能的代码来处理,从用户空间直接访问和控制设备内存,避免数据从设备拷贝到内核,再从内核拷贝到用户空间。Kernel Bypass目前主流实现方案有SPDK、DPDK、SolarFlare。

SPDK是一套存储开发套件,专门为专用设备(NVME)设计。全称是The Storage Performance Development Kit。SPDK提供了一系列的高性能、可扩展、用户态下面的工具和库。

SPDK有以下优势:

  1. 存储设备的驱动代码运行在用户态,不会运行在内核态,避免了内核的上下文切换节省了大量的处理开销,节省下来的CPU时间片可以用于实际的数据处理,比如重复数据剔除、压缩、加密。
  2. 轮询模式驱动(Polled Mode Drivers, PMDs),改变了I/O的基本模型。在传统的I/O模型中,应用程序提交读写请求后睡眠,一旦I/O完成,中断就会将其唤醒。PMDs的工作方式不同,应用程序提交读写请求后继续执行其他工作,以一定的时间间隔回头检查I/O是否已经完成。这种方式避免了中断带来的延迟和开销,并使得应用程序提高了I/O的效率。在旋转设备时代(磁带和机械硬盘),中断开销只占整个I/O时间的一个很小的百分比,因此给系统带来了巨大的效率提升。然而,在固态设备的时代,持续引入更低延迟的持久化设备,中断开销成为了整个I/O时间中不能被忽视的部分。这个问题在更低延迟的设备上只会越来越严重。系统已经能够每秒处理数百万个I/O,所以消除数百万个事务的这种开销,能够快速地复制到多个内核中。数据包和数据块被立即分发,等待时间减小到最少,使得延迟更低,一致性延迟更多(抖动更少),吞吐量也得到提高。
  3. 拥有无锁数据结构,使用Lock-free queue,降低并发时的同步开销。

AI增强存储

AI领域相关技术,Machine Learning在很多领域,如推荐、风控、视觉领域证明了有效性。AI也能在存储领域带来一些存储方式的决策。

例如一般数据库分为行式存储和列式存储,如果需要频繁使用实体的全部数据一般用行式存储,如Mysql;如果需要统计某些数据则适合列式存储,如HBase。行列混合存储数据库会针对数据本身的使用情况,对于某些数据进行行式存储,某些数据进行列式存储。这时候我们可以使用AI决策监察数据,并自动选择适合的存储方式。

image.png

新硬件革命

  1. RDMA网络

    1. 传统的网络协议栈,需要基于多层网络协议处理数据包,存在用户态&内核态的切换,足够通用但性能不是最佳
    2. RDMA是kernel bypass的流派,不经过传统的网络协议栈,可以把用户态虚拟内存映射给网卡 ,减少拷贝开销,减少cpu开销
  2. Persistent Memory

    1. 处于在NVMe SSD和Main Memory间,IO时延介于SSD和Memory之间,约百纳秒量级
    2. 可以用作易失性内存(memory mode) ,也可以用作持久化介质(app-direct)
  3. 可编程交换机

    1. P4 Switch,配有编译器、计算单元、DRAM,可以在交换机层对网络包做计算逻辑。在数据库场景下,可以实现缓存一致性协议等
  4. CPU/GPU/DPU

    1. CPU:从multi-core走向many-core

    2. GPU:强大的算力&越来越大的显存空间

    3. DPU:异构计算,减轻CPU的workload

课后作业

实现一个(分布式)key-value存储系统

要求:

  1. 基于本地文件系统实现,支持常用的put(k, v)、get(k, v)、scan_by_prefix(prefix)接口
  2. 支持存储server独立进程部署,支持跨进程或者网络访问
  3. IO操作做到低时延
  4. 支持扩展成分布式架构,多台存储server组成一个分布式key-value存储系统,并保证全局的数据一致性*

参考文档: