02| 基本架构:一个键值数据库包含什么?

126 阅读3分钟

利用第一性原则思考,如何制造一个kv存储工具

从大局了解一个系统的设计与基本功能,在深入到细节中

目的是为了:实践中定位和解决问题时,就会轻松很多

\

对于一对一的查询可以将原先的sql转换成缓存存储,对于有聚合要求的还是应该是用关系型数据库

1.设计

设计一个SimpleKV的键值对存储系统

1.1存储那些数据(数据模型)

  • 基本的key-value模型

  • memcached

    • value为string
  • redis(支持多类型value)

    • value包含string,hash,列表,集合等
  • 不同的value实现,不同数据结构在性能、空间效率等方面的差异

1.2对数据有什么操作(操作接口)

  • PUT

    • 新写入或更新一个key-value
  • GET

    • 根据一个key获取对应的value
  • DELETE

    • 根据key删除key-value
  • SCAN

    • 根据一段key的返回返回对应的value值
  • EXISTS

    • 某个key是否存在

\

  • 存储方式

    • 内存\

      • 读写很快,访问速度很快(不需要磁盘寻址)
      • 一旦掉电数据都会丢失
    • 外存

      • 数据持久化,不会丢失
      • 整体性能会被拉低

1.3架构设计

  • 架构设计

    • 访问框架(俗称客户端)
    • 索引模块(怎么找?)
    • 操作模块(执行具体操作)
    • 存储模块(实际存储位置)

1.4访问模式

  • 通过行数据调用的方式供外部应用使用(没接触过)

    • libsimplekv.so,就是以动态链接库的形式链接到我们自己的程序中,提供键值存储功能
    • RocksDB\
  • 通过网络框架以socket通信的形式对外提供键值对操作

    • 网络框架中包括 Socket Server 和协议解析

    • Memcached 和 Redis 则是通过网络框架访问\

    • 特点

      • 提供了数据库的受用性
      • 键值数据库的性能、运行模型提供了不同的设计选择,带来了一些潜在的问题\
    • 设计上需要思考的点

      • 网络连接
      • 网络请求的解析
      • 数据存取的处理
      • 一个线程处理所有过程,可能导致阻塞后影响系统性能,降低系统响应速度
      • 多线程处理会存在资源竞争等问题

1.5如何定位键值对位置

  • 利用索引模块快速定位key是否存在和存储位置

  • 索引类型

    • 哈希表(Memcached 和 Redis)(高性能随机访问可以与hash的o(1)操作相匹配)
    • B+树(mysql)
    • 字典树
    • 跳表(有序索引链表)(RocksDB)

1.6不同操作具体逻辑

  • 对于 GET/SCAN 操作而言,此时根据 value 的存储位置返回 value 值即可
  • 对于 PUT 一个新的键值对数据而言,SimpleKV 需要为该键值对分配内存空间
  • 对于 DELETE 操作,SimpleKV 需要删除键值对,并释放相应的内存空间,这个过程由分配器完成
  • 涉及到键值对的分配与释放

1.7重启后快速提供服务

  • 内存分配器 glibc 的 malloc 和 free(用于内存管理)

    • 但是可能造成内存碎片问题
  • Redis 的内存分配器提供了多种选择,分配效率也不一样

    • redis持久化机制
    • 每次操作都落盘,效率比较低
    • 周期落盘,可能会有数据丢失
  • 可以采用文件保存(kafka是通过文件保存)

2.总结

  • 计算机存储只有(cpu缓存,内存,外存(磁盘))

  • Redis 主要通过网络框架进行访问,而不再是动态库了,这也使得 Redis 可以作为一个基础性的网络服务进行访问,扩大了 Redis 的应用范围

  • Redis 数据模型中的 value 类型很丰富,因此也带来了更多的操作接口\

  • Redis 的持久化模块能支持两种方式:日志(AOF)和快照(RDB)\

  • Redis 中包含了相应的集群功能支撑模块\