2、内存数据库基础:内存数据库 vs 磁盘数据库、核心特性(持久化、事务、ACID)、常见产品对比
好,咱们进入正题。这一章我打算聊聊内存数据库最基础的东西。很多人觉得内存数据库就是把数据放内存里,读写快一点而已。其实没那么简单。我在做量化交易系统的时候,踩过不少坑,今天把这些经验掰开揉碎了讲给你听。
2.1 内存数据库 vs 磁盘数据库:到底差在哪?
先问个问题:你写一个SQL查询,磁盘数据库要10毫秒,内存数据库只要1微秒。差了一万倍。为什么会这样?
说白了,磁盘数据库的瓶颈在I/O。数据要读进内存,写回磁盘,这个过程慢得像蜗牛。内存数据库呢?数据就在内存里,CPU直接访问,没有磁盘I/O的拖累。
我举个例子。你在MySQL里执行一条UPDATE,它要写redo log、binlog,还要刷脏页。一套流程下来,几毫秒就过去了。换成Redis,一条SET命令,微秒级就搞定了。
但这里有个陷阱——内存数据库不是万能的。我见过有人把几十G的数据全塞进Redis,结果内存爆了,系统直接OOM。你想想看,内存多贵啊,1TB内存的价格够买好几台磁盘阵列了。
所以,选型的时候要权衡:
- 数据量:如果数据量超过内存容量,别硬上内存数据库
- 访问模式:高频读写、低延迟场景,内存数据库是首选
- 持久化要求:磁盘数据库天生持久化,内存数据库需要额外机制
核心区别总结:
- 磁盘数据库:数据在磁盘,读写慢,容量大,持久化天然
- 内存数据库:数据在内存,读写快,容量受限,持久化靠策略
2.2 核心特性:持久化、事务、ACID
内存数据库不是简单的「内存版MySQL」。它有自己的一套玩法。我重点讲三个核心特性:持久化、事务、ACID。
2.2.1 持久化:数据不会丢吗?
很多人问我:「内存数据库一断电不就全没了?」嗯,这是个好问题。早期的内存数据库确实有这个问题,但现在主流产品都有持久化机制。
以Redis为例,它提供了两种持久化方式:
- RDB(快照):定期把内存数据全量dump到磁盘。优点是恢复快,缺点是可能丢数据(两次快照之间的数据)
- AOF(追加日志):每条写操作都记录到日志文件。优点是数据更安全,缺点是文件大、恢复慢
我个人的习惯是:RDB + AOF 混用。RDB做全量备份,AOF做增量保护。这样既保证了恢复速度,又减少了数据丢失的风险。
但要注意,持久化不是免费的。AOF的fsync频率太高,会拖慢写入性能。我曾经在一个高频交易项目中,因为AOF的fsync策略没调好,导致写入延迟从微秒级飙升到毫秒级。后来改成「每秒fsync一次」,才把性能拉回来。
避坑指南: 我曾经把AOF的fsync设成「每次写入都fsync」,结果性能直接崩了。建议生产环境用「每秒fsync」或「由操作系统决定」。
2.2.2 事务:内存数据库的事务靠谱吗?
磁盘数据库的事务,靠的是锁和日志。内存数据库呢?它靠的是乐观锁和原子操作。
拿Redis来说,它的事务是通过MULTI/EXEC实现的。你把多条命令打包,Redis保证它们要么全部执行,要么全部不执行。但注意,Redis的事务不支持回滚——如果某条命令执行失败,它不会撤销之前已经执行的命令。
这跟MySQL的事务不一样。MySQL有undo log,可以回滚到事务开始前的状态。Redis没有这个机制。
所以,我的建议是:别把内存数据库当关系数据库用。如果你需要强事务支持,比如转账场景,还是用MySQL或PostgreSQL。内存数据库更适合「单条命令原子性」的场景,比如计数器、排行榜。
2.2.3 ACID:内存数据库能保证吗?
ACID是数据库的四大特性:原子性、一致性、隔离性、持久性。内存数据库能保证多少?
| 特性 | 磁盘数据库(MySQL) | 内存数据库(Redis) |
|---|---|---|
| 原子性 | 强(undo log支持回滚) | 弱(不支持回滚) |
| 一致性 | 强(约束、触发器) | 弱(依赖应用层保证) |
| 隔离性 | 强(MVCC、锁) | 弱(单线程模型,天然隔离) |
| 持久性 | 强(WAL、双写缓冲) | 中等(依赖RDB/AOF) |
你看,内存数据库在ACID上做了很多妥协。它牺牲了部分ACID保证,换来了极致的性能。这在量化交易场景下是可以接受的——我们更关心的是低延迟,而不是强一致性。
注意: 如果你的业务要求严格的ACID,比如金融交易中的「资金划转」,别用内存数据库做主存储。它更适合做缓存、会话管理、实时计算。
2.3 常见产品对比:选哪个?
市面上内存数据库产品很多,我挑几个常用的说说。
2.3.1 Redis vs Memcached
这两个经常被放在一起比。Memcached更简单,只支持key-value,不支持持久化。Redis功能更丰富,支持多种数据结构、持久化、集群。
我个人的经验是:能用Redis就别用Memcached。Redis的灵活性高太多了。除非你只需要简单的缓存,而且对性能要求极致,那Memcached可能更轻量。
2.3.2 Redis vs Aerospike
Aerospike是专门为闪存优化的内存数据库。它支持混合存储——热数据在内存,冷数据在SSD。这在数据量超过内存容量时特别有用。
我在一个广告推荐项目中用过Aerospike。数据量大概500G,内存只有128G。Aerospike自动把热数据留在内存,冷数据放到SSD,性能依然很好。换成Redis的话,要么加内存,要么做分片,麻烦很多。
2.3.3 产品对比表
| 产品 | 数据模型 | 持久化 | 集群 | 适用场景 |
|---|---|---|---|---|
| Redis | key-value、list、set、hash等 | RDB/AOF | 主从、哨兵、Cluster | 缓存、会话、实时计算 |
| Memcached | key-value | 无 | 客户端分片 | 简单缓存 |
| Aerospike | key-value | SSD持久化 | 自动分片 | 大数据量、混合存储 |
| VoltDB | 关系型 | 快照+日志 | 分区+复制 | 实时分析、OLTP |
2.4 知识体系图
下面这张图,我画了内存数据库的核心知识结构。你可以把它当个地图,后面讲到具体技术时,随时回来对照。
这张图把内存数据库的核心知识点串起来了。左边是跟磁盘数据库的对比,中间是核心特性,右边是常见产品。底部是选型的关键点。
好了,这一章就到这里。记住一句话:内存数据库不是银弹。它适合低延迟、高吞吐的场景,但别指望它能替代磁盘数据库的所有功能。下一章,我会讲内存数据库的架构设计,包括数据分片、复制、一致性哈希这些实战内容。