Go_

[TOC]

数据库

特点

  • 作为后端软件的底座, 性能敏感 ( 没有数据还有服务? )
  • 存储系统软件架构, 容易受硬件影响 (别人发明了快十倍的硬件, 但是需要从头写, 你用不)
  • 存储系统代码,既"简单"又"复杂"

设计程序原则

  • 「缓存」很重要,贯穿整个存储体系
  • 「拷贝」很昂贵,应该尽量减少
  • 硬件设备五花八门, 需要有抽象统一的接入层 , 例如 linux 的 一切皆文件

高速数据库的设计应该归为操作系统这一级别

  • 必不可少, 所有的计算机必须存储数据
  • 缓存的数据必须由程序员控制, 而不是操作系统的某个算法来控制
    • 例如, 用户查找了 A表的数据, 下一个行为必须是查询B表, 算法计算出来的是缓存C表, 那缓存还有用吗

RAID技术

RAID(Redundant Array of Independent Disks)技术是一种数据存储技术,通过将多个硬盘组合在一起来提供更高的性能、容错性和数据冗余。RAID 技术可以应用在服务器、工作站和个人计算机等各种存储设备上。

RAID 技术采用了不同的级别或配置,每种级别都具有其特定的优点和用途。以下是常见的几种 RAID 级别:

RAID 0

  • 多块磁盘简单组合

  • 数据条带化存储, 提高磁盘带宽

  • 没有额外的容错设计

RAID 1

  • 一块磁盘对应一块额外镜像盘
  • 真实空间利用率仅50%
  • 容错能力强

RAID 0+1

  • 结合了RAID0和RAID1
  • 真实空间利用率仅50%
  • 容错能力强,写入带宽好

为什么要使用数据库

  • 所有的系统都会产生数据, 所以 数据库系统是所有系统不可或缺的模块
  • 逻辑层和物理层之间的 存在 紧耦合
  • 复杂查询很麻烦

事物具有

  • A(tomicity),事务内的操作要么全做,要么不做
  • C(onsistency), 事务执行前后,数据状态是一致的
  • I(solation),可以隔离多个并发事务,避免影响
  • D(urability),事务一旦提交成功,数据保证持久性

使用文件系统来存储数据的弊端

  • 数据的冗余和不一致
  • 数据访问图难
  • 数据孤立
  • 完整性问题
  • 原子性问题
  • 并发访问异常

概念解释

名词 解释
关系 一组无序的元素或者记录
主键(primary key) 某一个唯一属性或一个属性组能唯一标识一条记录
外键(foreign key ) 指定一张表中的属性必须存在于另一张表中
SQL (Structured Query Language) 结构化查询语言

notes:

  • 原始关系模型中,所有的值都必须保证原子性或者单个属性值 (不能是数组 或者嵌套对象)
  • relationtable 是一回事
  • n元组 就是一个有n个值的元组,它对应于中的一行.

关系代数

符号 解释 注释
$\sigma _{predicate}(R)$ 选择
$\prod_{A1,A2,,,An}(R)$ 投影, 即选择部分列,而元组不改变 A1是属性
( R- S ) R中有但是S中没有
并集
交集
$R \times S$ 笛卡尔积, 产生 所有可能的不重复的组合
$R \bowtie S$ R表 和 S 中 每个属性都相同

聚合函数

函数名 解释
AVG( col ) 返回平均值
MIN( col ) 返回最小值
MAX( col ) 返回最大值
SUM( col ) 返回 值
COUNT( col ) 计数

Notes:

  • 聚合函数接收一组 Tuple 作为其输入,然后产生一个单一的标量值作为其输出。
  • 只能在 SELECT 输出列表中使用。

