全局索引_数据系统 - 分区和二级索引

到目前为止,我们讨论的分区方案只依赖于键值数据模型。如果数据记录只是通过它们的主键访问的话,我们就可以从它们的键来决定分区,并且使用它来读取和写入这个键相对应的分区。

但如果包含了一个二级索引,那么情况就会变得更加复杂了。一个二级索引通常不能唯一的识别一条数据记录,反而是搜寻特定值发生频次的一种方式,比如说:

  • 查找所有用户123的相关行为
  • 查找包含单词hogwash的所有文章
  • 查找所有颜色是红色的小汽车

二级索引是关系数据库的基础,它们在文档数据库中也很常见。许多键值存储(诸如HBase和Voldemort)已经避免了二级存储,因为它们增加了实现的复杂度,但也有一些,诸如Riak已经开始添加二级索引,因为它们对于数据模型来说是很有用的。最后,二级索引是诸如Solr和Elasticsearch之类的搜索服务器的存在理由。

二级索引的问题在于它们没有整齐的映射分区。使用二级索引分区数据库,主要有两种方式:

  • 基于文档的分区
  • 基于术语的分区

基于文档分区二级索引

比方说,你正在运营一个销售二手汽车的网站。每个列表都使用一个独一无二的ID,我们称它文档ID,并且你通过文档ID对数据库进行分区,比如,ID0~499在分区0,ID500~999在分区1,以此类推。

你想让你的用户,可以通过筛选颜色和品牌来查找车辆,所以你需要一个对于颜色和品牌的二级索引(在文档型数据库中,这会是字段;在关系型数据库中,这会是列)。如果你声明了索引,数据库会自动执行索引。比方说,当一辆红色的汽车添加进数据时,数据库分区会把它自动添加进索引颜色是红色的文档ID列表中。

在这样的分区方式中,每个分区是完全独立的:每个分区都维护着自己的二级索引,只包含那一部分的文档。并且不关心其他分区存储了什么数据。当你需要写数据库时 —— 添加,删除或更新文档时 —— 你只需要处理你正在写入的包含文档ID的那个分区就可以了。所以,按照文档分区的索引也被称为本地索引。

然而,当从文档分区索引读取数据时需要十分小心:除非你已经对文档ID做了一些特殊处理,否则没有理由为什么所有具有特定颜色或品牌的汽车都位于同一分区中。在下图中。红色汽车同时出现在分区0和分区1中。因此,如果你想要查找红色汽车,你必须对所有的分区发送查询,并且把你得到的所有结果组合起来。

50cdb96436eb07f11643a51046c35d1e.png

这种查询分区数据库的方式也被称为分散scatter/聚集gather,并且对于二级索引的读取查询的开销是很大的。即使你并发的查询所有的分区,scatter/gather也容易造成尾部延迟的扩大。尽管如此,它也被广泛使用,诸如MongoDB、Riak、Cassandra、Elasticsearch、SolrCloud以及VoltDB,这些都在使用文档分区的二级索引。大多数的数据库供应商会建议你搭建你自己的分区方案以便二级索引查询只为单个分区服务,但这一般是不可能的,特别是当你在单个查询中使用多个二级索引时,比方说筛选车辆时同时使用颜色和品牌。

基于术语的二级索引分区

除了让每个分区拥有自己的二级索引,我们也可以构建一个全局的索引来覆盖所有分区中的数据。但是,我们不能仅将索引存储在一个节点上,因为它可能会成为瓶颈并破坏分区的目的。全局索引也必须进行分区,但是可以与主键索引以不同方式进行分区。

下图展示了,这会看上去是怎么样的:

3642d2fbd3c53b6865a37b2c78eaa5cd.png

所有分区中的红色车辆出现在color:red的索引中,但索引是分区的,颜色以字母a到r为开头的在分区0中,以s到z为开头的在分区1中。汽车品牌的索引分区也类似。

我们称这样的索引方式为term-partitioned术语分区,因为我们找寻的术语决定了索引的分区。并发说,我们在这里使用的术语:color:red。名称术语来自全文索引(一种特殊的二级索引),其中术语是文档中出现的所有单词。

和以前一样,我们可以按术语本身或使用该术语的哈希对索引进行分区。用术语本身进行分区可用于范围扫描(例如,在数字属性上,例如汽车的要价),而用术语的散列进行分区则可以更均匀地分配负载。

与文档分区索引相比,全局(术语分区)索引的优势在于它可以提高读取效率:与其对所有分区进行分散/聚集,客户端只需要向包含术语的分区发出请求它想要的。但是,全局索引的缺点是写入速度较慢且更复杂,因为写入单个文档现在可能会影响索引的多个分区(文档中的每个术语可能位于不同的分区,不同的节点上) 。

在理想情况下,索引将始终是最新的,并且写入数据库的每个文档都将立即反映在索引中。但是,在术语分区索引中,这将需要一个因为写入而跨所有分区的分布式事务,并非所有数据库都支持。

实际上,对全局二级索引的更新通常是异步的(也就是说,如果您在写操作后不久就读取了索引,则您刚刚进行的更改可能尚未反映在索引中)。例如,Amazon DynamoDB指出,在正常情况下,其全局二级索引会在几分之一秒内更新,但是如果基础架构发生故障,则可能会经历更长的传播延迟。

全局术语分区索引的其他用途包括Riak的搜索功能和Oracle数据仓库,您可以在本地索引和全局索引之间进行选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值