☰
OceanBase社区版部署实操:从资源规划到三副本集群避坑指南
2026/10/20 16:39:03 网站建设 项目流程

社区版OceanBase部署流程看着就是下载安装包、敲几条命令的事,但真到自己动手的时候,你会发现真正耗时间的不是命令本身,而是命令背后的规划。单机还是三节点?内存给到多少Observer才不会频繁告警?进程到底用哪个系统用户跑?这些问题没想清楚之前,所谓部署不过是把一套默认参数抄一遍而已。这篇内容不是官方文档的复述,而是我从裸机环境到集群可用的实操记录,适合刚拿到社区版准备体验的开发者,也适合公司内部要搭一套测试环境的DBA。我会尽量把“为什么这样做”也讲清楚,而不是只给一串能直接复制的命令。

1. 部署前先回答三个问题:资源怎么定、单机还是三机、哪个用户来跑

很多人在部署前最容易犯的一个错误,是先把安装包装上再说。结果就是Observer进程起了、 sys 租户连上了,但过两天就被内存告警、磁盘写满、节点时钟漂移这类问题反复折腾。所以第一步不是下载,而是用十分钟把下面三个问题定下来。

1.1 硬件资源的下限与舒适区

社区版官方给过很低的硬件下限,比如 2 个 vCPU、8GB 内存就能装一个单机环境。这个配置做功能验证是够的,但如果你打算让它承载任何带一点并发的测试,我建议直接把内存放到 32GB 以上,CPU 给到 8 核以上。

原因在于Observer的内存模型。它会把配置里memory_limit对应的内存预占掉,内部再分出两部分:一部分放MemTable的写入缓冲,一部分留给系统表和各种缓存。如果物理内存只有 8GB,而你按默认比例分配了 6GB 给Observer,留给操作系统和ssh进程的余量就非常局促。我在最小配置上碰到过多次节点假死,排查到最后都是Swap和OOM Killer的锅。

磁盘方面,首先要保证的是节点之间的本地盘独立,尽量不要用共享盘/网络盘承载datafile_size。社区版默认数据文件是自动扩展的,初始创建的文件大小和datafile_size参数有关,而这个文件最终会占满你给它预留的空间。所以部署前要做一件很朴素的事:df -h看清楚哪个分区是独立数据盘,别顺手把数据目录写在系统盘上。

1.2 单机、三副本和“三台机器”之间的关系

“分布式数据库”这几个字容易让人产生一个误解:只要我有三台机器,部署出来就是三副本高可用。黑马的是,OceanBase里“副本”的分发是按zone来理解的,一台机器上也可以塞一个zone,而三副本其实是三个zone里各一份数据。

做一个单机学习环境,最简单的拓扑就是一台机器、一个zone、一个observer。这个形态能验证绝大多数功能,但不能提供高可用。想要有容灾效果,至少需要三个不同的节点,分别对应三个zone,每个zone各部署一个observer,然后创建租户时把副本数设置为3。

这里我整理过一张很直接的对比表:

部署形态节点数量副本数用途风险
单机单副本11功能体验、开发联调节点挂了数据可能就没了
单机多observer13模拟三副本的SQL层行为同一台物理机,磁盘/OS还是单点
三机三观测者33测试环境、轻生产网络分区和时钟同步必须处理
三机混合多cluster3多大规模压测或隔离资源分配和运维复杂度上升

如果你在公司内部只要一套测试环境,我建议直接按“三机三zone三副本”来搭。这一步的规划决定了后面租户副本数的上限,集群搭好了再想从单副本改成三副本,虽然能通过添加observer和修改租户来实现,但过程涉及数据均衡,远比一开始就搭对要麻烦。

1.3 运行用户与安装包选型

社区版目前的部署工具OBD(oceanbase-deployer)会自动去目标机器上创建和管理observer进程,但这里有一个很多教程都没强调的点:尽量不要用root直接启动整个集群,更不要用一个密码强度为空的普通用户。官方文档里的通用做法是预先在所有节点上创建一个统一的系统用户,比如 admin。

我每次部署前都会先在每台机器上执行:

