数据结构

追加型数据库和哈希索引

数据库最简单的形式,是追加型的方式:

  1. 写入数据直接追加到文件尾部,O(1)复杂度
  2. 读取数据从文件头遍历,获取最新的数据

这种数据库,没有删除操作,所有的数据都是追加性质的,这也是日志形式的数据库。

为了改善查询效率,我们需要给追加型数据库创建索引,一般来说是Hash索引。

最基础的Hash索引:

  1. 每个键值都有一个唯一的Hash值
  2. Hash值对应一个偏移量,用于映射数据在文件中的偏移位置
  3. 内存够大的情况下,Hash表存储到内存中,先查询Hash表,如果Key存在,则根据获取到的偏移量读取Key
    Hash会减慢写入性能,因为写的时候,还需要更新Hash表。

上述方案面临几个问题:

  1. 如果及其故障,那么内存中的数据会丢失,重启后需要重新建立索引,耗时较长。
  2. 内存可能不够用
  3. 追加的方式,会有空间浪费的现象,旧的数据用不到了

针对上述3个主要问题,我们给出如下的解决方案:

  1. 针对磁盘空间浪费or用尽的情况,我们把文件分段存储,按照固定的size分段。这样,可以启动异步线程去合并&压缩这些文件块,同时更新有关的索引。
  2. 针对机器故障的问题,我们把内存定期写一个磁盘的快照,比如每出现一个新的block,就把旧的所有的block的索引写入快照,这样当重启之类的,我们只需要加载快照,然后重新给新的block建立索引即可。合并&压缩过程中,旧的block是『冻结』的块,即仍然可以提供读写请求;合并完成之后,再切换到新的block中
  3. 内存不够用,可以考虑建立二级索引等

操作记录也可以追加到日志中,这种情况是防止日志文件损坏导致数据无法回复。

Bitcask数据库是典型的应用。

SSTables && LSM Tree

SSTable的定义:

  1. 文件块中的键按照顺序排列
  2. 每个文件块中的键只能在合并的块中出现一次

SSTable的优点:

  1. 合并算法更加高效,归并有序段的思路即可完成压缩&合并

  2. 节省内存索引空间,不需要给每个键建立索引,只要给部分键值创建索引即可,因为可以区间查询。比如,Hash Horrible只要建立这两个单词的索引,那么在这两个单词之间的数据,可以定位到Hash之后,顺序查找即可。缺点是,查找时间稍微增加,存在遍历的过程。 — 注:Q: 为什么不用二分查找?A: 因为块的size不是严格固定的,二分查找不容易确定记录的起始&停止的位置

  3. 如果读请求需要查询一个范围内部的多个KV,那么可以把有关的记录执行压缩,内存索引直接指向对应的文件头;可以节省磁盘空间&减少IO带宽。

构建SSTable & LSM-Tree
构造SSTable:

  1. 写入数据时,把数据放入内存的有序结构中,比如AVL树、跳表等
  2. 当内存的有序结构到达一定size后,把该结构刷新到磁盘中。write disk的有序结构冻结,只提供读的服务;有新的写入请求的时,直接创建新的有序结构即可
  3. 读请求发生的过程:先找内存,然后是最新的block,之后是次新的block,依次类推。
  4. 后台线程(进程)周期性压缩&合并block,丢弃已经覆盖or删除的值

LSMT查询的速度比较慢,可以使用bloom filter执行性能优化。
同样,可以利用追加操作日志的方式,防止机器崩溃导致的内存数据丢失。

LSM相对于BTree优势:写入速度快,基于追加的方式
劣势:compaction过程会影响读写的速率,因为compaction也占用磁盘IO

LSM-Tree就是根据上述结构构建的:

  1. 创建流程:
  2. 读取数据,这里是前面提到的,区间范围的Key在一个块中:
  3. 压缩操作,相当于是归并,在后台执行。压缩的过程,基本思想在前一小节提到了
  4. 删除操作,标记数据为已删除的,但是不会立刻执行,只有后台compaction的时候,才会执行:

事务处理与分析处理

OLTP: Online traction process,在线事物处理,比如读写等。
OLAP: Online analysis process,在线分析处理,比如统计数据等。

OLTP对IO要求较高,OLAP可能涉及到大量的计算等,批量或者流处理等。

列式存储

与列式存储对应的是行存储。行存储,即传统SQL中所说的数据表。

为什么使用列存储?

假设有一个业务表,该业务对应的特性有几百个甚至更多。如果我们要获取某一行或者几行的数据,则需要把几百列的数据都加载到内存中。当然,我们有数据库的表的规范化,不过规范化会让业务更加难以理解。
同样的,这么多属性列,必然会有大量的重复数据,比如说,主键是用的id,某一列是用户的年龄,而且我们有数以亿计的用户,那么年龄必然存在大量的重复数据。

如果面向列存储,那么我们只需要指定需要的列和对应的数据位置,就可以直接加载对应的数据,而不必把所有的列都加载到内存。同时,当列中有大量的重复数据时,我们可以对列执行压缩,节约大量的空间。因此,列存储非常利于空间压缩&加速查询。

列存储的排序
单纯对列执行排序是没有意义的,列式存储的排序本身也是面向行的。可以指定某个列作为主键,然后执行有关的排序。排序可以极大地优化压缩率。

