
OceanBase 数据库架构深度解析从 Shared-Nothing 集群到多租户与日志流【免费下载链接】oceanbaseOceanBase is the unified distributed database for the AI era — open-source, multi-model, one engine for your most demanding workloads.项目地址: https://gitcode.com/GitHub_Trending/oc/oceanbaseOceanBase 采用无共享Shared-Nothing的分布式集群架构通过 Paxos 共识协议、分区与日志流机制实现高可用、水平扩展与多租户隔离。本文以官方架构文档为主体结合本仓库源码实现系统讲解 Zone、分区Partition、日志流Log Stream、OBServer、多租户、资源单元与 obproxy 等核心概念的底层原理与工程落地。图中展示了 OceanBase 的分层架构应用层通过多个 OBProxy 连接代理接入OBProxy 将 SQL 请求路由到数据服务层的 OBServer 节点OBServer 内部以分区Partition为单位组织数据每个分区维护主副本蓝色与备副本灰色分布在多个 Zone可用区中从而实现跨机房容灾与读写高可用。一、Shared-Nothing 集群架构OceanBase 的集群由若干完全对等的计算机节点组成每个节点都拥有私有的物理资源CPU、内存、硬盘等并在其上运行独立的存储引擎、SQL 引擎与事务引擎。这就是无共享Shared-Nothing架构节点之间相互独立不共享内存或磁盘仅通过网络设备相互协调共同对外提供完整的数据库服务。正是由于节点之间的独立性OceanBase 获得了四大核心特性可扩展新节点加入后通过分区与日志流在节点间迁移即可完成水平扩容高可用数据多副本分布在不同的节点/可用区任一节点故障可由 Paxos 协议自动完成主副本切换高性能读写请求由主副本就近处理obproxy 将请求路由到数据所在节点减少网络开销低成本支持普通服务器集群部署通过多租户共享资源摊薄硬件成本。二、可用区Zone集群中的节点分属于若干个可用区Zone每个节点属于且仅属于一个可用区。Zone 是一个逻辑概念用于实现数据的高可用性和灾备特性。可用区可以部署在不同的机房、不同区域甚至不同城市从而支撑同城双活、两地三中心等不同层次的容灾场景OceanBase 使用强一致性协议Paxos实现高可用同一个 Paxos 组即同一份数据的所有副本位于不同的可用区一般建议至少部署 3 个 Zone以保证在任意一个 Zone 故障时多数派Majority副本仍然存活、集群可继续提供服务。三、分区Partition与 Tablet3.1 水平拆分的分区机制在 OceanBase 中一张表的数据可以按某种划分规则水平拆分为多个分片每个分片称为一个表分区Partition。支持的分区类型包括Hash 分区按哈希值均匀分布适合无自然区间可言的流水类数据Range 分区按值区间划分适合按时间、ID 范围组织的业务数据List 分区按离散值枚举划分适合按地区、类型等维度组织二级分区例如交易库中的订单表可以先按用户 ID 划分为若干一级分区再按月份把每个一级分区细分为二级分区。对于二级分区表第二级的每个子分区才是物理分区第一级分区只是逻辑概念。一个表的多个分区可以分布在一个可用区内的多个节点上从而实现单表数据在多节点间的并行处理与负载均衡。3.2 Tablet分区的物理存储载体每个物理分区都有一个用于存储数据的存储层对象称为Tablet用于存储有序的数据记录。从源码结构看Tablet 是存储引擎src/storage侧的核心对象承载 MemTable内存表与 SSTable静态数据文件之间的数据流转是读写路径上的最小数据载体。四、日志流Log Stream与 Paxos 复制4.1 日志流的职责当用户修改 Tablet 中的记录时为了保证数据持久化需要将重做日志REDO写入 Tablet 对应的日志流Log Stream。一个日志流对应其所在节点上的多个 Tablet即同一节点上的多个 Tablet 可以共享一个日志流由该日志流统一负责数据的持久化与复制。4.2 主副本与从副本Tablet 通过多副本机制保证高可用副本一般分散在不同的可用区主副本Leader有且只有一个接受修改操作负责将日志复制给从副本从副本Follower其余副本跟随主副本同步数据不直接对外提供写服务。主从副本之间通过基于Multi-Paxos的分布式共识协议保证数据一致性而 Multi-Paxos 正是使用 Log Stream 来实现数据复制的。当多数派副本确认写入后该日志即视为已提交committed这是 OceanBase 强一致性的核心来源。4.3 源码印证PALF 日志实现日志流在仓库中由palf模块实现目录 src/logservice/palf模块内的关键实现包括日志块管理log_block_mgr.h/cpp、log_block_handler.h/cpp负责日志文件的分配与回收日志写入log_group_buffer.h/cpp、log_group_entry.h/cpp负责日志的组提交与批量写入日志读取log_iterator_impl.h、log_iterator_storage.h/cpp用于日志回放与追平日志补齐fetch_log_engine.h/cpp、log_learner.h/cpp实现从副本向主副本拉取缺失日志共识与选举election/algorithm/目录下包含election_impl、election_proposer、election_acceptor等实现是 Paxos 选举与提案的核心算法。在 log_define.h 中可以看到日志流的关键工程参数帮助理解其设计取舍单条日志体最大 3.5MBMAX_LOG_BODY_SIZE 3 * 1024 * 1024 512 * 1024物理日志块大小为 64MBPALF_PHY_BLOCK_SIZE 1 26Leader 的 group buffer 默认 32MBLEADER_DEFAULT_GROUP_BUFFER_SIZE 1 25Follower 在此基础上多预留 8MB共识滑动窗口默认 2048PALF_SLIDING_WINDOW_SIZE 1 11Leader 最多并发提交的日志数为窗口的一半日志同步延迟阈值 3 秒PALF_LOG_SYNC_DELAY_THRESHOLD_US 3 * 1000 * 1000可作为判断副本是否健康的标准。4.4 日志流迁移与负载均衡Tablet 可以在日志流之间迁移以实现资源的负载均衡。这一能力与分区的分布调度相配合当某节点负载过高时可以通过迁移 Tablet 把数据与日志压力分散到其他节点从而支持在线扩缩容与热点治理。五、OBServer单节点数据库服务集群的每个节点上运行一个名为observer的服务进程入口见 src/observer/main.cpp。每个 observer 进程负责本节点上分区数据的存取路由到本机的 SQL 语句的解析与执行监听来自外部应用的连接请求建立连接和数据库会话对外提供数据库服务。节点之间通过 TCP/IP 协议通信。observer 进程内部同时包含 SQL 引擎src/sql、存储引擎src/storage与事务引擎是计算与存储一体的数据库服务节点。六、多租户架构6.1 租户即数据库实例为简化大规模部署多个业务数据库的管理并降低资源成本OceanBase 提供了多租户Multi-Tenant特性在一个集群内可以创建多个相互隔离的数据库实例每个实例称为一个租户Tenant。从应用程序视角看每个租户等同于一个独立的数据库实例。每个租户可以选择MySQL 兼容模式或Oracle 兼容模式应用连接到 MySQL 租户后可以创建用户、database使用体验与独立 MySQL 库一致集群初始化后会自动存在一个名为sys的系统租户保存集群元数据本身是 MySQL 兼容模式租户。从源码结构看多租户的核心实现在 src/observer/omtOMTObserver Multi-Tenant其中 ob_multi_tenant.h 定义了ObMultiTenant类提供create_tenant、create_tenant_without_unit、update_tenant_unit等接口对应租户创建与资源单元变更等操作租户对象的定义在 ob_tenant.h。6.2 Meta 租户除了系统租户与用户租户OceanBase 还有一个特殊的Meta 租户每创建一个用户租户系统就自动创建一个对应的 Meta 租户生命周期与用户租户保持一致Meta 租户用于存储和管理用户租户的集群私有数据这部分数据不需要进行跨库物理同步以及物理备份恢复典型内容包含配置项、位置信息、副本信息、日志流状态、备份恢复相关信息、合并信息等。将集群私有的元数据与用户数据分离是 OceanBase 多租户能够做到高效隔离与快速恢复的关键设计。七、资源单元Resource Unit与资源池为了隔离租户的资源每个 observer 进程内可以有多个属于不同租户的虚拟容器称为资源单元resource unit。资源单元封装了CPU内存磁盘资源多个资源单元组成一个资源池resource pool资源池用于指定使用哪个资源单元使用多少个资源单元资源分布的可用区。创建租户时指定所使用的资源池列表即可控制租户可使用的资源总量与数据分布位置。这一机制配合ObMultiTenant::update_tenant_unit等接口见 ob_multi_tenant.h支持租户资源的在线调整。八、obproxy无状态连接代理应用程序通常并不直接与 OBServer 建立连接而是先连接obproxy再由 obproxy 将 SQL 请求转发到合适的 OBServer 节点。路由能力obproxy 会缓存数据分区相关的信息将 SQL 请求路由到尽量合适的 OBServer 节点尽量做到请求直达数据所在节点减少跨节点转发开销无状态设计obproxy 本身不保存任何持久化状态多个 obproxy 节点可以通过网络负载均衡SLB对外提供统一的网络地址实现代理层自身的水平扩展与高可用兼容接入在 SQL 引擎侧也存在与 obproxy 的交互逻辑例如 src/sql/optimizer/ob_route_policy.h 中的路由策略定义进一步印证了路由到合适节点这一设计在查询优化层面的配合。九、架构总结回顾全文OceanBase 的架构可以概括为一条完整的数据链路接入层应用 → SLB → 多个无状态 obproxy统一入口并做初步路由服务层obproxy 将请求转发至 Zone 内合适的 observer 进程observer 负责 SQL 解析执行与数据存取数据层数据按分区Partition水平拆分每个分区对应一个 Tablet 存储载体Tablet 归属于日志流Log Stream一致性层日志流基于 Multi-Paxos 在多个 Zone 的副本间复制 REDO 日志主副本Leader对外服务多数派确认即提交隔离层资源单元/资源池划分 CPU、内存与磁盘多租户含系统租户、用户租户与 Meta 租户在同一集群内实现相互隔离的数据库实例。这套Shared-Nothing Paxos 分区/日志流 多租户的组合构成了 OceanBase 可扩展、高可用、高性能、低成本四大特性的底层根基也是理解其后续存储、事务与 SQL 引擎实现的总纲。【免费下载链接】oceanbaseOceanBase is the unified distributed database for the AI era — open-source, multi-model, one engine for your most demanding workloads.项目地址: https://gitcode.com/GitHub_Trending/oc/oceanbase创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考