阿里云HBase SQL服务简介

云HBase2.0是阿里云对社区HBase2.0的深度定制,在内核层面做了大量优化升级,并提供全球多活、备份恢复、冷存储等企业级特性,目前已被广泛应用于车联网、社交、推荐、画像等场景。阿里云HBase SQL基于Phoenix 5.0版本,为云HBase2.0赋予NewSQL特性,降低KV接口使用复杂性,并提供Schema、Secondary Indexes、View 、Bulk Loading(离线大规模load数据)、Atomic Upsert、Salted Tables、Dynamic Columns、Skip Scan等特性的能力,大大降低了用户的使用门槛,关于更多Phoenix的介绍参考“HBase进化之从NoSQL到NewSQL,凤凰涅槃成就Phoenix”:

https://yq.aliyun.com/articles/680772

阿里云HBase团队将SQL能力服务化,在产品、内核上做了一系列优化升级,笔者将在本文中对这些特性做深度解读。


HBase SQL服务化

HBase SQL服务如图所示,用户在阿里云HBase实例管理页面可以一键开通,并在界面进行配置、重启、升级,获取URL串之后直接可以访问。用户可以使用Java、Python、Go、C#开发应用程序访问SQL服务,也可以使用命令行工具直接访问SQL服务,详细使用说明,参考我们的文档“SQL服务使用文档”:

https://help.aliyun.com/document_detail/104059.html

使用过Phoenix的开发者都知道,Phoenix社区提供两种访问方式,重客户端和轻客户端,关于这两者之间的区别,参考“Phoenix客户端进化之由重到轻”:

https://yq.aliyun.com/articles/688631

除了将Phoenix服务化外,我们还做了一系列优化升级,既有对轻客户端的优化升级,也有对Phoenix Core本身的优化升级。


轻客户端优化

云HBase SQL团队针对社区Phoenix5.0版本进行深度测试,对轻客户端进行了一系列的优化和Bug Fix,并反馈给Phoenix和Avatica社区,推动社区共同发展。

1.轻客户端写性能优化
在对轻客户端的写入性能测试时,我们发现社区轻客户端的写入性能比直接使用重客户端慢2~3倍,主要原因正式由于轻客户端相比重客户端多了一层HTTP传输链路,因此在尽量不修改业务代码的前提下,如何减少请求次数是优化写性能的重点。
在业务代码中经常使用JDBC的PreparedStatement的executeUpdate进行写入,社区轻客户端在autoCommit为false时会将数据传输至QueryServer并缓存,在commit时将数据batch写入到HBase中。阿里云Phoenix修改executeUpdate执行逻辑,将数据缓存在客户端,commit时将批量数据发到QueryServer并直接写入HBase,在这一阶段减少了轻客户端到QueryServer的RPC请求次数,并避免缓存在QueryServer的数据在未提交前由于服务挂掉而丢失。优化后在代码写入性能提升了2倍多,与重客户端性能基本没有差距。

2.支持upsert multi values语法
原生Phoenix在写入时仅支持单次upsert一条数据的语法,这在对接MyBatis等不支持commit的框架时,每次写入一条数据并提交HBase性能上较差,为此阿里云Phoenix在SQL服务上支持单次upsert写入多值功能,语法示例:upsert into tableName(col1,col2,...) values (v11,v12,...),(v21,v22,...),...,(vn1,vn2,...)
在使用时注意:

  • 为避免列次序混乱,必须指定写入列

  • 写入数据其中一条失败导致整批数据写入失败

3.支持QueryServer线程池最大线程和HTTP传输参数可配
QueryServer使用Jetty做为HttpServer,在初始化时默认最大200个线程,在使用配置比较高的HBase集群时,往往由于处理线程数成为性能瓶颈,阿里云Phoenix修改了Avatica代码,通过增加配置方式使得线程数以及HTTP传输size大小等都可配,增加Phoenix使用的灵活性,具体配置及说明如下:

参数名描述
phoenix.queryserver.maximun.threadsQueryServer最大线程数,默认200
phoenix.queryserver.minimum.threadsQueryServer最小线程数,默认8
phoenix.queryserver.idle.timeout线程空闲超时时间,默认60s
phoenix.queryserver.maximum.header.sizeHTTP请求包头大小,默认65536byte

以上参数在云HBase控制台都可以进行修改,并重启HBase SQL服务后生效。

4.轻客户端Connection超时Reopen时设置参数丢失问题
轻客户端连接默认空闲10min会超时,下次使用时会进行重建,如果在超时前设置autoCommit、schema等连接属性会在reOpen时失效,这是社区avatica的一个bug,我们对此进行修复并贡献到社区,对应JIRA:

https://issues.apache.org/jira/browse/CALCITE-2882(贡献社区calcite-avatica 1.14.0版本)

5.轻客户端PrepareStatement预编译带有子查询/join语句时参数越界
在使用轻客户端PrepareStatement预编译SQL时会将Phoenix客户端的ParamMetaData同步到轻客户端的Connection,当SQL带有子查询或join语句时,Phoenix在实现上缺失了右表的Meta信息,导致出现参数越界的问题。
阿里云的Phoenix版本也对此进行修复,详细见JIRA:

https://issues.apache.org/jira/browse/PHOENIX-5192

