先介绍一下 GaussDB 发展史在目前华为云数据库产品体系中与 GaussDB 相关的两条主要产品线分别是GaussDB和GaussDB(DWS)。其中GaussDB 主要面向 OLTP 及通用关系型数据库场景其技术体系可追溯至早期的GaussDB 100后发展为GaussDB T并进一步演进为当前的GaussDBGaussDB(DWS)则主要面向 OLAP、数据仓库及分析型业务其技术体系源可追溯至早期的GaussDB 2002019 年GaussDB 200合并了GaussDB 300的部分设计更名为GaussDB A后来演变成了华为云上的DWS服务。1. GaussDB 体系结构GaussDB主要包含了CN、DN、GTM、OM、CM和ETCD等模块。主备版逻辑架构图分布式版逻辑架构图ETCD、DN、CM 是三种软件架构共有的组件GTS、CN 则是分布式架构独有的组件1.1 协调节点(CN)协调节点Coordinator NodeCN是 GaussDB 分布式数据库中的管理与调度中心主要负责接收客户端 SQL 请求、解析 SQL 语句、生成执行计划并将执行任务分发至各数据节点DN执行。同时CN 负责汇总各 DN 返回的执行结果并将最终结果返回给客户端。CN 还负责维护全局系统目录Global System Catalog确保分布式集群中元数据的一致性。在 GaussDB 分布式集群中可以部署多个 CN各 CN 之间角色平等不存在主从关系。客户端连接任意一个 CN 执行 DML 语句都能够获得一致的执行结果通常建议在CN 与应用程序之间部署负载均衡器(F5、LVS。与 DN 不同CN 不存在类似 DN 的主备复制机制。CN 本身不承担数据持久化和数据副本同步因此配置 CN 高可用时主要通过部署多个 CN 实例来实现而不是通过主备同步实现。CN 是 GaussDB分布式部署形态特有的组件集中式部署不需要单独部署 CN。CN 的核心职责概括为以下四个方面SQL 解析与优化接收客户端 SQL完成 SQL 解析、语义分析、查询优化并生成执行计划。任务调度与数据分片根据执行计划将 SQL 任务拆分并调度到相应 DN 执行同时协调分布式执行过程。全局事务管理参与分布式事务的协调与管理保证跨 DN 事务的正确执行。元数据一致性维护维护全局系统目录和元数据信息确保各 CN 对数据库对象及相关元数据具有一致的认知。1.2 数据节点(DN)数据节点Data NodeDN是 GaussDB 分布式数据库中负责数据存储与数据计算的核心节点。DN 负责存储业务数据支持行存、列存以及混合存储同时承担 SQL 执行、数据查询、数据处理等任务并将执行结果返回给协调节点CN。DN 主要承担数据存储和数据计算任务从功能职责上可以概括为SQL 执行引擎和存储引擎两大部分。SQL 引擎负责 SQL 的解析、优化和执行并通过存储相关接口访问数据存储引擎负责数据的组织、读写和持久化。在分布式集群中每个 DN 负责管理部分业务数据并通过高速网络与其他 DN 协同完成分布式查询和分布式事务。为保证数据的高可用性和一致性DN 主备节点之间通过Quorum 或 Paxos等数据复制机制进行数据同步。因此分布式环境中一台主机经常会部署多个 DN 实例一个 DN Group 的副本分布在多台主机上。1.3 全局事务管理器(GTM)GTM Global Transaction Manager是分布式事务的核心组件负责生成和维护全局事务ID、事务快照、时间戳、Sequence 信息等全局唯一的信息。确保 ACID 特性在跨节点事务中生效。GTM 采用多版本并发控制MVCC机制支持高效的并发访问。整个集群只有一组GTM一个主GTM一个或多个备GTM。GTM 仅处理全局时间戳请求64位 CSN可以理解为全局递增的序列号递增几乎都是CPU和消息收发操作。为了避免频繁持久化带来的性能开销GTM 采用批量/周期性持久化的方式将 CSN 状态定期持久化到 ETCD。GTM 在持久化 CSN 时预留一定的安全增长区间backup_step使得即使 GTM 发生故障并从 ETCD 恢复也能够继续生成严格递增的 CSN避免出现 CSN 回退的问题。传统 GTM 架构属于一种中心化的全局事务服务全局时间统一、 CSN 生成简单、 分布式事务协调逻辑清晰。但随着集群规模不断扩大所有节点都依赖一个 GTM Group会形成一定的中心化扩展瓶颈。因此未来的架构演进方向是逐步降低对中心化 GTM 的依赖向去中心化架构演进。1.4 ## 集群管理器(CM)CMCluster Manager集群管理器是 GaussDB 分布式数据库的集群管理与高可用控制组件主要负责集群状态监控、故障检测、主备切换、资源管理以及高可用仲裁等工作。可以将 CM 理解为 GaussDB 集群的“大脑”它持续感知 CN、DN、GTM 等关键实例的运行状态并根据集群当前状态进行故障判断和恢复决策在必要时触发主备切换从而保证数据库集群的高可用性。CM 由 CM Agent、CM Server 和 OM Monitor 组成其中 CM Agent 负责进程保活、仲裁指标采集和命令执行CM Server 根据状态判定是否需要修复并下发指令OM Monitor 负责 OM、etcd、cm_agent 的保活与启停。CM采用 Paxos 协议实现高可用。CM 本身也存在主备关系当 CM Primary 发生故障时通过高可用仲裁机制选出合适的备用 CM 接管服务。① CM AgentCM Agent 部署在集群各主机上主要负责本机实例监控和命令执行。其主要职责包括监控所在主机上的 CN、DN 等数据库实例运行状态采集实例状态及相关仲裁指标将监控信息和状态周期性上报给 CM Server接收并执行 CM Server 下发的控制和仲裁指令配合完成实例启动、停止、主备切换等操作。② CM ServerCM Server 是 CM 的核心控制与仲裁组件负责根据各 CM Agent 上报的信息判断集群状态并决定是否需要进行故障恢复或主备切换。主要职责包括汇总各 CM Agent 上报的实例状态判断实例是否发生故障判断当前集群是否需要执行修复制定故障恢复和主备切换策略向 CM Agent 下发相应的控制指令负责集群高可用仲裁。③ OM MonitorOM Monitor 是 CM 体系中的监控与保活组件主要负责对 OM、ETCD、CM_Agent 等关键基础管理进程进行监控。当相关进程异常退出时OM Monitor 可以根据管理策略执行相应的保活、拉起或启停操作。1.5 分布式键值存储系统(ETCD)ETCD 是一个高可用的分布式键值数据库用于共享配置和服务发现(服务注册和查找)负责存储集群各个节点状态便于集群 CM 管理各个节点。 ETCD 存储 CM 所需的数据集群的启动中先启动的是 ETCD然后才是其余的组件其操作命令也是分开的。在 GaussDB 集群中ETCD 主要用于保存集群管理所需的关键状态信息包括集群配置信息、集群拓扑信息、CM 高可用及仲裁相关信息、节点及实例状态等。 ETCD 一般部署为奇数个角色分Leader和Follower。Leader 向 Follower 复制数据通过 Raft 多数派保证数据一致性。因此3 节点 ETCD 集群最多可以容忍 1 个节点故障。ETCD 的作用概括为配置共享为集群中的管理组件提供统一的配置数据存储使不同节点能够获取一致的配置信息服务发现保存服务注册信息使集群管理组件能够发现其他服务和实例集群状态与拓扑信息存储保存节点、实例以及集群拓扑等状态信息为 CM 的集群管理提供数据基础高可用与一致性保障通过 Raft 共识机制保证 ETCD 数据的一致性并通过 Leader 重新选举实现自身的高可用支撑集群仲裁ETCD 为 CM 等管理组件提供可靠的共享状态存储从而支撑集群的高可用仲裁和故障处理。也就是说CM 负责“管理和决策”ETCD 负责“可靠地保存 CM 等组件进行管理和决策所需要的共享状态”。在新版 GaussDB 中已经开始用自研的 DCCDistributed Configuration Center分布式配置中心替代 ETCD 的部分能力尤其是CM/CMS 的选主和仲裁。DCF Distributed Consensus Framework是支撑 DCC 等组件实现强一致和高可用的分布式共识框架。DCF 并不是一个独立运行的数据库进程而是以动态库的形式集成到 GaussDB 数据库进程中由 DN 调用 DCF 提供的相关接口实现数据库节点之间的高可用协同。当开启DCF 模式后DN 可以基于 DCF 提供的Paxos 共识机制实现节点之间的自选主、自仲裁以及 XLOG 日志复制等能力从而降低对外部集群管理组件进行数据复制和主备仲裁的依赖。2. 单进程多线程架构GaussDB抛弃了PostgreSQL的多进程架构采用了单进程多线程运行模式同一进程内运行用户线程、系统线程、I/O 线程、日志线程等线程之间协同工作共同完成数据库的各项任务。多线程具有以下四大主要优势优势一低启动开销线程的启动开销远小于进程的启动开销。与进程相比线程是一种更为“节俭”的多任务操作方式。在Linux系统下启动一个新进程需要分配独立的地址空间并建立多种数据表来维护其代码段、堆栈段和数据段这是一种“昂贵”的多任务工作方式。相反运行于同一进程中的多个线程共享相同的地址空间和大部分数据因此启动一个线程所需的空间远小于启动一个进程。优势二便捷的通信机制不同进程间具有独立的数据空间数据传递只能通过通信方式进行这不仅费时且不方便。而同一进程下的线程共享数据空间一个线程的数据可以直接被其他线程使用这不仅快捷而且方便。优势三低切换开销在Linux系统中进程切换分为两步切换页目录以使用新的地址空间以及切换内核栈和硬件上下文。对于线程切换切换页目录以使用新的地址空间是不必要的只需执行切换内核栈和硬件上下文。因此线程切换的开销明显小于进程切换。优势四较小的系统调用开销在多线程架构中系统调用的开销相对较小因为线程切换仅涉及用户态和内核态之间的切换而进程切换还需涉及用户态和内核态之间的切换以及地址空间的切换。在启动GaussDB时main 函数首先启动服务守护线程Postmaster。随后Postmaster 线程负责启动其他辅助线程因此Postmaster是所有线程的父线程。当用户的 SQL 请求到达时服务守护线程会启动一个 worker 线程由该worker线程处理用户请求执行SQL并返回数据。除了主业务线程外GaussDB还提供了一些辅助线程用于实现维护和调度功能。主要线程类型有线程名称线程介绍main thread数据库主线程。1. 连接监听和接收主线程负责监听来自客户端的连接请求并接收新的连接。当有新的连接请求到达时主线程处理连接并分配相应的资源以确保客户端能够与数据库进行通信。2. 工作线程监控和处理主线程持续监控所有工作线程的状态确保工作线程正常运行。worker thread工作线程。GaussDB 会根据需要创建多个工作线程来处理SQL语句的执行。每个工作线程都会独立地执行SQL语句并将结果返回给主线程。startup数据库启动线程。background writer后台数据写线程。将数据库数据缓冲区的内容周期性地同步到磁盘上以确保数据持久性。checkpointer检查点线程。负责进行检查点操作完成数据库的周期性检查点和执行检查点命令以确保数据库的一致性和恢复能力。WAL writer后台WAL写线程。将日志缓冲区的内容周期性地同步到磁盘上以确保事务日志的持久性。system logger运行日志写线程。将各个线程的运行日志信息写入运行日志文件中以便于系统监控和故障排查。autovacuum launcher垃圾清理启动线程。autovacuum worker垃圾清理线程。对GaussDB数据库中的垃圾数据进行清理以释放存储空间和提高系统性能。archiver日志归档线程。完成归档操作将在线日志复制到归档目录以确保日志的长期保存和备份。GaussDB早期是基于PostgreSQL 9.2开发的在架构上借鉴了PostgreSQL-XC但后来进行了重构。进程模型容易遇到OOM当爆发连接风暴时work_mem这类参数的设置可能造成内存溢出。线程模型提高了内存信息的安全性也降低了内存溢出的风险。但是如果某条SQL杀不掉的话PostgreSQL可以在操作系统层面使用kill命令杀掉该连接而高斯则不能因为如果使用kill杀掉会造成数据库主进程也被kill。那么你觉得数据库是采用多进程模式还是单进程多线程模式好呢欢迎打在评论区。也欢迎点赞、推荐和转发本博客。