揭秘 Hologres 如何支持超高 QPS 在线服务(点查)场景
Hologres(中文名交互式分析)是阿里云自研的一站式实时数仓,这个云原生系统融合了实时服务和分析大数据的场景,全面兼容 PostgreSQL 协议并与大数据生态无缝打通,能用同一套数据架构同时支持实时写入实时查询以及实时离线联邦分析。它的出现简化了业务的架构,为业务提供实时决策的能力,让大数据发挥出更大的商业价值。
本期将为大家揭秘 Hologres 如何支持超高 QPS 点查。
传统的 OLAP 系统在业务中往往扮演着比较静态的角色,以通过分析海量的数据得到业务的洞察(比如说预计算好的视图、模型等),从这些海量数据分析到的结果再通过另外一个系统提供在线数据服务(比如 HBase、Redis、MySQL 等)。这里的服务(Serving)和分析(Analytical)是个割裂的过程。与此不同的是,实际的业务决策过程往往是一个持续优化的在线过程。服务的过程会产生大量的新数据,我们需要对这些新数据进行复杂的分析。分析产生的洞察实时反馈到服务,让业务的决策更实时,从而创造更大的商业价值。
Hologres 定位是一站式实时数仓,融合分析能力(Analytical)与在线服务(Serving)为一体,减少数据的割裂和移动。本文的内容将会针对 Hologres 的服务能力(核心为点查能力),介绍 Hologres 到底具备哪些服务能力,以及背后的实现原理。
通常我们所说的点查场景是指 Key/Value 查询的场景,广泛用于在线服务。由于点查场景的广泛需求,市场上存在多种 KV 数据库定位于支持高吞吐、低延时的点查场景,例如被大家广而熟知的 HBase,它通过自定义的一套 API 来提供点查的能力,在许多业务场景都能够获得较好的效果。但是 HBase 在实际使用中也会存在一定的缺点,这也使得很多业务从 HBase 迁移至 Hologres,主要有以下几点:
当数据规模大到一定程度的时候,HBase 在性能方面将会有所下降,无法满足大规模的点查计算,同时在稳定性上也变得不如人意,需要有经验的运维支持
HBase 提供的是自定义 API,上手有一定的成本。Hologres 直接通过 SQL 提供高吞吐、低延时的点查服务。相比于其它 KV 系统提供自定义 API,SQL 接口无疑更加的简单易用。
HBase 采用 Schema Free 设计,没有数据类型,对于检查数据质量,修正数据质量也带来了复杂度,查错难,修正难。Hologres 具备与 Postgres 兼容的几乎所有主流数据类型,可以通过 Insert/Select/Update/Delete 标准 SQL 语句对数据进行查看、更新。
在 Hologres 中的点查场景是指行存表基于主键(PK)的查询。
点查场景技术实现难点
正常情况下,一条 SQL 语句的执行,需要经过 SQL Parser 进行解析成 AST(抽象语法树),再由 Query Optimizer 处理生成 Plan(可执行计划),最终通过执行 Plan 拿到计算结果。而要想通过 SQL 做到高吞吐、低延时、稳定的点查服务,则必须要克服如下困难:
在不破坏 PostgreSQL 生态的情况下,SQL 接口如何做到高 QPS?
如何做低甚至避免 SQL 解析与优化器的开销
一套高效的 Client SDK 如何与后端存储进行交互?
如何在低消耗的情况下,做到高并发的交互
如何减少消息传递过程中的开销
如何感知后端的压力、配合做到最好的吞吐与延迟
后端存储如何在高性能的情况下更加稳定?
如何最大化利用 cpu 资源
如何减少各种内存的分配与拷贝、避免热点 key 等问题对系统带来的不稳定性
如何减少冷数据 IO 的影响
在克服上述 3 大类困难后,整体的工作方式就可以非常的简洁:在接入层(FrontEnd)上直接通过 Client SDK 与后端存储通信。
下面将会介绍 Hologres 是如何克服以上 3 大困难,从而实现高吞吐低延时的点查。
降低、避免 SQL 解析与优化器的开销
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 协议两种:
simple 协议:是一次性交互的协议,Client 每次会直接发送待执行的 SQL 给 Server,Server 收到 SQL 后直接进行解析、执行,并将结果返回给 Client。simple 协议里 Server 无可避免的至少需要对收到的 SQL 进行解析才能理解其语义。
extended 协议:Client 与 Server 的交互分多阶段完成,整体大致可以分成两大阶段。
第一阶段:Client 在 Server 端定义了一个带名字的 Statement,并且生成了该 Statement 所对应的 generic plan(不与特定的参数绑定的通用 plan)。
第二阶段:用户通过发送具体的参数来执行第一阶段中定义的 Statement。第二阶段可以重复执行多次,每次通过带上第一阶段中所定义的 Statement 名字,以及执行所需要的参数,使用第一阶段生成的 generic plan 进行执行。由于第二阶段可以通过 Statement 名字和附带的参数来反复执行第一个阶段所准备好的 generic plan,因此第二个段在 Frontend 的开销几乎等同于 0。
为此 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 的操作保证了其只会顺序的写盘。
一个行存 tablet 上会存在一个 memtable,和多个 immutable memtable。
数据更新都会写入到 memtable 中,当 memtable 写满后会转变为 immtable memtable,immutable memtable 会 Flush 成 Key 有序的 SST(Sorted String Table)文件,SST 文件一旦生成则不能修改,因此不会发生随机写的操作。
SST 文件在文件系统里面按层组织,除了 level 0 上的 SST 文件间无序,且存在 overlap 外,其它 level 上的 SST 文件间有序,且无 overlap。因此查询的时候,对于 level 0 上的文件需要逐个遍历,而其它 level 的文件可以二分查找。底层的 SST 文件通过 Compaction 成新的 SST 文件去到更高层,因此低层的数据要比高层的新,所以一旦在某层上找到了满足条件的 key 则无需往更高层去查询。
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 获得低延时、高吞吐的在线服务能力,简化学习成本,提升开发效率。
评论