ndb集群是独立部署的内存型分布式数据库系统,mysql server仅为sql接入层;需用mysql cluster版本、启用--ndbcluster参数、主键强制显式定义、数据节点存数据、sql节点无本地数据、join性能依赖分区键命中。

NDB 集群不是 MySQL 的“分布式存储插件”,它是一套独立部署、强耦合的内存型分布式数据库系统,MySQL Server 只是它的 SQL 接入层;直接在现有 MySQL 上启用 ENGINE=NDB 不等于搭好了分布式存储。
为什么 CREATE TABLE ... ENGINE=NDB 总是报错 Unknown storage engine 'NDB'
这是最常见误解的起点:NDB 不是随 MySQL 二进制包默认启用的引擎。MySQL 官方编译版(尤其是 yum/apt 安装的)默认不带 NDB 支持,mysqld 进程根本没加载对应模块。
- 必须使用 MySQL Cluster 版本(即
mysql-cluster-community-server),而非普通mysql-server - 确认
mysqld启动时加载了--ndbcluster参数,且配置文件中包含ndbcluster和ndb-connectstring -
SHOW ENGINES;输出里NDB行的Support列必须是YES,不是NO或DISABLED - 即使启用了,
CREATE TABLE仍可能失败——NDB 要求主键必须显式定义,且不能为NULL;TEXT/BLOB列不支持(除非用LONG VARCHAR替代)
ndb_mgmd、ndbd、mysqld 三个进程到底谁存数据、谁管 SQL
NDB 是“计算与存储分离”的典型设计,但分工和依赖比想象中更刚性:
-
ndb_mgmd是管理节点,只存集群配置,不存业务数据;停掉它不影响查询,但无法增删节点或在线改表结构 -
ndbd(或新版ndbmtd)是数据节点,真正存表数据(全内存,可配持久化日志);至少 2 个才能保证高可用,单点故障即丢数据 -
mysqld是 SQL 节点,无本地数据,所有 DML/DDL 请求都转发给ndbd;它挂了不影响数据安全,但客户端连不上 SQL 接口 - 三者必须版本严格对齐(比如都是 8.0.33-ndb-8.0.33),混用小版本会导致连接拒绝或静默数据截断
为什么简单 JOIN 查询变慢,甚至超时
NDB 对跨数据节点操作极其敏感,SQL 节点不是“智能路由”,而是按分区键硬拆请求:
- 没指定分区键(如
PRIMARY KEY或SHARD KEY)的JOIN,会被广播到所有数据节点执行,再由mysqld汇总结果——网络+CPU 开销指数级增长 -
WHERE条件中若没命中分区键,同样触发全节点扫描;NDB 不支持索引下推到数据节点外的二级索引(ONLINE ALTER创建的除外) - 大结果集
SELECT *容易撑爆mysqld内存,因为 NDB 返回的是行数据流,不支持游标分页;必须用LIMIT+ 合理ORDER BY控制返回量 - 事务默认隔离级别是
READ COMMITTED,不支持SELECT ... FOR UPDATE在非主键条件上加锁,容易出现幻读
真正难的不是启动集群,而是把业务逻辑适配到 NDB 的数据分布模型里:主键即分片键、避免跨分片 JOIN、接受最终一致性、容忍 SQL 层功能阉割(比如没有外键、视图不可更新、子查询限制多)。没做过数据建模迁移就上 NDB,大概率是用分布式代价换来了更差的性能和更高的运维复杂度。











