文章目录
- 0.简介
- 1.Citus整体架构
- 2.数据存储
- 2.1 数据分片
- 2.2 表类型
- 3.分布式计划
- 4.分布式事务
- 4.1 角色
- 4.2 流程
- 5.集群管理
- 5.1 高可用
- 5.2 备份
0.简介
本文主要介绍PG的分布式插件Citus,主要介绍其实现方式(如何将单机转换为分布式的):主要包含数据存储(分片方式,表类型)处理,分布式计划,分布式事务以及集群管理内容。
1.Citus整体架构
Citus是share nothing分布式架构,其中每个角色都是PG,没有其他中间件。节点分为以下两种类型:
1)Coordinator节点(也叫CN):负责接受客户端请求,集群元数据管理和分布式计划。
2)Worker节点(也叫DN):负责实际存储分片数据。
2.数据存储
2.1 数据分片
从数据存储角度来看,如何将数据分布到多个worker节点上,Citus提供了两种常用的方式:
1)hash分片:使用一致性hash原理,按照常用的hash算法来将对应的key哈希到一个具有232次方个桶的空间中,即0~(232)-1的数字空间中。选择一个合理的分布列可以很好的解决数据分布不均匀和访问热点的问题。
2)range分片:设置节点不同值的范围,分片范围人工指定。
2.2 表类型
其分片是需要存储的,citus中存储了三种表记录相关信息:
1)Distributed tables:分片表,就是使用上述hash分片和range分片的表。
2)Reference tables:参考表,每个DN上有表的全部数据,相当于复制表。
3)Local tables:本地表,只存在于CN上,可以直接使用,不需要使用worker。
3.分布式计划
其分布式计划的改写主要利用PG本身提供的扩展接口,使用扩展插件的方式来处理,不改动内核代码,关键点在于查询计划器和执行器的hook,将其替换为Citus的实现,在PG语法解析后,如果有涉及的Citus表,将会生成一个包含CustomScan节点的计划树,其会调用分布式查询执行器,发送查询给其他worker节点,然后收集结果。
其中执行器可以执行各种复杂的操作,如需要重分布的操作。这部分充分考虑了三种表类型需要的计划逻辑和尽可能做到逻辑下推,本文不详细讨论这些细节,而是重点关注其扩展方式。
4.分布式事务
Citus分布式事务的实现是采用的2PC的方式,2PC是分布式事务的一种常见做法,主要流程是Prepare和Commit,也就是分了准备阶段和提交阶段,下面对Citus的实现来进行分析。
4.1 角色
1)CN:是二阶段事务的发起者,其中有daemon进程负责事务恢复和回滚。
2)DN:负责执行和返回状态
4.2 流程
流程中包含多种可能的异常场景,和常规2PC提交类似,本节主要描述正常提交流程和遇到异常时的对于需要频繁访问的表的一些优化操作。
对于这三个步骤做的事情每一步都有失败的可能,其对应的操作就是去清理相关信息(也就是回滚),在此过程中有一些事务相关的表会成为读写热点,为了去除锁造成的性能影响,其采用的是二次检测方式,同时为了避免死锁,采用有向图的方式来进行死锁检测。
5.集群管理
集群管理主要介绍高可用和备份。
5.1 高可用
PG本身就是支持多副本的复制,在HA的设置中,集群中的每个节点都存在热备份节点,当一个节点失败后,会主备交换,更新Citus元数据和其节点地址,这就是高可用的处理。
5.2 备份
备份时通过定时的创建磁盘快照或者数据库目录副本,并在每个服务器中将WAL持续存档到远程存储来实现,Citus还支持定期创建还原点,也就是每个节点的WAL记录,保证多节点的一致性。