上一篇介绍了Phoenix基于HBase的二级索引的基本知识,这一篇介绍一下和索引相关的一致性和优化相关内容。

一致性的保证

Phoenix客户端在成功提交一个操作并且得到成功响应后,就代表你所做的操作已经成功应用到原表和相关的索引表中。换句话说,索引表的维护和处理原表数据是同步的,并且各自是强一致性保证的。但是因为索引表和原表是在不同的表中,根据表的属性和索引的类型,当服务端崩溃导致一次提交失败时,原表和索引表中的数据就会有一些变化。所以在使用二级索引的时候,就要根据需求个用例充分考虑。

下面列出了一些不同级别的一致性保证供你选择。

1. 事务表

如果把表定义成事务表(Transactional),你将获得最高级别的一致性保证。原表的操作和索引表的操作完全就是一个原子操作。如果提交失败,原表和索引表的数据都不会被更新,如果启用了这种级别的一致性,你的原表和索引表永远都保持同步。目前这个功能还是beta版本阶段,它是实现依赖于另一个Apache项目Apache Tephra。它是一个分布式事务框架。

那为什么不把所有的表都设置能事务的呢?特别是一些被声明了是不可变的表(只写一次,不修改的表),因为这个时候事务的损耗是非常小的。但是一旦你的表中的数据会变化,那么你就要承担一些冲突检测和事务管理器的开销;同时做事务表中建二级索引,会潜在的降低系统的可用性,因为原表和二级索引表都必须可用行,不然都会失败。

2. 不可变表

不可变表中的数据之写入一次,之后就再也不会被更新了。对于这种表,Phoenix会做特别的优化,降低写入的损耗和增量维护的损耗。这类数据通常就是一些时间序列的数据,比如日志、事件、或者传感器的周期数据等等。这类表结构需要在见表的时候加上 IMMUTABLE_ROWS=true 语句,这样数据表就会被优化。默认建表是可变的。

CREATE TABLE HAO2 (k VARCHAR PRIMARY KEY, v VARCHAR) IMMUTABLE_ROWS=true;

在不可变表上面建的所有的索引都是不可变的。对于全局的不可变索引来说,索引全部由客户端来维护,原表的数据变化会触发索引的修改。本地索引在服务端维护。需要注意的是,Phoenix没有强制在一张申明了不可变的原表上修改数据,索引将不再与原表同步。

如果你有一个已经存在的表,想把不可变索引修改成可变索引的话,可以用如下语句实现:

alter table HAO2 set IMMUTABLE_ROWS = false;

另外,非事务性、不可变表的索引没有自动处理提交失败的机制。保持表和索引之间的一致性留给客户端处理。因为更新是幂等的,最简单的解决方案是客户端不断尝试直到成功。

3. 易变的表

对于非事务的可变表,我们通过添加索引更新到原表的WAL日志里来维护索引信息的更新。只有当WAL同步后,才会去真的更新索引或原表。Phoenix写索引文件是并行的,这样有助于性能的提高,吞吐量增大。如果我们正在更新索引的时候,服务器挂了,我们会找到对应的WAL,重新执行所有的更新。更新的幂等性保证了数据的准确性。

不过需要注意一下几点:

1. 由于是非事务表,有时候也可能出现原表和索引表的数据不同步。

2. 就像上文所说,Phoenix是有可能在很短暂的时间里数据和索引不一致的,但是这是一个很短的过程,一般来说不会有影响。

3. HBase保证了每一个数据行或索引行都保证要么写入,要么丢失,你不可能看到一条数据有部分列写入而部分列没有写入。

4. 数据是先入HBase原表,然后再插入索引表。

为了保证易变的表和索引同步,Phoenix主要提供三种级别:

1. 如果不一致,禁止原表写入

这是最高级别的一致性级别,需要也别设置。当索引表更新出错的时候,原表会暂时禁用,不能写或更新数据。这个时候索引会自动重建,等索引和原表同步后,索引和原表才能恢复使用。

