1.Secondary Indexing
二级索引
二级索引就是从主要访问路径的另一个hbase表的方式。
1.覆盖索引机制
phoenix提供了一个强大的覆盖机制,就是一旦从索引中找到检索的条目就不去访问主表了。就是说它将关心的数据绑定到索引中,这样就可以节省读取时间,典型的用空间换时间的案例。
例如,以下内容将在v1和v2列上创建索引,并在索引中包含v3列,以防止必须从数据表中获取它:
CREATE INDEX my_index ON my_table(v1,v2)INCLUDE(v3)
2.函数索引机制
当查询使用到了函数,而不是数据表本事,例如UPPER(FIRST_NAME ||''||| LAST_NAME),这样我们就可以使用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支持两种索引技术:全局索引和本地索引。每种方法在不同的场景中都很有用,并且具有自己的故障特征和性能特征
3.global indexes
global indexes 合适与大量读取的场景。性能的主要开始在写入索引的时候,它拦截了所有的数据操作修改和写入的语句,来创建索引的修改和写入。在读取的时候,phoenix将选择索引表去提高查询时间并直接扫描它的数据,就像读取另一个hbase的表一样,实际上就是一个hbase表。但是如果index中没有include我们要查询的所有字段,索引就无效了,所以要合理的include字段。就是我们在覆盖索引里提到的机制。
4. local indexes
local index 适合于大量写入数据的场景。和global一样phoenix也是自动判断是否走索引查询数据。index 数据和 table数据在同一个服务上,所以没有额外的网络开销。local indexes 可以使用在没有全面覆盖include的场景,也就是说phoenix自动去获取不在index中的列。与全局索引不同,表的所有本地索引都存储在4.8.0版本之前的单个独立共享表中。从4.8.0开始,我们将所有本地索引数据存储在同一数据表中的单独阴影列族中。在使用本地索引的读取时,必须检查每个区域的数据,因为不能预先确定索引数据的确切区域位置。因此,一些开销在读取时发生。
5.异步创建索引
默认的情况下,创建index是同步的。但是当数据量比较大的时候同步就不可行了。这样就引入了异步创建表的机制。 DDL语句如下:
CREATE INDEX async_index ON my_schema.my_table (v) ASYNC
这样必须通过hbase的命令行单独启动mr来填充数据入如下:
$ {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
6.索引的用法
当确定更高效的查询时,Phoenix会自动使用索引来为查询提供服务。但是,除非查询中引用的所有列都包含在索引中,否则不会使用全局索引。例如,以下查询不会使用索引,因为在查询中引用了v2但未包含在索引中:
SELECT v2 FROM my_table WHERE v1 ='foo'
获得在这种情况下使用的索引有三种方法:
通过在索引中包含v2来创建覆盖索引:
CREATE INDEX my_index ON my_table(v1)INCLUDE(v2)
这将导致v2列值复制到索引中并在更改时保持同步。这显然会增加索引的大小。
提示查询强制它使用索引:
SELECT / * + INDEX(my_table my_index)* / v2 FROM my_table WHERE v1 ='foo'
这将导致在遍历索引时检索每个数据行以查找缺少的v2列值。仅当您知道索引具有良好的选择性时才应使用此提示(即,在此示例中少量表行的值为'foo'),否则您将通过执行以下操作的默认行为获得更好的性能全表扫描。
创建本地索引:
CREATE LOCAL INDEX my_index ON my_table (v1)
与全局索引不同,即使查询中引用的所有列都未包含在索引中,本地索引也将使用索引。对于本地索引,默认情况下这是完成的,因为我们知道表和索引数据位于同一区域服务器上,从而确保查找是本地的。
与CREATE TABLE语句一样,CREATE INDEX语句可以传递属性以应用于基础HBase表,包括对其进行加盐的能力:
CREATE INDEX my_index ON my_table(v2 DESC,v1)INCLUDE(v3) SALT_BUCKETS = 10,DATA_BLOCK_ENCODING ='NONE'
请注意,如果主表被加盐,则索引将以相同的方式自动为全局索引加盐。此外,相对于主表与索引表的大小,索引的MAX_FILESIZE向下调整。欲了解更多关于盐析看这里。另一方面,使用本地索引时,不允许指定SALT_BUCKETS。
一致性保证
在提交后成功返回客户端时,所有数据都保证写入所有感兴趣的索引和主表。换句话说,索引更新与HBase提供的相同强一致性保证同步。
但是,由于索引存储在与数据表不同的表中,因此根据表的属性和索引的类型,如果由于服务器端崩溃而导致提交失败,则表和索引之间的一致性会有所不同。这是由您的要求和用例驱动的重要设计考虑因素。
下面概述了具有不同级别一致性保证的不同选项。
禁止表写入,直到可变索引一致
保持非事务性表和索引之间一致性的最高级别是声明在更新索引失败时应暂时禁止对数据表的写入。在此一致性模式下,表和索引将保留在发生故障之前的时间戳,不允许写入数据表,直到索引重新联机并与数据表同步。索引将保持活动状态并继续像往常一样由查询使用。
以下服务器端配置控制此行为:
- phoenix.index.failure.block.write必须为true,以便在发生提交失败时使对数据表的写入失败,直到索引可以被数据表捕获。
- phoenix.index.failure.handling.rebuild必须为true(默认值),以便在发生提交失败时在后台重建可变索引。
在写入失败时禁用可变索引,直到恢复一致性
可变索引的默认行为是,如果对它们的写入在提交时失败,在后台部分重建它们,然后在恢复一致性后再次将它们标记为活动,则将索引标记为已禁用。在此一致性模式下,在重建二级索引时,不会阻止对数据表的写入。但是,重建发生时查询将不会使用辅助索引。
以下服务器端配置控制此行为:
- phoenix.index.failure.handling.rebuild必须为true(默认值),以便在发生提交失败时在后台重建可变索引。
- phoenix.index.failure.handling.rebuild.interval控制服务器检查是否需要部分重建可变索引以赶上数据表更新的毫秒频率。默认值为10000或10秒。
- phoenix.index.failure.handling.rebuild.overlap.time控制从发生故障的时间戳返回多少毫秒,以便在执行部分重建时返回。默认值为1。
在写入失败时禁用可变索引,需要手动重建
这是可变二级索引的最低一致性级别。在这种情况下,当对辅助索引的写入失败时,索引将被标记为已禁用,并且需要手动重建索引以使其能够再次被查询使用。
以下服务器端配置控制此行为:
- 必须将phoenix.index.failure.handling.rebuild设置为false才能在发生提交失败时禁用可变索引在后台重建
Index Scrutiny Tool
使用Phoenix 4.12,现在有一个工具可以运行MapReduce作业来验证索引表是否对其数据表有效。在任一表中查找孤立行的唯一方法是扫描表中的所有行,并在另一个表中查找相应行。因此,该工具可以使用数据或索引表作为“源”表运行,另一个作为“目标”表运行。该工具将找到的所有无效行写入文件或输出表PHOENIX_INDEX_SCRUTINY。无效行是源行,它在目标表中没有对应的行,或者在目标表中具有不正确的值(即覆盖的列值)。
该工具具有跟踪其状态的作业计数器。VALID_ROW_COUNT,INVALID_ROW_COUNT,BAD_COVERED_COL_VAL_COUNT。请注意,无效行 - 错误列数行=孤立行数。这些计数器与其他作业元数据一起写入表PHOENIX_INDEX_SCRUTINY_METADATA。
Index scrutiny Tool可以通过hbase命令(在hbase / bin中)启动,如下所示:
hbase org.apache.phoenix.mapreduce.index.IndexScrutinyTool -dt my_table -it my_index -o
它也可以使用phoenix-core或phoenix-server jar从Hadoop运行,如下所示:
HADOOP_CLASSPATH = $(hbase mapredcp)hadoop jar phoenix- <version> -server.jar org.apache.phoenix.mapreduce.index.IndexScrutinyTool -dt my_table -it my_index -o
默认情况下,启动两个mapreduce作业,一个以数据表作为源表,另一个以索引表作为源表。
以下参数可与Index Scrutiny Tool一起使用:
参数 描述 -dt,-data表 数据表名称(必填) - 它,-index表 索引表名称(必填) -s,-schema Phoenix模式名称(可选) -src,-source DATA_TABLE_SOURCE,INDEX_TABLE_SOURCE或BOTH。默认为BOTH -o,-output 是否输出无效行。默认关闭 -of, - 输出格式 TABLE或FILE输出格式。默认为TABLE -om,-output-MAX 每个映射器输出的最大无效行数。默认为1M -OP, - 输出路径 对于FILE输出格式,写入文件的HDFS目录 -t,-time 以毫秒计的时间戳进行审查。这很重要,因此传入的写入不会引起审查。默认为当前时间减去60秒 -b,-batch尺寸 一次比较的行数