面对海量数据复杂查询场景,目前的主流选择是HBase搭配ElasticSearch或者直接用ElasitcSearch实现,本文提出一个新的解决方案,基于HBase实现更加轻量,无需增加硬件投入,我们将这个核心组件命名为Pharos(灯塔)。

自研背景可插拔的HBase索引组件

NoSQL兴起无疑是大数据时代的标志性事件,创新者们不断打破关系型数据库“一种存储模式解决所有问题”的思路,发明了很多不同的产品应对细分的数据访问模式,它们提供了更好的服务特性,比如低延时、高并发等等。HBase是其中极具代表性的产品,作为Hadoop生态体系的明星产品,时至今日已在很多企业得到广泛应用。

NoSQL这种为特定的数据使用模式设计存储系统的思路,收获了性能的大幅提升,但随着存储数据量的激增,对解决方案整体性价比的满意度却在不断走低。毕竟,相较几个TB和数百TB,存储成本对用户的冲击力是不同的,人们总是不满于线性增长的成本,希望能花更少的钱做更多的事。

通过适度拓展数据访问模式提升性价比,成为业内很多技术方案追求的目标。

光大银行是金融行业中较早引入HBase的,经过若干年建设已经积累了大量数据。如果仅是为了满足不同条件的查询,就copy一个同等规模的集群,是各方都难以接受的。

HBase作为一种KV数据库,数据访问模式以主键为核心,当面对非主键查询时,其原生解决方案Filter无法满足大多数联机应用的性能需求。所以,很多基于HBase的二级索引方案都在尝试应对复杂查询场景的需求。

Pharos是基于HBase的技术中间件,研究起点同样是二级索引,致力于提升多条件复杂查询的性能,应用在海量数据低延时复杂查询场景。

构建思路三种二级索引方案的选型与分析

在启动研发工作前,我们对现存的二级索引方案进行了分析,除原生Filter外大致可以分为三种。

Elastic Search + HBase

这个方案流行度最高,在ES中存储索引信息,HBase存储数据本身,两者协同完成索引查询。方案的优点是组合成熟产品,实施难度低;但缺点也有很多,首先是整体架构复杂、设备投入增加、运维成本高;其次是性能相对较低,每一次索引查询,都要先访问ES获得匹配的索引后,再访问HBase读取数据内容,查询链路延长,带来更多的网络开销;最后是开发技能要求较高,程序员必须熟悉ES和HBase两种产品接口。

Phoenix

Phoenix无疑是一款优秀的开源产品,产品的理念是Put the SQL back in NoSQL。产品成熟,Apache社区背书,都是该方案的优势。

但因为目标高远,Phoenix的体量也偏重,这样在没有商业厂商支持下,运维难度很高(2019年Cloudera宣布支持Phoenix后,可能会有所改善)。第二点,对SQL的支持成为它的核心目标,但在很多查询场景中,SQL并非不可替代,高性能才是首要目标,性能却是Phoenix尚待改进的地方。Phoenix在整体机制上,并没有实现完善的索引下推,很多情况下索引查询需要从客户端发起两次与服务端的交互,第一次获得匹配的索引信息,第二次才是匹配的数据,这无疑带来了性能损耗。

云厂商方案

在云计算时代,HBase已经成为云服务的标配,部分公有云也提供了二级索引功能。这个方案的优点当然是厂商的一站式服务,运维成本极低。缺点首先是部分企业因为安全因素无法使用公有云,例如金融行业;其次在于技术方案本身,例如阿里的HBase二级索引,其内核依然是Elastic与HBase的组合,虽然接口上进行封装降低了开发难度,但架构带来的性能损耗依旧存在。

通过上述的分析,我们发现这些方案都不能满足光大银行的应用场景,因此我们决定自研产品。

