GBase 8a 生产部署前的操作系统调优:ulimit、内核参数、磁盘与网络全攻略
数据库性能的天花板,很大程度上由操作系统层决定。本文系统整理 GBase 8a 上线前必须完成的 OS 级配置:文件句柄限制、虚拟内存参数、I/O 调度器、网络栈调优,以及常见因 OS 配置不当导致集群异常的排查方法。
一、为什么 OS 调优对 MPP 很重要
GBase 8a 的 gnode 进程在高并发查询时会同时打开大量数据文件,gcluster 节点间通信会建立大量 TCP 连接,数据加载期间 I/O 吞吐量会接近磁盘上限。如果操作系统的默认限制没有放开,轻则性能低下,重则节点报错 CLOSE、集群进入 INACTIVE。
二、用户级资源限制(ulimit)
2.1 查看当前限制
# 切换到 gbase 用户后查看
su - gbase
ulimit -a
# 重点关注:
# open files (-n) 1024 ← 太小,会导致 "too many open files" 错误
# max user processes (-u) 4096
GBase 8a 生产环境的推荐值:
| 参数 | 含义 | 推荐值 |
|---|---|---|
nofile (open files) |
单进程最大打开文件数 | 655360 |
nproc (max user processes) |
用户最大进程/线程数 | 655360 |
stack (stack size) |
线程栈大小 | unlimited 或 65536 |
core (core file size) |
core dump 文件大小 | unlimited(便于故障分析) |
2.2 配置方法(多处都要改,缺一不可)
方法一:/etc/security/limits.conf
vim /etc/security/limits.conf
# 在文件末尾追加(对所有用户生效,也可替换 * 为 gbase)
* soft nofile 655360
* hard nofile 655360
* soft nproc 655360
* hard nproc 655360
* soft core unlimited
* hard core unlimited
方法二:/etc/security/limits.d/20-nproc.conf
某些 CentOS/RHEL 版本会用此文件覆盖 limits.conf 中的 nproc 设置:
vim /etc/security/limits.d/20-nproc.conf
# 修改或追加:
* soft nproc 655360
root soft nproc unlimited
方法三:/etc/profile(针对 SSH 登录 Shell)
vim /etc/profile
# 末尾追加
ulimit -n 655360
ulimit -u 655360
source /etc/profile
方法四:/etc/systemd/system.conf(针对 systemd 管理的服务进程)
如果 gbase 服务通过 systemd 启动,limits.conf 不一定生效,必须同时配置 systemd:
vim /etc/systemd/system.conf
# 找到并修改(或取消注释):
DefaultLimitNOFILE=655360
DefaultLimitNPROC=655360
DefaultLimitCORE=infinity
# 使配置生效
systemctl daemon-reexec
service sshd restart
2.3 验证配置是否生效
# 重新登录 gbase 用户后验证
su - gbase
ulimit -n # 应显示 655360
ulimit -u # 应显示 655360
# 验证 gnode 进程的实际限制
PID=$(pgrep -f gbase | head -1)
cat /proc/$PID/limits | grep -E "Max open files|Max processes"
⚠️ 常见陷阱:limits.conf 已配置,但进程限制未生效。原因通常是服务通过 systemd 启动,而 systemd 有自己独立的 limits 配置(
/etc/systemd/system.conf或服务单元文件中的LimitNOFILE)。必须两处都配置。
三、虚拟内存与内核参数(sysctl)
3.1 核心参数配置
vim /etc/sysctl.conf
追加以下配置:
# ============================================================
# 虚拟内存
# ============================================================
# 禁用 swap(MPP 数据库的内存操作不适合 swap,一旦 swap 性能断崖式下降)
# 0 = 内存不足时尽量不用 swap;生产建议设 1,避免 OOM Killer
vm.swappiness = 1
# 内存脏页刷新比例(比例越小,刷盘越频繁,避免 I/O 突刺)
vm.dirty_ratio = 10
vm.dirty_background_ratio = 5
# 大页内存(HugePage)支持,减少 TLB 缺失
# 先计算需要的大页数:gnode 使用内存 / 2MB(HugePage 默认 2MB)
# 例如 gnode 使用 64GB:64 * 1024 / 2 = 32768
vm.nr_hugepages = 32768
# 关闭透明大页(THP),THP 的动态碎片整理会引起不可预测的延迟
# (通过 grub 或 rc.local 控制,见后文)
# ============================================================
# 文件系统
# ============================================================
# 系统级最大打开文件数(所有进程合计)
fs.file-max = 6553560
# 文件系统通知实例上限(inotify)
fs.inotify.max_user_instances = 8192
fs.inotify.max_user_watches = 1048576
# ============================================================
# 网络
# ============================================================
# TCP 发送/接收缓冲区(节点间数据传输大缓冲区)
net.core.rmem_max = 134217728 # 128MB
net.core.wmem_max = 134217728 # 128MB
net.core.rmem_default = 25165824 # 24MB
net.core.wmem_default = 25165824 # 24MB
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 87380 134217728
# 网络接收队列长度(高并发下防止丢包)
net.core.netdev_max_backlog = 250000
net.core.somaxconn = 65535
# TIME_WAIT 连接快速回收(节点间频繁短连接场景)
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
# 本地端口范围(增大可用端口数,避免端口耗尽)
net.ipv4.ip_local_port_range = 10000 65000
# Keepalive(及时检测死连接)
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
# ============================================================
# 共享内存(进程间通信,gcluster 内部使用)
# ============================================================
kernel.shmmax = 68719476736 # 64GB,不低于单个 gcluster/gnode 使用的内存
kernel.shmall = 4294967296 # 系统总共享内存页数
kernel.sem = 250 32000 100 128
立即生效:
sysctl -p
3.2 关闭透明大页(THP)
THP 的后台碎片整理(khugepaged)会在不可预测的时间点产生明显的 CPU 和 I/O 延迟,是数据库查询 P99 延迟抖动的常见根因之一。
# 临时关闭(重启失效)
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
# 永久关闭(CentOS 7 / RHEL 7)
# 修改 /etc/rc.d/rc.local,追加:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
chmod +x /etc/rc.d/rc.local
# 验证
cat /sys/kernel/mm/transparent_hugepage/enabled
# 期望输出:always madvise [never] ← [never] 表示已关闭
四、磁盘 I/O 调优
4.1 I/O 调度器选择
GBase 8a 的 gnode 数据目录有大量顺序读写(列存扫描)和随机读写(索引/元数据)混合的 I/O 模式。
# 查看当前调度器
cat /sys/block/sdb/queue/scheduler
# 示例输出:[mq-deadline] kyber bfq ← 方括号内是当前使用的
# 对于 HDD(机械硬盘):推荐 deadline 或 mq-deadline
echo deadline > /sys/block/sdb/queue/scheduler
# 对于 SSD / NVMe:推荐 noop 或 none(绕过调度队列,SSD 自身处理)
echo noop > /sys/block/sdb/queue/scheduler
永久生效(写入 udev 规则):
vim /etc/udev/rules.d/60-io-scheduler.rules
# HDD 设备
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="deadline"
# SSD 设备
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="noop"
4.2 块设备队列深度
对于 SSD/NVMe,增大队列深度可以充分利用设备的并发 I/O 能力:
# 查看当前队列深度
cat /sys/block/nvme0n1/queue/nr_requests # NVMe
cat /sys/block/sdb/queue/nr_requests # SATA SSD
# NVMe 推荐值
echo 1024 > /sys/block/nvme0n1/queue/nr_requests
# HDD 推荐值(过大反而增加延迟)
echo 128 > /sys/block/sdb/queue/nr_requests
4.3 文件系统选择与挂载参数
GBase 8a 数据目录推荐使用 XFS(性能优于 ext4,特别是大文件和高并发场景):
# 格式化为 XFS
mkfs.xfs -f /dev/sdb
# 挂载参数(/etc/fstab)
# noatime:不更新访问时间,减少不必要的写操作
# nodiratime:目录也不更新访问时间
# nobarrier:SSD 上可以关闭写屏障(HDD 和有电容保护的 RAID 卡不要关)
/dev/sdb /opt/gbase xfs defaults,noatime,nodiratime 0 0
五、NUMA 架构注意事项
多路服务器(2 路、4 路 CPU)具有 NUMA(Non-Uniform Memory Access)架构,内存分属不同的 NUMA 节点。跨 NUMA 内存访问延迟是本地访问的 2~3 倍。
5.1 查看 NUMA 拓扑
numactl --hardware
# 示例输出:
# available: 2 nodes (0-1)
# node 0 cpus: 0-15 32-47
# node 0 size: 64430 MB
# node 1 cpus: 16-31 48-63
# node 1 size: 64508 MB
5.2 绑定 gnode 进程到指定 NUMA 节点
如果服务器是 2 路 CPU,可以将 gnode 进程绑定到 NUMA 节点 0,避免跨节点内存访问:
# 启动 gnode 时指定 NUMA 节点
numactl --cpunodebind=0 --membind=0 -- gbase_services gbase start
# 或在 gbase 启动脚本中加入 numactl 前缀
5.3 关闭 NUMA 平衡(避免内存自动迁移抖动)
# 禁用自动 NUMA 内存页迁移
echo 0 > /proc/sys/kernel/numa_balancing
# 永久化(写入 sysctl.conf)
kernel.numa_balancing = 0
六、网络配置检查
6.1 节点间网络带宽验证
GBase 8a 数据重分布和加载期间,节点间网络是瓶颈之一。上线前用 iperf3 验证实际带宽:
# 在节点 B 启动服务端
iperf3 -s
# 在节点 A 测试到节点 B 的双向带宽
iperf3 -c 10.168.10.27 -t 30 -P 4 # 4 个并发连接,测 30 秒
# 期望:万兆网卡应达到 9Gbps 以上
6.2 网卡中断绑定(IRQ Affinity)
高带宽场景下,网卡中断集中在 CPU 0 会成为瓶颈。开启 irqbalance 或手动绑定:
# 检查中断分布
cat /proc/interrupts | grep -i eth
# 开启 irqbalance 自动均衡(CentOS 7)
systemctl enable irqbalance
systemctl start irqbalance
七、一键检查脚本
将以下脚本保存为 check_os_params.sh,在部署前在每个节点执行:
#!/bin/bash
# GBase 8a 部署前 OS 参数检查
echo "===== 文件句柄限制 ====="
su - gbase -c "ulimit -n" 2>/dev/null || echo "无法切换 gbase 用户"
echo "系统级 file-max: $(cat /proc/sys/fs/file-max)"
echo ""
echo "===== 透明大页 ====="
cat /sys/kernel/mm/transparent_hugepage/enabled
echo ""
echo "===== Swap 使用情况 ====="
free -h
cat /proc/sys/vm/swappiness
echo ""
echo "===== 磁盘调度器 ====="
for disk in $(ls /sys/block/ | grep -E '^sd|^nvme'); do
echo "$disk: $(cat /sys/block/$disk/queue/scheduler 2>/dev/null)"
done
echo ""
echo "===== 网络参数 ====="
sysctl net.core.rmem_max net.core.wmem_max net.ipv4.tcp_tw_reuse
echo ""
echo "===== 时间同步状态 ====="
timedatectl status | grep -E "synchronized|NTP"
echo ""
echo "===== SELinux 状态 ====="
sestatus 2>/dev/null || echo "sestatus 不可用"
echo ""
echo "===== 防火墙状态 ====="
systemctl status firewalld 2>/dev/null | grep Active
八、配置清单
以下是部署 GBase 8a 之前需要完成的 OS 配置项汇总:
| 配置项 | 推荐值 | 配置文件 |
|---|---|---|
| nofile(文件句柄) | 655360 | limits.conf + systemd |
| nproc(最大进程数) | 655360 | limits.conf + 20-nproc.conf |
| vm.swappiness | 1 | /etc/sysctl.conf |
| vm.dirty_ratio | 10 | /etc/sysctl.conf |
| 透明大页(THP) | never | /etc/rc.local |
| I/O 调度器(HDD) | deadline | udev rules |
| I/O 调度器(SSD) | noop | udev rules |
| 文件系统 | XFS,noatime 挂载 | /etc/fstab |
| net.core.rmem_max | 134217728 | /etc/sysctl.conf |
| net.core.wmem_max | 134217728 | /etc/sysctl.conf |
| NUMA 平衡 | 关闭 | /etc/sysctl.conf |
| SELinux | disabled | /etc/selinux/config |
| 防火墙 | 关闭或放行 5258/UDP 5405 | systemctl |
| 时间同步 | NTP 已开启,各节点差 < 1s | chrony/ntpd |
九、常见因 OS 配置不当引发的集群问题
| 现象 | 根因 | 解决 |
|---|---|---|
gnode CLOSE,日志报 Too many open files |
nofile 限制未放开 | 修改 limits.conf + systemd,重启服务 |
| 查询随机出现几秒卡顿(P99 延迟高) | THP 后台碎片整理 | 关闭透明大页 |
| 数据加载时网络吞吐不足(< 1Gbps) | TCP 缓冲区太小 | 调大 rmem_max/wmem_max |
| 大内存节点 gnode 频繁 OOM | swap 过度使用,内存压力触发 OOM Killer | vm.swappiness=1,扩大内存或调小 gbase_memory_pct_target |
| 节点间连接频繁断开 | TCP keepalive 时间太长,中间防火墙断空闲连接 | 调小 tcp_keepalive_time |
gcware 报 port_scanning error cfg_connect_timeout |
防火墙阻断了 corosync UDP 5405 端口 | 放行该端口或关闭防火墙 |
安装脚本报 IPV6 protocol not supported |
IPv6 被禁用 | 开启 IPv6:net.ipv6.conf.all.disable_ipv6=0 |
热门帖子
- 12025-12-01浏览数:183632
- 22023-05-09浏览数:26324
- 42023-09-25浏览数:19993
- 52020-05-11浏览数:18703