You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js多Worker场景下MySQL原子读写及高性能共享内存方案咨询

可行性结论

该需求完全可以基于MySQL实现,数百级WebSocket并发场景下性能冗余度极高,完全满足ACID要求,不会出现计数失真、并发冲突问题。

MySQL落地实现方案

首先建InnoDB引擎的服务器负载表,结构如下:

CREATE TABLE `server_load` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `server_addr` varchar(128) NOT NULL COMMENT '服务器访问地址',
  `conn_count` int unsigned NOT NULL DEFAULT '0' COMMENT '当前承载连接数',
  `is_available` tinyint NOT NULL DEFAULT '1' COMMENT '1=可用 0=不可用',
  PRIMARY KEY (`id`),
  KEY `idx_available_count` (`is_available`,`conn_count`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

核心逻辑不要拆成「先查询再更新」的两步操作,也不要用普通事务包裹两步SQL,直接用单条原子SQL完成「选最低负载可用节点+计数+1+返回选中节点」全流程:

-- MySQL 8.0及以上版本支持RETURNING语法,直接返回更新后的节点信息
UPDATE server_load
SET conn_count = conn_count + 1
WHERE id = (
  SELECT id FROM (
    SELECT id FROM server_load
    WHERE is_available = 1
    ORDER BY conn_count ASC
    LIMIT 1
    FOR UPDATE SKIP LOCKED
  ) AS tmp
)
RETURNING id, server_addr, conn_count;

如果是5.7及以下老版本MySQL不支持RETURNING,可以把更新和查结果放在同个事务里,因为FOR UPDATE SKIP LOCKED已经加了行锁,不会出现并发冲突:

BEGIN;
SELECT id, server_addr, conn_count FROM server_load
WHERE is_available = 1
ORDER BY conn_count ASC
LIMIT 1
FOR UPDATE SKIP LOCKED;
-- 拿到上一步返回的id后执行更新
UPDATE server_load SET conn_count = conn_count +1 WHERE id = ?;
COMMIT;

该方案的可靠性说明:

  • 所有操作基于InnoDB事务机制,原子性、一致性、隔离性、持久性完全满足ACID规范
  • FOR UPDATE SKIP LOCKED会给选中的单条记录加排他锁,并发请求不会阻塞在同一行锁上,会自动跳过已加锁的记录选择下一个符合条件的节点,既不会出现重复选同一台服务器导致计数不准的问题,也不会阻塞无关资源的操作
  • 联合索引idx_available_count覆盖了查询过滤、排序的全字段,不需要回表,单条SQL执行耗时在亚毫秒级,数百并发场景下几乎无性能压力,常规配置的MySQL实例可以轻松支撑数万QPS的调度请求
  • 业务侧连接断开时,执行UPDATE server_load SET conn_count = conn_count -1 WHERE id = ?回退计数即可,服务器上下线直接修改is_available字段值。
性能更优的替代方案

如果后续并发规模上涨到万级以上,想要更低的调度延迟,可以选择以下内存级方案,性能比MySQL高1~2个量级:

  • Redis方案:将服务器负载数据存在Redis有序集合中,用conn_count作为成员score,编写Lua脚本实现「取score最小的可用成员+对应score+1」逻辑,Redis单线程执行Lua脚本天然保证原子性,整个操作在内存中完成,延迟在微秒级,只需要开启AOF持久化避免宕机丢数据即可,运维成本也很低。
  • 调度服务本地原子计数方案:如果调度服务是单实例部署,直接在服务内存中用原子变量维护每台服务器的连接计数,每次调度直接选计数最小的节点,零网络开销,性能最高。如果调度服务多实例部署,配合轻量gossip协议同步各节点负载数据即可,适合超大规模集群场景。
选型建议

当前数百并发的场景直接用MySQL方案即可,不需要额外引入新组件,运维成本最低,稳定性经过大量生产场景验证。等后续并发规模涨到万级以上再考虑切换Redis方案也完全来得及。

内容的提问来源于stack exchange,提问作者BGPHiJACK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 20:06:27