欢迎你们前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~node
李跃森,腾讯云PostgreSQL首席架构师,腾讯数据库团队架构师,负责微信支付商户系统核心数据库的架构设计和研发,PostgreSQL-x2社区核心成员,获多项国家发明专利。从事PG内核开发和架构设计超过10年。sql
2015年以前,微信支付业务快速发展,须要一款数据库可以安全高效的支撑微信支付商户系统核心业务,这个重任落在了腾讯数据库团队自研PostgreSQL上。数据库
2016年7月,腾讯云对外发布云数据库PostgreSQL,提供腾讯自研的内核优化版和社区版两个版本,以及提供分布式集群架构(分布式集群内部代号PostgreSQL-XZ)两种方案。目前云数据库PostgreSQL在腾讯大数据平台、广点通、腾讯视频等腾讯多个核心业务中稳定运行。安全
腾讯PostgreSQL-XZ是由PostgreSQL-XC社区版本地化而来,能支撑水平扩展数据库集群。虽然PostgreSQL-XC很强大,但在性能、扩展性、安全、运维方面仍是有明显的瓶颈,而腾讯PostgreSQL通过多年的积累,在这些方面都有较大提高和强化。因为是用于微信支付的核心数据库,腾讯PostgreSQL被定位为安全、高效,稳定,可靠的数据库集群。下面将以腾讯PostgreSQL-XZ为表明介绍腾讯自研PostgreSQL所作的优化和改进。bash
PostgreSQL-XC在事务管理系统方案自己有一个明显的缺点,那就是事务管理机制会成为系统的瓶颈,GTM(Global Transaction Manager全局事务管理器)会限制系统的扩展规模。如图1所示,是每一个请求过来CN(Coordinator 协调节点)都会向GTM申请必需的gxid(全局事务ID)和gsnapshot(全局快照)信息,并把这些信息随着SQL语句自己一块儿发往DN(Datanode数据库节点)进行执行。另外,PostgreSQL-XC的管理机制,只有主DN才会获取的gxid,而备DN没有本身的gxid,所以没法提供只读服务,对系统也是不小的浪费。微信
图1架构
而腾讯PostgreSQL-XZ改进了事务管理机制,改进后,CN再也不从GTM获取gxid和gsnapshot,每一个节点使用本身的本地xid(事务ID)和gsnapshot(快照),如此GTM便不会成为系统的瓶颈;而且,DN备机就还能够提供只读服务,充分利用系统闲置资源。如图2,优化后的事务管理系统架构以下:运维
图2机器学习
固然,事务管理系统的优化为进行备DN只读提供了基础,然而原始集群并无负载、调度等能力。在这方面,咱们也作了大量的创新,总结起来包括:
经过这些方式,集群能够提供带有智能负载能力的备DN只读功能,充分利用系统资源。
图3
业务的快速增加不可避免的须要对资源进行扩容,社区版本的实现使得扩容成本高昂,须要对业务进行长时间的中断。由于,在社区版本PostgreSQL-XC中,经过 DN=Hash(row) % nofdn
的方式决定一条记录的存储节点:
也就是说,先对分布列计算hash值,而后使用这个值对集群中的节点个数取模来决定记录去哪一个节点(如图4)。
这种方案简单,但实际应用中须要长时间停机扩容。这是由于,扩容后节点数会变多,数据没法按照原有的分布逻辑进行读写,须要从新分布节点数据。而再均衡数据须要停机并手工迁移再均衡到各个节点。对于规模较大的交易系统来讲,因为原有节点存储的是海量数据,再均衡过程可能会持续好几天。相信这是业务彻底没法忍受的。
图4
所以咱们引入了一种新的分表方法—sharded table。Shardedtable
的数据分布采用以下(图5)的方式:
Hash(row) % #shardmap entry
来决定记录存储到哪一个shardid,经过查询shardmap的存储的DN。经过上面的方案,在扩容新加节点时,就只须要把一些shardmap中的shardid映射到新加的节点,并把对应的数据搬迁过去就能够了。扩容也仅仅须要切换shardmap中映射关系的,时间从几天缩短到几秒。
图5
数据倾斜是指,在分布式数据库系统中会由于物理节点、hash或shard分布缘由,致使某些DN物理空间不足,而另外的物理空间剩余较大。例如,若是以商户做为分布key,京东天天的数据量和一个普通电商的数据量确定是天地差异。可能某个大商户一个月的数据就会把一个DN的物理空间塞满,这时系统只有停机扩容一条路。所以咱们必需要有一个有效的手段来解决数据倾斜,保证在表数据分布不均匀时系统仍然可以高效稳定的运行。
首先咱们把系统的DN分为group(以下图6),每一个group里面:
图6
对于系统中数据量较大用户进行特别的识别,并为他们建立白名单,使用不一样的数据分布逻辑(以下图7):普通用户使用默认的数据分布逻辑,也就是:
Shardid = Hash(merchantid) % #shardmap
复制代码
大商户使用定制的数据分布逻辑,也就是:
Shardid = Hash(merchantid) % #shardmap + fcreate_timedayoffset from 1970-01-01
复制代码
图7
经过在大商户group分布逻辑中加入日期偏移,来实现同一个用户的数据在group内部多个节点间均匀分布。从而有效的解决数据分布不均匀问题。
下面是一个例子(以下图8):
图8
业务在列表查询场景下会收到以下的查询SQL:
在微信支付的场景中,某个商户天天的数据有300W,一个月数据超过9000W条,也就是说PostgreSQL须要面向一个9000W数据级数据进行快速排序,并且业务逻辑要求须要秒级输出,快速获取排序结果。
为此,咱们提供表定义方案,即创建集群分区表。根据上述需求,能够采用按月分表,即每月一张表,并对排序字段ffinish_time创建索引,这样每一个分区进行扫描是可使用索引。
咱们再经过一系列执行计划的优化,CN下推order by和limit offset子句到DN;DN上在执行对应的sql使用使用Merge Append算子对各个子表执行的结果进行汇总输出,这个算子自己会保证输出是有序的,也就是说对子表进行索引扫描,同时Merge Append又对各个子表的结果进行归并,进而保证节点自己的结果是排序的。CN对多个DN的结果一样使用Merge Append进行归并,保证整个输出结果是有序的,从而完成整个排序过程。
下面是咱们对排序进行的性能测试结果:
经过在24核CPU,64G内存的机型上进行测试,9000W数据的排序在最短能够在25 ms内完成,QPS最高可达5400。
随着当前硬件的发展,系统资源愈来愈丰富,多CPU大内存成了系统标配,充分利用这些资源能够有效的提高的处理效率优化性能。腾讯在2014年末开始进行PostgreSQL多核执行优化。
目前PostgreSQL9.6社区版也会包含部分并行化特性,可是没有咱们这边这么丰富,下面介绍下腾讯PostgreSQL并行化的原理和效果:
咱们完成优化的算子:
经过在24核CPU,64G内存的机型下测试,各个算子的优化结果:
总体来讲性能广泛是优化前的10-12倍,优化的效果比较明显。
两地三中心容灾是金融级数据库的必备能力,对于金融类业务数据安全是最基本也是最重要诉求,所以咱们为了保障高效稳定的数据容灾能力,也为PostgreSQL-XZ建设了完善的两地三中心自动容灾能力。具体的两地三中心部署结构以下:
同城节点间采用强同步方式,保障数据强一致;异地采用专网异步同步。
节点内,每台物理机上部署CAgent,agent收集机器状态并进行上报,并进行相应的告警和倒换执行功能。
每一个IDC至少部署一个JCenter,JCenter负责收集上报每一个agent上报的状态到ZK集群。这么多个JCenter中只有一个是主用,主用的JCenter除了进行状态上报还进行故障裁决和倒换。在主用的JCenter异常后,系统经过ZK自动裁决挑选一个备用的JCenter升主。
JCenter和CAgent是两地三中心的控制和裁决节点。
对于数据库节点,CN在每一个IDC至少部署一个。DN在每一个中心部署一个,一个为主,另外两个并联做为备机放在主机上,一个为同步备机,另一个为异步备机。
在主机故障宕机时,JCenter优先选择同城的备机升主。
目前,腾讯云已经提供云数据库PostgreSQL的内测使用,并将提供内核优化版和社区版两个版原本知足更多客户的要求。
问答
相关阅读
万亿级调用下的优雅:微信序列号生成器架构设计及演变 ( 上 )
此文已由做者受权腾讯云+社区发布,更多原文请点击
搜索关注公众号「云加社区」,第一时间获取技术干货,关注后回复1024 送你一份技术课程大礼包!
海量技术实践经验,尽在云加社区!