分享一个负载均衡的NDB高可用集群架构+部署详细说明

部署说明:

1个管理节点 :192.168.10.61

2个SQL 节点 :192.168.10.62/63

2个数据节点 :192.168.10.64/65

2个HAProxy+keepalived节点:IP:192.168.10.68/69 虚拟 VIP:192.168.10.100

优点

  • ✅ 业务零改动
  • ✅ 自动剔除故障 SQL 节点
  • ✅ 性能高
  • ✅ 生产最常见

架构:1个NDB-MGR节点、3个sql节点、2个db节点,2个HAProxy

业务系统


|


HAProxyA +KeepalivedA HAProxyB+KeepalivedB

linuxA:192.168.10.68 linuxB:192.168.10.69

(VRRP)虚拟 VIP:192.168.10.100 配置文件中优先级高的为主


|


sql1 sql2

命令汇总:

复制代码
DB节点:
#关闭+启动db节点
[root@localhost src]# pkill -9 ndbd
[root@localhost src]# ndbd
MGR节点:
#查看所有的节点状态
ndb_mgm -e "show"
#停止ndb_mgm
/usr/local/mysql/bin/ndb_mgm -e "shutdown"
#启动ndb_mgm
ndb_mgmd --ndb-nodeid=1 --config-file=/usr/local/mysql/ndb_data/config.ini
sql节点:
systemctl start mysqld

HAProxy+keepalived:
systemctl start keepalived
systemctl start haproxy

部署NDB集群:

第一步:所有节点通用环境准备(必做)

登录每个节点(61/62/63/64/65)执行以下操作,统一环境基础。

1. 关闭防火墙和 SELinux(避免端口 / 权限拦截)
复制代码
# 临时关闭防火墙
systemctl stop firewalld && systemctl disable firewalld
# 临时关闭 SELinux
setenforce 0
# 永久关闭 SELinux(重启生效)
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config


cat > /etc/hosts << EOF
192.168.10.61  ndb-master
192.168.10.62  ndb-sql1
192.168.10.63  ndb-sql2
192.168.10.64  ndb-db1
192.168.10.65  ndb-db2
EOF
2. 安装基础依赖(解决组件启动依赖)
复制代码
yum install -y libaio-devel numactl-devel perl net-tools wget libnuma-devel gcc-c++
3. 创建 MySQL 专用用户(权限隔离)
复制代码
groupadd -r mysql
useradd -r -g mysql -s /sbin/nologin mysql
4. 上传并解压安装包(统一路径)
复制代码
# 1. 将 mysql-cluster-gpl-7.6.36-linux-glibc2.17-x86_64.tar.gz 上传至 /usr/local/src
# 可通过 scp 上传:scp 本地包路径 root@节点IP:/usr/local/src

# 2. 解压并创建软链接(简化后续路径)
cd /usr/local/src
tar -zxvf mysql-cluster-gpl-7.6.36-linux-glibc2.17-x86_64.tar.gz
ln -s /usr/local/src/mysql-cluster-gpl-7.6.36-linux-glibc2.17-x86_64 /usr/local/mysql

# 3. 设置目录权限(避免启动权限不足)
chown -R mysql:mysql /usr/local/mysql
5. 配置系统环境变量(全局可执行 MySQL 命令)
复制代码
echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile
source /etc/profile

# 验证:执行以下命令能看到版本则成功
mysql --version

第二步:管理节点(192.168.10.61)部署
1. 创建配置 / 数据目录
复制代码
mkdir -p /usr/local/mysql/ndb_data  # 存储集群配置、日志
chown -R mysql:mysql /usr/local/mysql/ndb_data
2. 编写核心集群配置文件(config.ini)

创建 /usr/local/mysql/ndb_data/config.ini,内容适配你的 IP 规划:

复制代码
cat > /usr/local/mysql/ndb_data/config.ini << EOF
# 数据节点通用配置(NDB 7.6 兼容版)
[NDBD DEFAULT]
NoOfReplicas=2              
# 副本数,匹配2个数据节点
DataMemory=1G               
# 数据内存(7.6版本仍支持)
IndexMemory=512M            
# 索引内存(虽提示过时,但7.6仍兼容,无需修改)
DataDir=/usr/local/mysql/ndb_data
MaxNoOfConcurrentTransactions=1000
MaxNoOfLocalOperations=100000  # 替换废弃的 MaxNoOfOperations
AutoReconnect=1
# 管理节点通用配置
[NDB_MGMD DEFAULT]
DataDir=/usr/local/mysql/ndb_data

