在实时聊天系统里,传统的关系型数据库往往因为写入频率和并发量的限制而显得笨拙。把消息直接留在进程内存或临时文件里,既能保持毫秒级的响应,又免去了持久化层的繁琐配置,这正是“无数据库”模式的核心吸引力。
常见的无数据库存储方式
- 纯内存数组:适用于用户规模在千级以下的轻量聊天室,所有消息只在服务器进程的全局数组里循环保存。
- 共享内存(shm):利用
shmop或sysvshm将数据映射到系统级内存,跨进程读取更安全。 - 文件轮转日志:把每条消息写入按时间分段的文本文件,读取时只打开最新的几段,磁盘IO控制在可接受范围。
- Redis(非持久化模式):将
expire与list结合,既保留了内存速度,又能在服务器重启时自动清空。
基于内存的实现细节
以 PHP + Workerman 为例,往往在 onMessage 回调里把收到的文本推入一个全局数组,然后遍历该数组向所有已连接的客户端广播。为了防止数组无限增长,常见的做法是采用环形缓冲区:当数组长度超过 200 条时,最旧的记录被直接 array_shift 丢弃。

// 全局消息缓存(环形缓冲区示例)
$cache = new SplFixedArray(200);
function pushMessage($msg) {
static $pos = 0;
global $cache;
$cache[$pos] = $msg;
$pos = ($pos + 1) % 200;
}
持久化的折中方案
如果业务要求在服务器意外宕机后还能恢复最近的聊天记录,往往会在内存写入的同时,异步把同一条消息追加到本地日志文件或 Redis 的持久化实例。这样既保留了“无数据库”时的低延迟,又在极端情况下提供了最小化的数据丢失。
| 存储方式 | 读写延迟 | 数据安全性 | 实现复杂度 |
| 纯内存数组 | ≈1 ms | 极低(进程崩溃即丢失) | 低 |
| 共享内存 | ≈2 ms | 低至中 | 中 |
| 文件轮转 | ≈5 ms | 中(磁盘写入可靠) | 中 |
| Redis(非持久化) | ≈1 ms | 低(重启即清空) | 低 |
选型时,往往要在“实时性”与“容错性”之间找平衡点;如果用户峰值在数千人以下,单机内存环形缓冲已经足够;若要支撑更大规模或跨机房同步,Redis + 持久化日志的组合则更为稳妥。

评论(0)