一张图掌握数据存储
数据存储有个学名:数据持久化,对信息系统来说,本质也是解决数据收集,数据存储,数据使用的问题,所以有必要对相关的知识点建立知识体系。数据存储体系五花八门,如果没有把握好技术选型,就有可能碰到访问速度慢,扩展性低的问题。
1、单机文件系统
文件存储在机械或者固态硬盘上,存储容量和单机磁盘空间大小相关。
1.1、文件保存格式
操作系统将硬盘空间以块为单位进行划分,每个文件占据若干个块。操作系统通过一个文件控制块 FCB 记录每个文件占据的硬盘数据块。如下图所示

文件控制块也叫inode,存储文件的元信息,要想访问文件,就必须获得文件的 inode(文件控制) 信息,在 inode 中查找文件数据块索引表,根据索引中记录的硬盘地址信息访问硬盘,读写数据。inode 最多可以存储 12+256+256*256+256*256*256 个数据块,如果每个数据块的大小为 4k,也就是单个文件最大不超过 70G

1.2、存储空间扩容
1.2.1、单机磁盘扩容
单机磁盘大小可以使用linux工具扩容,linux系统提供了物理卷和逻辑卷管理工具,使用逻辑卷整合物理卷,增加逻辑卷大小扩充可用磁盘空间。
1.2.1.1、逻辑卷使用
物理卷和逻辑卷使用pv--> vg-->lv三个命令
pv操作物理卷:常用命令:创建物理卷 pvcreate ; 查询物理卷pvs

vg操作卷组,一个卷组包含多个物理卷:常用命令:创建卷组vgcreate ;查询卷组vgs

lv操作逻辑卷:常用命令:创建逻辑卷 lvcreate -L 100M(空间大小) -n(lv名称) vg1(卷组名称) ;查询lv :lvs
逻辑卷可以动态扩容,这是linux卷管理最强大的地方,目录如果mount逻辑卷,有新的磁盘加入可以随时扩容。
1.2.2、使用RAID扩容
如果有独立的多块磁盘或磁盘阵列,可以使用raid工具做raid磁盘。
1.3 文件操作
文件有随机读写和顺序读写两种,程序操作单机文件,可以使用各自语言类库,比如java有File、FileReader、FileWriter等类库。
2、分布式文件系统
分布式文件系统主要有FastDFS,Minio,HDFS,其中:Minio是最常用的对象存储,它兼容Amason的S3 分布式对象存储,用Golang语言实现,客户端支持python,java。
2.1 分布式对象存储
存储形式:以对象形式存储,可以用返回josn object形式
对象存储要点:1、把文件分成大小相等块儿,便于维护管理;2、把这些块儿分散到不同的数据节点上,来提升读写性能;3、文件在那些数据节点,由原数据服务器维护,可以用ZooKeeper做元数据集群,存储服务首先用请求中的 Key,去元数据集群查找这个 Key 在哪个数据节点上,然后再去访问对应的数据节点读写数据,最后把结果返回给客户端。4、为了减少元数据的数据量,数据块会被聚合,放到一个容器里面,容器的大小是固定的,容器内的块数也是固定的。

2.2 HDFS存储框架
第HDFS是hadoop生态系统标准的存储框架,hadoop系统还有计算框架map reduce(现在基本都是spark替代了,saprk算子丰富,速度快),调度框架yarn。
HDFS存储要点:1、由NAMENODE(生产环境不会单点,是集群)和DataNode构成;2、数据读取,先访问NameNode,获得block位置再访问block所在datanode;3、写数据反之,如图所示

总结
1.维护整个文件系统的文件目录树,文件目录的元信息和文件数据块索引
2.以FsImage和EditLog形式存储在本地(FsImage目录树镜像到磁盘,EditLog日志文件)
3.整个系统的单点,存在SPOF(Simple Point of Failure)
4.没有元数据中心的情况:使用hash取模:一致性hash算法
1.又名CheckPoint Node,定期合并FsImage和EditLog
2.不接收客户端的请求,作为NameNode的冷备
3.使用Zookeeper实现NameNode HA

1.实际存储数据的单元
2.以Block为单位
3.数据以普通文件形式保存在本地文件系统
4.dataNode演示图如下

3、数据库存储
数据库软件作为业务逻辑处理和数据存储的中间环节,包括hive sql与spark sql所有的数据库软件基本实现思路都一样,查询sql经过词法分析,语法分析产生执行计划,根据数据的存储方式(单机,raid,分布式文件系统hdfs),逻辑执行计划和物理执行计划会有所不同。这篇文章重点在存储部分,其它内容会简单提一下,在其它文章中再详细说。
3.1 关系型数据库
关系型数据的存储的逻辑结构都是表
3.1.1 mysql
mysql的架构:

MySQL默认的存储引擎是 InnoDB,数仓的话MyISAM。
在 InnoDB 中存储引擎中,数据表的物理存储结构是以主键为关键字的 B+ 树,每一行数据直接就保存在 B+ 树的叶子节点上。在 InnoDB 中,表的索引也是以 B+ 树的方式来存储的,和存储数据的 B+ 树的区别是,在索引树中,叶子节点保存的不是行数据,而是行的主键值。

虽然逻辑上每个表是一颗 B+ 树,但是物理上,每条记录都是存放在磁盘文件中的,这些记录通过一些位置指针来组织成一颗 B+ 树。当 MySQL 删除一条记录的时候,只能是找到记录所在的文件中位置,然后把文件的这块区域标记为空闲,然后再修改 B+ 树中相关的一些指针,完成删除。其实那条被删除的记录还是躺在那个文件的那个位置,所以并不会释放磁盘空间。
3.1.2 oracle
oracle的基本存储单位是block,这和mysql是不一样的,mysql的存储单位是页
Oracle数据存储单位
a、block 数据块: 2k 最小的I-O单位,伴随database产生而产生,不可变
b、extent 一组连续的数据块:是用户所能分配存储的最小单位
c、segment 段:有共同结构的一个或几个区域( extent)
d、tablespace 表空间:一组物理数据的逻辑组合,(象逻辑间数据仓库)
e、 file 文件:属于某个表空间的物理文件
3.2 其他数据库
3.2.1 hbase
3.2.1.1 hbase存储的逻辑结构
使用的列族设计,在创建表的时候,只需要指定列族的名字,无需指定字段(Column)。在数据写入时再指定指定字段即可

3.2.1.2 hbase存储物理结构

这里HFile也是HDFS文件
3.2.2 hive
Hive可以看做一个执行器,如下图所示,就是我们上图看到词法分析、语法分析到执行计划,存储引擎是HDFS+Map-Reduce

sHive的执行引擎(严格来说是物理执行引擎)是可以替换的,有了Hive on Spark,Hive on Tez。
3.2.3 redis
Redis 只能支持有限的几个 API,几乎没有聚合查询的能力,也不支持 SQL。它的存储引擎也非常简单,直接在内存中用最简单的数据结构来保存数据
redis支持的逻辑层数据结构有:String(字符串)、List(列表)、Hash(哈希)、Set(集合)和 Sorted Set(有序集合)(List,Hash、Set和 Sorted Set称为集合类型,一个键对应了一个集合的数据)。
reids物理存储结构一共有 6 种:简单动态字符串、双向链表、压缩列表、哈希表、跳表和整数数组。

redis更新一般采用Cache Aside模式
Cache Aside

3.2.4 mq消息队列
mq提供了异步数据传输,数据通过消息队列传递
3.2.4.1 Rabbitmq
1、业务系统之间一般rabbitmq用的比较多
2、、消息是可以持久化保持到磁盘的,持久化消息在到达队列时写入磁盘,同时会内存中保存一份备份,非持久化消息一般只存于内存中,当内存压力大时数据刷盘处理,以节省内存空间
3、消息队列消息体中传递的是字节序列,。消息体中字节序列由文本、 二进制数、JSON、XML这些基本数据结构序列化
3.2.4.2 Kafka
使用 Kafka 来存储。现代的消息队列,本质上就是分布式的流数据存储系统,Kafka 官方给自己的定位也是“分布式流数据平台”,不只是一个 MQ。Kafka 提供“无限”的消息堆积能力,具有超高的吞吐量,可以满足我们保存原始数据的大部分要求。下游的计算任务,可以作为消费者订阅消息,也可以按照时间或者位点来读取数据。 Kafka 的吞吐量远大于HDFS。
3.2.5 时序数据库
这些时序数据库能提供很方便的查询和聚合数据的能力。主要存储有时间特征并且数据内容都是数值的数据。国产的TDengin在项目中使用,感觉不错。
总结:
数据库做为应用程序和存储之间的一层,极大丰富了存储形式和存储空间的使用;各类五花八门的数据库,基本思路是一致的。下面这张图总结了上面内容。
数据库选型思路:数据量支持的情况下,首选关系型数据库,如果mysql,功能丰富能解决大部分问题;如果数据量级已经超过 MySQL 极限(单表300万以上就已经很慢),可以选择es或者一些列式数据库,比如:HBase、Cassandra、ClickHouse,数据量再增长也可以考虑Spark、Hive 。总的来说,就是根据不同的查询需求,组织成不同的数据结构,存放在适合的存储系统。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2022-02-19 macbook安装scala、hadoop、saprk环境