首页 > 编程知识 正文

文件索引(索引)

时间:2023-05-05 01:01:52 阅读:92260 作者:3932

前言

表存储Tablestore是由AlibabaCloud (阿里巴巴云)自行开发的面向大容量结构化数据存储的Serverless NoSQL多模型数据库。 Tablestore在AlibabaCloud (阿里巴巴云)的官网上介绍了各种各样的文章,发表了很多序列文章,这些文章被收录在了这个专集里

《表格存储Tablestore权威指南》 有趣的是,Tablestore支持大量的数据规模,提供多个索引以支持丰富的查询模式,同时作为多个模型数据库,提供多个模型的抽象和固有接口。 本文主要对Tablestore的存储和索引引擎进行介绍和解读,使其认识Tablestore引擎层的原理和能力、索引的作用和使用方法等。

基本架构

Tablestore是云上Serverless的分布式NoSQL多模型数据库,提供丰富的功能。 假设用户可以使用各种开源组件构建类似的服务,成本非常高,但使用Tablestore只需要在控制台中创建一个实例就可以享受所有功能,并且完全被计费

整体架构如下图所示,本论文中不对各模块的功能进行展开。

服务终端引擎层有两个引擎:存储引擎和索引引擎。 这两个引擎的数据结构和原理不同,为了便于读者理解,本文将这两个引擎称为表引擎(Table )和多元索引引擎) Searchindex )。 总体而言,引擎层基于LSM体系结构和共享存储(盘古),支持自动Sharding和存储计算分离。

表引擎

表引擎的整体架构类似于谷歌的BigTable,在开源领域的实现有HBase等。

数据模型可以定义为宽行模型,如下图所示。 其中不同的分区可以加载到不同的机器上,实现水平扩展。

首先介绍为什么Tablestore的主键可以包含多个主键列,而像HBase一样只有一个RowKey。 这里有几点:

多列主键列按顺序组成一个主键,就像MySQL联盟主键一样。 如果使用过HBase,可以将这里多列的主键列连接起来视为一个RowKey。 各列实际上只是整体主键的一部分。 第一列的主键列是分区键,使用分区键的范围进行分区,确保分区键必须在同一行上,并且必须在同一分区(Partition )。 一些功能依赖于该特性,如分区内事务(Transection )、本地2级索引) LocalIndex、预定发行版)、分区内自增加等。 业务经常需要多个字段来配置主键,如果只支持一个主键列,则业务需要拼接,多个列的主键列可以避免业务层主键的拼接和分解。 许多用户第一次看到多列主键列时,经常会误以为主键范围查询(获取范围接口)可以对每列单独执行。 实际上,这里的主键范围是指整个主键的范围,而不是单个列的范围。 这个模型有以下优点。

由于完全水平扩展,可支持的读写并发处理和数据大小几乎没有上限。 Tablestore在线版还有数千万级的tps/qps和10 Pb级的存储。 可以说一般的业务没有达到这样的上限,但实际的上限只依赖集群当前的机器资源,业务数据量大幅增加时只需要增加机器资源。 此外,基于共享存储的体系结构可以轻松实现动态负载平衡,而无需数据库层来复制复制的数据。 提供表模型,使其比纯KeyValue数据库更具有列和多个版本的概念,并且可以分别读写列。 表模型也是比较通用的模型,容易与其他系统进行数据模型映射。 表格模型支持主键范围扫描,因为它基于主键而不是散列映射进行排序存储。 类似于HashMap和SortedMap的区别。 在这个模型中是有序地图。 方案自由,即每行可以有不同的属性列,数据列的数量也没有限制。 这适用于存储半结构化的数据。 另外,在业务执行过程中,也可以变更任意的属性列。 支持数据自动过期和多个版本。 每列可以存储多个版本的值。 每个值都有版本号,也是时间戳。 如果设置了数据自动过期,则系统将根据该时间戳确定数据的过期日期,并自动清除后台过期的数据。 这个模型也有一些缺点:

查询依赖于主键。 可以将该数据模型理解为SortedMap。 如您所知,SortedMap只能进行点检查和顺/逆序扫描。 例如,以下查询方法: 主键点检查:通过知道主键,可以准确地读取表中的一行。 主键范围检查:从“开始主键”(StartPrimaryKey )扫描结束)主键)或按相反顺序扫描。 即,按顺序或相反顺序遍历Table,支持开始位置和结束位置的指定。 主键前缀范围检查:实际上等效于主键范围检查。 虽然在此仅进行了说明,但主键前缀的范围实际上可以转换为主键的范围。 用表依次扫描就可以了。 对属性列的查询必须使用过滤器。 过滤器模式在过滤大量数据时效率不高,甚至会成为全表扫描。 一般来说,数据查询的效率与基本扫描的数据量成正相关,基本扫描的数据量取决于数据的分布和结构。 数据的默认值是

照主键有序存储,那么要按照某一属性列查询,符合条件的数据必然分布动人的花生表的范围内,需要扫描后筛选。全表数据越多,扫描的数据量也就越大,效率也就越低。

那么在实际业务中,主键查询常常不能满足需求,而使用Filter在数据规模大的情况下效率很低,怎么解决这一问题呢?

上面提到,数据查询的效率与底层扫描的数据量正相关,而Filter模式慢在符合条件的数据太分散,必须扫描大量的数据并从中筛选。那么解决这一问题也就有两种思路:

让符合条件的数据不再分散分布:使用全局二级索引,将某列或某几列作为二级索引的主键。相当于通过数据冗余,直接把符合条件的数据预先排在一起,查询时直接精确定位和扫描,效率极高。**加快筛选的速度: **使用多元索引,多元索引底层提供了倒排索引,BKD-Tree等数据结构。以上面查询某属性列值为例,我们给这一列建立多元索引后,就会给这一列的值建立倒排索引,倒排索引实际上记录了某个值对应的所有主键的集合,即Value -> List, 那么要查询属性列为某个Value的所有记录时,直接通过倒排索引获取所有符合条件的主键,进行读取即可。本质上是加快了从海量数据中筛选数据的效率。

全局二级索引

全局二级索引采用的仍然是表引擎,给主表建立了全局二级索引后,相当于多了一张索引表。这张索引表相当于给主表提供了另外一种排序的方式,即针对查询条件预先设计了一种数据分布,来加快数据查询的效率。索引的使用方式与主表类似,主要的查询方式仍然是上面讲的主键点查,主键范围查,主键前缀范围查。常见的关系型数据库的二级索引也是类似的原理。

列举一个最简单的例子,比如我们有一张表存储文件的MD5和SHA1值,表结构如下:

通过这张表,我们可以查询文件对应的MD5和SHA1值,但是通过MD5或SHA1反查文件名却不容易。我们可以给这张表建立两张全局二级索引表,表结构分别为:

索引1:

索引2:

为了确保主键的唯一性,全局二级索引中,会将原主键的主键列也放到主键列中,比如上面的FilePath列。有了上面两张索引表,就可以通过主键前缀范围查的方式里精确定位某个MD5/SHA1对应的文件名了。

多元索引引擎

多元索引引擎相比于表引擎,底层增加了倒排索引,多维空间索引等,支持多条件组合查询、模糊查询、地理空间查询,以及全文索引等,还提供一些统计聚合能力(统计聚合功能待发布)。因为功能较单纯的二级索引更加丰富,而且一个索引就可以满足多种维度的查询,因此命名为多元索引。

上面在讲解决Filter模式查询慢的问题时,提到倒排索引加快了数据筛选的速度,因为记录了某列的Value到符合条件的行的映射,Value -> List 。实际上,倒排索引这一方式,不仅可以解决单列值的检索问题,也可以解决多条件组合查询的问题。

我们举一个订单场景的例子,比如下表为一个订单记录:

上面一共16个字段,我们希望按照任意多个字段组合查询,比如查询某一售货员、某一产品类型、单价在xx元之上的所有记录。可以想到,这样的排列组合会有非常多种,因此我们不太可能预先将任何一种查询条件的数据放到一起,来加快查询的效率,这需要建立很多的全局二级索引。而如果采用Filter模型,又很可能需要扫描全表,效率不高。折中的方式是,可以先对某个字段建立二级索引,缩小数据范围,再对其中数据进行Filter。那么有没有更好的方式呢?