useradd -m admin echo '自定义强密码' | passwd --stdin admin echo 'admin ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/admin

这个用户的作用不只是启动进程。OBD在初始化集群时,需要在目标机器上做目录创建、权限修改、日志收集等操作,如果sudo权限没提前配好,后面会死在各种莫名其妙的“Permission denied”上。至于安装包,社区版现在都是rpm/tar包形式,我推荐rpm方式,因为它会把obd命令和依赖一并装好,省得手工折腾Python依赖。

2. 用OBD拉起集群前,配置文件里的每个关键字段都要先算一遍

OBD是社区版里负责部署、启停、扩容、日志聚合的工具。它的工作逻辑很直接:你给它一份YAML配置,它根据配置分发安装包、初始化目录、生成observer启动参数,然后按顺序拉起所有节点。如果你不用OBD,强行手工拆rpm再手写observer启动命令,也不是不行,但光参数就有上百个,任何一个填错都会让整个集群处于“半死不活”的状态。

2.1 OBD的安装和第一条命令

OBD本身是个Python工具,rpm装完后直接验证版本:

obd --version

如果输出正常,就可以开始写集群配置。值得先说明的是,OBD支持两种部署风格:一种是完全凭配置文件部署,另一种是obd demo直接起一个本地演示集群。演示模式适合第一次跑通,但生产或测试环境我基本不用,因为它会把很多资源参数设置得过于保守,后续改成真实环境时反而要重新调整。

2.2 一份基础配置的逐字段拆解

下面这份配置是我在测试环境常用的简化版,三个节点,三副本,没有额外的OBProxy部分。你可以先看整体结构,后面我会逐段解释关键字段为什么这样填。

user: admin oceanbase-ce: servers: - name: ob1 ip: 192.168.10.11 - name: ob2 ip: 192.168.10.12 - name: ob3 ip: 192.168.10.13 global: home_path: /data/oceanbase/observer data_dir: /data/oceanbase/store redolog_dir: /data/oceanbase/log mysql_port: 2881 rpc_port: 2882 cluster_id: 1 cpu_count: 16 memory_limit: 40G system_memory: 8G datafile_size: 100G log_disk_size: 20G

解释几个最重要的:

  • data_dir:这是数据文件目录,对应后续SSTable的存放位置。我习惯放到独立数据盘,路径和系统盘分开。
  • redolog_dir:clog和ilog文件所在目录。这个目录的写延迟直接决定事务提交的响应时间,所以优先选SSD或高性能磁盘,别和data_dir挤在同一个机械盘上。
  • mysql_port、rpc_port:前者是MySQL协议接入端口,默认2881;后者是节点间内部通信端口,默认2882。很多人只记得开2881,忘了2882,结果客户端能连上,集群内部却一直起不来。
  • memory_limit:直接限定observer进程最多能使用的内存。它不是物理内存总量减去操作系统的剩余量,而是你主动告诉observer“你最多可以占这么多”。
  • system_memory:给系统租户用的内存,主要存放系统表、字典等基础元数据。不能设得太小,否则部分系统查死慢。
  • datafile_size:SSTable数据文件的预分配上限,可以理解成一个文件块文件。它会在启动时按这个值预留空间,所以不能超过所在分区的大小。
  • log_disk_size:redo log写的磁盘占用量,通常会大于内存里的事务日志缓冲。

说一个常见的计算逻辑:假设物理内存是 64G,我一般会先把memory_limit设为 45G 左右,再给system_memory留 8G 到 12G,同时确保操作系统和tcp缓冲区还有差不多 8G 余量。如果你直接填memory_limit: 60G,大概率会在高并发下触发系统Swap,因为内存并没有完全被observer独占,内核的page cache、网络协议栈还要吃一部分。

2.3 从deploy到start的完整命令链路

配置文件写好之后,整个拉起流程非常短:

obd cluster deploy myob -c myob.yaml obd cluster start myob obd cluster status myob

