单机存储系统
在单机存储系统中,所有的数据都存储在本地设备上,这种方式通常用于资源需求较小、访问频率较低的场景。单机存储系统有以下几种典型实现:
- 本地文件系统 本地文件系统是最基础的存储方式,直接将数据以文件的形式存储在硬盘上。操作系统提供了对文件的基本操作,如读写、删除、移动等。常见的文件系统有 FAT32、NTFS、EXT4 等。尽管它简单易用,但在面对大规模数据存储需求时,其扩展性和性能容易成为瓶颈。
- 键值存储(Key-Value Storage) 键值存储是一种将数据以键值对(Key-Value)形式存储的系统,典型的代表是本地的嵌入式数据库,如 SQLite 或 LevelDB。键值存储可以高效地查找、更新和删除数据,但通常仅支持单机环境。它的优势在于操作简单,性能高,适用于小型应用或临时性数据存储。
分布式存储系统
当单机存储无法满足需求时,分布式存储系统成为一种更具弹性的解决方案。它将数据分散存储在多个节点上,具备高可用性、可扩展性和容错性。常见的分布式存储系统分为以下几类:
-
分布式文件系统
- HDFS(Hadoop Distributed File System) HDFS 是 Hadoop 生态系统中的核心组件,擅长处理大文件和批量数据分析任务。它将数据分块存储到不同的节点中,并通过副本机制保障数据安全。
- Ceph Ceph 是一个支持对象存储、块存储和文件存储的分布式存储系统。它通过动态负载均衡和故障自动恢复实现了高可靠性和高性能。
-
非关系型数据库(NoSQL) 非关系型数据库是一种专为非结构化或半结构化数据设计的数据库,能够灵活应对复杂的数据存储需求:
- MongoDB:一个面向文档的数据库,适合存储 JSON 格式的半结构化数据,支持灵活的查询。
- Redis:一个高性能的内存键值数据库,广泛用于缓存、会话管理等场景。
- Elasticsearch:一个支持模糊搜索的分布式搜索引擎,可以根据文档的内容计算关联程度,广泛应用于全文搜索和日志分析。
非关系型数据库的特点:
- 灵活的数据模型:可以存储 JSON、XML 等复杂格式。
- 高扩展性:通过分片和副本机制支持大规模横向扩展。
- 适应高并发:对动态需求和实时访问有很好的支持。
-
关系型数据库(SQL) 与非关系型数据库不同,关系型数据库基于表结构来组织和存储数据,数据以行和列的方式记录,表与表之间可以通过外键建立关联。
- 常见的关系型数据库有 MySQL、PostgreSQL 和 SQL Server。 特点:
- 强一致性:事务支持 ACID 特性。
- 查询能力强:支持复杂的 SQL 查询。
- 适用于结构化数据存储。
为什么要用分布式架构?
随着业务需求的增长,单机架构难以满足高并发、大容量和高可用性需求,分布式架构成为主流。其主要优势包括:
- 容量扩展 单机存储受限于硬件资源,硬盘的容量和 I/O 性能都是有限的,而分布式系统通过节点池化技术,将存储需求分散到多个节点,实现动态扩容。
- 弹性灵活 分布式架构支持动态迁移和资源调度,可以根据业务负载灵活调整节点数量,以应对流量高峰或减少低谷期的资源浪费。
- 性价比优化 单机系统的 CPU 和存储资源可能无法充分利用,而分布式系统可以通过合理分配任务,提升资源的利用率。
主键的设置问题
各个算法的缺陷
传统的递增:
交给数据库处理,1)增加数据库的压力 2)业务层无法明确知道现在递增到哪一位了 3)安全问题:如果被识破了,有安全隐患
UUID:
- 随机性强,字符串形式 2)数据库的底层是B+树,UUID过于庞大所以会导致索引过于庞大 而且还不是递增的 很浪费空间 还是字符串形式 更不方便B+树 裂变之类的 3)生成底层算法可能不安全(以前出现过利用Mac地址进行生成的
雪花算法
64位 刚好对应Long型 第一位是传统的符号位 后面41位是时间戳位 然后是机器标识位 然后是进程ID位
问题:1)时间戳位 经过原本也是Long型 经过了压缩压缩到41位 有损失 2)就是 时间戳位上可能出现时光回溯现象,因为信号传播是电信号 3)12 位序列号(在同一毫秒内对不同的 ID 进行区分 都是从0开始分配的话 进行分表采用取模运算的时候会都大部分落在同一张表上4)采用震荡 加 移位操作
-
工作进程位可能出现的问题
-
工作进程数量限制问题
- 雪花算法中 10 位工作进程 ID 最多可以表示个不同的工作进程。在一个小型系统或者刚开始发展的系统中,1024 个工作进程可能看起来足够了。但是,如果系统规模不断扩大,例如在一个大型的分布式系统中,有大量的服务器、容器或者微服务实例(工作进程)参与 ID 生成,1024 个标识可能就不够用了。
- 这就好比一个停车场只有 1024 个停车位(工作进程 ID),当车(工作进程)越来越多,超过了这个数量,就没办法给每辆车分配一个单独的停车位了。
-
工作进程位分配不灵活问题
- 当企业或项目有不同的部门、不同的业务线或者不同的机房等情况时,10 位工作进程 ID 可能很难灵活地进行分配。例如,企业有 3 个不同的机房,每个机房有多个服务器,每个服务器上又运行多个服务实例,要合理地分配这 10 位工作进程 ID 来区分这些不同的层次结构就会比较复杂。
- 假设把工作进程 ID 简单地按照机房来划分,每个机房分配一部分 ID,可能会出现某个机房业务增长迅速,很快用完了分配的 ID,而其他机房还有很多空闲 ID 的情况。这就好比把停车场的停车位按照楼层(类比机房)划分,某个楼层的车(工作进程)很快就停满了,其他楼层还有很多空位,但没办法灵活调整。
-
工作进程位精度相对不足问题
- 在一些对工作进程区分要求很高的场景下,10 位的精度可能不够。例如,在一个金融系统中,可能需要精确区分不同的交易终端、不同的风险评估模块等众多非常精细的工作单元,10 位工作进程 ID 可能无法满足这种精细的区分需求。
- 这就好像在一个大型的科学实验中,需要精确记录每个微小的实验设备(工作进程)产生的数据,但是现有的标识系统(工作进程位)没办法把每个设备都分得很清楚,可能会导致数据记录混乱或者难以追溯。
-