我们将产品命名为Pharos,源自英文单词 [Pharos],其含义是灯塔。这个名称有两层含义:

  • 第一层是词义本身,灯塔对夜行的船只进行指引保证其安全地出入港口。而索引指向符合条件的数据地址,用于提升每次查数据访问操作的效率,两者有神似之处;

  • 第二层含义,Pharos最初是指代亚历山大灯塔,这也是世界上第一座灯塔。而Pharos是光大银行首次尝试自研基础产品,我们希望这个命名能够激励团队,做出有开创意义的产品。

设计目标低延时,架构简单,非侵入性

在Pharos设计目标中最重要的有三点:

  1. 低延时:我们希望未来Pharos的应用场景不仅限于数据查询分析,也能够嵌入到业务交易系统中,这样低延时就是一个刚性需求;

  2. 架构简单:这样开发人员可以很容易上手使用,而运维的成本也很低;

  3. 非侵入性:是指对HBase的侵入,事实上除了前述分析的二级索引方案外,还有一些小众的二级索引方案是直接对HBase进行改造,但这种侵入式改造带来了后续的版本维护问题,考虑到多数企业不可能维护独立的HBase版本分支,我们的方案直接排除了这种技术路线,必须是对HBase非侵入的。

Pharos的研发是从2018年开始的,相对于目前的产品成熟度来说研发过程显得有点长,主要原因是开发人力投入相对较小。我们希望随着产品的应用推广,能扩充人员,加快产品的演进速度。

研发过程,我们受到了很多同类产品的启发,包括Phoenix、华为与360等公司的二级索引方案,也借鉴了很多好的设计方法,这里要特别致敬一下。

设计要点四大关键设计的权衡

前面讲了Pharos的外部特性,接下来我会着重讲一些关键设计时的tradeoff,希望对大家的研发工作有所帮助。

存储策略

HBase是没有索引概念的,我们首先要解决的是如何存储索引。

Pharos采用的方式是在数据表增加一个“独立列族”用于存储索引信息,利用列族对应独立文件的特点,形成独立的索引文件,不会直接受到原始数据量的影响,降低磁盘I/O开销。这个设计另一个好处在于,索引与数据同分布,不必干预HBase的Region分布策略。后续的所有设计都是在同Region基础上,这大大简化了实现的复杂度。

这种索引与数据同分布的模式,可以简称为“分区索引”;而索引与数据各自存储的方式,则成为“全局索引”。“全局索引”的缺点在于无法完成索引查询的下推,优点是可以进行全局控制,例如唯一索引。选择“分区索引”是因为我们期望实现低延时目标,当然同时也就放弃了对“唯一索引”的支持,至少目前是不支持的。

存储模型

索引记录的Key部分,最开始是Region头信息,保证与数据的同分布,而后是被索引字段的信息,接下来是存储索引名称等信息,数据记录的Key则被拼接为尾部信息;value部分则存储反序列化的元数据。

可以看到,这样设计的优点是索引检索速度快,存储成本也比较小。所以,当查询条件较复杂需要建立多个索引时,整体存储成本依然是可接受的。

分页机制

传统的后台分页方法是由应用服务记录每页的末尾记录主键,这个主键通常是由数据库提供的row number,数据库本身并不感知分页动作。对于分布式存储的HBase,每个Region都可能存在分页断点,如果延续该思路,应用端要记录大量断点信息,不仅增加传输数据量,也增大了开发的难度。在Pharos的设计中,我们通过Client作为汇聚点,缓存每个Region的断点信息,在Pharos的Client中增加Session概念,应用端仅需持有Session ID即可顺利完成翻页操作。

索引与数据的事务一致性(实验版本)

根据Pharos的存储设计,我们可以知道索引实质上是与数据行前缀相同的另一行记录,保证索引与数据的一致性要使用跨行事务,但HBase本身不支持跨表、跨行事务,这就成为一个死结,也是几乎所有二级索引方案都不支持索引事务一致性的原因。