deploy会做一次预检,包括目标机器连通性、磁盘剩余空间、admin用户的sudo权限、端口占用等。如果预检报错,不要硬skip,我吃过亏:在端口被占用的机器上强制部署,结果OBD提示部署成功,但obd cluster start时节点日志里全是“bind: Address already in use”。

status会列出每个组件的运行状态。正常的输出里observer进程应该是active,并且Version列显示具体版本号。如果某节点起不来,第一件事是看日志,而不是重装:

obd cluster log myob --tail=100

日志里最常出现的三个关键词是disk space、permission denied和network unreachable。这三个词分别对应我第5节要讲的三个坑。

3. 两条典型部署路径:单机练手和三节点生产

配置文件的参数理解了以后,实际部署路径其实就两条。一条是单机跑通流程,另一条是三节点直接进入可用状态。这两条路径的区别不只是机器数量,还包括你该关注的检查项。

3.1 单机:用最少资源把全链路跑通

单机部署时,我会把第2节那份三节点配置改成一个节点、一个zone。还有一个更偷懒但也足够用的方式,是把配置文件里的servers只保留127.0.0.1,zone不专门设置,OBD会默认生成一个zone。

部署命令和前面一样:

obd cluster deploy ob-test -c single.yaml obd cluster start ob-test

这里要注意一个反常识的点:单机也可以创建三副本租户,前提是你在同一台机器上拉了三个observer进程,并把它们划分到三个zone。这种形态的本质意义是验证SQL层、分布式事务和副本切换的代码路径,但它不能抵御物理机故障。如果你只是为了熟悉命令和验证业务SQL,完全没有必要搞三个observer,单节点单副本就够。

单机环境下,创建租户的语法和集群环境完全一致。我经常看到有人以为单机就不能用三副本资源池,其实是可以创建的,只是底下的副本都会落在同一台机器上,节点间RPC走的是回环地址。

3.2 三节点生产形态:zone规划比参数配置更容易忽略

三节点部署时,我习惯把三个节点分别命名为zone1、zone2、zone3,每个zone里只放一台observer。这样做的好处是后续扩容、替换、升级时,zone的边界非常清晰,不会出现“一个zone里同时有两台observer,其中一台还挂了”的状态。

Oracle的部署阶段,还有一个绕不开的检查项:节点间网络延迟。observer之间通过2882端口做内部通信,如果三台机器跨了很大的网络延迟区间,比如一台在本地、一台在异地机房,那么每次事务提交的同步耗时会被明显拉长。社区版默认参数对网络分区不会有太多宽容,日志里会出现大量“heartbeat timeout”信息。

三节点部署完成后,我做的第一件不是跑压测,而是在sys租户下执行:

SELECT * FROM oceanbase.DBA_OB_SERVERS;

正常状态应该是三条记录,每个节点的STATUS为ACTIVE且STOP_TIME为空。接下来建议立刻修改root用户的密码,因为在初始化阶段root@sys可能用的是无密码或弱密码状态:

ALTER USER 'root'@'%' IDENTIFIED BY '新密码';

这一步放在业务接入前做,可以避免后续安全扫描时的尴尬。

3.3 部署完成后的节点替换视角

很多人部署完就把节点信息丢一边了,等到要加机器时才重新翻文档。这里我建议从一开始就记录三份信息:机器IP、observer数据目录、observer所在zone。后续某台物理机要下线,或者在控制台里看到某个observer的STATUS变灰了,你需要的是“先补一个同等资源配置的observer”,再“把故障节点从集群中剔除”。

这个过程不是简单的obd cluster destroy重来。正确做法是先改配置把新节点加入,然后等数据副本迁移完成,再让故障节点下线。理解这个逻辑后,你就知道为什么当初部署时不能把三个节点塞到同一个zone里,因为那样做会让副本调度无从选择。

4. 第一次启动后别急着接业务,先做这套体检流程

Observer进程全部active,不代表集群已经准备好接业务了。我通常会在启动后的两个小时内做一套体检,按顺序检查节点、租户、接入层和备份,每一项都不复杂,但漏掉一项后面都会找补很久。

4.1 检查observer节奏,而不是只看进程是否活着

