Phoenix 索引生命周期

转自: https://yq.aliyun.com/articles/236804?spm=a2c4e.11155435.0.0.5bf24db4AiMZ6z

本文主要介绍Phoenix索引状态的生命周期,帮助大家解惑“为什么我的phoenix索引不能正常使用了?”

索引状态

索引总共有以下几个状态,其状态信息存储在SYSTEM.CATALOG表中。可以通过以下SQL来查看所有索引表信息:

select TABLE_NAME,DATA_TABLE_NAME,INDEX_TYPE,INDEX_STATE,INDEX_DISABLE_TIMESTAMP
from system.catalog where INDEX_TYPE is not null;

Screen_Shot_2017_11_09_at_20_54_05

SQL中字段:

  • TABLE_NAME                   表示索引表名
  • DATA_TABLE_NAME        表示原数据表名
  • INDEX_TYPE                    表示索引类型
    • 1  表示全局索引 GLOBAL
    • 2  表示本地索引 LOCAL
  • INDEX_STATE                  表示索引状态
    • a  ACTIVE           表示索引表能被正常用于查询中
    • b  BUILDING      表示将从索引不可用的时间戳处重建索引直到重建完成。
    • d  UNUSABLE   表示索引将不能用于查询中,但索引仍然在不可用的维护状态。
    • e  USABLE        表示索引表能被正常用于查询中。
    • i  INACTIVE       表示索引将不能用于查询中,但索引仍然在不可用的维护状态。
    • r  REBUILD        表示索引将完成重建,同时一旦重建完成此索引将能被在此用于查询中。
    • x  DISABLE       表示索引将处于不可用的维护状态,同时将不能用于查询中。
  • INDEX_DISABLE_TIMESTAMP
    表示索引disable时的时间戳。当索引是active或者手动置为disable时值为0,当索引写失败引起disable时值为非0。

下图就显示了索引的状态转换关系, 包括自动重建索引和手动重建索引之间的状态转换.

8062_screen_shot_2016_09_28_at_35743_pm
注:disable状态的索引必须重建,不能设置为USABLE状态。

 

自动重建索引过程

  1. MetaDataRegionObserver类负责运行重建索引线程,SYSTEM.CATALOG表是disable索引表更新的关键,因为它记录着索引表的所有状态。
  2. INACTIVE和DISABLE索引将会被选择重建(所有Online索引表region)。
  3. 所有表的所有索引表重建过程将串行执行(运行在cp上)。
  4. 索引表的建立是从disabled timestamp开始的。(此处会生成disable 时间到现在时间, 并带有需要更新索引信息的scan, RS在执行scan时触发cp重建索引)
  5. 对应的执行sql "UPSERT /+ NO_INDEX / INTO index_table_name(indexedCols) select dataCols from data_table”  完成索引同步。

  注: (这里对SQL说明一下)

        UPSERT /*+ NO_INDEX */ INTO 索引表名 select 索引中的列(!desc看一下,这里要包含索引的所有列) from 数据主表;

       例如: UPSERT /*+ NO_INDEX */ INTO TEST_INDEX select b,a from test;

       这个SQL执行的比较慢, 采用批处理 提交upsert 的方式更新索引, 对于大数据量不适用, 这里写应该就是方便理解, Phoenix的自动重建应该不是这么做的, 应该是从WAL获取数据, 采用bulkload的方式重建索引.

 

索引重建生命周期

8063_screen_shot_2016_09_28_at_35855_pm

控制自动重建索引的属性

  • "phoenix.index.failure.handling.rebuild"(default true)   是否开启自动重建索引机制
  • "phoenix.index.failure.handling.rebuild.interval" (default 10 seconds) 检查索引是否需要重建的间隔时间

更新索引表失败处理实践

  1. 写索引表失败会试图禁用索引,向SYSTEM.CATALOG表写入索引状态。
  2. 在集群状态异常情况下,比如存在rit(region变迁)。此时CATALOG表的写操作可能失败,也就是状态不能得到更新,索引数据也同步失败,导致不断的执行起重建索引任务。
  3. 为了确保索引已经能得到更新,杀死RS,来触发WAL的replay,这样就能使得索引表的更新在WAL replay过程中得到重试。 同时需要手工介入,通过alter命令设置索引状态使之可用。

以上是社区版本通过RS failover来解决问题,但这种方法也存在一些问题:

  1. 雪崩效应,整个集群的RS全部自杀:因为自杀的RS上也host了很多region,这些region可能是其他RS的索引表。某一RS自杀后,会导致其他RS的索引表更新失败,从而触发其他RS自杀,而其他RS自杀又会因为同样的原因导致更多的RS自杀,恶性循环。在很短的时间内,集群中所有RS都自杀了。
  2. 禁用的index表需要人工介入才能启用,在集群多了以后,会成为管理负担
  3. 禁用index表之后,本来通过命中索引表来完成的查询,就需要对主表做全表扫描来完成了。小scan会立即变成大scan,这可能会快速耗尽RS的资源,并导致client端大量超时。

云HBASE针对以上问题,提出了以下解决方法,并已经实现。

  1. 在sync WAL之前出现的问题,由client负责重试: 因为没有WAL没有写下去,就不会导致主表和索引表的数据不一致。
  2. 在sync WAL之后出现的问题,由RS负责重试:因为WAL已经写下去了,此时,部分索引表的更新也可能已经完成,客户端如果不重试且RS不重启,主表和索引表会保持长时间的不一致。

 

注:

    自动重建索引引起的雪崩我正好遇到了, 集群都起不来了, 每次启动都会陆续宕机, 没啥好办法, 最后把自动重建索引给关了, 以后有好的办法了再来这里更新.

 

索引与主表的数据一致性验证, 请看老衲的另外一篇文章: https://blog.csdn.net/yuanhaiwn/article/details/81907484

 

参考

  1. https://community.hortonworks.com/articles/58818/phoenix-index-lifecycle.html
  2. https://phoenix.apache.org/secondary_indexing.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值