# 具体管理节点配置
[NDB_MGMD]
NodeId=1
HostName=192.168.10.61

# 数据节点配置
[NDBD]
NodeId=2
HostName=192.168.10.64

[NDBD]
NodeId=3
HostName=192.168.10.65

# SQL节点配置
[MYSQLD]
NodeId=4
HostName=192.168.10.62

[MYSQLD]
NodeId=5
HostName=192.168.10.63

[MYSQLD]
NodeId=6
HostName=192.168.10.67
EOF
3. 启动管理节点
复制代码
# --initial:首次启动加(初始化配置),后续重启需去掉,否则会清空配置
ndb_mgmd --ndb-nodeid=1 --config-file=/usr/local/mysql/ndb_data/config.ini --initial

# 验证启动状态(查看 1186 端口是否监听,这是管理节点默认端口)
netstat -tulnp | grep 1186
# 正常输出:tcp  0  0 0.0.0.0:1186  0.0.0.0:*  LISTEN  xxx/ndb_mgmd
# 2. 查看集群拓扑状态(确认配置加载成功)
ndb_mgm -e "show"

第三步:数据节点(192.168.10.64/65)部署

两个数据节点操作完全一致,以下步骤在 64 和 65 节点分别执行,核心是部署 ndbd 组件,负责存储集群数据。

1. 创建数据存储目录
复制代码
mkdir -p /usr/local/mysql/ndb_data
chown -R mysql:mysql /usr/local/mysql/ndb_data
2. 编写 my.cnf 配置文件

创建 /etc/my.cnf(覆盖系统默认,若有原有文件先备份:cp /etc/my.cnf /etc/my.cnf.bak):

复制代码
cat > /etc/my.cnf << EOF
[mysqld]
# 启用NDB集群引擎(核心)
ndbcluster
# 指向管理节点IP(数据节点通过此连接管理节点)
ndb-connectstring=192.168.10.61
ndb-reconnect-delay=10  
# 断开后每10秒重试连接
ndb-try-reconnect=100   
# 最大重试次数(0=无限重试)
# 数据存储目录
datadir=/usr/local/mysql/ndb_data
# 套接字文件路径
socket=/tmp/mysql.sock
# 运行用户
user=mysql
# 禁用符号链接
symbolic-links=0

[mysql_cluster]
# 再次指定管理节点(双重保障)
ndb-connectstring=192.168.10.61

[mysqld_safe]
# 日志和PID文件路径
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

EOF
3. 启动数据节点
复制代码
# --initial:首次启动加(初始化数据目录),后续重启去掉
ndbd --initial

# 验证启动状态
netstat -tulnp | grep ndbd

第四步:SQL 节点(192.168.10.62/63)部署

两个 SQL 节点操作完全一致,以下步骤在 62 和 63 节点分别执行,核心是部署 mysqld 组件,负责接收客户端请求并转发到数据节点。

1. 初始化 MySQL(生成临时密码,核心步骤)
复制代码
# 创建日志和PID目录(避免初始化失败)
mkdir -p /var/log /var/run/mysqld
chown -R mysql:mysql /var/log /var/run/mysqld
chmod 755 /var/run/mysqld

# 2. 提前创建日志文件,避免权限问题
touch /var/log/mysqld.log
chown mysql:mysql /var/log/mysqld.log
chmod 640 /var/log/mysqld.log

# 3. 创建数据目录(和你之前一致)
mkdir -p /usr/local/mysql/ndb_data
chown -R mysql:mysql /usr/local/mysql/ndb_data

# 初始化MySQL(生成临时密码,务必保存)
/usr/local/mysql/bin/mysqld \
--initialize \
--user=mysql \
--datadir=/usr/local/mysql/ndb_data \
--socket=/tmp/mysql.sock \
--log-error=/var/log/mysqld.log

