这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记
一:存储系统
1.1 存储系统基础
What——存储系统是一个提供了读写、控制类接口,能够安全有效地把数据持久化的软件
How——①作为后端软件的底座,性能敏感;②存储系统软件架构,容易受硬件影响;③存储系统的代码,既简单又复杂
1.2 数据如何从应用到存储介质?
数据的缓存很重要,几乎贯穿整个存储体系
而在存储中要尽量少使用昂贵的拷贝操作
存储的硬件设备五花八门,需要有抽象统一的接入层
1.3 存储技术:RAID磁盘阵列(独立冗余磁盘阵列)
——技术背景:
- 性能: 单块磁盘写入性能 < 多块磁盘的并发写入性能
- 成本: 单块大容量磁盘价格 < 多块小容量磁盘
- 可靠性 : 单块磁盘的容错能力有限,不够安全
单机存储系统如何做到高性能/高性价比/高可靠性?
——RAID:
- 把多块独立的物理硬盘按照不同的方式组合起来形成一个硬盘组(逻辑硬盘)。从而提供比单个硬盘更高的存储性能和提供数据备份技术。
——RAID 0 // RAID 1 // RAID 1+0
- RAID0(条带化存储)——提性能
连续以位或字节为单位分割数据,并行读/写于多个磁盘上,因此具有很高的传输效率。但RAID0只是单纯地提高性能,并没有为数据的可靠性提供保证,而且其中一个磁盘失效将影响到所有的数据。因此无法应用到对数据安全性很高的场合
- RAID1(镜像存储)——提可靠性
通过磁盘数据镜像实现数据冗余,在成对的独立磁盘上产生互为备份的数据,因此写入效率较低。当原始的数据繁忙时,可直接从镜像拷贝中读取数据,因此RAID1可以提高读取性能。RAID1是所有磁盘阵列中单位成本最高的。但提供了很高的数据安全性和可用性。当一个磁盘失效时,系统可以自动切换到镜像磁盘上读写,而不需要重组失效的数据
- RAID 1+0(先做镜像,再做条带)——提性能和可靠性
将RAID0和RAID1结合,既满足了存储的可靠性,也大大提高了性能
——更多对RAID技术的介绍,详见这篇文章:t.csdn.cn/R9QKA
\
二:数据库系统
2.1 数据库分类
数据库分为两类:关系型数据库和非关系型数据库
——关系是啥?
关系 = 集合 = 任意元素组成的若干有序偶对
——关系代数是啥?
关系代数 = 对关系作运算的抽象查询语言(交、并、补、笛卡尔积等)
——关系型数据库是啥?
本质就是存储系统,但是在存储之外,又发展出了其他能力。比如:①对结构化数据很友好,处理高效;②支持事务;③支持复杂的查询语言(如SQL)
——非关系型数据库是啥?
本质也是存储系统,但是和关系型数据库不同,非关系型数据库一般不要求严格的结构化数据,它也可能会支持事务,甚至可能支持复杂的查询语言。
2.2 数据库VS经典存储
- 结构化数据管理
比如一条用户的注册数据,现在要将其进行存储:
如果用经典存储:
如果用数据库:
一般存储的意义,就是要实现对数据的查询。而数据在实际的应用中,不可能是一成不变的,因此还需要实现增删改。而判断一个存储系统的性能好坏,一个重要标准就是增删改查是否方便。对比经典存储和数据库两种存储方式可发现:经典存储是要求对每个数据进行元信息(比如长度、格式等)和数据本身的存储,这时候对数据的增删改是个极大的麻烦
比如我要删除"xiaoming"这个数据,为了不浪费存储空间,就需要对后面的数据进行移位操作,而且删除"xiaoming"这个信息,后面的"helloworld"和"coding"两个数据也要一并删除,逻辑之多处理也不方便,对程序员是一个极大的痛苦
而使用数据库则方便得多,因为数据存储的结构是十分清晰的
\
- 事务能力
经典存储很难或根本无法对事务进行处理,但数据库支持。
事务具有以下四个特性:
- A(原子性) :事务内的操作要么全做,要么不做
- C(一致性) :事务执行前后,数据状态要是一致的
- I(隔离性) :可以隔离多个并发事务,避免互相影响
- D(持久性) :事务一旦提交成功,要保证持久性
\
- 复杂查询能力
经典存储如果要做很复杂的查询,实现的代码也是相当复杂的,需要不断地对数据进行遍历。而数据库提供了SQL语言,对复杂的查询十分友好。
\
三:主流产品介绍
3.1 单机存储
单机存储 = 单个计算机节点上的存储软件系统,一般不涉及网络交互
- 本地文件系统
- 文件系统的管理单元:文件
- 文件系统接口:如Ext2/3/4,sysfs、rootfs等
- Linux文件系统的两大数据结构:Index Node & Directory Entry
Index Node: 记录文件的元数据,如id、大小、权限、磁盘位置等。inode是一个文件的唯一标识,会被存储到磁盘上。
Directory Entry: 记录文件名、inode指针、层级(parent)关系等。dentry是内存结构,与inode关系是N:1
- key - value存储
——key相当于是数据/文件的身份证,value相当于是数据本身
- 常用数据结构:LSM-Tree,是一种牺牲读性能,追求写入性能的数据结构
3.2 分布式存储
- 分布式文件系统
- HDFS(堪称大数据时代的基石)
HDFS的核心特点:
- 高吞吐量:支持海量数据存储
- 高容错性:数据自动保存多个副本,某一副本丢失可以自动恢复
- 弱POSIX语义:牺牲了一些POSIX的需求来补偿性能,有些操作会和传统的文件系统不同
- 性价比高:使用普通x86服务器
- 分布式对象存储
- Ceph(开源分布式存储系统里的万金油)
Ceph的核心特点:
- 一切皆为对象:一套系统支持对象接口、块接口、文件接口
- 数据写入采用主备复制模型
- 数据分布模型采用CRUSH算法(HASH+权重+随机抽签)
3.3 单机关系型数据库
单机数据库 = 单个计算机节点上的数据库系统。事务在单机内执行,但也可能通过网络交互实现分布式事务
——关系型数据库通用组件
- Query Engine —— 负责解析Query,生成查询计划
- Txn Manager——负责事务并发管理
- Lock Manager——负责锁相关的策略
- Storage Engine——负责组织内存/磁盘数据结构
- Replication——负责主备同步
——关键内存数据结构: B-Tree、LRU List
——关键磁盘数据结构: WriteAheadLog(RedoLog)、Page
——常用的关系型数据库: Oracle、MySQL、SQL Server
3.4 单机非关系型数据库
- 关系型数据库一般直接使用SQL交互,而非关系型数据库交互方式则各不相同,且数据结构千奇百怪。但不管是否为关系型数据库,两者都在尝试支持SQL和事务
——常用的非关系型数据库
- Elasticsearch:
- 面向文档存储
- 文档可序列化为JSON、并支持嵌套
- 存在index,index = 文档的集合
- 存储和构建索引能力依赖Lucene引擎
- 实现了大量搜索数据结构和算法
- 支持RESTFUL API、也支持弱SQL交互
- 跟RDBMS(关系型数据库管理系统)相比,ES天然能做模糊搜索,还能自动算出关联程度
- MongoDB:
- 面向文档存储
- 文档可序列化为JSON/BSON,并支持嵌套
- 存在collection、collection = 文档的集合
- 存储和构建索引能力依赖wiredTiger引擎
- 4.0后开始支持事务(多文档、跨分片多文档等)
- 常用client/SDK交互,可通过插件转译支持弱SQL
- Redis:
- 数据结构丰富(hash表、set、zset、list)
- C语言实现,性能超高
- 主要基于内存,但支持AOF、RDB持久化
- 常用redis-cli/多语言SDK交互
\
3.5 分布式数据库
——单机数据库遇到了哪些问题和挑战,需要我们引入分布式架构来解决?
- 容量:
单机数据库,一个数据库只能对应一个节点下的硬盘,而一个节点所能挂载的硬盘数量是有限的。在数据爆炸的大数据时代,一套业务逻辑所需要存储的数据量很大,一个节点根本无法实现存储。因此引入了分布式的数据库。而目前主流的分布式数据库架构——"池化节点技术"则很好地解决了上述痛点。
这一技术是通过动态地扩张/紧缩存储节点实现海量数据存储的。当一套业务逻辑所产生的数据量逐渐上升时,会自动地添加存储节点,数据库是不需要感知存储空间是否足够的。
- 弹性:
一个APP产品,是有生命周期的,业务从逐渐火爆到逐渐被市场淘汰。这一整个过程中,用户的数据量刚开始会逐步上升,因此需要动态对存储数据进行搬迁,数据量少的时候为了提高性价比,通常选用内存和磁盘容量较小的服务器进行数据存储,当数据量大了之后才会换成更大的。而且随着业务的逐渐火爆,对服务器的请求次数也是逐渐上升,因此对于CPU的性能会有更高的要求。但是当APP进入衰退期后,对CPU性能的要求就不是太高了。因此会选用核数较少的CPU,但一个性能较低的CPU通常对应的硬盘和内存空间也比较低,然而即使APP进入了衰退期,数据量也是在上升的,因此更换CPU的方式不可行。这时候就需要用到上面的"池化节点技术"了,有了池化节点,当业务进入衰退期时,就可以换成以下的架构方式:换成更多台CPU核数更低的节点进行存储
- 性价比:
业务上,会存在以下这种情况:APP数据非常多,但是对服务器的请求次数少(即日活低但是数据量高),这种情况对CPU是极大的浪费,可能一个节点的内存和硬盘用光了,CPU的利用率还不到20%。这时候随着数据量的再度增大,就需要更多的节点进行数据存储,然而CPU的问题不但没有解决,反而更严重了。因此,就需要进行架构上的优化以提升CPU使用率。解决方法其实跟上面同理,还是使用池化技术,换成更多CPU核数低的节点来提升性价比。