Neo's Blog

不抽象就无法深入思考
不还原就看不到本来面目!

0%

存储系列-概览

存储模型有哪些?

关系模型

文档模型:数据通常是自我包含的,而且文档之间的关系非常稀少

图数据模型:任意事物都可能与任何事物相关联

底层方法论

海量存储系列参考:
https://blog.51cto.com/aliapp/1327613

是什么

也就是用于处理数据的一类方法的抽象,最主要的作用是,按照某个条件选出一批数据,然后再进行一些简单的统计计算的功能。如是而已:)

事务

事务,本质来说就是一组由一个人(或机器)发起的连续的逻辑操作,共同的完成一件事情,在完成整个事情之前,其所有的改动,都不应该对其他人可见和影响。而在事务结束之后,其一切的改动,都必须“全部”“立刻”对其他的人(或机器)可见。

单机事务

这个排队可供选择的方法,就我知道的有:1,排他锁。2. 读写锁。3. Copy on write(MVCC) .4. 队列。5. 内存事务。这些方式。

从性能来说,排他锁最慢,而读写锁因为读可以并发,所以效率稍高,但写和读不能同时进行。
Copy on write(MVCC) 则读取和写入之间可以互相不影响,所以效率更高。
队列这种方式,内存时效果很好,省去中断上下文切换的时间。内存事务,目前还在研究阶段,具备很大潜力的东西。

分布式事务

背景:异地延迟、scale out、冗余带来的一致性

索引

加速找到想要的数据:索引

成本:你付出了空间成本,本质来说就是空间换时间的过程。同时,也会降低写入的效率。

B树

如果是一个运行时间很长的b树,那么几乎所有的请求,都是随机io。因为磁盘块本身已经不再连续,很难保证可以顺序读取。

两种思路:

  1. 使用ssd,让寻道成为往事,提升硬件,让随机读写没有那么慢。

  2. 放弃部分读性能,使用更加面向顺序写的树的结构来提升写性能。

这个类别里面,从数据结构来说,就我所知并比较流行的是两类,

一类是COLA(Cache-Oblivious Look ahead Array)(代表应用自然是tokuDB)。

一类是LSM tree(Log-structured merge Tree)或SSTABLE

(代表的数据集是cassandra,hbase,bdb java editon,levelDB etc.).

那么,b树的写太烂了,我需要提升写,可以放弃部分磁盘读性能,怎么办呢?

简单,那就弄很多个小的有序结构,比如每m个数据,在内存里排序一次,下面100个数据,再排序一次……这样依次做下去,我就可以获得N/m个有序的小的有序结构。

在查询的时候,因为不知道这个数据到底是在哪里,所以就从最新的一个小的有序结构里做二分查找,找得到就返回,找不到就继续找下一个小有序结构,一直到找到为止。

很容易可以看出,这样的模式,读取的时间复杂度是(N/m)*log2N 。读取效率是会下降的。

这就是最本来意义上的LSM tree的思路。

那么这样做,性能还是比较慢的,于是需要再做些事情来提升,怎么做才好呢?

于是引入了以下的几个东西来改进它

  1. Bloom filter : 就是个带随即概率的bitmap,可以快速的告诉你,某一个小的有序结构里有没有指定的那个数据的。于是我就可以不用二分查找,而只需简单的计算几次就能知道数据是否在某个小集合里啦。效率得到了提升,但付出的是空间代价。

  2. 小树合并为大树: 也就是大家经常看到的compact的过程,因为小树他性能有问题,所以要有个进程不断地将小树合并到大树上,这样大部分的老数据查询也可以直接使用log2N的方式找到,不需要再进行(N/m)*log2n的查询了。

这就是LSMTree的核心思路和优化方式。

不过,LSMTree也有个隐含的条件,就是他实现数据库的insert语义时性能不会很高,原因是,insert的含义是: 事务中,先查找该插入的数据,如果存在,则抛出异常,如果不存在则写入。这个“查找”的过程,会拖慢整个写入。

====

W+R>N

相信这个大家都耳熟能详了吧?呵呵,我从其他角度来说明这件事吧。

N表示这个复制集群的总数【很多地方解释的不是很准确造成了不少误解】。

W表示写入份数

R表示一次一致性读所需要的份数(这里要注意,是随机从N中选择的机器数量哦)

===

gossip协议

gossip协议是这两套存储的基础之一,说复杂也复杂,说不复杂也不复杂。。其实gossip就是p2p协议。他主要要做的事情是,去中心化。

怎么做到的呢?我只希望在这篇文章里给大家留下几个印象:gossip是干什么的?怎么做到的?优势劣势是什么?即可。对协议的细节感兴趣的,可以自己去深入研究。

gossip的核心目标就是去中心。

做到的方式:

根据种子文件,按照某种规则连接到一些机器,与他们建立联系,不追求全局一致性,只是将对方机器中自己没有的数据同步过来。这里就设计到如何能够快速的知道自己的数据和其他人的数据在哪些部分不一致呢?这时候就要用到Merkle tree了,它能够快速感知自己所持有的数据中哪里发生了变更。

优势:

去中心化,看看伟大的tor,只要能连到一个seed,有一个口子能出长城,那么你最终就能跳出长城。。

劣势:

一致性比较难以维持
你的支持是我坚持的最大动力!