# 查看临时密码(关键!后续登录MySQL需要)
grep 'temporary password' /var/log/mysqld.log
# 示例输出:2026-01-09T08:00:00.000000Z 1 [Note] A temporary password is generated for root@localhost: abc123*xyz
2. 编写 my.cnf 配置文件
复制代码
cat > /etc/my.cnf << EOF
[mysqld]
# 核心:启用NDB集群引擎
ndbcluster
# 指向管理节点IP(确认是192.168.10.61,不是之前的51)
ndb-connectstring=192.168.10.61
# 数据存储目录(和初始化一致)
datadir=/usr/local/mysql/ndb_data
# 修正:改为实际的sock路径
socket=/var/run/mysqld/mysql.sock
# 运行用户
user=mysql
# 端口(默认3306)
port=3306
# 禁用符号链接
symbolic-links=0
# 跳过域名解析(提升连接性能)
skip_name_resolve=1
# 字符集配置(避免中文乱码)
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
# 消除TLS警告(禁用旧版TLS)
tls_version=TLSv1.2
# 消除TIMESTAMP警告
explicit_defaults_for_timestamp=1
# SQL节点ID(根据你的集群规划填,比如52节点填4,53节点填5)
#ndb-nodeid=5

[mysql_cluster]
# 指向管理节点(双重保障)
ndb-connectstring=192.168.10.61

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysql]
# 客户端连接用的sock路径(和mysqld一致)
socket=/var/run/mysqld/mysql.sock
EOF
3. 配置 MySQL 系统服务并启动
复制代码
# 创建服务文件
cat > /usr/lib/systemd/system/mysqld.service << EOF
[Unit]
Description=MySQL Server
After=network.target ndb_mgmd.service ndbd.service
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html