这个问题的解决比较复杂,所以我们先简单介绍下HBase内部机制。HBase采用LSM-Tree模型,在联机写入时,数据在日志和内存中各保留一份,两者通过MVCC与日志的协调机制可以保证事务一致性。我画了一张图来表示HBase 1.2.6的事务控制逻辑,具体如下:

HBase内部会监控WAL的异常,但在Coprocessor事件体系中并未开“回滚标志位”,第三方开发者也就无法回滚相关数据行。

按说,到这里问题已经无解了,不过某天恰好受到了Percolator事务模型的启发,找到了另一种解决问题的思路。既然无法在写入过程通过回滚控制异常情况,那我们可以延后在读取过程中来补充对异常的操作,也就是说在下一次查询操作中再次确认并维护索引的一致性。

具体处理过程是,在首次写入索引信息时,置事务标志位为“不确定”,数据行更新完成后,将该标志改为“成功”;如果出现回滚,则标志位保留“不确定”状态。查询操作中一旦发现“不确定”标志,则根据索引查找相应的数据行是否存在,如存在,则将该标志更新为“成功”。

我们用流程图来体现处理过程,如下图:

该方式付出的代价是写入时需要两次更新事务标志,相对于仅写入数据行(无索引)肯定增加了一些开销,在测试环境下我们发现损耗在15%左右,主要是指延时;在查询环节虽然存在确认索引事务的可能性,但因为其发生的概率极低,不会对查询产生实质性影响。

未来展望彻底解决Region分裂问题

目前Pharos主要还是在内部使用场景中测试,收集需求和问题,近期我们会发布V0.3版本。新版本会推出一些让人激动的特性,主要仍是围绕查询性能的提升,推出Pharos自有的数据组织形式,提供更加丰富的查询加速手段,完成从二级索引组件到一个完整的技术中间件的演进。

其中,特别重要的一点是彻底解决了Region分裂问题,我要迫不及待地做个剧透。

Region分裂是HBase数据再平衡的手段,保证每个数据节点上的数据量分布大致平均,也会有一些打散热点的效果。但是,分裂机制却破坏了索引与数据的同分布,在同类方案中通常采用很重的更新操作来调整索引的位置,追随数据的分布情况。

这种方式显得过于笨拙,并且更新过程会影响整体方案的可用性。因此,Pharos在V0.22版本中是建议索引延后加载,这样在数据更新导致的重分布完成后再更新索引。

实际操作中,这种方式要重复读取数据文件,延长了整体数据加载周期,对运维操作来说不够友好。在V0.3中,我们加入了Pharos自有的数据组织方式,实现在Region分裂时维持索引的同分布效果。

考虑到篇幅的限制,就介绍到这里。几个月后,我会择机与大家分享在新版本的改进,使用了更多独创性的方法,敬请期待。