主要有两个配置项配置在服务端:

  • phoenix.index.failure.block.write:是否禁止原表的写入,这个需要设置成true,不然索引的重建追不上原表数据的增加。
  • phoenix.index.failure.handling.rebuild:默认true,在索引表出错后,是否自动启动后台任务,重建索引。

2. 如果不一致,禁用索引表

这是Phoenix的默认级别。如果写入索引表失败,索引表会标记成失效并且禁用索引,然后启动后台任务重建部分索引,等到完成之后再次激活索引。这种级别下,索引的失效和重建不会影响HBase原表的操作,只是在查询的时候索引不能使用了。

主要有二个服务端配置项:

  • phoenix.index.failure.handling.rebuild:默认是true,是否在索引操作失败后自动后台重建索引。
  • phoenix.index.failure.handling.rebuild.interval:检测是否要部分重建索引的时间间隔,多少毫秒检测一次。默认值是:10000,也就是10秒。

3. 如果不一致,需要人工重建索引

这是最低级别的同步策略。如果写入索引失败,Phoenix不会自动重建,而是需要人工命令重建索引。

服务端配置如下:

  • phoenix.index.failure.handling.rebuild:需要设置成false,不自动重建。

索引重建

Phoenix的索引重建是把索引表清空后重新装配数据。入上文所说,重建有可能是某个操作失败后系统后台自动的行为,也可以是人工来重建。人工重建的语法如下:

alter index index1_local on hao1 rebuild;

索引性能调优

一般来说,索引已经很快了,不需要特别的优化。这里也提供了一些方法,让你在面对特定的环境和负载的时候可以进行一些调优。下面的这些需要在hbase-site.xml文件中设置,针对所有的服务器。

1. index.builder.threads.max
创建索引时,使用的最大线程数。

默认值: 10。

2. index.builder.threads.keepalivetime

创建索引的创建线程池中线程的存活时间,单位:秒。

默认值: 60

3. index.writer.threads.max

写索引表数据的写线程池的最大线程数。

更新索引表可以用的最大线程数,也就是同时可以更新多少张索引表,数量最好和索引表的数量一致。

默认值: 10

4. index.writer.threads.keepalivetime

索引写线程池中,线程的存活时间,单位:秒。

默认值:60

5. hbase.htable.threads.max

每一张索引表可用于写的线程数。

默认值: 2,147,483,647

6. hbase.htable.threads.keepalivetime

索引表线程池中线程的存活时间,单位:秒。

默认值: 60

7. index.tablefactory.cache.size

允许缓存的索引表的数量。

增加此值,可以在写索引表时不用每次都去重复的创建htable,这个值越大,内存消耗越多。

默认值: 10

8. org.apache.phoenix.regionserver.index.handler.count

处理全局索引写请求时,可以使用的线程数。

默认值: 30

