部署说明:
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 EOF2. 安装基础依赖(解决组件启动依赖)
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 mysql4. 上传并解压安装包(统一路径)
# 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/mysql5. 配置系统环境变量(全局可执行 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_data2. 编写核心集群配置文件(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 EOF3. 启动管理节点
# --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_data2. 编写 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 EOF3. 启动数据节点
# --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*xyz2. 编写 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 EOF3. 配置 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) # 退出管理工具 exit3. 数据同步验证(核心!验证集群有效性)
# 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 / 数据节点(因为新节点需要连接管理节点获取配置)。
2. 启动管理节点时:无需停 SQL / 数据节点
- 启动管理节点后,已运行的 SQL / 数据节点会自动重新连接管理节点(无需手动操作);
- 如果启动时修改了
config.ini(如新增节点、调整参数),需要在管理节点执行ndb_mgm -e "reload",数据节点会自动加载新配置(部分参数需重启数据节点)。
3. 特殊场景:管理节点 + 数据节点 + SQL 节点的完整启停顺序(维护时用)
如果需要整体重启集群(如升级、修改核心配置),建议按以下顺序操作,避免数据不一致:
停止顺序(从依赖端到核心端)
- 先停SQL 节点(mysqld):避免应用继续发请求,防止连接报错;
- 再停数据节点(ndbd/ndbmtd):确保数据落盘,避免丢失;
- 最后停管理节点(ndb_mgmd)。
启动顺序(从核心端到依赖端)
- 先启管理节点(ndb_mgmd):先加载集群配置,为其他节点提供配置;
- 再启数据节点(ndbd/ndbmtd):连接管理节点获取配置,同步数据;
- 最后启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 } } EOF2:配置备节点 (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 } } EOF3:启动服务
两台机器都执行:
systemctl start keepalived systemctl enable keepalived4:在 SQL 节点创建健康检查用户
HAProxy 需要一个账号来检测 MySQL 是否存活。你需要在两个 SQL 节点 (62 和 63)上都执行以下 SQL 语句:
- 登录 MySQL:
mysql -uroot -p'你的Root密码'- 创建专用用户(仅用于检测,无权限):
CREATE USER 'haproxy_check'@'%' IDENTIFIED BY ''; -- NDB 集群会自动同步用户,理论上在一个节点执行即可,但为了保险,建议两个都执行或确认同步。5:启动 HAProxy 并验证
1. 启动服务
systemctl start haproxy systemctl enable haproxy systemctl status haproxy2. 验证负载均衡效果
打开浏览器访问:http://192.168.10.60:8080/haproxy_stats(账号 admin, 密码 admin123)。你应该能看到node62和node63的状态都是绿色的 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能正常进行访问和转发