传统的 OLAP 系统在业务中往往扮演着比较静态的角色,以通过分析海量的数据得到业务的洞察(比如说预计算好的视图、模型等),从这些海量数据分析到的结果再通过另外一个系统提供在线数据服务(比如HBase、Redis、MySQL等)。这里的服务(Serving)和分析(Analytical)是个割裂的过程。与此不同的是,实际的业务决策过程往往是一个持续优化的在线过程。服务的过程会产生大量的新数据,我们需要对这些新数据进行复杂的分析。分析产生的洞察实时反馈到服务,让业务的决策更实时,从而创造更大的商业价值。
Hologres定位是一站式实时数仓,融合分析能力(Analytical)与在线服务(Serving)为一体,减少数据的割裂和移动。本文的内容将会针对Hologres的服务能力(核心为点查能力),介绍Hologres到底具备哪些服务能力,以及背后的实现原理。
通常我们所说的点查场景是指Key/Value查询的场景,广泛用于在线服务。由于点查场景的广泛需求,市场上存在多种KV数据库定位于支持高吞吐、低延时的点查场景,例如被大家广而熟知的HBase,它通过自定义的一套API来提供点查的能力,在许多业务场景都能够获得较好的效果。但是HBase在实际使用中也会存在一定的缺点,这也使得很多业务从HBase迁移至Hologres,主要有以下几点:
--建行存表BEGIN;CREATE TABLE public.holotest ( "a" text NOT NULL, "b" text NOT NULL, "c" text NOT NULL, "d" text NOT NULL, "e" text NOT NULL,PRIMARY KEY (a,b));CALL SET_TABLE_PROPERTY('public.holotest', 'orientation', 'row');CALL SET_TABLE_PROPERTY('public.holotest', 'time_to_live_in_seconds', '3153600000');COMMIT;-- Hologres通过SQL进行点查select * from table where pk = ?; -- 一次查询单个点select * from table where pk in (?, ?, ?, ?, ?); -- 一次查询多个点
正常情况下,一条SQL语句的执行,需要经过SQL Parser进行解析成AST(抽象语法树),再由Query Optimizer处理生成Plan(可执行计划),最终通过执行Plan拿到计算结果。而要想通过SQL做到高吞吐、低延时、稳定的点查服务,则必须要克服如下困难:
在克服上述3大类困难后,整体的工作方式就可以非常的简洁:在接入层(FrontEnd)上直接通过Client SDK与后端存储通信。
下面将会介绍Hologres是如何克服以上3大困难,从而实现高吞吐低延时的点查。
Query Optimizer进行Short Cut
由于点查的Query足够简单,Hologres的Query Optimizer进行了相应的short cut,点查Query并不会进入Opimizer的完整流程。Query进入FrontEnd后它会交由Fixed Planner进行处理,并由其生成对于的Fixed Plan(点查的物理Plan),Fixed Planner非常轻,无需经过任何的等价变换、逻辑优化、物理优化等步骤,仅仅是基于AST树进行了一些简单的分析并构建出对应的Fixed Plan,从而尽量规避掉优化器的开销。
Prepared Statement
尽管Query Optimizer对点查Query进行了short cut,但是Query进入到FrontEnd后的解析开销依然存在、Query Optimizer的开销也没有完全避免。
Hologres兼容Postgres,Postgres的前、后端通信协议有extended协议与simple协议两种:
为此Hologres基于Postgres的extended协议,支持了Prepared Statement,做到了点查Query在Frontend上的开销接近于0。
BHClient是Hologres实现的一套用于与后端存储直接通信的高效Private Client SDK,主要有以下几个优势:
1)Reactor模型、全程无锁的异步操作
BHClient工作方式类似reactor模型,每个目标shard对应一个eventloop,以“死循环”的方式处理该shard上的请求。由于HOS对调度执行单元的抽象,即使是shard很多的情况下,这种工作方式的基础消耗也足够低。
2)高效的数据交换协议binary row
通过自定义一套内部的数据通信协议binary row来减少整个交互链路上的内存的分配与拷贝。
3)反压与凑批
BHClient可以感知后端的压力,进行自适应的反压与凑批,在不影响原有Latency的情况下提升系统吞吐。
1)LSM(Log Structured Merge Tree)
Hologres的行存表采取LSM进行存储,相比于传统的B+树,LSM能够提供更高的写吞吐,因为它不会出现任何的随机写,Append Only的操作保证了其只会顺序的写盘。
2)基于C++纯异步的开发
采用LSM对数据进行组织存储的系统并不仅仅只有Hologres,LSM在谷歌的"BigTable"论文中被提出后,很多的系统都对其进行了借鉴采用,例如HBase。Hologres采用C++进行开发,相较于Java,native语言使得我们能够追求到更极致的性能。同时基于HOS(Hologres Operation System)提供的异步接口进行纯异步开发,HOS通过抽象ExecutionContext来自我管理CPU的调度执行,能够最大化的利用硬件资源、达到吞吐最大化。
3)IO优化与丰富的Cache机制
Hologres实现了非常丰富的Cache机制row cache、block cache、iterator cache、meta cache等,来加速热数据的查找、减少IO访问、避免新内存分配。当无可避免的需要发生IO时,Hologres会对并发IO进行合并、通过wait/notice机制确保只访问一次IO,减少IO处理量。通过生成文件级别的词典及压缩,减少文件物理存储成本及IO访问。
Hologres致力于一站式实时数仓,除了具备处理复杂OLAP分析场景的能力之外,还支持超高QPS在线点查服务,通过使用标准的Postgres SDK接口,就能通过SQL获得低延时、高吞吐的在线服务能力,简化学习成本,提升开发效率。
作者:周思华(花名:思召),阿里巴巴技术专家,现从事交互式分析引擎Hologres研发工作。
原文链接:http://click.aliyun.com/m/1000285794/
本文为阿里云原创内容,未经允许不得转载。