美文网首页设计数据密集型应用
《设计数据密集型应用》第六章(2) 数据分区:二级索引

《设计数据密集型应用》第六章(2) 数据分区:二级索引

作者: MeazZa | 来源:发表于2019-03-26 09:12 被阅读0次

    之前我们介绍过Key-value数据的分区模型。如果数据只能由主键进行访问,我们可以由Key确定分区,并用它路由到Key所在的分区进行读取操作。

    如果引入二级索引(Secondary Indexes),情况会更加复杂。二级索引通常不像主键那样,可以唯一确定数据,二级索引更多用来查找出现某个特定值的所有数据,比如:查找用户123的所有行为,查找包含hogwash的所有文章等。

    二级索引是数据库的重要功能,在文档型数据库中也很常见,但并不是所有数据库都支持它。许多Key-Value数据库,例如HBase和Voldemort,由于二级索引的复杂性,因此并未支持;其他数据库,比如Risk,考虑到二级索引对数据模型的重要性而做了支持;类似Solr和Elasticsearch这种数据库,天生是为二级索引而存在的。

    二级索引的最大问题是它和数据分区不是完全对应的,因此有两种设计二级索引的方法,分别为:基于文档的二级索引分区和基于词的二级索引分区。

    基于文档的二级索引分区

    假设我们有一个售车网站,每辆车有一个唯一ID,称为文档ID,数据库的分区基于此ID,比如分区0中包含的数据ID范围为0-499,分区1中包含的数据ID范围为500-999等。

    现在用户想要查找车辆,我们允许它通过颜色和品牌过滤,因此需要在颜色和品牌上添加二级索引。当一个红色的卡添加到数据库时,数据库分区中自动将文档ID添加到color:red的索引列表里,如下图所示。

    基于文档的二级索引分区

    在这种索引方式下,每个分区维护自己的二级索引,只管理分区内的文档,它并不关心其他分区存储的数据。当写数据库时,只需要修改文档ID对应的分区。因此,这种索引方式也被称为本地索引

    在查询红色的车时,需要查询所有的分区,并将每个分区的结果合并在一起,这种查询分区数据库的方式称为scatter/gather。该查询方式使得二级索引的查询成本很高,很容易出现尾延迟的情况。特别是如果查询多个二级索引字段的情况,很难避免查询所有的分区。即使如此,它也被广泛使用,比如MongoDB、Riak、Cassandra、Elasticsearch、SolrCloud和VoltDB等。

    基于词(Term)的二级索引分区

    基于词的二级索引分区,也称为全局索引,将所有二级索引的内容进行统一维护,并按照和主键不同的方式进行分区。比如汽车的颜色,将颜色字母从a到r的存储在分区0,从s到z的存储在分区1。

    基于词的二级索引分区

    可以用词本身,或者词的Hash确定二级索引的分区。使用词本身的话对范围查找支持更好,比如查询车的价格在某区间范围的场景;使用词的Hash会将负载分配得更加平均。

    采用这种二级索引的方式,如果查找红色的车,客户端不需要读取所有的分区,使读更加有效。客户端先向二级索引包含这个词的分区发送请求,然后再根据索引指向的位置,向数据所在的分区发起请求。但写会更复杂,并且性能会下降,因为写入一个文档会操作更多分区,同时还会引入分布式事务的问题。

    使用基于词的二级索引分区,通常是以异步的方式,可能是并不是立即读到写入的数据,比如Amazon的DynamoDB。

    有一些数据库允许用户从这两种二级索引分区方式进行选择,比如Riak。

    小结

    本节介绍了关于数据二级索引的设计方式,基于文档的二级索引分区和基于词的二级索引分区,和它们各自的特点和优缺点对比。

    相关文章

      网友评论

        本文标题:《设计数据密集型应用》第六章(2) 数据分区:二级索引

        本文链接:https://www.haomeiwen.com/subject/ohebvqtx.html