列存储的写入
行存储的写入分为两种情况:

  • 不存在的行,直接按照规则插入即可
  • 存在的行,原地更新

列式存储最困难的地方在于:不能原地更新数据,或者在列中间插入数据,尤其是压缩过的列,更不可能。

因此,列式存储采用LSMT的方式写入,定期执行compaction操作。

数据密集型应用系统设计--数据存储与检索相关推荐

  1. 数据密集型应用系统设计--数据分区

    数据分区与数据复制 分区的目的一般是提高可扩展性.容错性和集群吞吐,同一个分区会在多个节点中都有副本. 容错性:一个节点挂掉,则这个节点上的分区,在其他节点上都有副本,可以查询其他的节点 可扩展性:新 ...

  2. 数据密集型应用系统设计--数据复制

    简介 引入数据复制的原因: 数据距离用户更近,让用户访问延迟降低 提高容错机制,某个节点坏掉后,其备份节点仍然能提供服务 负载扩展到多台机器,提高吞吐量 复制技术的真正难点在于如何处理持续变更的数据. ...

  3. Designing Data-Intensive Application《数据密集型应用系统设计》笔记

    Designing Data-Intensive Application 中译<设计数据密集型应用>又名<数据密集型应用系统设计>,我看的是冯若航在gitbook开源的翻译版本 ...

  4. 《数据密集型应用系统设计》读书笔记——第一部分 数据系统基础

    第一部分 数据系统基础 第1章 可靠.可扩展与可维护的应用系统 当今许多新型应用都属于数据密集型,而不是计算密集型.对于这些类型应用,CPU的处理能力往往不是第一限制性因素,关键在于数据量.数据的复杂 ...

  5. 豆瓣评分 9.7 的神书:《数据密集型应用系统设计》

    我最近在读一本好书<数据密集型应用系统设计>(也被叫做 DDIA).这真是本相见恨晚的神书. 这是怎样一本神书?豆瓣评分高达 9.7 分! 什么是「数据密集型应用系统」? 当数据(数据量. ...

  6. 数据密集型应用系统设计——笔记

    本篇章内容为阅读<数据密集型应用系统设计>一书的读书笔记. 作为个人成长学习使用,同时希望对刷到的朋友有所帮助,一起加油哦! 生命就像一朵花,要拼尽全力绽放,芳香四溢,在风中舞蹈! 写在前 ...

  7. 《数据密集型应用系统设计》读书笔记——数据系统基础

    因为个人兴趣,想学学分布式方面的知识,然后找到了这本<数据密集型应用系统设计>,确实非常的不错,无论对于以前的工程还是现在的科研都有启迪和感悟,所以就写份读书笔记记录一下,里面提到的知识非 ...

  8. 数据密集型应用系统设计-第七章分布式系统的麻烦-笔记

    这阵子在看数据密集型应用系统设计书籍,自己把书籍比较重要的内容整理出来,基本一天一更,请感兴趣的朋友多多关注! 整个系列会在这几天都发布出来,可以关注一下 链接: 数据密集型应用系统设计-笔记. 文章 ...

  9. 数据密集型应用系统设计 [Designing Data-Intensive Applications]

    作者:[美] Martin Kleppmann(马丁·科勒普曼) 著,赵军平 吕云松 耿煜 李三平 译 出版社: 中国电力出版社 出版时间:2018-09-01 数据密集型应用系统设计 [Design ...

最新文章

  1. apply()和call()的区别
  2. java returnaddress_Java虚拟机规范】Java SE 7虚拟机结构
  3. mysql x64界面配置版下载_MySQL下载安装、配置与使用(win7x64)
  4. 整数域上的多项式辗转相除
  5. hibernate工厂模式_Hibernate锁定模式–乐观锁定模式如何工作
  6. JavaScript时间事件:setTimeout和setInterval
  7. yii2 ajax访问控制器,如何在yii2中运行控制器动作作为ajax
  8. 魔方财务对接码支付插件
  9. 微信模板消息47001错误
  10. 一个很好用的JavaScript的文件上传插件plupload
  11. JAVA学习IO(1)
  12. json转为tfrecord格式文件怎么转_怎么把pdf转换成jpg图片?pdf转图片格式的方法很好用...
  13. elastix中NAT穿越问题解决办法
  14. FastStone Capture滚动截屏丢失行解决办法
  15. 前嗅ForeSpider教程:采集新浪新闻
  16. Windows的Git Bash使用tree命令
  17. QQ音乐解析API,支持搜索、歌单、单曲、专辑、MV解析、多音质切换
  18. 推荐一款笔记软件 Notion
  19. practice之Python爬取今日头条图片(正则表达式)
  20. C#开发测量程序-计算坐标方位角

热门文章

  1. NOI Online能力测试2视频版,让我们看看出题专家怎么说!(入门组)
  2. 深入理解SpringBoot配置
  3. 突击计划——求n的阶乘
  4. Java中的可变参数方法
  5. JAVA中向量类Vector
  6. elasticsearch 安装sql
  7. 数据库复习 库 表 记录的 增删改查 基础
  8. Shell脚本实现模拟并发及并发数控制
  9. strong和weak 细节
  10. 做一个聪明的前端开发者