说到分布式索引时,我们在谈论什么?
首先,我要说明一下谈到分布式索引,需要了解什么样的内容。你已经知道存储引擎中包含数据文件和索引文件,同时索引文件中又有索引组织表这种主要的形式。
目前世界上主要的分布式数据库的数据存储形式,就是围绕着索引而设计的。
为什么会这样呢?
由于分布式数据库的数据被分散在多个节点上,当查询请求到达服务端时,目标数据有极大的概率并不在该节点上,需要进行一次甚至多次远程调用才可查询到数据。由于以上的原因,在设计分布式数据库存储引擎时,我们更希望采用含有索引的数据表,从而减少查询的延迟
。
这同时暗含了,大部分分布式数据库的场景是为查询服务的
。数据库牺牲了部分写入的性能,在存入数据的时候同时生成索引结构。故分布式数据库的核心是以提供数据检索服务为主,数据写入要服务于数据查询。从这个意义上说,分布式索引就是数据存储的主要形式。
本讲会以 NewSQL 和 Cassandra 为代表,介绍典型的 NoSQL 的存储引擎中的主要技术,力图帮助你理解此类数据库中存储引擎检索数据的路径。
读取路径
掌握分布式数据库存储引擎,一般需要明确其写入路径与读取路径
。但如上文讨论的那样,写入是严重依赖读取的,故明确读取路径我们就可以指明写入的规则。
因此这一部分,我们先来明确存储引擎是如何处理查询请求的。一般的规则如下:
1 寻找分片和目标节点;
2 检查数据是否在缓存与缓冲中;
3 检查数据是否在磁盘文件中;
4 合并结果。
第一步就是要查找数据在分布式系统的哪个目标节点上
。严格说,这一步并不是存储引擎所囊括的部分,但为了表述清楚,我们也将它加入读取路径中来。由于分布式数据库采用分片技术来分散数据,那么查询条件中如果有分片键,就可以应用分片算法来计算出分片,也就是目标节点所在的位置;而如果不包含分片键,就需要“二级索引”来帮忙寻找分片键了,之后的逻辑与使用分片键查找就相似了。
第二步,既然确定了所在节点,那么剩下的就交给存储引擎了
。首先需要在缓存(Cache)中进行查找。缓存包含数据缓存或行缓存,其中包含真实的数据,用于快速检索经常访问的数据,一般元数据和静态配置数据都会放在数据缓存里面。而后再缓冲查找数据,缓冲是为了批量写入数据而预留的一段内存空间,当写满缓冲后,数据会被刷入磁盘中,所以会有部分数据存在缓冲之中。
第三步,确定了数据并不在内存中,这时就需要检查磁盘了
。我们需要在具有索引的数据文件内查找响应的数据。通过之前的学习我们可以知道,每个数据文件都有主键索引,可以直接在其中查找数据。但是,存储引擎为了写入性能,会把数据拆分在众多的数据文件内部。所以我们需要在一系列文件中去查找数据,即使有索引的加成,查找起来的速度也不是能够令人满意的。这个时候我们可以引入布隆过滤,来快速地定位目标文件,提高查询效率。
最后一步是对结果进行归并。根据执行层的不同需求,这里可以马上返回部分匹配结果,也可以一次性返回全部结果
。
现在我们已经勾勒出存储引擎的一个完整的读取路径,可以看到路径上一些关键技术是保证数据查询与读取的关键点。
ps
- 存储引擎中包含数据文件和索引文件
- 索引文件中又有索引组织表这种主要的形式
- 世界上主要的分布式数据库的数据存储形式,就是围绕着索引而设计的
ask
- 存储引擎如何处理查询请求?