多元索引可以很好的解决这一问题,而且只需要建立一个多元索引,将所有可能查询的列加入到这个多元索引中即可,加入的顺序也没有要求。多元索引中的每一列默认都会建立倒排,倒排就记录了Value到List的映射。针对多列的多个条件,在每列的倒排表中找到对应的List,这个称为一个倒排链,而筛选符合多个条件的数据即为计算多个倒排链的交并集,这里底层有着大量的优化,可以高效的实现这一操作。因此多元索引在处理多条件组合查询方面效率很高。

此外,多元索引还支持全文索引、模糊查询、地理空间查询等,以地理空间查询为例,多元索引通过底层的BKD-Tree结构,支持高效的查询一个地理多边形内的点,也支持按照地理位置排序、聚合统计等。

索引选择

不是一定需要索引

如果基于主键和主键范围查询的功能已经可以满足业务需求,那么不需要建立索引。如果对某个范围内进行筛选,范围内数据量不大或者查询频率不高,可以使用Filter,不需要建立索引。如果是某种复杂查询,执行频率较低,对延迟不敏感,可以考虑通过DLA(数据湖分析)服务访问Tablestore,使用SQL进行查询。

全局二级索引还是多元索引

一个全局二级索引是一个索引表,类似于主表,其提供了另一种数据分布方式,或者认为是另一种主键排序方式。一个索引对应一种查询条件,预先将符合查询条件的数据排列在一起,查询效率很高。索引表可支撑的数据规模与主表相同,另一方面,全局二级索引的主键设计也同样需要考虑散列问题。一个多元索引是一系列数据结构的组合,其中的每一列都支持建立倒排索引等结构,查询时可以按照其中任意一列进行排序。一个多元索引可以支持多种查询条件,不需要对不同查询条件建立多个多元索引。相比全局二级索引,也支持多条件组合查询、模糊查询、全文索引、地理位置查询等。多元索引本质上是通过各种数据结构加快了数据的筛选过程,功能非常丰富,但在数据按照某种固定顺序读取这种场景上,效率不如全局二级索引。多元索引的查询效率与倒排链长度等因素相关,即查询性能与整个表的全量数据规模有关,在数据规模达到百亿行以上时,建议使用RoutingKey对数据进行分片,查询时也通过指定RoutingKey查询来减少查询涉及到的数据量。简而言之,查询灵活度和数据规模不可兼得。

关于使用多元索引还是全局二级索引,也有另外一篇文章描述:《Tablestore索引功能详解》。

除了全局二级索引之外,后续还会推出本地二级索引(LocalIndex),推出后再进行详细介绍。

常见组合方案

丰富的查询功能当然是业务都希望具备的,但是在数据规模很大的情况下,灵活的查询意味着成本。比如万亿行数据的规模,对于表引擎来说,因为水平扩展能力很强,成本也很低,问题不大,但是建立多元索引,费用就会非常高昂。全局二级索引成本较低,但是只适合固定维度的查询。

常见的超大规模数据,都带有一些时间属性,比如大量设备产生的数据(监控数据),或者人产生的数据(消息、行为数据等),这类数据非常适合采用Tablestore存储。对这类数据建立索引,会有一些组合方案:

对元数据表建立多元索引,全量数据表不建立索引或采用全局二级索引。元数据表可以是产生数据的主体表,比如设备信息表,用户信息表等。在时序模型中,产生数据的主体也可以认为是一个时间线,这条线会不断的产生新的点。Tablestore的时序数据模型(Timestream)采用的也是类似的方式,对时序数据中的时间线建立一张表,专门用来记录时间线的元数据,每个时间线一行。时间线表建立多元索引,用来做时间线检索,而全量数据则不建立索引。在检索到时间线后,对某个时间线下的数据进行范围扫描,来读取这个时间线的数据。热数据建立多元索引,老数据不建立索引或者采用全局二级索引:很多情况下仅需要对非常热的数据进行多种维度查询,对冷数据采取固定维度查询即可。因此冷热分离可以给业务提供更高的性价比。目前多元索引还不支持TTL(后续会支持),需要业务层区分热数据和冷数据。

总结

本文对Tablestore的存储和索引引擎进行了介绍和解读,并在如何选择和应用索引方面给了一些参考,目的是加深大家对Tablestore的认识和理解,更好的应用Tablestore来解决业务需求。

本文作者:亦征

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。