[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
LimitNOFILE = 5000
Restart=on-failure
RestartPreventExitStatus=1

[Install]
WantedBy=multi-user.target
EOF

# 加载服务并启动
systemctl daemon-reload
systemctl enable mysqld && systemctl start mysqld

# 验证启动状态
systemctl status mysqld
netstat -tulnp | grep 3306  # 查看3306端口是否监听
4. 修改 root 密码并配置远程访问
复制代码
# 用临时密码登录MySQL(替换为你查到的临时密码)
mysql -uroot -p';klxbUCWC90U'

# 修改root密码(替换为你的自定义密码,如 Root@123456,需符合复杂度)
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Root@123';
FLUSH PRIVILEGES;

# 允许root远程登录(生产环境建议限制IP,如 192.168.10.%)
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'Root@123' WITH GRANT OPTION;
FLUSH PRIVILEGES;

# 退出MySQL
exit;

第五步:集群启动顺序与验证
1. 严格遵守启动顺序(核心!)
复制代码
管理节点(61)→ 数据节点(64 → 65)→ SQL节点(62 → 63)

若启动顺序错误,会导致节点无法加入集群。

2. 集群状态验证(在管理节点 61 执行)
复制代码
# 进入NDB集群管理工具
ndb_mgm

# 查看集群所有节点状态
show

# 正常输出示例(关键看 Node status 为 started):
# Connected to Management Server at: 192.168.10.61:1186
# Cluster Configuration
# ---------------------
# [ndbd(NDB)]     2 node(s)
# id=2    @192.168.10.64  (mysql-7.6.36 NDB 7.6.36, Nodegroup: 0, *)
# id=3    @192.168.10.65  (mysql-7.6.36 NDB 7.6.36, Nodegroup: 0)
# 
# [ndb_mgmd(MGM)] 1 node(s)
# id=1    @192.168.10.61  (mysql-7.6.36 NDB 7.6.36)
# 
# [mysqld(API)]   2 node(s)
# id=4    @192.168.10.62  (mysql-7.6.36 NDB 7.6.36)
# id=5    @192.168.10.63  (mysql-7.6.36 NDB 7.6.36)

# 退出管理工具
exit
3. 数据同步验证(核心!验证集群有效性)
复制代码
# 1. 在 SQL 节点 62 执行:创建测试库和表(必须指定 ENGINE=NDB)
mysql -uroot -p'Root@123456' -e "
CREATE DATABASE IF NOT EXISTS ndb_test;
USE ndb_test;
CREATE TABLE IF NOT EXISTS test_table (
  id INT PRIMARY KEY,
  name VARCHAR(50)
) ENGINE=NDB;
INSERT INTO test_table VALUES (1, 'ndb_cluster_test');
SELECT * FROM test_table;"

# 2. 在 SQL 节点 63 执行:查询数据,验证同步
mysql -uroot -p'Root@123456' -e "USE ndb_test; SELECT * FROM test_table;"

# 若能查到数据(id=1, name=ndb_cluster_test),说明集群数据同步正常!

说明:

NDB启停管理节点时,SQL / 数据节点是否需要停?

  1. 停止管理节点时:无需停 SQL / 数据节点(核心结论)

NDB 集群的设计特点是管理节点仅负责集群配置分发和节点状态监控,不参与实际数据存储 / 查询,因此:

  • ✅ 停止管理节点后,已运行的 SQL 节点、数据节点会继续正常工作(数据读写不受影响);
  • ❗ 但此时无法执行集群管理操作(如新增节点、修改配置、查看节点状态),也无法重启 / 新增 SQL / 数据节点(因为新节点需要连接管理节点获取配置)。
  1. 启动管理节点时:无需停 SQL / 数据节点
  • 启动管理节点后,已运行的 SQL / 数据节点会自动重新连接管理节点(无需手动操作);
  • 如果启动时修改了config.ini(如新增节点、调整参数),需要在管理节点执行ndb_mgm -e "reload",数据节点会自动加载新配置(部分参数需重启数据节点)。
  1. 特殊场景:管理节点 + 数据节点 + SQL 节点的完整启停顺序(维护时用)

如果需要整体重启集群(如升级、修改核心配置),建议按以下顺序操作,避免数据不一致:

停止顺序(从依赖端到核心端)

  1. 先停SQL 节点(mysqld):避免应用继续发请求,防止连接报错;
  2. 再停数据节点(ndbd/ndbmtd):确保数据落盘,避免丢失;
  3. 最后停管理节点(ndb_mgmd)。

启动顺序(从核心端到依赖端)

  1. 先启管理节点(ndb_mgmd):先加载集群配置,为其他节点提供配置;
  2. 再启数据节点(ndbd/ndbmtd):连接管理节点获取配置,同步数据;
  3. 最后启SQL 节点(mysqld):连接管理节点 + 数据节点,提供 SQL 服务。

安装HAProxy+keepalived

第一步:安装 HAProxy和Keepalived (在 192.168.10.68、192.168.10.69分别 执行)

CentOS 7 源里直接有 HAProxy,直接安装即可:

复制代码
yum install -y haproxy keepalived psmisc net-tools
第二步:配置 HAProxyA 和HAProxyB

编辑配置文件 /etc/haproxy/haproxy.cfg,两台配置要完全一样

然后写入以下配置:

复制代码
cat > /etc/haproxy/haproxy.cfg << 'EOF'
global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/lib/haproxy/stats

defaults
    mode                    tcp
    log                     global
    option                  tcplog
    option                  dontlognull
    option http-server-close
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

# 管理监控页面 (可选,方便查看状态)
listen stats
    bind *:8080
    mode http
    stats enable
    stats uri /haproxy_stats
    stats realm Haproxy\ Statistics
     # 账号密码,自行修改
    stats auth admin:admin123

# MySQL 主负载均衡入口 (监听 3306)
listen mysql_cluster
    bind *:3306
    mode tcp
    balance roundrobin      
    # 轮询策略
    option mysql-check user haproxy_check  
    # 健康检查用户
    
    # 后端 SQL 节点
    server node62 192.168.10.62:3306 check weight 1 maxconn 1000
    server node63 192.168.10.63:3306 check weight 1 maxconn 1000
EOF
配置Keepalived
1:配置主节点 (Master - 192.168.10.68)

编辑 /etc/keepalived/keepalived.conf

复制代码
cat > /etc/keepalived/keepalived.conf << 'EOF'
global_defs {
   router_id LVS_DEVEL_60  # 标识,主备要不一样
}

# 定义脚本:检测 HAProxy 是否挂了
vrrp_script chk_haproxy {
    # 检查进程是否存在
    script "killall -0 haproxy"
    # 每2秒检查一次
    interval 2     
    # 如果检测失败,优先级减20
    weight -20                  
}

vrrp_instance VI_1 {
    # 主节点
    state MASTER
    # 你的网卡名称 (用 ip addr 查看)
    interface ens33
    # 主备必须一致
    virtual_router_id 51
     # 优先级,主比备大 (比如 100 > 80)
    priority 100 
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        # 这里写你的 VIP
        192.168.10.100
    }
    track_script {
         # 引用上面的检测脚本
        chk_haproxy
    }
}
EOF
2:配置备节点 (Backup - 192.168.10.69)

