Skip to content

MySQL 存储插件

分布式模式下,多个 IM 实例需要共享同一份数据。MySQL 插件将存储层从 SQLite 切换为 MySQL,所有实例读写同一个数据库。

为什么需要 MySQL

SQLite 是单文件数据库,适合单实例部署。但当运行多个 IM 实例时,每个实例需要看到相同的用户、消息和群组数据,因此必须使用共享的关系型数据库。

MySQL 插件实现了与 SQLite 完全相同的 StorageInterface,上层业务代码无需任何改动。

环境要求

  • MySQL 5.7+ 或 MariaDB 10.3+
  • 建议 InnoDB 引擎,utf8mb4 字符集

配置

通过环境变量启用 MySQL 存储:

bash
STORAGE=mysql \
MYSQL_HOST=127.0.0.1 \
MYSQL_PORT=3306 \
MYSQL_USER=im_user \
MYSQL_PASSWORD=your_password \
MYSQL_DATABASE=im_chat \
node index.js

也可以在 config.yaml 中配置:

yaml
storage: mysql

mysql:
  host: 127.0.0.1
  port: 3306
  user: im_user
  password: your_password
  database: im_chat

数据库初始化

MySQL 插件首次启动时会自动创建表结构,无需手动导入 SQL。自动创建的表包括:

表名说明
users用户账号信息
groups群组信息
group_members群成员关系
messages聊天消息
friends好友关系
friend_requests好友申请
config系统配置
push_subscriptions推送订阅
unread_counts未读计数
blocked_users屏蔽关系

性能建议

连接池:插件默认使用连接池,connectionLimit 默认为 10。高并发场景可适当调大。

索引优化:建表时已自动创建关键索引,包括消息的 from_id + to_id 组合索引、时间戳索引等。

读写分离:如果使用了 MySQL 主从复制,可以在前面加一层 Proxy(如 ProxySQL)实现读写分离,IM 插件只需连接 Proxy 地址。

数据迁移

从 SQLite 迁移到 MySQL 时,需要导出旧数据并导入。基本流程:

bash
# 1. 导出 SQLite 数据为 JSON(可写脚本读取)
node scripts/export-sqlite.js > data.json

# 2. 启动 MySQL 模式的 IM 服务(自动建表)
STORAGE=mysql MYSQL_HOST=... node index.js &

# 3. 导入数据
node scripts/import-mysql.js data.json

迁移脚本可根据实际数据量定制开发。

免费版与收费版区别

免费版使用 SQLite,数据存储在单个文件中,部署简单但无法多实例共享。收费版使用 MySQL 插件,支持多实例共享同一数据库,配合 Redis 消息总线实现完整的分布式架构。

两个版本使用同一套代码,仅通过环境变量 STORAGE 切换,业务逻辑完全一致。