贵州省住房和城乡建设厅官网站,哈尔滨网页制作公司电话,怎么创建一个公司网站,学校网站设计理念前言
表格存储Tablestore是阿里云自研的面向海量结构化数据存储的Serverless NoSQL多模型数据库。Tablestore在阿里云官网上有各种文档介绍#xff0c;也发布了很多场景案例文章#xff0c;这些文章收录在这个合集中《表格存储Tablestore权威指南》。值得一提的是#xff0…前言
表格存储Tablestore是阿里云自研的面向海量结构化数据存储的Serverless NoSQL多模型数据库。Tablestore在阿里云官网上有各种文档介绍也发布了很多场景案例文章这些文章收录在这个合集中《表格存储Tablestore权威指南》。值得一提的是Tablestore可以支撑海量的数据规模也提供了多种索引来支持丰富的查询模式同时作为一个多模型数据库提供了多种模型的抽象和特有接口。本文主要对Tablestore的存储和索引引擎进行介绍和解读让大家对Tablestore引擎层的原理和能力索引的作用和使用方式等有一个认识。
基本架构
Tablestore是一款云上的Serverless的分布式NoSQL多模型数据库提供了丰富的功能。假设用户可以采用各种开源组件搭建一套类似服务可以说是成本非常高昂而使用Tablestore仅需在控制台上创建一个实例即可享受全部功能而且是完全按量计费可以说是0门槛。
整体架构如下图所示本文不展开叙述每个模块的功能。 在服务端引擎层中存在两个引擎存储引擎和索引引擎。这两个引擎的数据结构和原理不同为了方便读者理解本文将这两个引擎称为表引擎(Table)和多元索引引擎(Searchindex)。整体来说引擎层是基于LSM架构和共享存储(盘古)支持自动的Sharding和存储计算分离。
表引擎
表引擎的整体架构类似于Google的BigTable在开源领域的实现有HBase等。
数据模型可以定义为宽行模型如下图所示。其中不同的分区可以加载到不同的机器上实现水平扩展 首先说明一下为什么Tablestore的主键可以包含多个主键列而像HBase只有一个RowKey。这里有几点
多列主键列按照顺序共同构成一个主键类似MySQL的联合主键。如果使用过HBase可以把这里的多列主键列拼接起来看作一个RowKey每一列其实都只是整体主键的一部分。第一列主键列是分区键使用分区键的范围进行分区划分保证了分区键相同的行一定在同一个分区(Partition)上。一些功能依赖这一特性比如分区内事务(Transection)本地二级索引(LocalIndex, 待发布)分区内自增列等。业务上常需要多个字段来构成主键如果只支持一个主键列业务需要进行拼接多列主键列避免了业务层做主键拼接和拆解。许多用户第一次看到多列主键列时常会有误解认为主键的范围查询(GetRange接口)可以针对每一列单独进行实际上这里的主键范围指的是整体主键的范围而非单独某一列的范围。
这个模型具有这样的一些优势
完全水平扩展因此可支撑的读写并发和数据规模几乎无上限。Tablestore线上也有一些业务在几千万级的tps/qps以及10PB级的存储量。可以说一般业务达不到这样的上限实际的上限仅取决于集群目前的机器资源当业务数据量大量上涨时只要增加机器资源即可。同时基于共享存储的架构也很方便的实现了动态负载均衡不需要数据库层进行副本数据复制。提供了表模型相比纯粹的KeyValue数据库而言具有列和多版本的概念可以单独对某列进行读写。表模型也是一种比较通用的模型可以方便与其他系统进行数据模型映射。表模型中按照主键有序存储而非Hash映射因此支持主键的范围扫描。类似于HashMap与SortedMap的区别这个模型中为SortedMap。Schema Free, 即每行可以有不同的属性列数据列个数也不限制。这很适合存储半结构化的数据同时业务在运行过程中也可以进行任意的属性列变更。支持数据自动过期和多版本。每列都可以存储多个版本的值每个值会有一个版本号同时也是一个时间戳如果设置了数据自动过期就会按照这个时间戳来判断数据是否过期后台对过期数据自动清理。
这个模型也有一些劣势 数据查询依赖主键。可以把这个数据模型理解为SortedMap大家知道在SortedMap上只能做点查和顺/逆序扫描比如以下查询方式 主键点查通过已知主键精确读取表上的一行。主键范围查按照顺序从开始主键(StartPrimaryKey)扫描到结束主键(EndPrimaryKey)或者逆序扫描。即对Table进行顺序或逆序遍历支持指定起始位置和结束位置。主键前缀范围查其实等价于主键范围查这里只是说明主键前缀的一个范围其实可以转换成主键的一个范围在表上进行顺序扫描即可。针对属性列的查询需要使用FilterFilter模式在过滤大量数据时效率不高甚至变成全表扫描。通常来说数据查询的效率与底层扫描的数据量正相关而底层扫描的数据量取决于数据分布和结构。数据默认仅按照主键有序存储那么要按照某一属性列查询符合条件的数据必然分布于全表的范围内需要扫描后筛选。全表数据越多扫描的数据量也就越大效率也就越低。
那么在实际业务中主键查询常常不能满足需求而使用Filter在数据规模大的情况下效率很低怎么解决这一问题呢
上面提到数据查询的效率与底层扫描的数据量正相关而Filter模式慢在符合条件的数据太分散必须扫描大量的数据并从中筛选。那么解决这一问题也就有两种思路
让符合条件的数据不再分散分布使用全局二级索引将某列或某几列作为二级索引的主键。相当于通过数据冗余直接把符合条件的数据预先排在一起查询时直接精确定位和扫描效率极高。加快筛选的速度 使用多元索引多元索引底层提供了倒排索引BKD-Tree等数据结构。以上面查询某属性列值为例我们给这一列建立多元索引后就会给这一列的值建立倒排索引倒排索引实际上记录了某个值对应的所有主键的集合即Value - List, 那么要查询属性列为某个Value的所有记录时直接通过倒排索引获取所有符合条件的主键进行读取即可。本质上是加快了从海量数据中筛选数据的效率。
全局二级索引
全局二级索引采用的仍然是表引擎给主表建立了全局二级索引后相当于多了一张索引表。这张索引表相当于给主表提供了另外一种排序的方式即针对查询条件预先设计了一种数据分布来加快数据查询的效率。索引的使用方式与主表类似主要的查询方式仍然是上面讲的主键点查主键范围查主键前缀范围查。常见的关系型数据库的二级索引也是类似的原理。
列举一个最简单的例子比如我们有一张表存储文件的MD5和SHA1值表结构如下
FilePath(主键列)MD5(属性列)SHA1(属性列)oss://abc/files/1.txt0cc175b9c0f1b6a831c399e26977266186f7e437faa5a7fce15d1ddcb9eaeaea377667b8oss://abc/files/2.txt92eb5ffee6ae2fec3ad71c777531578fe9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98oss://abc/files/3.txt4a8a08f09d37b73795649038408b5f3384a516841ba77a5b4648de2cd0dfcb30ea46dbb4
通过这张表我们可以查询文件对应的MD5和SHA1值但是通过MD5或SHA1反查文件名却不容易。我们可以给这张表建立两张全局二级索引表表结构分别为
索引1:
MD5(主键列1)FilePath(主键列2)0cc175b9c0f1b6a831c399e269772661oss://abc/files/1.txt4a8a08f09d37b73795649038408b5f33oss://abc/files/3.txt92eb5ffee6ae2fec3ad71c777531578foss://abc/files/2.txt
索引2:
SHA1(主键列1)FilePath(主键列2)84a516841ba77a5b4648de2cd0dfcb30ea46dbb4oss://abc/files/3.txt86f7e437faa5a7fce15d1ddcb9eaeaea377667b8oss://abc/files/1.txte9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98oss://abc/files/2.txt
为了确保主键的唯一性全局二级索引中会将原主键的主键列也放到主键列中比如上面的FilePath列。有了上面两张索引表就可以通过主键前缀范围查的方式里精确定位某个MD5/SHA1对应的文件名了。
多元索引引擎
多元索引引擎相比于表引擎底层增加了倒排索引多维空间索引等支持多条件组合查询、模糊查询、地理空间查询以及全文索引等还提供一些统计聚合能力(统计聚合功能待发布)。因为功能较单纯的二级索引更加丰富而且一个索引就可以满足多种维度的查询因此命名为多元索引。 上面在讲解决Filter模式查询慢的问题时提到倒排索引加快了数据筛选的速度因为记录了某列的Value到符合条件的行的映射Value - List 。实际上倒排索引这一方式不仅可以解决单列值的检索问题也可以解决多条件组合查询的问题。
我们举一个订单场景的例子比如下表为一个订单记录
订单号订单md5主键消费者编号消费者姓名售货员编号售货员姓名产品编号产品名产品品牌产品类型下单时间支付时间支付状态产品单价数量总价钱o0000000000c49f5fd5aba33159accae0d3ecd749a7c0019消陈九s0020售楚十p0003004vivo x21vivo手机2018-07-17 21:00:00 否2498.9924997.98
上面一共16个字段我们希望按照任意多个字段组合查询比如查询某一售货员、某一产品类型、单价在xx元之上的所有记录。可以想到这样的排列组合会有非常多种因此我们不太可能预先将任何一种查询条件的数据放到一起来加快查询的效率这需要建立很多的全局二级索引。而如果采用Filter模型又很可能需要扫描全表效率不高。折中的方式是可以先对某个字段建立二级索引缩小数据范围再对其中数据进行Filter。那么有没有更好的方式呢
多元索引可以很好的解决这一问题而且只需要建立一个多元索引将所有可能查询的列加入到这个多元索引中即可加入的顺序也没有要求。多元索引中的每一列默认都会建立倒排倒排就记录了Value到List的映射。针对多列的多个条件在每列的倒排表中找到对应的List这个称为一个倒排链而筛选符合多个条件的数据即为计算多个倒排链的交并集这里底层有着大量的优化可以高效的实现这一操作。因此多元索引在处理多条件组合查询方面效率很高。
此外多元索引还支持全文索引、模糊查询、地理空间查询等以地理空间查询为例多元索引通过底层的BKD-Tree结构支持高效的查询一个地理多边形内的点也支持按照地理位置排序、聚合统计等。
索引选择
不是一定需要索引
如果基于主键和主键范围查询的功能已经可以满足业务需求那么不需要建立索引。如果对某个范围内进行筛选范围内数据量不大或者查询频率不高可以使用Filter不需要建立索引。如果是某种复杂查询执行频率较低对延迟不敏感可以考虑通过DLA(数据湖分析)服务访问Tablestore使用SQL进行查询。
全局二级索引还是多元索引
一个全局二级索引是一个索引表类似于主表其提供了另一种数据分布方式或者认为是另一种主键排序方式。一个索引对应一种查询条件预先将符合查询条件的数据排列在一起查询效率很高。索引表可支撑的数据规模与主表相同另一方面全局二级索引的主键设计也同样需要考虑散列问题。一个多元索引是一系列数据结构的组合其中的每一列都支持建立倒排索引等结构查询时可以按照其中任意一列进行排序。一个多元索引可以支持多种查询条件不需要对不同查询条件建立多个多元索引。相比全局二级索引也支持多条件组合查询、模糊查询、全文索引、地理位置查询等。多元索引本质上是通过各种数据结构加快了数据的筛选过程功能非常丰富但在数据按照某种固定顺序读取这种场景上效率不如全局二级索引。多元索引的查询效率与倒排链长度等因素相关即查询性能与整个表的全量数据规模有关在数据规模达到百亿行以上时建议使用RoutingKey对数据进行分片查询时也通过指定RoutingKey查询来减少查询涉及到的数据量。简而言之查询灵活度和数据规模不可兼得。
关于使用多元索引还是全局二级索引也有另外一篇文章描述《Tablestore索引功能详解》。
除了全局二级索引之外后续还会推出本地二级索引(LocalIndex)推出后再进行详细介绍。
常见组合方案
丰富的查询功能当然是业务都希望具备的但是在数据规模很大的情况下灵活的查询意味着成本。比如万亿行数据的规模对于表引擎来说因为水平扩展能力很强成本也很低问题不大但是建立多元索引费用就会非常高昂。全局二级索引成本较低但是只适合固定维度的查询。
常见的超大规模数据都带有一些时间属性比如大量设备产生的数据(监控数据)或者人产生的数据(消息、行为数据等)这类数据非常适合采用Tablestore存储。对这类数据建立索引会有一些组合方案 对元数据表建立多元索引全量数据表不建立索引或采用全局二级索引。 元数据表可以是产生数据的主体表比如设备信息表用户信息表等。在时序模型中产生数据的主体也可以认为是一个时间线这条线会不断的产生新的点。Tablestore的时序数据模型(Timestream)采用的也是类似的方式对时序数据中的时间线建立一张表专门用来记录时间线的元数据每个时间线一行。时间线表建立多元索引用来做时间线检索而全量数据则不建立索引。在检索到时间线后对某个时间线下的数据进行范围扫描来读取这个时间线的数据。 热数据建立多元索引老数据不建立索引或者采用全局二级索引 很多情况下仅需要对非常热的数据进行多种维度查询对冷数据采取固定维度查询即可。因此冷热分离可以给业务提供更高的性价比。目前多元索引还不支持TTL(后续会支持)需要业务层区分热数据和冷数据。
总结
本文对Tablestore的存储和索引引擎进行了介绍和解读并在如何选择和应用索引方面给了一些参考目的是加深大家对Tablestore的认识和理解更好的应用Tablestore来解决业务需求。如果有疑问或需求或者希望进一步技术探讨欢迎大家加入Tablestore官方的钉钉技术交流群群号11789671。
原文链接 本文为云栖社区原创内容未经允许不得转载。