编辑 /etc/keepalived/keepalived.conf

复制代码
cat > /etc/keepalived/keepalived.conf << 'EOF'
global_defs {
   router_id LVS_DEVEL_61
}

vrrp_script chk_haproxy {
    script "killall -0 haproxy"
    interval 2
    weight -20
}

vrrp_instance VI_1 {
     # 备节点
    state BACKUP               
    interface ens33
     # 必须和主节点一致
    virtual_router_id 51  
     # 优先级必须比主节点小
    priority 80
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.10.100
    }
    track_script {
        chk_haproxy
    }
}
EOF
3:启动服务

两台机器都执行:

复制代码
systemctl start keepalived
systemctl enable keepalived

4:在 SQL 节点创建健康检查用户

HAProxy 需要一个账号来检测 MySQL 是否存活。你需要在 两个 SQL 节点 (62 和 63) 上都执行以下 SQL 语句:

  1. 登录 MySQL:

    mysql -uroot -p'你的Root密码'

  2. 创建专用用户(仅用于检测,无权限):

    CREATE USER 'haproxy_check'@'%' IDENTIFIED BY '';
    -- NDB 集群会自动同步用户,理论上在一个节点执行即可,但为了保险,建议两个都执行或确认同步。


5:启动 HAProxy 并验证
1. 启动服务
复制代码
systemctl start haproxy
systemctl enable haproxy
systemctl status haproxy
2. 验证负载均衡效果

打开浏览器访问:http://192.168.10.60:8080/haproxy_stats (账号 admin, 密码 admin123)。你应该能看到 node62node63 的状态都是 绿色的 UP


6:客户端连接测试

现在,你的应用程序或客户端不要直接连 62 或 63 了,而是连接 keepalived 的 VIP (192.168.10.100)

测试读写分离(或轮询): 由于 NDB 集群是全节点写入 (所有 SQL 节点都可以读写),HAProxy 采用 roundrobin 策略会将请求均匀分发到 62 和 63。

复制代码
# 连续连接几次,观察日志或端口占用
mysql -h192.168.10.100 -uroot -p'Root@123' -e "SELECT @@hostname;"

你会发现返回的主机名会在 62 和 63 之间切换。

7:keepalived主/备状态检测

在 LinuxA (192.168.10.68) 上执行 ip addr show ens33,能获取到VIP说明已是主节点

8:keepalived主/备切换测试

切换后通过192.168.10.100能正常进行访问和转发

相关推荐
丁丁点灯o10 小时前
oracle中基于正则表达式匹配规则提取子串的函数REGEXP_SUBSTR
数据库·oracle·正则表达式
木风小助理10 小时前
Android 数据库实操指南:从 SQLite 到 Realm,不同场景精准匹配
jvm·数据库·oracle
Elseide艾思10 小时前
数字经济专利数据库(1994年更新至今)
数据库
optimistic_chen10 小时前
【Redis系列】事务特性
数据库·redis·笔记·缓存·事务
踏月的造梦星球10 小时前
浅究Oracle迁移至DM8产生数据文件膨胀的原因
数据库·oracle
DBA小马哥10 小时前
时序数据库迁移替换与选购指南
数据库·时序数据库
Knight_AL10 小时前
深入解析数据库四大事务隔离级别及其实际应用
服务器·数据库·oracle
xj75730653310 小时前
《精通Django》 第三章 Django模板
数据库·django·sqlite
小北方城市网10 小时前
Python FastAPI 异步性能优化实战:从 1000 QPS 到 1 万 QPS 的踩坑之路
大数据·python·性能优化·架构·fastapi·数据库架构