Phoenix系列:二级索引(2)的更多相关文章

  1. Phoneix(三)HBase集成Phoenix创建二级索引

    一.Hbase集成Phoneix 1.下载 在官网http://www.apache.org/dyn/closer.lua/phoenix/中选择提供的镜像站点中下载与安装的HBase版本对应的版本. ...

  2. phoenix创建二级索引

    create table user (id varchar primary key, firstname varchar, lastname varchar); create index user_i ...

  3. [Phoenix] 五、二级索引

    摘要: 目前HBASE只有基于字典序的主键索引,对于非主键过滤条件的查询都会变成扫全表操作,为了解决这个问题Phoenix引入了二级索引功能.然而此二级索引又有别于传统关系型数据库的二级索引,本文将详 ...

  4. phoenix中添加二级索引

    Phoenix创建Hbase二级索引 官方文档 1. 配置Hbase支持Phoenix创建二级索引   1.  添加如下配置到Hbase的Hregionserver节点的hbase-site.xml  ...

  5. 「从零单排HBase 12」HBase二级索引Phoenix使用与最佳实践

    Phoenix是构建在HBase上的一个SQL层,能让我们用标准的JDBC APIs对HBase数据进行增删改查,构建二级索引.当然,开源产品嘛,自然需要注意“避坑”啦,阿丸会把使用方式和最佳实践都告 ...

  6. Apache Phoenix系列 | 从入门到精通(转载)

    原文地址:https://cloud.tencent.com/developer/article/1498057 来源: 云栖社区 作者: 瑾谦 By 大数据技术与架构 文章简介:Phoenix是一个 ...

  7. Phoenix系列:二级索引(1)

    Phoenix使用HBase作为后端存储,对于HBase来说,我们通常使用字典序的RowKey来快速访问数据,除此之外,也可以使用自定义的Filter来搜索数据,但是它是基于全表扫描的.而Phoeni ...

  8. HBase的二级索引,以及phoenix的安装(需再做一次)

    一:HBase的二级索引 1.讲解 uid+ts 11111_20161126111111:查询某一uid的某一个时间段内的数据 查询某一时间段内所有用户的数据:按照时间 索引表 rowkey:ts+ ...

  9. Phoenix二级索引(Secondary Indexing)的使用

    摘要 HBase只提供了一个基于字典排序的主键索引,在查询中你只能通过行键查询或扫描全表来获取数据,使用Phoenix提供的二级索引,可以避免在查询数据时全表扫描,提高查过性能,提升查询效率   测试 ...

随机推荐

  1. python测试开发django-44.xadmin自定义菜单项

    前言 xadmin后台的菜单项是放到一个app下的,并且里面的排序是按字母a-z排序,有时候我们需要划分多个项,需要自定义菜单列表,可以通过重写CommAdminView类实现. xadmin后台提供 ...

  2. C#SpinWait和volatile一点温习

    今天看ConcurrentQueue<T> 源码发现里面居然没有用到lock,我记得ConcurrentDictionary里面是有lock的,lock的是字典里面每一个key,但是Con ...

  3. (转)Unity3D - 动作动画忽略timeScale

    转自:http://blog.csdn.net/ynnmnm/article/details/46866347 最近在调战斗时的动画与特效,Unity3D对加/减速提供了Time.timeScale支 ...

  4. MySql之触发器的使用

    一:触发器的使用场景 当数据库的记录发生变化时,自动触发某些操作. MySQL的触发器响应三种操作,六种场合: 三种操作:DELETE.INSERT.UPDATE. 六种场合:三种操作的BEFORE. ...

  5. java的impl

    java impl 是一个资源包,用来存放java文件的. 在Java开发中,通常将后台分成几层,常见的是三层mvc:model.view.controller,模型视图控制层三层,而impl通常处于 ...

  6. javascript中return function与return function()的区别

    参考https://stackoverflow.com/questions/7629891/functions-that-return-a-function-javascript 问题:唯一的区别是r ...

  7. 保持APP后台NSTimer运行

    [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil]; self.timer = [NSTi ...

  8. 海量数据拆分到nosql系统的一种方案

    获取某用户的好友最新动态. 我们大体上来说先按照用户ID将用户的好友一致性哈希到几个mongodb集群,然后把用户的最新信息也存储到mongodb中.然后利用消息系统保持数据库中的数据和mongdb中 ...

  9. Android 使用WebView加载含有Canvas的页面截屏处理

    无法截屏主要原因是webview渲染方式所导致:只需要AndroidManifest.xml中设置属性Android:hardwareAccelerated=”false”.

  10. 适合初学者的python实际例子

    最近在github上发现了一个有意思的项目,很适合初学者学习python代码. 学习一门语言刚开始的时候是很枯燥的,各种概念语法以及无聊的打印都会让人失去更进一步学习的动力. 很多同学在学习了一段时间 ...