MySQL Cluster (NDB Cluster)
MySQL Cluster 是基于 NDB 存储引擎的分布式数据库,提供无共享架构、同步复制、自动分片和高可用能力。
架构原理
无共享架构(Shared-Nothing)
ini
┌──────────────────────────────────────────────────────────┐
│ Management Node │
│ (MGM Node / ndb_mgmd) │
│ 配置管理 │
└──────────────────────────┬───────────────────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ API Node │ │ API Node │ │ API Node │
│ (MySQL Server│ │ (MySQL Server│ │ (MySQL Server│
│ mysqld) │ │ mysqld) │ │ mysqld) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└────────────────┼────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Data Node │ │ Data Node │ │ Data Node │
│ (ndbd/ndbmtd)│ │ (ndbd/ndbmtd)│ │ (ndbd/ndbmtd)│
│ 节点组1 │ │ 节点组2 │ │ 节点组3 │
│ ┌────┬────┐│ │ ┌────┬────┐│ │ ┌────┬────┐│
│ │N1 │N2 ││ │ │N3 │N4 ││ │ │N5 │N6 ││
│ │主 │备 ││ │ │主 │备 ││ │ │主 │备 ││
│ └────┴────┘│ │ └────┴────┘│ │ └────┴────┘│
└──────────────┘ └──────────────┘ └──────────────┘
三类节点
| 节点类型 | 进程 | 功能 |
|---|---|---|
| Management Node | ndb_mgmd | 配置管理、集群监控 |
| Data Node | ndbd / ndbmtd | 数据存储、事务处理 |
| API Node | mysqld | SQL 接口、应用连接 |
数据分片与副本
ini
节点组(Node Group):
┌─────────────────────────────────────────────┐
│ 节点组 0 │
│ ┌───────────┐ ┌───────────┐ │
│ │ Data Node │ │ Data Node │ │
│ │ N1 │◀────▶│ N2 │ │
│ │ (主) │同步复制│ (备) │ │
│ │ 分片 0 │ │ 分片 0副本 │ │
│ └───────────┘ └───────────┘ │
└─────────────────────────────────────────────┘
数据分布:
Table: users (id, name)
┌─────────┬─────────┬─────────┐
│ 分片0 │ 分片1 │ 分片2 │
│ id%3=0 │ id%3=1 │ id%3=2 │
│ 节点组0│ 节点组1│ 节点组2│
└─────────┴─────────┴─────────┘
关键概念:
- 分片(Fragment):数据按主键哈希分片到不同节点组
- 副本(Replica):每个分片有多个副本,同步复制
- 节点组:包含主副本和备副本的节点集合
NDB 存储引擎特性
与 InnoDB 对比
| 特性 | NDB Cluster | InnoDB |
|---|---|---|
| 架构 | 分布式、无共享 | 单机、共享存储 |
| 存储位置 | Data Node 内存+磁盘 | 本地磁盘 |
| 复制方式 | 同步复制(两阶段提交) | 异步/半同步 |
| 事务隔离 | READ COMMITTED | 多种隔离级别 |
| 外键支持 | 不支持 | 支持 |
| 全文索引 | 不支持 | 支持 |
| 单事务限制 | 跨节点事务开销大 | 本地事务高效 |
| HA 能力 | 自动故障恢复 | 需额外方案 |
NDB 存储结构
Bash
内存存储(主):
┌────────────────────────────────────┐
│ Data Memory │
│ ├─ 数据记录 │
│ ├─ 索引数据 │
│ └─ 事务状态 │
└────────────────────────────────────┘
磁盘存储(可选):
┌────────────────────────────────────┐
│ Disk Data │
│ ├─ 磁盘数据表 │
│ ├─ 磁盘索引 │
│ └─ Undo 日志 │
└────────────────────────────────────┘
部署配置
配置文件:config.ini
SQL
[NDBD DEFAULT]
# 数据节点通用配置
NoOfReplicas = 2 # 副本数
DataMemory = 80M # 数据内存
IndexMemory = 20M # 索引内存
BackupMemory = 4M # 备份内存
TransactionInactiveTimeout = 100 # 事务超时(秒)
[TCP DEFAULT]
# 网络 TCP 配置
PortNumber = 2202
[NDB_MGMD]
# 管理节点
HostName = 192.168.1.100
NodeId = 1
[NDBD]
# 数据节点 1
HostName = 192.168.1.101
NodeId = 2
DataDir = /var/lib/mysql-cluster
[NDBD]
# 数据节点 2
HostName = 192.168.1.102
NodeId = 3
DataDir = /var/lib/mysql-cluster
[NDBD]
# 数据节点 3
HostName = 192.168.1.103
NodeId = 4
DataDir = /var/lib/mysql-cluster
[NDBD]
# 数据节点 4
HostName = 192.168.1.104
NodeId = 5
DataDir = /var/lib/mysql-cluster
[MYSQLD]
# MySQL API 节点 1
HostName = 192.168.1.105
NodeId = 6
[MYSQLD]
# MySQL API 节点 2
HostName = 192.168.1.106
NodeId = 7
MySQL 配置:my.cnf
SQL
[mysqld]
# NDB 配置
ndbcluster
ndb-connectstring = 192.168.1.100:1186
# 存储引擎默认值
default-storage-engine = NDB
[mysql_cluster]
ndb-connectstring = 192.168.1.100:1186
启动集群
ini
# 1. 启动管理节点
ndb_mgmd -f /etc/mysql-cluster/config.ini --initial
# 2. 启动数据节点(首次需要 --initial)
ndbd --initial
# 或后续启动
ndbd
# 3. 启动 MySQL API 节点
mysqld --user=mysql
# 4. 查看集群状态
ndb_mgm -e show
集群状态查看
Bash
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)] 4 node(s)
id=2 @192.168.1.101 (Version: 8.0, Nodegroup: 0, *)
id=3 @192.168.1.102 (Version: 8.0, Nodegroup: 0)
id=4 @192.168.1.103 (Version: 8.0, Nodegroup: 1)
id=5 @192.168.1.104 (Version: 8.0, Nodegroup: 1)
[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.1.100 (Version: 8.0)
[mysqld(API)] 2 node(s)
id=6 @192.168.1.105 (Version: 8.0)
id=7 @192.168.1.106 (Version: 8.0)
数据节点管理
创建 NDB 表
Bash
-- 创建 NDB 表
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(200)
) ENGINE = NDB;
-- 指定分区数
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2)
) ENGINE = NDB PARTITION BY KEY (order_id) PARTITIONS 4;
内存表 vs 磁盘表
Bash
-- 内存表(默认)
CREATE TABLE mem_table (
id INT PRIMARY KEY,
data VARCHAR(100)
) ENGINE = NDB;
-- 磁盘表(需定义表空间)
CREATE TABLESPACE ts_disk
ADD DATAFILE 'disk_data.dat'
INITIAL_SIZE = 100M
ENGINE = NDB;
CREATE LOGFILE GROUP lg_disk
ADD UNDOFILE 'undo_file.dat'
INITIAL_SIZE = 20M
ENGINE = NDB;
CREATE TABLE disk_table (
id INT PRIMARY KEY,
data TEXT
) ENGINE = NDB TABLESPACE ts_disk STORAGE DISK;
磁盘数据配置参数
ini
[NDBD DEFAULT]
# 磁盘数据配置
DiskDataMemory = 20M # 磁盘数据内存缓冲
DiskDataDiskSpace = 100M # 磁盘数据空间
DiskPageBufferMemory = 10M # 磁盘页缓冲
同步复制机制
两阶段提交
ini
阶段1:Prepare
┌──────────┐ ┌──────────┐ ┌──────────┐
│ API Node │───▶│ Data N1 │───▶│ Data N2 │
│ │ │ PREPARE │ │ PREPARE │
│ │◀───│ ACK │◀───│ ACK │
└──────────┘ └──────────┘ └──────────┘
阶段2:Commit
┌──────────┐ ┌──────────┐ ┌──────────┐
│ API Node │───▶│ Data N1 │───▶│ Data N2 │
│ │ │ COMMIT │ │ COMMIT │
│ │◀───│ ACK │◀───│ ACK │
└──────────┘ └──────────┘ └──────────┘
同步保证:所有副本确认后才返回成功
事务协调器
ini
事务协调器(Transaction Coordinator):
┌─────────────────────────────────────────┐
│ Data Node │
│ ┌─────────────────────────────────────┐│
│ │ Transaction Coordinator ││
│ │ ├─ 接收事务请求 ││
│ │ ├─ 协调参与者 ││
│ │ ├─ 两阶段提交 ││
│ │ └─ 返回结果 ││
│ └─────────────────────────────────────┘│
└─────────────────────────────────────────┘
协调器选择:根据主分片位置确定
高可用与故障恢复
自动故障检测
SQL
心跳检测:
Data Node ──▶ Management Node
│
├─ 定期发送心跳
│
└─ 超时(HeartbeatIntervalDbDb)则标记故障
故障检测时间:
HeartbeatIntervalDbDb = 1500ms(默认)
TimeBetweenWatchdogCheckInitial = 60000ms
故障恢复流程
text
1. 检测节点故障
↓
2. 确认故障(超时3次)
↓
3. 重组集群(Network Partition)
↓
4. 选择新主节点(副本升级)
↓
5. 从其他副本同步数据
↓
6. 集群恢复,继续服务
节点恢复操作
text
# ndb_mgm 管理命令
ndb_mgm
# 查看节点状态
ndb_mgm> show
# 启动单个节点
ndb_mgm> 2 START
# 停止节点
ndb_mgm> 2 STOP
# 查看节点详情
ndb_mgm> 2 STATUS
# 恢复备份
ndb_mgm> START BACKUP 1
备份与恢复
NDB 备份
text
# 在 ndb_mgm 中执行备份
ndb_mgm> START BACKUP 1 WAIT COMPLETED
# 备份文件位置(数据节点)
/var/lib/mysql-cluster/BACKUP/BACKUP-1/
├── BACKUP-1-0.2.Data # 数据文件
├── BACKUP-1.2.ctl # 控制文件
├── BACKUP-1.2.schema # 元数据文件
NDB 恢复
text
# 1. 停止数据节点
ndb_mgm> 2 STOP
# 2. 恢复数据
ndb_restore -n 2 -b 1 -m -r /var/lib/mysql-cluster/BACKUP/BACKUP-1/
# 3. 启动节点
ndb_mgm> 2 START
# 参数说明
# -n: 节点 ID
# -b: 备份 ID
# -m: 恢复元数据
# -r: 恢复数据
性能优化
内存配置
text
[NDBD DEFAULT]
# 根据数据量调整
DataMemory = 80M # 数据内存(行数据)
IndexMemory = 20M # 索引内存(哈希索引)
# 共享内存传输
SharedGlobalMemory = 20M
LockPagesInMainMemory = 1
并行执行
text
[NDBD DEFAULT]
# 多线程数据节点(ndbmtd)
MaxNoOfExecutionThreads = 4
MaxNoOfTCThreads = 2
# 或使用单线程 ndbd(简单场景)
网络优化
text
[TCP DEFAULT]
# TCP 传输参数
SendBufferMemory = 2M
ReceiveBufferMemory = 2M
TCP_MEM_LIMIT = 4M
监控指标
text
-- 查看集群状态
SELECT * FROM ndbinfo.nodes;
-- 查看内存使用
SELECT
node_id,
memory_type,
used,
total,
used / total * 100 AS usage_pct
FROM ndbinfo.memoryusage;
-- 查看表信息
SELECT
table_name,
node_id,
rows,
memory_used
FROM ndbinfo.table_memory_usage;
-- 查看事务统计
SELECT * FROM ndbinfo.operations;
使用限制
| 限制 | 说明 |
|---|---|
| 外键 | 不支持 |
| 全文索引 | 不支持 |
| 触发器 | 不支持 |
| 事务隔离级别 | 仅 READ COMMITTED |
| BLOB/TEXT | 存储效率低 |
| 大事务 | 跨节点开销大 |
| 内存需求 | 数据需内存存储 |
适用场景
| 适用 | 不适用 |
|---|---|
| 电信计费系统 | 复杂关联查询 |
| 会话存储 | 大字段存储 |
| 高写入场景 | 外键约束场景 |
| 要求强一致 | 低延迟单点查询 |
要点总结
- 架构:无共享架构,三类节点(Management/Data/API)
- 存储:NDB 存储引擎,内存+磁盘混合存储
- 复制:同步复制,两阶段提交保证一致性
- 分片:自动分片,每个节点组包含主备副本
- 高可用:自动故障检测和恢复,副本自动升级
- 限制:不支持外键、全文索引,仅 READ COMMITTED
- 适用:高写入、强一致、电信/会话等场景
📝 发现内容有误?点击此处直接编辑