课后思考

  1. 写入存储系统的粒度太大,会不会导致数据原子性问题?例如一次性写 100MB,如果系统突然 crash,会不会只有一部分数据持久化了,另一部分丢失了?如果要解决原子性问题,一般会设计什么机制?
  2. 在从应用程序到存储介质的链路上,无论读还是写,数据可能要被拷贝好几次,这几次拷贝能不能去掉?如果我们去掉大部分拷贝操作,会有什么副作用,要怎么缓解副作用?
  3. 一个关系型数据库大概率是会被并发访问的,如果要保证并发安全,除了在行数据上加悲观锁还有其他方式吗?
  4. 在数据库领域,把数据按行存和按列存各有好处,你能从性能优先的角度设计出一种混合存储格式吗?

主流 存储产品

单机存储=单个计算机节点上的存储软件系统,一般不涉及网络交互

Linux文件系统的两大数据结构:Index Node&DirectoryEntry

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

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

世间一切皆 key-value

  • key是你身份证,value是你的内涵:
  • 感觉就像是数学中的映射 y = f(x), 在数组中, index -> value, map中 key-> value

常见使用方式:put(k,v)&get(k) 常见数据结构:LSM-Tree,某种程度上牺牲读性能,追求写入性能拳头产品:RocksDB

分布式文件系统

HDFS:堪称大数据时代的基石 ( 又是谷歌 )

时代背景:专用的高级硬件很贵,同时数据存量很大,要求超高吞吐

HDFS核心特点

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

( 既要又要还要 )

分布式存储 一Ceph

  • Ceph:开源分布式存储系统里的「万金油」

建议去读源码

Ceph的核心特点

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

关系型数据库的通用组件

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

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

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

mongoDB

  • 面向「文档」存储文档

  • 可序列化成JSON/BSON,支持嵌套

  • 存在「collection」,collection=文档的集合

  • 存储和构建索引能力依赖wiredTiger引擎

  • 4.0后开始支持事务(多文档、跨分片多文档等)

  • 常用client/SDK交互,可通过插件转译支持弱SQL

  • 数据结构丰富(hash表、set、zset、list)

  • C语言实现,超高性能

  • 主要基于内存,但支持AOF/RDB持久化

  • 常用redis-cli/多语言SDK交互

Kernel Space -> User Space

  • 避免syscall带来的性能损耗,直接从用户态访问磁盘

中断->轮询

  • 磁盘性能提高后,中断次数随之上升,不利于IO性能SPDK poller可以绑定特定的cpu核不断轮询,减少cs,提高性能

无锁数据结构

  • 使用Lock-free queue,降低并发时的同步开销

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

02 Persistent Memory在NVMeSSD和Main Memory间有一种全新的存储产品:Persistent Memory O时延介于SSD和Memory之间,约百纳秒量级可以用作易失性内存(memorymode),也可以用作持久化介质(app-direct

03.可编程交换机P4Switch,配有编译器、计算单元、DRAM,可以在交换机层对网络包做计算逻辑.在数据库场景下,可以实现缓存一致性协议等

CPU/GPU/DPU CPU:从multi-coremany-core GPU:强大的算力&越来越大的显存空间DPU:异构计算,减轻CPU的workload

存储系统

  • 块存储:存储软件栈里的底层系统,接口过于朴素
  • 文件存储:日常使用最广泛的存储系统,接口十分友好,实现五花八门
  • 对象存储:公有云上的王牌产品,immutable语义加持
  • key-value存储:形式最灵活,存在大量的开源/黑盒产品

数据库系统关系型数据库:

  • 基于关系和关系代数构建的,一般支持事务和SQL访问,使用体验友好的存储产品
  • 非关系型数据库:结构灵活,访问方式灵活,针对不同场景有不同的针对性产品

分布式架构

  • 数据分布策略:决定了数据怎么分布到集群里的多个物理节点,是否均匀,是否能做到高性能
  • 数据复制协议:影响IO路径的性能、机器故障场景的处理方式
  • 分布式事务算法:多个数据库节点协同保障, 一个事务的ACID特性的算法,通常基于2pc的思想设计

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

Licensed under CC BY-NC-SA 4.0
最后更新于 Oct 13, 2024 18:49 +0800
使用 Hugo 构建
主题 StackJimmy 设计