hbase 查询_不用ES也能海量数据复杂查询秒回相关推荐

  1. 类型的值怎么用es查询_腾讯游戏信用分怎么查询在哪看 有什么用怎么提升介绍...

    腾讯游戏信用分查询方法是很多小伙伴们都不知道的,在腾讯游戏中腾讯信用分是极其重要的,那么各位小伙伴们知道腾讯信用分怎么查吗?相信还有很多小伙伴不太清楚,那么接下来和大家一起分享一下腾讯游戏信用分查询方 ...

  2. mongodb cond 模糊查询_为了实现在线库的复杂查询,你还在双写吗?

    一.在线库不支持在线复杂查询 做在线业务的开发者经常会碰到这样的难题:在线数据库上面运行稍微复杂点的查询,在线业务就挂了!不管是单机数据库如MySQL.PG,还是分布式数据库,HBase.MongoD ...

  3. .net函数查询_特来电智能分析平台动态查询架构创新实践

    一.业务背景及痛点 目前主流互联网智能分析平台中,数据查询作为基础的设施服务支撑着基础数据及业务分析的功能展现.随着数据量的增长,数据存储方式多元化,相对静态数据可能存储到关系型数据库中,订单类动态数 ...

  4. mysql水果表查询_最全MySQL数据库表的查询操作

    序言 本节比较重要,对数据表数据进行查询操作,其中可能大家不熟悉的就对于INNER JOIN(内连接).LEFT JOIN(左连接).RIGHT JOIN(右连接)等一些复杂查询. 通过本节的学习,可 ...

  5. java多线程查询_利用Java函数式接口处理多线程查询

    Java函数式接口 有且只有一个抽象方法的接口被称为函数式接口. @FunctionalInterface注解: 该注解可用于一个接口的定义上, 一旦使用该注解来定义接口, 编译器将会强制检查该接口是 ...

  6. from server sql 拼接统计两个子查询_[SQL SERVER系列]之嵌套子查询和相关子查询

    子查询有两种类型,一种是只返回一个单值的子查询,这时它可以用在一个单值可以使用的地方,这时子查询可以看作是一个拥有返回值的函数:另外一种是返回一列值的子查询,这时子查询可以看作是一个在内存中临时存在的 ...

  7. 高性能mysql 小查询_高性能MySQL06-查询优化(慢查询)

    一.分析原因 SQL语句慢查询的原因有多种,如: 1)数据方面: 需要查询的表数据量太大导致性能下降: 是否向数据库请求了不需要的数据行或数据列: MySQL是否在扫描额外的记录 2)SQL语句太过于 ...

  8. mysql怎么子查询_在mysql中如何进行子查询?

    在mysql中,子查询是指将一个查询语句嵌套在另一个查询语句中,可以在SELECT.UPDATE和 DELETE语句中配合WHERE子句进行实现,WHERE子句中语法格式为"WHERE (另 ...

  9. sql镶嵌查询_超实用的SQL语句之嵌套查询

    嵌套查询 什么是嵌套查询. 嵌套查询的意思是,一个查询语句(select-from-where)查询语句块可以嵌套在另外一个查询块的where子句中,称为嵌套查询.其中外层查询也称为父查询,主查询.内 ...

最新文章

  1. softmax(a,axis=0)的用法理解 总结
  2. 爱python网_Python
  3. python观察日志(part21)--ord,chr,unichr方法的联系与区别
  4. 服务器网口和虚拟服务器网口配置,Apache服务器使用不同端口配置多个虚拟主机站点...
  5. 查看Oracle有哪些表或者视图
  6. 历史的天空-【1】配置
  7. hive:函数:自定义函数(笔记)
  8. 06.ESP8266驱动OLED屏
  9. 全年DDoS攻击分析|知道创宇云安全2018年度网络安全态势报告
  10. outlook服务器拒绝访问文件夹,无法打开共享日历文件夹 - Outlook | Microsoft Docs
  11. 判断虚拟键盘是删除键的方法
  12. python报错Ran out of input
  13. 结构型设计模式(七种)
  14. 计算机网络实验——路由器基本配置
  15. Revit二次开发_修改快捷键
  16. 在文件夹及其子文件夹内,批量提取相同后缀名的文件
  17. 计算机应用程序池在哪,win10系统iis修改站点的应用程序池权限的详细方案
  18. 数学运算中浓度问题解题技巧集锦
  19. 大型欧姆龙PLC NJ系列ST语言Ethercat总线24轴
  20. MySQL独立表空间的优缺点

热门文章

  1. C#写文本写Csv文件操作
  2. t3网络计算机浏览卡死,凭证一点打印 系统就卡死了 重启后还是这样
  3. jira confluence 作用 ppt_有没有一个PPT技巧让自己觉得人生都亮了?
  4. 界面无小事(六):来做个好看得侧拉菜单!
  5. 在通往VR内容的道路上,音乐将成为一项重要助力
  6. 代理服务器反向代理varnish配置文件解析
  7. 数组的几种定义方式及初始化
  8. 201409-3-字符串匹配
  9. 【iCore3应用】基于iCore3双核心板的编码器应用实例
  10. Linux链接文件、管道、重定向讲解