用obd cluster status只能确认进程没退。数据库内部的“活”要满足两个条件:节点心跳正常、系统日志没有持续刷错误。最直观的检查语句:

SELECT zone, server_ip, status, stop_time FROM oceanbase.DBA_OB_SERVERS;

如果所有stop_time都有值,说明节点还在恢复过程中;如果某个节点status是INACTIVE,先看它的心跳是否超时,再检查网络和时钟。

接着看一下资源参数是否与配置文件一致:

SHOW PARAMETERS LIKE '%memory_limit%'; SHOW PARAMETERS LIKE '%system_memory%';

这一步是为了确认OBD在推送配置时没有做换算或覆盖。我遇到过memory_limit在配置文件里写的是40G,但实际observer进程只识别到32G的情况,原因是在某些平台下OBD会根据内核参数做默认校准。

4.2 以最快的节奏创建业务租户

集群本身只有一个 sys 租户,业务数据不应该直接写进 sys。创建业务租户需要三步,用一条SQL脚本串联起来:

CREATE RESOURCE UNIT u_test MAX_CPU 4, MIN_CPU 4, MEMORY_SIZE '8G', MAX_IOPS 10000, MIN_IOPS 10000; CREATE RESOURCE POOL p_test UNIT = 'u_test', UNIT_NUM = 1, ZONE_LIST = ('zone1', 'zone2', 'zone3'); CREATE TENANT t_test RESOURCE_POOL_LIST = ('p_test');

MAX_CPU和MIN_CPU我建议保持一致,避免CPU被调度器来回收缩导致延迟抖动。MEMORY_SIZE决定了这个租户能用的内存,它不能超过每个observer的memory_limit减去系统租户占用后的剩余值。

创建完成后,切到新租户验证连接:

obclient -h127.0.0.1 -P2881 -uroot@t_test -p

第一次登录建议马上改密码:

ALTER USER root IDENTIFIED BY '新密码';

4.3 接入层不要绕开OBProxy

单机或测试环境里,直接通过2881连observer没有任何问题。但进入三节点结构后,客户端如果直接连某一个observer,等于把连接全压到一台节点上,另一侧observer发生主备切换时,客户端也会因为连接断掉而报错。

更合理的方式是再部署一个OBProxy作为统一入口,它对外暴露2883端口,内部自动把请求分发到正确的observer。用OBD部署OBProxy的流程和部署observer基本一样,核心配置如下:

obproxy-ce: servers: - name: proxy1 ip: 192.168.10.20 global: home_path: /data/oceanbase/proxy listen_port: 2883 prometheus_listen_port: 2884 observer_cluster_name: myob

部署完成后客户端统一连:

obclient -h192.168.10.20 -P2883 -uroot@t_test -p

需要注意的是,OBProxy本身不参与数据副本,它不是数据库的高可用单元,所以它所在机器挂了,只是意味着入口没了,数据不会丢。

4.4 备份配置一定从启动当天就固化

我见过很多团队把备份放到“上线前”才想起来,实际上社区版的日志归档和数据备份应该从第一天就打开。在sys租户下设置备份目的路径:

ALTER SYSTEM SET backup_dest = 'file:///data/backup' ;

更稳妥的方式是挂一个独立的网络存储或对象存储目录,避免和observer数据放在同一块盘上。备份的目的不是保数据不出事,而是给自己一个“随时可以重来”的底气。部署后越早把这条链路打通,后面应对误删、误操作时越从容。

5. 部署路上最常翻车的四个细节:时钟、权限、端口、内存

最后这部分是我踩坑最集中的地方,也是每次给别人排查问题时第三句话就能猜中的情况。四个细节看起来都特别基础,但它们叠加起来,足够让一个看起来部署成功的集群在半夜报警。

5.1 时钟不同步:分布式集群的慢性病

Observer内部很多事情都依赖时间戳,比如事务版本、心跳、副本同步。三台机器的时钟如果差了几百毫秒,短期内看不出问题,但当主库切换或副本合并发生时,各种“timestamp not monotonic”会开始刷屏。

