经典案例
数据的产生
某天,小明同学下载了一个新的APP。因为第一次登录,所以进入APP后要注册一个新的账号
于是小明同学三下五除二的填好了资料,按下了[注册]按钮
就这样,数据就从无到有的产生了,并且在数十数百毫秒内向APP后端服务器飞奔而去......
数据的流动
先从客户端的发送信息,然后服务端处理,符合存储要求就会存储在数据库中去,然后就是其他操作。
代码举例
客户端发送信息
register.go/服务端校验
func Register(username, password string) (id int64, tokenString string, err error) {
// 校验数据合法性
if len(username) > 32 {
return 0, "", errors.New("用户名过长,不可超过32位")
}
if len(password) > 32 {
return 0, "", errors.New("密码过长,不可超过32位")
}
// 判断用户是否存在
user := domain.User{}
dao.DB.Model(&domain.User{}).Where("name = ?", username).Find(&user)
if user.Id != 0 {
return 0, "", errors.New("用户已存在")
}
register.go/服务端存数据库
// 加盐加密存储用户密码
user.Name = username
user.Salt = randSalt()
buf := bytes.Buffer{}
buf.WriteString(username)
buf.WriteString(password)
buf.WriteString(user.Salt)
pwd, err := bcrypt.GenerateFromPassword(buf.Bytes(), bcrypt.MinCost)
if err != nil {
return 0, "", fmt.Errorf("bcrypt加密错误: %w", err)
}
user.Pwd = string(pwd)
// 创建用户
dao.DB.Model(&domain.User{}).Create(&user)
// 生成jwt
tokenString, err = GenerateJWT(user.Id, util.JWTSecret())
if err != nil {
return 0, "", errors.New("生成jwt错误")
}
// 缓存jwt
dao.RedisClient.Set(context.Background(), tokenString, user.Id, 0)
return user.Id, tokenString, nil
}
潜在的问题
- 数据库怎么保证
数据不丢 - 数据库怎么处理
多人同时修改的问题 - 为什么用数据库,处理数据库还能存到
别的存储系统吗? - 数据库只能处理
结构化数据? - 有些操作数据库的
方式,要用什么编程语言?
存储&数据库的简介
存储系统-系统概览
什么是存储系统
存储系统:一个提供了读写、控制类接口,能够安全有效地把数据持久化的软件。
- 用户(User)、介质(Medium)
- 内存(Memory):设计性能高效的操作方便的内存数据结构
- 网络(Network)编程:单机系统->分布式存储系统 满足苛刻的应用需求
存储系统的特点
性能敏感
- 存储系统作为后端软件的底座和最后一道门槛,掌握着上下层交互的关键。在现代大型后端架构中,许多服务都离不开持久化数据的保存和交互。大量的用户带来的是庞大的数据访问量,存储系统必须拥有强大的性能,才能处理如此之大的数据并发。
简繁并具
- 一方面,存储系统对性能的要求及其苛刻,这就意味着在我们
IO的过程中,任何过于复杂的操作都可能会对存取的性能造成巨大的影响,处理业务的代码必须简洁高效,此为”简“ - 另一方面,在
IO或非IO的业务处理过程中,可能会出现各种各样的错误或异常情况,既然存储系统是一个软硬件集合,那么在设计存储系统时就应该考虑到软件和硬件都有可能出现问题。墓碑上的墓志铭尚且会因风吹日晒而导致磨损或腐蚀,更别提现代的高精度硬件。存储系统的设计必须能覆盖可能考虑到的所有异常情况,无论是多复杂的异常,此为”繁“
硬大于软
- 存储系统的软件架构容易受到硬件影响。无论如何,硬件是一切的基石。无论用户层的软件大厦多么辉煌靓丽,没有了硬件作为最基础的地基,一切都是空中楼阁,无稽之谈。当存储结构的硬件发生改变的时候,软件也必须进行相应的改变才能适配,当硬件改变过大时,甚至需要对整个软件架构进行重构,从零开始。
存储器层级结构
对于通用计算机而言,存储层次至少应具有三级:最高层为CPU寄存器,中间为主存,最底层是辅存。在较高档的计算机中,还可以根据具体的功能细分为寄存器、高速缓存、主存储器、磁盘缓存、固定磁盘、可移动存储介质等6层。如下图所示。
数据怎么从应用到存储介质
1. 数据产生:首先,应用程序(如Web浏览器、办公软件等)根据用户的需求生成数据,这些数据可能是文本、图像、音频或视频等不同类型。
2. 数据封装:应用程序将生成的数据封装成特定的数据结构或文件格式。例如,文本数据可以封装成纯文本文件(如.txt)或者富文本文件(如.docx),图像数据可以封装成图片文件(如.jpg、.png)等。
3. 数据写入:应用程序将封装好的数据写入到计算机的内存中。对于需要持久化存储的数据,应用程序还需要将内存中的数据写入到存储介质中,如硬盘、U盘或云端存储等。
4. 数据传输:在数据写入到存储介质之前,数据需要通过计算机的输入/输出(I/O)系统传输。数据传输可以使用不同的接口和协议,如USB、SATA、PCIe等。此外,数据传输还可以通过网络,如互联网或局域网,传输到其他设备或云端存储。
5. 数据存储:当数据传输到存储介质时,存储介质的控制器会将数据写入到存储介质的特定区域。存储介质的物理结构决定了数据存储的方式,如磁盘、闪存或磁带等。存储介质的类型和性能也会影响数据存储的速度和安全性。
6. 数据读取:当需要读取存储介质中的数据时,存储介质的控制器会找到存储数据的特定区域,并将数据传输到计算机的内存中。应用程序可以从内存中读取数据,并将其呈现给用户。
整个过程中,涉及到的数据格式、传输协议、存储介质和硬件设备等都可能影响数据传输的效率和安全性。在实际应用中,需要根据具体需求和场景选择合适的技术和方案。
特别注意:1.缓存很重要,应该贯穿整个过程。2.拷贝很昂贵,应该尽量没有拷贝。
RAID技术
概述
RAID出现的背景︰
- 单块大容量磁盘的价格 > 多块小容量磁盘
- 单块磁盘的写入性能 < 多块磁盘的并发写入性能
- 单块磁盘的容错能力有限,不够安全
RAID(redundant array of independent disks)技术,独立磁盘冗余阵列,是提高磁盘可靠性和可用性的一种技术。RAID技术出现的初衷是把多个小容量的硬盘组合起来,以获得更大的存储容量。当前我们所说的RAID技术更多则是与数据保护相关,换言之,当物理设备失效时,RAID能够用来防止数据的丢失。
优势
- 把多个硬盘组合成一个逻辑盘组,以提供更大容量的存储。
- 将数据分割成数据块,对多个硬盘并行进行写入/读出,提高硬盘访问速度。
- 通过提供镜像或奇偶校验来提供容错。
- 高性能,高性价比,高可靠性
RAID 0:
- 多块磁盘简单组合
- 数据条带化存储,提高磁盘带宽:一个用户写入切片分为多个写入,分别并发写在磁盘上
- 没有额外的容错设计(无冗余、备份)
RAID 1:
- 一块磁盘对应一块额外镜像盘
- 真实空间利用率仅50%
- 容错能力强
RAID 0 + 1
- 结合了RAID 0和 RAID 1
- 真实空间利用率仅50%
- 容错能力强,写入带宽好
数据库
数据库和存储系统的不同
存储系统和数据库系统是两个不同的概念。 存储系统是用于存储数据的硬件和软件系统。 它的主要目的是提供大容量的存储空间,以便用户能够保存大量的数据。 存储系统可以是本地的,也可以是远程的。 数据库系统是一种用于组织,存储和管理数据的软件系统。 它使用特定的数据模型和语言来存储数据,并提供各种工具和接口,使用户能够查询和管理数据。 数据库系统通常在存储系统之上运行,使用存储系统提供的空间来存储数据。 因此,存储系统和数据库系统之间的区别在于,前者是用于存储数据的硬件和软件系统,而后者是用于组织,存储和管理数据的软件系统。
数据库的种类:关系数据库,非关系数据库。
数据库的概述
数据库(DataBase,简称DB)是“按照数据结构来组织、存储和管理数据的仓库”,是一个长期 … 数据库系统(DataBase System,简称DBS),是由数据库及其管理软件组成的系统。数据库系统是为适应数据处理的需要而发展起来的一种较为理想的数据处理系统,也是一个为实际可运行的存储、维护和应用系统提供数据的软件系统,是存储介质 、处理对象和管理系统的集合体。
什么是关系型数据库
关系数据库是一种用于存储相互关联的数据点并提供数据点访问的数据库。它采用关系模型,直接、直观地在表中展示数据。在关系数据库中,表中的每一行都代表一条记录,每条记录都具有一个唯一的 ID(又被称为键),而表中的列则用于存储数据的属性 — 每条记录的每一个属性通常都有一个值。籍此,用户可以轻松在数据点之间建立关联。
关系型数据库的特点
1. 结构化数据:关系型数据库使用表格(表)来组织数据,每一行代表一条记录,每一列代表一个字段。这种结构化的数据使得数据的存储、查询和管理更加方便和高效。
2. 数据完整性:关系型数据库具有强大的数据完整性约束,如主键、外键、唯一性约束、检查约束等,以确保数据的准确性和一致性。
3. 事务支持:关系型数据库支持事务处理,即一组操作要么全部成功,要么全部失败。事务的特性包括原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),简称ACID。
4. 查询语言:关系型数据库使用结构化查询语言(SQL)进行数据查询和操作。SQL是一种功能强大、简单易学的语言,用于管理和操作关系型数据库。
5. 索引:关系型数据库支持索引,可以提高查询速度。索引是数据库中用于加速数据检索的一种数据结构,通过索引可以快速地定位到符合条件的数据记录。
6. 数据库连接:关系型数据库支持多个客户端同时连接到数据库,实现数据的共享和并发访问。
7. 数据安全性:关系型数据库提供了多种安全措施,如访问控制、数据加密、审计等,以确保数据的安全性和隐私保护。
8. 数据完整性恢复:关系型数据库具有数据备份和恢复功能,可以在发生故障或灾难时,恢复数据库到之前的状态。
9. 可扩展性:关系型数据库可以通过增加硬件资源(如内存、存储和CPU)或优化数据库结构(如分区、分片)来提高性能和容量,满足不断增长的数据需求。
非关系型数据库
NoSQL 数据库的数据存储不需要固定的表结构,通常也不存在连接操作,其在大数据存取上具备关系型数据库无法比拟的性能优势,满足了企业应用需要将数据存储在横向且伸缩性上更强的功能需求。例如,Google 的 BigTable、Amazon 的 Dynamo 都是非常成功的商业 NoSQL 实现。
非关系型数据库(NoSQL,Not Only SQL)是一种与关系型数据库不同的数据存储和管理方式。非关系型数据库主要针对大规模、高并发、分布式的场景,提供高性能、可扩展性和灵活性。与关系型数据库相比,非关系型数据库具有以下特点:
非关系型数据库的特点
1. 数据模型:非关系型数据库不使用结构化的数据模型,而是采用其他灵活的数据模型,如键值(Key-Value)、文档(Document)、列族(Column-Family)和图(Graph)等。这使得非关系型数据库可以更好地处理复杂的、半结构化的数据。
2. 横向扩展:非关系型数据库通常可以通过分布式架构实现水平扩展,即通过添加更多的服务器节点来提高性能和容量。这使得非关系型数据库能够应对大规模数据和高并发访问的场景。
3. 高性能和低延迟:非关系型数据库通常针对特定场景进行优化,以实现高性能和低延迟。这使得非关系型数据库更适合用于实时应用和大数据处理。
4. 数据一致性:非关系型数据库通常采用最终一致性(Eventual Consistency)模型,而非强一致性(Strong Consistency)。这意味着在不同的节点之间,数据可能存在短暂的不一致。这使得非关系型数据库更适合处理分布式环境下的数据访问。
5. 简化的数据操作:非关系型数据库通常使用简化的查询语言和API,使得数据操作更加简单和方便。这对于开发和维护非关系型数据库系统来说,降低了复杂性。
常见的非关系型数据库有:MongoDB(文档型)、Redis(键值型)、Apache Cassandra(列族型)和Neo4j(图型)等。
数据库vs经典存储-结构化数据管理
数据库和经典存储是两种不同的结构化数据管理方法。它们在存储、检索、管理和分析数据方面有所不同。下面是数据库和经典存储之间的一些关键区别:
1. 数据组织:
数据库:数据库将数据组织成表(表格),每个表包含一组相关的数据项。表可以具有多个列(数据属性)和行(数据记录)。这种组织方式有助于轻松地存储、查询和更新数据。
经典存储:经典存储通常采用文件或记录系统,数据以文件的形式存储,每个文件包含一组相关的数据记录。数据可能以文本、二进制或其他格式存储。
2. 数据关系:
数据库:数据库支持数据之间的关系,通过外键、索引和关系来维护这些关系。这有助于维护数据的一致性、完整性和可用性。
经典存储:经典存储通常不直接支持数据之间的关系,需要手动维护数据关系。这增加了数据管理和分析的复杂性。
3. 数据访问:
数据库:数据库支持SQL(结构化查询语言),这是一种用于查询、更新和管理数据的标准语言。SQL使得从数据库中检索和操作数据变得简单且高效。
经典存储:经典存储通常需要程序员编写自定义的代码来访问和操作数据。这可能导致更多的代码开发和维护工作。
4. 数据管理:
数据库:数据库管理系统(DBMS)负责管理数据的存储、检索、备份和恢复。DBMS还提供事务处理、并发控制、安全性和数据完整性等高级功能。
经典存储:经典存储通常需要手动管理数据,包括备份、恢复和版本控制。这可能导致更多的管理和维护工作。
5. 可扩展性:
数据库:数据库通常可以轻松扩展,支持大量数据和多用户并发访问。许多数据库系统还支持分布式存储和计算。
经典存储:经典存储的可扩展性通常较差,难以支持大量数据和多用户并发访问。
数据库vs经典存储-事务能力
数据库vs经典存储-复杂查询能力
主流产品剖析
单机存储
基本概念
单机存储系统是单机存储引擎(数据结构在机械磁盘、SSD等持久化介质上的实现)的一种封装,对外提供文件、键值、表格或者关系模型的存储服务。
本地文件系统
key-value存储
put(K,v)&get(k)
某种程度上牺牲读性能,追求写入性能
存储引擎
存储引擎是存储系统的发动机,决定了存储系统能够提供的功能和性能, 提供功能包含:
- 增加(Create)
- 读取(Retrieve),随机读取和顺序扫描
- 更新(Update)
- 删除(Delete)
引擎间差异如下:
| 引擎 | 机理 | 支持 | 不支持 | 对应的存储系统 |
|---|---|---|---|---|
| 哈希存储引擎 | 哈希表的持久化实现。基于哈希表结构的键值存储系统,数组+链表的方式实现 | 增、删、改、随机读取 | 顺序扫描 | 键值(Key-Value)存储系统 |
| B树存储引擎 | B树的持久化实现 | 增、删、改、随机读取 & 顺序扫描 | 关系数据库 | |
| LSM(Log-Structured Merge Tree)树存储引擎 | 与B树类似,区别在于把一棵大树拆分成N棵小树写时,先写入内存中,到一定阈值后,写入磁盘,磁盘中的树定期可以做merge操作,合并成一棵大树,以优化读性能 | 增、删、改、随机读取 & 顺序扫描 | Bigtable; HBase; |
分布式存储
分布式存储的概览
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。
分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
HDFS
HDFS 包含大量数据,并提供更轻松的访问。为了存储如此巨大的数据,这些文件存储在多台计算机上。这些文件以冗余方式存储,防止发生故障时使系统免受可能的数据损失,同时HDFS 还使应用程序可用于并行处理。
如果客户端需要从某个文件读取数据,首先从 NameNode 获取该文件的位置,然后从该 NameNode 获取具体的数据。在该架构中 NameNode 通常是主备部署( Secondary NameNode ),而 DataNode 则是由大量节点构成一个集群。由于元数据的访问频度和访问量相对数据都要小很多,因此 NameNode 通常不会成为性能瓶颈,而 DataNode 集群中的数据可以有副本,既可以保证高可用性,可以分散客户端的请求。因此,通过这种分布式存储架构可以通过这种分布式存储架构可以通过横向扩展 datanode 的数量来增加承载能力,也即实现了动态横向扩展的能力。
HDFS的功能
-
数据的分布式存储和处理。
-
Hadoop 提供了一个命令接口来与 HDFS 进行交互。
-
namenode 和 datanode 的内置服务器可帮助用户轻松检查群集的状态。
-
对文件系统数据的流式处理访问。
-
HDFS 提供文件权限和身份验证。
HDFS的架构
下面给出的是 Hadoop 文件系统的体系结构
HDFS的元素
1.Namenod
Namenode是包含 GNU/Linux 操作系统的产品硬件。它是一种可以在产品硬件上运行的软件。具有Namenode的系统充当主服务器,并执行以下任务
1)管理文件系统命名空间
2)调节客户端对文件的访问
3)执行文件系统操作,如重命名、关闭和打开文件和目录。
2.Datanode
Datanode是具有 GNU/Linux 操作系统和数据内核软件的产品硬件。对于cluster(群集)中的每个产品硬件/系统,都将有一个数据节点,这些节点管理其系统的数据存储。
1)根据客户端请求在文件系统上执行读写操作。
2)根据 namenode 的说明执行块创建、删除和复制等操作。
3.Block
通常,用户数据存储在 HDFS 的文件中。文件系统中的文件将分为一个或多个片段存储在单个数据节点中。这些文件段称为block。换句话说,HDFS 可以读取或写入的最小数据量称为block。默认块大小为 64MB,可以根据 HDFS 配置进行更改。
HDFS的特点
1、故障检测和恢复 – 由于 HDFS 包含大量产品硬件,组件故障频繁。因此,HDFS 应具有快速自动故障检测和恢复的机制。
2、数据集的管理 – HDFS 每个群集都有数百个节点来管理具有大型数据集的应用程序。
3、数据硬件处理 – 当计算在数据物理附近时,可以高效地完成请求的任务。特别是在涉及大量数据集时,它减少了网络流量并提高了吞吐量。
Ceph
1、什么是ceph
Ceph是一个开源的、统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。其中“统一”是说Ceph可以一套存储系统同时提供块设备存储、文件系统存储和对象存储三种存储功能。
Ceph项目最早起源于加州大学Santa Cruz分校的Sage Weil的博士论文所设计开发的新一代自由软件分布式文件系统,其设计目标是良好的可扩展性(PB级别以上)、高性能及高可靠性,并随后贡献给开源社区。在经过了数年的发展之后,目前已得到众多云计算厂商的支持并被广泛应用。
Ceph是一个开源的分布式文件系统。因为它还支持块存储、对象存储,所以很自然的被用做云计算框架openstack或cloudstack整个存储后端。当然也可以单独作为存储,例如部署一套集群作为对象存储、SAN存储、NAS存储等
官网:ceph.com/
2、ceph支持的三种存储方式
1)块存储RBD
RBD(RADOS Block Devices)即为块存储的一种,RBD 通过 librbd 库与 OSD 进行交互,RBD 为 KVM 等虚拟化技术和云服务(如 OpenStack 和 CloudStack)提供高性能和无限可扩展性的存储后端,这些系统依赖于 libvirt 和 QEMU 实用程序与 RBD 进行集成,客户端基于 librbd 库 即可将 RADOS 存储集群用作块设备,不过,用于 rbd 的存储池需要事先启用 rbd 功能并进行初始化。
优点:
使用磁盘映射,如RAID/LVM的方式提供磁盘空间给主机使用,进一步维护了数据的安全性 因为是多块磁盘组合而成的逻辑盘空间,所以多块盘可以并行执行读写操作,提升IO效率 很多大型企业或数据中心使用SAN架构组网,数据传输速度和读写效率进一步得到提升
缺点:
如果采取FC_SAN的方式,需要HBA光纤通道卡和光纤交换机,成本较高 不利于不同操作系统主机间的数据共享,例如Linux主机把盘给格式化为ext4格式,那么在Windows中对这个盘的操作使用就不太友好了,或者无法操作
2)对象存储RGW
对象存储,也就是键值存储,通过其接口指令,也就是简单GET、PUT、DEL和其他扩展指令,向存储服务上传下载数据等
RGW 提供的是 REST 接口,客户端通过 http 与其进行交互,完成数据的增删改查等管理操作。 radosgw 用在需要使用 RESTful API 接口访问 ceph 数据的场合,因此在使用 RBD 即块存储得场合或者使用 cephFS 的场合可以不用启用 radosgw 功能。
优点:
后端使用大量硬盘组,且不受复杂目录系统影响,达到高水平的读写效率 集群可扩展性强,且支持多副本存储,保证数据安全性 通过URL直接访问存储文件,简单易管理
缺点:
不适合存放内容变动性大的文件,不然每次变动都要重新更新上传对象,适合放静态的图 片镜像等非结构性的文件 不太适合作为数据库存储数据使用
操作系统无法像常规磁盘一样安装或挂载对象存储
3)文件系统存储ceph-fs
Ceph文件系统(CEPH FS)是一个POSIX兼容的文件系统,可以将ceph集群看做一个共享文件系统挂载到本地,使用Ceph的存储集群来存储其数据,同时支持用户空间文件系统FUSE。它可以像 NFS 或者 SAMBA 那样,提供共享文件夹,客户端通过挂载目录的方式使用 Ceph 提供的存储。
在CEPH FS中,与对象存储与块存储最大的不同就是在集群中增加了文件系统元数据服务节点MDS(Ceph Metadata Server)。MDS也支持多台机器分布式的部署,以实现系统的高可用性。文件系统客户端需要安装对应的Linux内核模块Ceph FS Kernel Object或者Ceph FS FUSE组件。
用户可以在块设备上创建xfs文件系统,也可以创建ext4等其他文件系统。如下图所示,Ceph集群实现了自己的文件系统来组织管理集群的存储空间,用户可以直接将Ceph集群的文件系统挂载到用户机上使用
优点:
成本低,随便一台服务器都可以来搭建 方便于公司内部的文件共享,内网云盘共享一些资料等等
缺点:
网络带宽影响,读写效率慢,传输速率稍低
3、ceph的主要特点
统一存储
Ceph支持三种调用接口:对象存储,块存储,文件系统挂载。三种方式可以一同使用。在国内一些公司的云环境中,通常会采用ceph作为openstack的唯一后端存储来提升数据转发效率。所以在开源存储软件中,能够一统江湖。
Crush算法
Crush算法是ceph的两大创新之一,简单来说,ceph摒弃了传统的集中式存储元数据寻址的方案,转而使用CRUSH算法完成数据的寻址操作。CRUSH在一致性哈希基础上很好的考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨机房、机架感知等。Crush算法有相当强大的扩展性,理论上支持数千个存储节点。
高扩展性
扩容方便、容量大。能够管理数千台服务器、EB级的容量。
可靠性强
Ceph中的数据副本数量可以由管理员自行定义,副本能够垮主机、机架、机房、数据中心存放。所以安全可靠。存储节点可以自管理、自动修复。无单点故障,容错性强。
高性能
因为是多个副本,因此在读写操作时候能够做到高度并行化。理论上,节点越多,整个集群的IOPS和吞吐量越高。另外一点ceph客户端读写数据直接与存储设备(osd) 交互。