api 原生hbase_数据查询的玄铁剑:云HBase原生二级索引发布
HBase原生提供了主键索引,用户可以根据Rowkey进行高效的单行读、前缀匹配、范围查询操作。但若需要使用属性列进行查询时,则只能使用filter在查询范围内进行逐行过滤。在扫描范围较大时,会浪费大量的IO,请求RT也无法保证。为此,HBase增强版推出了原生二级索引来解决非Rowkey查询的性能问题。
云HBase增强版是基于阿里内部的HBase分支(亦称Lindorm)构建的,二级索引是其核心能力之一,历经多年双11大考,在性能、吞吐、稳定性等方面都具备核心竞争力。
下面,我们从一组示例出发来了解索引的使用及其能力。
功能简介
从表设计和查询设计的角度看,HBase增强版二级索引的使用与RDBMS的二级索引基本一致。下面我们看一个简单的示例:大学生信息表(Students),该表的主键(即rowkey)是学号,非主键是学生姓名和所属的学院名称。学生与学院是多对一的关系。
通过HBase shell建表,建索引:
https://help.aliyun.com/document_detail/119572.html
# 创建主表student,列族名为fcreate 'student', 'f'
# 创建索引表department,为department列建索引# COVERED_ALL_COLUMNS是HBase增强版引入的新属性关键字,# 意味冗余主表student中的所有列,以此来避免回查主表create_index 'department', 'student', {INDEXED_COLUMNS => ['f:departement']}, {COVERED_COLUMNS => ['COVERED_ALL_COLUMNS']}
通过Java API进行数据访问
// 定义一些常量String id = "11"; // 一个随机的学号String studentName = "Harry";String department = "CS";byte[] f = Bytes.toBytes("f");byte[] qStudent = Bytes.toBytes("name");byte[] qDepartment = Bytes.toBytes("department");
// 写入一个学生的数据Put put = new Put(Bytes.toBytes(id));put.addColumn(f, qStudent, Bytes.toBytes(studentName));put.addColumn(f, qDepartment, Bytes.toBytes(department));Table t = conn.getTable("student");t.put(put); // put成功返回意味着主表和索引表都成功更新,变更立即可见
// 按department进行查询Scan scan = new Scan();SingleColumnValueFilter where = new SingleColumnValueFilter( f, qDepartment, EQUAL, Bytes.toBytes(department));scan.setFilter(where);ResultScanner rs = t.getScanner(scan);// 处理查询结果...
从上例可见,用HBase API直接描述查询请求即可使用索引。HBase增强版会自动根据filter以及索引schema来匹配到最合适的索引进行查询,必要时,在查完索引后也会回查主表(上例中,如果不是全冗余索引,则会回查主表来补全列)。更多使用上的说明请参考二级索引开发手册:
https://help.aliyun.com/document_detail/144577.html
HBase增强版二级索引的主要特性有:
支持为单个主表建多个索引
支持单列和多列索引(组合索引)
支持冗余索引:可显式指定冗余列,或冗余所有列,避免回查主表的性能损耗
查询优化:根据scan和filter自动选择合适的索引表进行查询,必要时会自动回查主表
online schema change:支持给已经在使用的表建索引,对主表读写无影响
支持TTL:索引表会自动继承主表的TTL,主表和索引表数据一起过期
支持自定义数据版本:用户自定义数据时间戳写入(暂未开放)
产品优势
高性能
HBase增强版二级索引直接内置于内核中,并做了深度优化,提供了强大的吞吐与性能。下图是HBase增强版二级索引与Apache Phoenix的全局索引的性能对比:
从上图可见,无论RT还是吞吐,HBase增强版二级索引均远超Apache Phoenix。
写后可读
数据写入返回成功后,则索引数据可立即被读到,消除传统异步建索引方案中的数据延迟,提供具有一定程度的强一致性语义(主表和索引表的数据一致性),具体语义如下:
返回客户端写入成功,之后可立即读到刚写入的数据(包括主表和索引数据);写入过程中不保证同时可见
返回超时或IO出错,则在一段时间内,该数据在主表和索引表中的可见性无法确定,但保证最终一致,即要么全成功,要么全不成功
HBase增强版提供的”写成功后更新立即可见的语义“,可用于一些分布式协同的任务,比如spark,在某些节点更新数据,另外一些节点读取上一轮计算写入的数据。此时,一定可以读到刚写入的数据。
全冗余索引
全冗余索引可彻底避免回查主表,提升性能;同时也是语法糖,避免手工维护复杂的DDL。下面分别介绍。
如果查询中需要的列在索引表中没有,则查完索引后,还需回查主表。在分布式场景下,回表查询会使得查询RT大幅度升高,最差情况下可能会回查主表的全部region,访问集群中的所有机器。此时,索引带来的性能收益已经可有可无。通过精良的查询设计和索引设计,我们可以在设计阶段避免回查,但随着业务发展变化,这个约束很难维持。因此,仍然需要冗余索引(Covered Index)来解决。
HBase增强版创造性的引入了全冗余索引的概念,即冗余主表中的所有列,以此来彻底避免回查主表。配合HBase的schema-free特性,主表中新增的任何列都会自动冗余到索引表中。无论业务模式如何变化,都不需要回查主表。
同时,全冗余也是可大幅度提升效率的语法糖,我们可以对比如下两个SQL语句:
CREATE INDEX idx ON dt (c1, c2) include(c3, c4, c5, c6, ....);CREATE INDEX idx ON dt (c1, c2) include(ALL);
对于大部分业务来说,表里有数十列是常态,个别表可能会有数百列。如果为了建冗余索引,而把这数百列的列名再写一遍,无疑是巨大的负担(只能写工具自动化做,人来做太容易出错)。全冗余索引的新语法给人工维护DDL提供了可能。
为了获得上述两点收益,全冗余索引的代价是会占用更多存储空间。配合HBase增强版深度优化的ZStandard压缩算法:
https://help.aliyun.com/document_detail/119549.html
可有效降低冗余带来存储开销。冷热分离特性亦可应用于索引表,进一步控制成本。
基于原生API的查询优化
对大部分场景来说,业务一行代码不改就能用上索引。
从本文开头的示例代码中可见:
写:写主表即可,会自动同步到索引,强一致。用户无需担心索引更新的问题
读:基于主表进行查询,直接按业务逻辑进行查询表达,系统自动选择合适的索引表进行查询
这样,用户只需为那些性能不好的查询设计并添加索引,即可从索引特性中受益,实际的数据读写代码一般不需要修改。同时,既有的HBase生态相关的产品,都可以无缝使用上索引。一些如Spring的框架软件也可帮助用户获得业务上的灵活性。
大表建索引
从一开始就设计好主表和全部索引几乎是不可能的。因此,在后续业务发展过程中,索引表可能需要不断的删除和新增。为此,对一个已经有大量数据表添加、删除索引,将是一个关键的运维操作。HBase增强版二级索引针对此场景做了特别的优化:
schema在线修改:索引的变更不影响主表的正常读写(就像一次普通的alter表操作),不影响其他索引表
服务端rebuild:在服务端为主表的历史数据构建索引
支持对超大主表添加索引:支持TB级别的主表添加新索引
流控:大主表的索引rebuild会消耗大量的系统资源,因此,精准的流控即可在兼顾索引构建速度的前提下,保障系统整体性能不会被影响
在有上述特性的加持下,索引变更的运维成本和风险大大降低,从容的适应业务发展。
原理简介
HBase增强版二级索引是一种全局二级索引,每个索引表都是一张独立的HBase表。每张表的主键(rowkey)设计决定了其能支持的查询模式。当同一份数据有多种rowkey组织时,就能支持多种查询模式。这里,主表和它的索引表,可以看做是同一份数据的不同组织形式,各自能够高效的支持一定的查询模式。
考虑本文开始时给出的学生信息表的示例:
主表Student:以学号(id)为主键(rowkey),每行有两列,学生姓名(name)和所属的学院(department)。该设计仅支持按id进行查询。如果用户要按department或者name来查询,需要全表扫描 + filter。在学生数较少时,这种暴力扫描完全可行。但在数据量大时(数十万乃至上亿时),这种操作是无法执行的。
为了高效的支持按department查询,可为其建立一个全冗余索引(使用HBase shell):
create_index 'department', 'student', {INDEXED_COLUMNS => ['f:departement']}, {COVERED_COLUMNS => ['COVERED_ALL_COLUMNS']}
在建索引时,系统会自动为主表中的存量数据构建索引,写入索引表中。主表行和索引行是一一对应的。之后主表上发生的数据更新,也会自动同步给索引表。
考虑如下查询:
-- 查找所有计算机学院(cs)的学生的姓名(name)select name from student where department = 'cs';
这个查询会直接命中索引表,按department列进行前缀匹配。从每一个索引行中提取name字段,返回给客户端。
如果我们没有建立冗余索引,则索引表中不会存在name列。此时,在从索引表中读取到学号(id)后,必须回查主表(三次按id的单行读)来读取name列。在分布式场景下,10/12/13这三个id的数据可能分布在三台机器上。因此,回查主表最差情况下需要3次RPC,加上查索引表的一次RPC,共需4次RPC。而如果是冗余索引,则只需查索引表的一次RPC即可。
因此,在分布式场景,尤其是节点很多的大集群,回查主表带来的性能损耗是巨大的(RT可能会增长数倍)。这也是我们设计全冗余索引的初衷:避免回查,提高性能。
总结
数据只有被查询才能创造价值,HBase原生高性能二级索引为多维度查询提供了一种有效的解决方案。在表设计上,用户可以参考MySQL等关系型数据库的索引设计思路来进行HBase的索引设计。业务无需更改代码,查询优化可自动进行索引表的选择。强一致、全冗余索引等特性也有效降低了业务的使用门槛。
未来,我们将对索引做进一步的优化和扩展,提供优质的用户体验。欢迎大家体验HBase增强版。如您有对HBase相关的任何问题,欢迎通过钉钉与我们联系(钉钉搜索“云HBase值班”)。
相关链接
HBase Java SDK
https://help.aliyun.com/document_detail/119568.html
HBase增强版Shell
https://help.aliyun.com/document_detail/119572.html
二级索引帮助文档
https://help.aliyun.com/document_detail/144577.html
HBase 官方社区推荐必读好文
HBase 原理|HBase 内存管理之 MemStore 进化论
HBase 抗战总结|阿里巴巴 HBase 高可用8年抗战回忆录
HBase 实践|说好不哭,但 HBase 2.0 真的好用到哭
↓扫码关注 HBase 技术社区公众号↓
api 原生hbase_数据查询的玄铁剑:云HBase原生二级索引发布相关推荐
- 1.php查询数据,数据查询 · thinkphp5 · 看云
# **Query** **查询一个数据** find 方法返回数组,查询结果不存在,返回 null ~~~ // table方法必须指定完整的数据表名 \think\Db::table('think ...
- 通过聚合数据API实现快递数据查询-短信验证码-企业核名
有位朋友让我给他新开的网站帮忙做几个小功能,如下: 输入快递公司.快递单号,查询出这个快件的所有动态(从哪里出发,到了哪里) 在注册.登录等场景下的手机验证码(要求有一定的防刷策略) 通过输入公司名的 ...
- 城市空气质量api 空气质量数据查询实现
现在人们越来越关注空气质量,在app中集成空气质量查询可以满足人们的查询需要,本次提供的城市空气质量api是集成了城市空气质量.城市空气PM2.5指数.城市辐射指数的应用数据接口,非常全面可靠. 接口 ...
- 数据 3 分钟 | 阿里云数据库 2020 技术年报发布、TiDB 开启 Hacking Camp、达梦云数据库免费体验...
数据 3 分钟 由 ACDU (中国 DBA 联盟) 与墨天轮联合出品的全新视频节目上线啦-三分钟带你来了解数据行业动态,节目内容主要包含数据行业最新的产品发布.公司大事件.行业新闻等.每周五更新,不 ...
- Hbase Solr 二级索引,更新数据部分字段丢失问题
问题: 第一次往hbase put数据,索引同步三个字段,第二次更新hbase数据,只更新一个字段,其他两个字段会消失. 原因: 在创建Hbase Indexer 时我们配置文件指定了 read-r ...
- 云原生大数据架构中实时计算维表和结果表的选型实践
简介: 随着互联网技术的日渐发展.数据规模的扩大与复杂的需求场景的产生,传统的大数据架构无法承载. 作者 | 志羽 来源 | 阿里技术公众号 一 前言 传统的大数据技术起源于 Google 三架马车 ...
- Prometheus:Java调用PromQL工具类(瞬时数据查询)
目录 PostMan瞬时数据查询:Windows主机空闲内存量 请求 响应数据 Java:调用PromQL工具类(瞬时数据查询) Prometheus返回结果反序列化 Prometheus常用Prom ...
- 大数据查询分析引擎比较
1.常见方案比较 首先,Hive/SparkSQL 在数据仓库的领域应用是比较广泛的,但是因为查询时延很难能够满足毫秒到秒级的要求,同时因为是离线计算,数据时效性也比较差. 其次,ES (Elasti ...
- 阿里云HBase增强版全文索引功能技术解析
新用户9.9元即可使用6个月云数据库HBase,更有低至1元包年的入门规格供广大HBase爱好者学习研究,更多内容请参考链接 阿里云HBase增强版(Lindorm)简介 阿里云数据库HBase增强版 ...
最新文章
- 【面试招聘】如何写出发光的简历|附10个模版
- mysql 多表查询 优化_Mysql 多表联合查询效率分析及优化
- php 开启mail函数 wo,php mail 函数发送邮件
- JVM系列之:对象的锁状态和同步
- 交换机putty怎么调试_使用在300和500系列托管型交换机的一个控制台连接通过PuTTY访问CLI...
- MLOG_CHECKPOINT缺失下紧急数据恢复
- 关于 错误 137 (net::ERR_NAME_RESOLUTION_FAILED) 的解决方案
- jQuery-实例方法
- Linux下分割、合并文件——dd和cat
- Word2007发布文章成功
- Vue-Treeselect三级动态加载
- presscad排样lisp_PRESSCAD统赢使用技巧(二)
- ElasticSearch搜索引擎搭建笔记
- es6 混合commjs_嵌入式JavaScript引擎 – mjs
- c#基础知识学习——枚举、元组(四)
- 32个c语言关键字发音,加注汉语发音的C语言32个语句和9种控制语
- python测试用例发送邮件用谷歌浏览器的方式
- Redis Cluster 集群管理维护
- 关于一些老手机打不开公司小程序,页面是一块白板,报错【系统繁忙,请稍后再试】。
- 解密NFT区块链游戏和收藏品市场
热门文章
- ping命令linux软件包,linux下安装 ping 命令
- mysql 批量替换域名_msyql 中批量替换url网址中的域名方案。
- cuid卡写入后锁死_CUID卡,CUID白卡,CUID门禁卡,CUID电梯卡,CUID可改写卡
- linux fdisk 权限不够,Linux 文件系统结构、磁盘的管理
- oracle mysql 线程数_oracle线程数更改
- ArcGis中这些你真的清楚么
- java 调度框架_java调度框架Quartz(一)
- matlab ascii 异或,GPS数据包的ASCII异或校验和计算方法(VC++)
- php可以更改html后缀名嘛,请问你们怎么将html的文件的内容改变为php
- java输入年月输出日历_12月营销热点日历 | 2020年创意冲刺倒计时!