解决办法是所有节点装同一套时间同步服务,比如 chrony。配置文件里让它指向同一个上游时间源,并设置较小的最大误差范围。这里提醒一句:不要只在其中一台机器上配置,另外两台靠“手工校对”撑场面,因为日常运行中机器重启或NTP服务中断都会让时钟重新偏移。

部署完成后用命令逐个节点检查:

chronyc tracking

重点关注System time是否为Normal,以及RMS offset是否在数十毫秒以内。

5.2 目录权限:OBD部署失败的“无头冤案”

目录权限问题经常伪装成“磁盘空间不足”或者“observer进程莫名退出”。第1节里我要求创建统一的admin用户,就是为了让observer的安装目录、数据目录、日志目录全部归这个用户所有。如果某个目录不小心被root创建了,OBD在启动阶段能创建文件但无法覆盖已有文件,表现就是节点反复重启。

我在部署时固定执行:

mkdir -p /data/oceanbase chown -R admin:admin /data/oceanbase

部署完以后也要检查一下/data/oceanbase/log是否持续产生新日志。如果日志目录权限不对,最常见的结果是obd cluster log拉不到任何内容,而那恰恰是问题已经发生的时候。

5.3 端口与防火墙:东西向流量比南北向更容易被忽略

对外暴露给业务的端口是2881(observer MySQL协议)和2883(OBProxy入口),但节点与节点之间的心跳、日志同步走的是2882。很多人在云控制台或机房防火墙上只开了2881和2883,结果客户端能连上,observer之间的RPC却始终建不起来。

我在部署前三台机器之间的网络连通性会用一行命令验证:

telnet 192.168.10.12 2882

如果通则跳过,不通就必须先解决防火墙和路由问题。否则你可能会看到一个很怪的状态:obd cluster status显示所有节点都active,但DBA_OB_SERVERS里某个节点的HEARTBEAT时间一直停留在几分钟前。

5.4 内存比例:为什么集群经常OOM或心跳卡顿

第2节已经解释过memory_limit和system_memory的基本含义,这里补一个真实场景。某次我给一台 16GB 内存的机器分配了 14GB 给observer,创建租户时又按物理内存的一半来分,结果集群刚跑起来半小时,操作系统就进入了内存紧张状态,最后触发内核把observer进程杀了。

内存规划不能只看“observer分多少”,还要考虑操作系统、SSH会话、监控agent和page cache。我的经验公式是:

  • observer总占用建议控制在物理内存的 75% 到 80% 以内;
  • system_memory建议不低于物理内存的 10%,但不高于“observer总占用的一半”;
  • 租户MEMORY_SIZE建议不超过memory_limit - system_memory的 80% 左右。

如果你在部署完成后才发现参数不合适,不需要重新destroy整个集群。用obd cluster edit-config myob进入配置编辑,改完保存后执行obd cluster restart myob就能让新参数生效。

5.5 一次完整的“部署后翻车”排查过程

最后分享一个我近期遇到的案例,帮助你把上面四个细节串起来。当时三节点集群部署完成后,obd cluster status显示两个节点active,一个节点老是拉起后几十秒就退出。我先看了日志,问题不是权限,而是system_memory设置过大,导致创建租户后可用内存不足。于是我把system_memory从 12G 降到 8G,又顺手检查了一遍三个节点的时钟,发现有一台的RMS offset已经到 200 多毫秒。等chrony完成校准后,再用obd cluster restart拉起所有节点,集群这才稳定下来。

这个过程看起来是三个不同的问题,实际上都源于部署第一天没有把资源规划和基础系统检查做到位。先修掉这些底层的“慢性病”,再往上查SQL层、业务层的问题,你会发现排障速度快很多。

社区版OceanBase的部署真正难倒人的地方,通常不是那些花哨的分布式概念,而是一开始的基础参数和节点环境。把资源边界定清楚,把OBD配置里每个字段的含义算明白,再按一套固定的体检流程走一遍,这套集群基本就能进入稳定运行的状态。我这些年每次部署都会把上面的五个环节当成默认动作,如果你第一次搭,也建议从第1节的三个问题开始,而不是先急着解压安装包。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询