导语 | TBase 是腾讯TEG数据平台团队在开源 PostgreSQL 的基础上研发的企业级分布式 HTAP 数据库系统,可在同一数据库集群中同时为客户提供强一致高并发的分布式在线事务能力以及高性能的数据在线分析能力。本文是对腾讯 TBase 专家工程师伍鑫在云+社区沙龙 online 的分享整理,将为你们带来腾讯云 TBase 在分布式 HTAP 领域的探索与实践。node
点击视频查看完整直播回放redis
腾讯云从 2009 年便开始在内部的业务上进行尝试,在企业分布式数据库领域的自研过程是比较有经验的。当时主要是为了知足一些较小的需求,好比引入PostgreSQL 做为 TDW 的补充,弥补 TDW 小数据分析性能低的不足,处理的需求量也较小。数据库
但业务慢慢的大了后,须要有一个更高效的在线交易事务的处理能力,对数据库要进行一个扩展,因此后面咱们就持续的投入到数据库的开发过程当中。安全
2014 年 TBase 发布的第一个版本开始在腾讯大数据平台内部使用;2015 年 TBase 微信支付商户集群上线,支持着天天超过 6 亿笔的交易;2018 年的时候 V2 版本对事务、查询优化以及企业级功能作了较大加强,慢慢的开始面向一些外部客户;2019 年 TBase 中标了 PICC 集团的核心业务,协助了他们在国内保险行业比较领先的核心系统,并稳定服务了很长的时间。服务器
考虑到 TBase 总体能力的持续发展,咱们是但愿把 TBase 的能力贡献给开源社区,这样能更多的支持数据库国产化项目。因而在 2019 年 11 月,咱们把数据库进行了开源,但愿能助力数字化产业升级。微信
TBase 是基于单机 PostgreSQL 自研的一个分布式数据库,除了具有完善的关系型数据库能力外,还具有不少企业级的能力。同时加强了分布式事务能力,以及比较好的支持在线分析业务,提供一站式的解决方案。网络
在数据安全上,咱们有着独特之处,包括三权分立的安全体系,数据脱敏、加密的能力。其次在数据多活、多地多中心的灵活配制上面,也提供了比较完善的能力,保障了金融行业在线交易中一些高可用的场景。为金融保险等核心业务国产化打下坚实基础。session
PostgreSQL 是一个开源的 RDBMS,开源协议基于 BSB 风格,因此源代码能够更加灵活的供你们修改,也能够在修改的基础上进行商业化。架构
PostgreSQL 是由图灵奖得主 MichaelStonebraker 主导的一个开源项目,如上图所示,它已经迭代得比较久了,到如今已经发布到 12 版本,而且一直在持续的迭代,总体处于一个比较活跃的水平。并发
PostgreSQL 在近十年开始受到的你们的关注,首先是由于它的内核功能,包括社区的持续活跃,在过去几年得到了持续的进步。上图是来自 DB-Engines 的统计,根据数据咱们能够看到在去年总体你们都有一些退步和增加不过高的状况下 PostgreSQL 的进步是比较明显的。
下图中黄色的曲线是 PostgreSQL,咱们能够很直观的看到它发展趋势是比较良好的。
目前开源的 TBase 版本是基于 PostgreSQL10,咱们也在持续的匹配 PostgreSQL 更多的功能,后续也会回馈到开源社区,但愿和总体的 PostgreSQL生态有一个良好的结合和互动。
数据库按照业务场景主要分为:OLAP、OLTP 和 HTAP。
OLAP 的业务特色是数据量较大,通常是 10PB+,对存储成本比较敏感。它的并发相对于 OLTP 不会过高,但对复杂查询能够提供比较好的支持。
OLTP 的数据量相对较小,不少中小型的系统都不会达到 TB 级的数据量,但对事务的要求和查询请求的要求会比较高,吞吐达到百万级 TPS 以上。而且 OLTP 对于容灾能力要求较高。
国内的国产化数据库不少会从 OLAP 领域进行切入,从OLTP 角度切入会相对比较难,目前这一块仍是被 IBM 或者Oracle 垄断的比较严重,咱们但愿尽快在这一块实现国产化。而 TBase 由于在保险行业有比较长时间的耕耘,在 OLTP 核心业务能力上有比较强的。
另一个是 HTAP。在以前大部分的业务部署中,你们会把 TP 和 AP 分开,在中间可能有 ETL 或者流复式的技术将两套系统进行交互。但更理想的状况是能够在一套系统中同时完成两种业务类型的支持。
固然这个会比较复杂。首先你们能够看到他们的业务特色差异比较大,内核领域的优化方向也是彻底不同的,或者说技术上差别比较大。
TBase 推出 HTAP 也是从具体的需求出发,实际上 TBase 是更偏向于 TP,同时兼顾了比较好的 AP 的处理能力,在一套系统里尽可能作到比较好的兼容。但若是要作更极致性能的话,仍是要对HTAP 进行隔离,对用户提供一种完整的服务能力。
TBase 的角度也是根据需求衍生出来的。腾讯云最先是作交易系统,后面慢慢的补充了 AP 的分析能力。
这块面临的主要的业务场景需求,首先是交易数据可能会大于 1T,分析能力大于 5T,并发能力要求达到 2000 以上,每秒的交易峰值可能会达到 1000 万。在须要扩展能力的状况下,须要对原有的事务能力、分析能力,或者数据重分布的影响降到最低。同时在事务层面作到一个完备的分布式一致性的数据库。
同时 TBase 也进行了不少企业级能力的加强,三权分立的安全保障能力、数据治理能力、冷热数据数据及大小商户数据的分离等。
前面咱们介绍了 TBase 的发展过程,在这过程当中咱们也但愿能够为开源社区进行一些贡献。
实际上在国内环境中替换核心业务仍是比较难,更多的是从分析系统切入,最近几年才开始有系统切入到核心的交易事务能力上,TBase 也但愿经过开源回馈社区,保证你们能够经过 TBase 的 HTAP 能力来填补一些空白,扩充生态的发展。
开源后咱们也受到了比较多的关注和使用,其中还包括欧洲航天局的 Gaia Mission 在用咱们的系统进行银河系恒星系统的数据分析,但愿有更多的同窗或者朋友加入到 TBase 的开发过程当中,也但愿经过本次介绍,方便你们更好的切入到 TBase 开源社区的互动中。
一个集群是由这几个部分组成:GTM、Coordinator和 Datanode。其中 GTM 主要负责全局事务的管控,是提供分布式一致性协议的基石;Coordinator 是用户业务的访问入口,对用户的请求进行分析和下发,具体的计算和数据存储则是放到了 Datanode 当中。
刚才咱们讲的是 HTAP,下面咱们先讲一下 OLTP,TBase 在这部分的能力是比较突出的。
若是用户须要在事务或者并发交易量上有要求的话,就须要一套比较好的分布式事务的系统。具体的需求包括高性能和低成本,在这部分,TBase 相较于传统的 IBM 或者国外更贵的一体机有较大的优点。
另一个需求就是可扩展,在节点扩展的状况下去近似线性的扩展事务处理能力。那要如何达成这个目标?
简单介绍一下事务的 MVCC 的处理,单机 PostgreSQL 主要是维护一个当前的活跃事务列表,它有一个结构叫 Proc array,至关于每个用户的 session 有新的事务请求的话,会在事物列表里去记录当前活跃的事务,当须要判断 tuple 的可见性的话,会在活跃事务列表里拿一个 Snapshot 去跟存储上面的 tuple header 中记录的 XID 信息进行一个对比,去作 MVCC 的访问控制。
若是是扩展到分布式的状况,一个比较简单的方式是须要有一个中心节点。按以前的构架,在 GTM 上面会有一个中心化的活跃事物列表,来统一的为每个访问的请求去分配 Snapshot。
但这个时候就有一个比较大的问题,中心节点会成为瓶颈,GTM 也会有一些问题,好比说快照的尺寸过大或者占用网络较高。
GTM 若是作一个中心化的节点的话,实际上存在一个单点瓶颈,每个请求都要保证它拿到 snapshot 的正确性,这就须要对活跃事务列表进行上锁,这个在高并发状况下锁冲突会很大。咱们是怎么解决这个问题的呢?
这实际上也是业界一个通用的问题。目前咱们看到互联网行业的方案,是从 Google Spanner 的方向衍生出来的。
Google Spanner 是一个全球分布式数据库,能够在各大洲之间提供一致性的数据库服务能力。它的控制并发技术特色,一是经过 KV 存储基于全局时间的多版本并发控制,另一个是它经过使用成本比较高的 GPS 和全球一致的服务时间戳机制来提供一个 TrueTime API,基于真实时间制做一套提交协议。由于它的总体全球分布式,致使平均偏差会大概在 6 毫秒左右,总体的事务时延是比较高的。
另外,有较多的系统会借鉴 Google Spanner 作事务模型,CockRoachDB 也是其中之一。
另外,Percolator 也是 Google 为搜索引擎提供的一个比较有效率的数据库,使用 KV 存储,基于全局逻辑时间戳的 MVCC 进行并发控制。它的时间戳由专门的时间戳服务提供,分布式事务第一阶段须要对修改记录加锁,提交阶段结束锁定;事务提交时间复杂度为 O(N),N 是记录数,致使提交的性能会有影响,固然这样的设计也和系统需求相关。
下面看一下 TBase 在分布式事务上的能力,这部分咱们也是在前面的基础上作了较大改进。
首先咱们对 GTM 集群作了优化,从原始的全局 XID 改为了分配全局时间戳GlobalTimeStamp(GTS),GTS 是单调递增的,咱们基于 GTS 设计了一套全新的 MVCC 可见性判断协议,包括 vacuum 等机制。这样的设计能够把提交协议从 GTM 的单点瓶颈下放到每个节点上,减轻压力,同时经过时间戳日志复制的方式实现 GTM 节点主备高可用。
这种协议下 GTM 只须要去分配全局的 GTS,这样的话单点压力就会被解决得比较明显。根据咱们的推算, 滕叙 TS85 服务器每秒大概能处理 1200 万 TPS,基本能知足全部分布式的压力和用户场景。
咱们刚才也提到,在 Percolator 的实现下,须要对 Tuple 上锁并修改记录,这样的话性能是比较差的。而实际上咱们对提交协议作了一个优化,在对 Tuple Header 的 GTS 写入作了延迟处理,事务提交的时候不须要为每个 Tuple 修改 GTS 信息,而是把 GTS 的信息存储在相应的 GTS Store File 当中,做为事务恢复的保障。
当用户第一次扫描数据的时候,会从 GTS Store File 中取到状态,再写入到 Tuple Header 中,以后的扫描就不须要再去遍历状态文件,从而实现加速访问,作到事务处理的加速。这样在总体上,让数据库在事务层面保证了比较高效的设计。
关于集中数据分布的分类状况,有如下三种。
第一种状况是复制表。复制表中的每一个存储节点都有完整的数据副本,适用于变化较少的小表,能够加速关联查询。
第二种是 HASH 分布,这是比较经典的一种方式。简单来说就是将数据按照分布列进行 hash,把数据打散在各个存储节点中,若是 hash key 选择不当,则可能形成数据倾斜的状况。
第三种是基于 RANGE 的分布。RANGE 分布会将数据按照分段打散成小的分片,和 hash 相比分布上不会特别严格,对上层的节点弹性有比较好的支持。但它在计算的时候,相对 hash 的效果不会特别好。
在总体上,TBase 选择的是复制表和加强的 hash分布。
下面介绍一下如何看分布式查询,PushQuery 和 PullData。
最开始早期的一些系统可能会选择更快速的实现,好比说存储上是分红多个 DN,而后把数据拉取到 CN 进行计算。
这种状况下优缺点都比较明显,优势是更高效更快速,缺点是 CN 是一个瓶颈,在网络上压力比较大。因此咱们更倾向于上图中右边的方式,把有的数据和计算下放到 DN 结点上。
最基本的状况下,但愿全部的计算能够放到 DN 上来进行。DN 在作重分布的时候,须要跟 DN 间有交互的能力,这个在 TBase V2 以后作了比较多的加强,目前 TBase 能够将计算尽可能的分散到 DN 结点上来进行。
上图介绍的是 SQL Shipping 和 PlanShipping 的区别。
实际上当处理一个 query 或者一个查询计划的时候,会有两种状况。一种是说我直接把 SQL 经过分析发到 DN 上执行,CN只负责结果的收集。这样的优化效果会比较好,由于不须要在多个节点创建分布式一致性的提交协议,另外在计算资源上效率会更高。咱们在 OLTP 领域的一些优化会采用这样的方式。
另外一种状况是在 OLAP 领域,更正规的 PLAN 的分布式。在 CN 上对 query 作一个总体的plan,按照重分布的状况把计划分解成不一样的计算分片,分散到 DN上进行处理
刚才讲到,就是若是能把对 OLTP 推到某单个 DN 上来作的话,效果会比较好。咱们举个简单的例子。
两张表的分布列是 f1,数据列是 f2,若 query 能够写成分布键的关联状况,而且采用的是 hash 分布,就能够把 query 推到不一样的 DN 上来作。由于不一样 DN 间的数据受到分布件的约束,不须要作交叉计算或者数据的重分布。
第二类是有分布键的等值连接,同时还有某一个分布键的具体固定值。
在这种状况下,CN 能够经过 f1 的值判断具体推到哪一个 DN 中去作。
还有一些更复杂的查询,好比存在子查询的状况,但方式也是相似的分析方法。
子查询可能会有一个复杂状况,若是在多层的子查询中均可以判断出来跟上层有相同的单一节点分布状况,query 也能够下发到 DN 中。这种状况下对 OLTP 性能会有比较好的影响,集群的能力会获得比较好的优化。
针对比较复杂的 query,可能就须要涉及到优化配置的调整。
方式主要分为两种:规则优化(RBO)和代价优化(CBO)。RBO 主要是经过规则来判断查询计划到底符不符合进行优化,这个是比较早期的一些实现方法,由于计算量相对较小,因此对某些场景比较高效,但明显的缺点是弹性不足,同时不能用于比较复杂的场景。
实际上更多的这种数据库使用的是 CBO 的方式。简单讲,CBO 会对全部路径的进行动态规划,选择成本最小的一条做为执行计划。这种方式的优势是有较好的适用性,可以适合复杂场景的优化,性能表现较稳定。缺点是实现复杂,须要必定的前置条件,包括统计信息、代价计算模型构建等。
但这也是不绝对的,二者没有谁能够“赢”过对方的说法,更可能是须要对两者进行一个结合。TBase 主要是在 CBO 上进行优化,好比在计算一些小表的场景中,不须要进行 redistribution,直接 replication 就能够了。
关于分布式中文 distribution 的一些调整的状况,咱们仍是打个简单的比方。两张表,TBL_A 和 TBL_B。
若是 f1 是分布列,分布类等值的状况下会变成 push down,这种状况下能够在 DN 上直接进行计算。
上图中间的状况中,TBL_A 是分布键,TBL_B 是非分布键。在这种状况下,若是 TBL_B 足够小,必需要对 TBL_B 进行重分布,也就是对 TBL_B 进行 replication,这时就会涉及到一些代价的估算。而若是 TBL_B 比较大的话,可能须要对 TBL_B 进行 redistribution。
刚才咱们也讲到,TBase 在 OLAP 方面也有比较强的能力,这部分的优化思路主要是借助了计算的并行。计算的全并行能力主要体如今几个方面。
首先是节点级的并行,由于咱们是分布式的数据库,因此能够有多个节点或者进程进行计算;另一层是进程级的并行,目前 TBase 没有改为线程模型,因此并行主要体如今进程级模型中,基于 PostgreSQL 进程并行的能力作了一些加强。还有一层是指令集的并行,对指令进行优化,后面也会对这部分进行持续的加强。
那么 Postgres 的查询计划,或者是进程并行的能力是如何实现的呢?最先期咱们 follow 的是 PG10,并行能力并非很是强,只提供了基础的框架和部分算子的优化,这是 TBase 当时进行优化的一个点。
在分布式的状况下,不少单机能够进行并行,但在分布式中就不能够进行并行,因此咱们但愿对这些能力进行一些加强,从而保证更大范围的一个并行能力。
并行计算实际上是一种自底向上推演的方式,好比说底层的一个节点能够并行,那么若是递推向上到了某一层不能并行,就能够把下面全部能够并行的地方加一个 Gather Node,把结果从多个进程中进行收集,继续向上进行规划。这也是咱们但愿加强的一个点。
下面咱们介绍一些具体的优化。
早期 PG 的 HashJoin 在 outer plan 是能够作并行的,但在 inner 构建 hash table 的状况则不能作并行的。
简单来讲,hashjoin 能够分为几步。首先是 build hash table,第二步是获取部分 outer plan 数据,计算哈希值,并进行匹配。这里咱们将 inner hash table 构建过程也作了并行化处理,保证 Hashjoin 的左右子树均可以进行并行,并继续向上层节点推到并行化。
另一种状况是 AGG(Aggregation)。
不少状况下都是一个两阶段的 Agg,须要在 DN 上作一些 partial agg,而后到上层计划分片进一步作 final agg。实际上在这种状况下,中间碰到 redistribute 须要先在 DN 进行数据的整合,而后再去作 final 的 Agg。
在有多层子查询的状况下,每一层都进行计算会致使最后总体的并行计算不会很高。因此咱们在 redistribution 也作了一些并行,也就是在 Partial Agg 的状况下能够按照 hash 分布去发到对应的上层 DN 节点上进行并行。
还有一些数据传输方面的优化。
咱们提到 redistributio 节点能够进行并行能力的加强,而在数据的接受和发送上也须要进行优化提高。早期的版本是单条的处理模式,网络的延迟会比较高,性能会不太好,因此咱们在这部分进行了一些优化,从而实现比较好的并行执行的能力。
实际上 TBase 还作了一些企业级能力的加强,后面也持续的会去作一些开源贡献和优化。
目前开源 Tbase 企业级已经能够实现多地多中心,或者是多活能力的构建,包括安全、管理、审计的能力,TBase 在安全上面有比较高的要求,后面也会持续的贡献出来。
还有就是在水平扩展能力上,TBase 能够作到在用户感知比较小的状况下进行扩容。扩容在大数据量的状况下是一个广泛的痛点,咱们在这方面的能力上也会有一个持续的加强。
此外,TBase 还有自研的分析表以及冷热数据的分离,也都是有比较好的效果,对于用户成本的下降,还有数据分布的灵活性都会有比较好的提高。
TBase 在今年 7 月 13 号开源发布了 v2.1.0 版本,咱们也持续的在开源能力上作着建设,包括多活能力的持续加强、维护性的加强,性能安全持续的升级,包括经过一些企业客户发现的问题也都会持续的贡献出来。还包括统计信息加强以及加强对小表重分布的优化,也是但愿你们能够持续关注 TBase,和咱们进行更多的讨论和切磋。
Q:TBase的布置有哪些要求?
A:你们能够访问 TBase 的开源版本,上面有具体的使用方法和基于源码的构建,还有搭建的流程,都有比较明确的文档。若是你们想尝试的话,可使用正常的 X86 服务器或者本机的 Linux 服务器就能够作一些简单的搭建,企业级项目上你们也能够作一些尝试,保持沟通。
Q:为何选择基于 PostgreSQL 开发呢?
A:实际上你们会面临 MySQL 和 PostgreSQL 两个方向上的选择,我主要介绍咱们选择 PostgreSQL 的缘由。
一是 PostgreSQL 的协议会更加友好,在协议的灵活性上会比较好一些,你们能够随意的对它的代码作改动和完整发布。
另外它的内核实现上也比较严谨,有本身的独到之处,持续的也在加强,包括它的迭代速度也是比较快。咱们早期一直在跟进,持续的 merge PostgreSQL 的一些 feature,也是伴随着 PostgreSQL 的成长,咱们的内核也作了一个比较快速的迭代。同时咱们也在了解内核的状况下,作了一些更深刻的调优。
Q:DN节点的存储集群是基于Raft吗?多Leader仍是单Leader呢?
A:目前咱们的 DN 结点没有用到 Raft 协议,是作的主备复制。我知道有不少新的业务会基于 Raft 的提交协议,或者是用这种复制的协议去作一致性和高可用。但实际上 Raft 的多副本对提交协议仍是有一些性能影响的,总体的流程相对于传统的会有更长的时延,至关于 CAP 原理,C提升了,A会有部分影响。
而咱们更倾向于 OLTP 系统,因此在事务上的要求和时延响应的要求是比较高的,因而作了这样的选择。
Q:能详细讲讲分布式事务的实现流程吗?怎么样保证多机之间的分布式事务,两阶段提交吗?
A:如今咱们基本是 follw 两阶段提交。一个是两阶段提交的控制流程、控制协议,另外一个是事务隔离的协议。刚才主要讲了 MVCC,在提交协议上基本上两阶段提交的加强版。
因为使用了 GTM,致使它和传统的单机模式不太同样,作了一些统一的协调,刚才也着重介绍了。这样的一个优点是减轻了 GTM 上的压力,另外在 prepare 阶段会有部分的阻塞状况,但在优化以后影响是很是小的,却能极大的减轻 GTM 的压力。
Q:底层的存储是怎么同时知足行存和列存的需求呢?仍是按照块(Tile)连续存储?
A:咱们开源版本的底层存储主要是行存,后面会在列存和 HTAP 进行持续的加强,进一步提高 HTAP 的能力。等逐步稳定以后,会再考虑迭代开源版本。
Q:最少须要多少服务器搭建?
A:其实单点搭建也是能够的。一个 DN、一个 CN、一个 GTM 也能够。实际上最好布成两 DN,能够体验更多的分布式搭建。实际上咱们在企业服务的集群上已经超过了上千个节点,包括解决 GTM 的单点压力上,对集群总体的扩展性有比较好的提高,因此从两个节点到多节点均可以去尝试一下。
Q:GTM的授时,有采用batch或者pipeline吗?还有如今Tbase支持的从库的读一致性吗?
A:有的。GTM 的授时咱们也作了更多的优化,简单说能够作一些并行的 GTS 的单调授时,根据现行的规模或者是咱们对客户场景的预估,在 x86服务器中大概能够达到1200万QPS的授时的能力。在加强服务器的状况下,总体的能力是比较强的,基本上不会在这部分产生瓶颈。
Q:tbase有什么安全保障机制?
A:从业务角度,咱们讲到了安全隔离,以及有很强的行级安全规则、列级访问控制以及数据加密、脱敏加强,这些均可以倾向于向一个企业级的数据库去应用,如今不少企业级服务的能力也在 TBase 里面,后面咱们会根据状况进行进一步的迭代。