美文网首页
Apache Phoenix(四)新特性之二级索引

Apache Phoenix(四)新特性之二级索引

作者: 我知他风雨兼程途径日暮不赏 | 来源:发表于2020-02-11 22:19 被阅读0次

      二级索引是通过直接方式访问数据在它的主要访问路径上。在Hbase中,在主row key上有个按照字典顺序排列的索引。除了通过主行之外,以任何的方式访问记录都需要扫描表中所有的行,以便根据你筛选对它们进行测试。使用二级索引,你的列或者表达式,将组成一个备用的行键指向,允许点查找和范围扫描沿着这个新轴。

    1. 覆盖索引
    2. 函数索引
    3. 全局索引
    4. 本地索引
    5. 索引填充
    6. 使用索引
    7. 索引删除
    8. 索引属性
    9. 分布式一致性保证
      9.1 事务表
      9.2 不可变表
      9.3 可变表
    10. 设置
      10.1 针对4.12及以后的版本
      10.2 针对4.8-4.11
      10.3 针对4.7及之前的版本
    11. 更新本地索引在4.8.0之前
    12. 调优
    13. 性能
    14. 索引审查工具
    15. 索引更新工具
    16. 限制
    17. 资源

    1. 覆盖索引

      总结:覆盖索引将不需要索引的列也包含在索引表中,这样可以减少回表操作。
      Phoenix的是特别强大在于我们提供的覆盖索引(covered indexes)。我们不需要去找到索引条目后返回主表。相反的,我们将关心的数据进行捆绑在索引行中,从而节约时间开销。
      举个例子,下面创建了一个索引在v1和v2上并且包含了v3列在索引中很好的避免了获取v3去数据表中拿,因为索引表就包含了v3列,没必要再进行回表操作。

    CREATE INDEX my_index ON my_table (v1,v2) INCLUDE(v3)
    

    2. 函数索引

      总结:可以将数据中的数据先按照特定函数进行处理,这样在每次做函数时可以走索引,而不是全表扫描的走数据表。
      函数索引(4.3及以后版本可用)允许你去创建一个索引,不仅包含在列上,也可以是任意的表达式。当查询使用表达式,可以使用索引来检索结果,而不是数据表,举个例子,你可以创建一个索引在UPPER(FIRST_NAME||''||LAST_NAME)去允许不敏感大小写进行一个人的姓和一个人的名进行组合。
    举例,下面将创建这个函数索引:

    CREATE INDEX UPPER_NAME_IDX ON EMP (UPPER(FIRST_NAME||' '||LAST_NAME))
    

      有这个索引,当发出以下查询时,使用索引去替代数据表中数据的检索结果。

    SELECT EMP_ID FROM EMP WHERE UPPER(FIRST_NAME||' '||LAST_NAME)='JOHN DOE'
    

      Phoenix支持两种方式的索引技术:全局索引(Global Index)和本地索引(Local Index)。两者的使用场景和它们的故障处理和性能特征都不同。

    3. 全局索引

      总结:减轻读取负担,但是会增加写入的负担。
      全局索引的目的是为了做读取任务繁重。在全局索引下,所有的性能损耗都发生在写上。我们拦截了该数据表所有的更新(删除、更新值,更新查询),构建索引更新,然后必须向所有的对应索引表进行更新。在读的时候,Phoenix会查询索引表去使用将会产生更快的查询速度和直接扫描它就像其他的Hbase表一样。默认情况下,除非有提示,否则不会将索引用于引用不属于索引列的查询。

    4. 本地索引

      总结:解决写的负担和空闲受限,所有的索引在同一张hbase表中。
      本地索引的目的在于解决写繁重,空间受限的例子。就像全局索引,Phoenix将会自动的查找是否有可用的本地索引在查询时。在本地索引下,索引数据和表数据同时驻留在同一处服务器上防止网络开销在写时。在查询不是全覆盖时,本地索引依然可以被使用(例如,Phoenix会根据数据表的指向获取自动检索不在索引中的列)。不同于全局索引,在4.8.0版本之前,表的所有本地索引都存在在一个单独的共享表上。4.8.0之后,我们存储所有的本地索引数据在同一个数据表中的独立shadow列簇中。在读时,当本地索引被使用,所有的区域都必须检测数据因为无法预先确定索引数据的准确区域位置。因此,一些开销也会发生在读取时。

    ##建立表
    create table test_local(id varchar primary key,f1 varchar,f2 varchar);
    ##建立local index
    create local index test_local_index on test_local(f1);
    

    5. 索引填充

      总结:创建索引默认是同步的,但是可以改成异步形式,这样就不会发生表的堵塞。
      默认情况下,在创建索引时,将在CREATE INDEX调用时同步填充索引。这可能是不行的,需要依赖当前的行数在数据表中,如果太大的数据量会导致同步卡顿。在4.5版本中,最初的索引填充是异步进行的通过包含ASYNC的关键字,在索引创建的DDL语句中:

    CREATE INDEX async_index ON my_schema.my_table (v) ASYNC
    

      这个map reduce任务会填充索引的表,必须通过hbase命令行分别执行,如下所示:

    ${HBASE_HOME}/bin/hbase org.apache.phoenix.mapreduce.index.IndexTool
      --schema MY_SCHEMA --data-table MY_TABLE --index-table ASYNC_IDX
      --output-path ASYNC_IDX_HFILES
    

      只有当map reduce任务是完成的,索引才会激活,并且开始可以使用在查询中。这个任务对于客户的退出是可复原的。output-path选项是指定一个HDFS目录作为写HFiles的用途。

    6. 使用索引

      总结:如何利用索引。
      索引是自动使用的通过Phoenix的服务进行查询,当确定查询更有效时。无论如何,一个全局的索引是不会的除非所有的索引列都在涉及的查询中时。举例,如下的查询时不会使用索引的,因为V2涉及到了查询,但不是包含在索引内:

    SELECT v2 FROM my_table WHERE v1 = 'foo'
    

      在这种情况下有三种方法可以通过索引检索:

    1. 创建覆盖索引去包含v2在索引中:
    CREATE INDEX my_index ON my_table (v1) INCLUDE (v2)
    

      这将会引起v2列的值会拷贝到索引中,并且同步更改索引里v2的值。
      这将会明显的增长索引的大小。

    1. 提示该查询强制使用该索引:
    SELECT /*+ INDEX(my_table my_index) */ v2 FROM my_table WHERE v1 = 'foo'
    

      这将导致在遍历索引以查找丢失的v2列值时检索每个数据行。这个提示应该只在您知道索引具有良好的选择性的情况下使用(例如,在本例中,少量的表行具有' foo '值),否则您将通过执行全表扫描的默认行为获得更好的性能。

    1. 创建本地索引:
    CREATE LOCAL INDEX my_index ON my_table (v1)
    

      即使查询中引用的所有列都不包含在索引中,本地索引也将使用索引。对于本地索引,这是默认的,因为我们知道表和索引数据共存于同一区域服务器上,从而确保查找是本地的。

    7. 索引删除

      删除索引,你需要发出以下声明:

    DROP INDEX my_index ON my_table;
    

      如果一个索引列在表中是被删除,那么这个索引就会自动被删除。另外,如果一个覆盖列是被删除的在数据表中,它将会自动的从索引中被删除。

    8. 索引属性

    就像CREATE TABLE语句一样,CREATE INDEX语句可以通过属性来应用于底层的Hbase表,包括为其添加salt能力:

    CREATE INDEX my_index ON my_table (v2 DESC, v1) INCLUDE (v3)
        SALT_BUCKETS=10, DATA_BLOCK_ENCODING='NONE'
    

      注意如果主表是加盐的,那么全局索引也会以同样的方式进行加盐。另外,这个MAX_FILESIZE对索引做了向下调整,相对于主索引表和索引表的大小。更多关于加盐的信息,请点击这里。另一方面,对于本地索引,不允许指定SALT_BUCKETS。

    9. 分布式一致性保证

      提交后成功返回客户端时,保证将所有数据写入所有感兴趣的索引和主表。换句话说,索引更新与HBase提供的强一致性保证是同步的。
      但是,由于索引存储在数据表之外的单独的表中,这取决于表的属性和索引的类型,所以在服务器端崩溃导致提交失败的情况下,表和索引之间的一致性会有所不同。这是由需求和用例驱动的重要设计考虑。
      下面列出了不同级别的一致性保证的不同选项。

    9.1 事务表

      通过将表声明为事务性的,可以在表和索引之间实现最高级别的一致性保证。在这种情况下,您提交的表突变和相关的索引更新是具有强ACID保证的原子性的。如果提交失败,则不会更新任何数据(表或索引),从而确保表和索引始终保持同步。
      为什么不总是将表声明为事务性的呢?这可能没问题,特别是如果您的表被声明为不可变的,因为在这种情况下,事务开销非常小。但是,如果数据是可变的,

    9.2 不可变表

    9.3 可变表

    10. 设置

    10.1 针对4.12及以后的版本

    10.2 针对4.8-4.11

    10.3 针对4.7及之前的版本

    11. 更新本地索引在4.8.0之前

    12. 调优

    13. 性能

    14. 索引审查工具

    15. 索引更新工具

    16. 限制

    17. 资源

    相关文章

      网友评论

          本文标题:Apache Phoenix(四)新特性之二级索引

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