6.轻客户端写入Array类型数据NPE
轻客户端写入Array类型数据时由于获取Array中子元素的类型默认处理为空,导致在写入时出现NPE。问题修复见JIRA:

https://issues.apache.org/jira/browse/CALCITE-2939(贡献社区calcite-avatica 1.14.0版本)


Phoenix Core优化与改进

我们对Phoenix Core做了大量稳定性、性能方面的优化和改进,提交了数十个patch给社区,团队的瑾谦同学也成为了Phoenix社区的Commiter。下面介绍几个比较有代表性的改进工作:

1.大表MetaCache缓存优化
Phoenix每次查询都需要使用表的所有Region信息,当表很大有上万个Region时,读取meta表的Region信息并缓存到客户端需要耗时几十秒,占用查询时间超过80%以上。阿里云Phoenix使用ZooKeeper订阅的方式,通过监控Region的状态变化,当Region发生balance/merge/split动作时,更新客户端缓存失效的Region信息,这样可以大大减少客户端因为Region元数据更新不及时导致的查询失败,同时显著提高查询性能。

优化效果:经过测试对一张大表查询时如果出现Region状态变化,查询时延由40s降低到5s左右。

2.使用Lookup Join提升大表的索引表回查性能
如果Phoenix二级索引不是覆盖索引,也就是说SELECT语句中的返回字段不在索引表中,那么在执行过程中会先查询索引表,获取RowKey,然后再用SemiJoin主表的方式获取最终结果。除了索引表本身的Scan开销外,还存在网络开销和SemiJoin本身的开销。我们采用Lookup Join的方式进行优化,在服务端scan索引表的时候,直接回查主表。经过测试,性能有大幅提高,500w数据量的查询,原有方式需要200s,而新的方式只需要10s,如果主表开启bloomfilter,性能还能进一步提高到5s左右。

3.使用MultiGet取代SkipScan
Phoenix在执行SemiJoin的时候会使用SkipScan的方式,该方式比较通用,scan的过程中会skip掉一定的读HFile开销,但是当SemiJoin的查询条件比较多并且比较分散时,就转变为了近似扫全表,这时性能就会下降严重,甚至超时。对于这种情况,我们采用了MultiGet的方式取代SkipScan会获得更好的性能。当用户对Primary Key做in查询时,可以通过添加“USE_GET”的hint使用该功能,可以支持10w级别的子查询结果。在查询条件比较多并且分散的情况,会有数量级的性能提升。

4.临时禁止掉存在风险的功能feature
社区Phoenix功能很多很全,但是某些功能存在一定缺陷,或者会引入风险,在确保功能完善可用之前,我们会选择将部分功能禁掉,以避免用户误用,导致错误。目前涉及到的功能有:

  • ColumnDef中的DESC关键字。对于可变长度类型,比如varchar、decimal,该功能可能范围查询结果返回错误。

  • 全表扫描。对于没有加查询条件的查询语句,可能会触发全表扫描,导致系统不稳定。

  • Local Index。由于社区反馈和我们在实际支持用户的过程中发现的Local Index问题较多,而且大部分二级索引的场景,Global Index已经足够使用,因此我们临时禁掉了Local Index的功能。

5.时区问题解决
社区Phoenix在时区处理上的逻辑会导致用户的不同用法,写入数据和查询结果不一致。详见文章“Phoenix关于时区的处理方式说明”:

https://yq.aliyun.com/articles/684390


总结展望

阿里云HBase团队在SQL服务上持续深耕,不断在稳定性、易用性、功能以及性能上继续增强优化,并不断反馈社区,积极推动Phoenx社区的发展。从HBase的架构上来看,相比于其他NoSQL存储引擎,其在数据规模,扩展性上具有明显优势。跟大数据其他组件,比如,搜索引擎、分析引擎、消息引擎,会更紧密的结合,SQL服务也会在这方面进行更多的探索,满足用户在实际使用过程中遇到的复杂查询、复杂分析等需求。在这里可以预告下,我们基于HBase和Solr双引擎,支持复杂查询的Phoenix Search Index功能即将上线。



©著作权归作者所有:来自51CTO博客作者mb5fdb0a6739180的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. HBase抗战总结|阿里巴巴HBase高可用8年抗战回忆录
  2. HBase服务|阿里云HBase推出普惠性高可用服务,独家支持用户的自建
  3. 中国唯一入选 Forrester 领导者象限,阿里云 Serverless 全球领先
  4. Phoenix兼容 | 深入探索Lindorm兼容PhoenixSQL背后的故事
  5. 阿里云_弹性公网IP地址(EIP)切换到新的ECS的方法
  6. 阿里1688运营智能化实践
  7. 阿里淘外商业化广告工程架构实践
  8. 视频 | 阿里文娱智能营销增益模型(uplift model)技术实践
  9. 阿里1688实时数据工程实践

随机推荐

  1. tensorflow 几个android demo源码环境搭
  2. 第七章 使用Intents与Phone Dialer——上
  3. adb安装及命令总结
  4. Android基础 : Android(安卓)Content Pro
  5. Android碎笔录2——按键的点击变色和圆角
  6. Android(安卓)从启动到程序运行发生的事
  7. Android(安卓)Studio使用Google Flutter
  8. Android(安卓)中SQLite技术实例详解
  9. android:如何从照片中获取拍摄地址信息
  10. Android之Activities