为什么持久化场景下MySQL的使用频率远高于Redis?
问题1:MySQL和Redis都支持持久化,为什么持久化场景下MySQL使用率更高?
你提到的Redis无磁盘索引的点就是核心原因之一,就算日常查询走内存,涉及到持久化相关的场景时这个缺陷会被放大:
- Redis的持久化文件(RDB/AOF)本质是内存快照/操作日志,没有配套的磁盘索引结构,一旦内存放不下全量数据需要磁盘兜底响应查询,或是需要从持久化文件里单独捞取部分数据做校验、回滚时,效率极低,基本只能全量加载回内存才能操作,完全不适合大容量的持久化存储场景。
- 反过来MySQL从设计之初就是磁盘导向的存储系统,B+树索引直接落地磁盘,就算数据量远大于内存容量,也能通过磁盘索引快速响应查询,天生适配需要长期持久化、数据量较大的业务场景。
- 除此之外MySQL对持久化相关的特性支持更完善:事务ACID的完整支持、复杂SQL查询、权限管控、容灾备份体系都是为持久化业务设计的,而Redis的持久化更多是为了宕机重启后能恢复内存数据做的兜底能力,本身定位就不是主打冷数据落地的持久化存储。
问题2:MySQL执行insert后会不会立即落盘,有没有数据丢失的时间窗口?
答案是也存在数据丢失窗口,具体要看你的数据库配置:
- MySQL的WAL(预写日志)机制里,insert执行成功的默认逻辑是写redo log buffer成功就返回,不是直接刷盘。redo log刷盘的时机由
innodb_flush_log_at_trx_commit参数控制:- 参数设为1时,每次事务提交都会把redo log直接刷到磁盘,这时候只要insert返回成功就不会丢数据,没有时间窗口,但性能损耗最高。
- 参数设为0时,每秒刷一次盘,最多丢1秒的数据。
- 参数设为2时,每次提交把日志写到操作系统页缓存就返回,操作系统每秒刷盘,最多丢1秒数据,性能最好。
- 大多业务线上MySQL为了平衡性能和可靠性,不会默认开
innodb_flush_log_at_trx_commit=1,所以也存在最多1秒的数据丢失窗口,只是这个风险比Redis默认的持久化配置要低得多,而且可以根据业务诉求调整参数完全消除窗口。
内容的提问来源于stack exchange,提问作者Yongqi Z
相关产品推荐
相关产品推荐

