微信搜索关注「水滴与银弹」公众号,第一时间获取优质技术干货。7年资深后端研发,给你呈现不一样的技术视角。
大家好,我是 Kaito。
这篇文章我想和你聊一聊 Redis 的架构演化之路。
现如今 Redis 变得越来越流行,几乎在很多项目中都要被用到,不知道你在使用 Redis 时,有没有思考过,Redis 到底是如何稳定、高性能地提供服务的?
你也可以尝试回答一下以下这些问题:
- 我使用 Redis 的场景很简单,只使用单机版 Redis 会有什么问题吗?
- 我的 Redis 故障宕机了,数据丢失了怎么办?如何能保证我的业务应用不受影响?
- 为什么需要主从集群?它有什么优势?
- 什么是分片集群?我真的需要分片集群吗?
- …
如果你对 Redis 已经有些了解,肯定也听说过数据持久化、主从复制、哨兵这些概念,它们之间又有什么区别和联系呢?
如果你存在这样的疑惑,这篇文章,我会从 0 到 1,再从 1 到 N,带你一步步构建出一个稳定、高性能的 Redis 集群。
在这个过程中,你可以了解到 Redis 为了做到稳定、高性能,都采取了哪些优化方案,以及为什么要这么做?
掌握了这些原理,这样平时你在使用 Redis 时,就能够做到「游刃有余」。
这篇文章干货很多,希望你可以耐心读完。
从最简单的开始:单机版 Redis
首先,我们从最简单的场景开始。
假设现在你有一个业务应用,需要引入 Redis 来提高应用的性能,此时你可以选择部署一个单机版的 Redis 来使用,就像这样:
这个架构非常简单,你的业务应用可以把 Redis 当做缓存来使用,从 MySQL 中查询数据,然后写入到 Redis 中,之后业务应用再从 Redis 中读取这些数据,由于 Redis 的数据都存储在内存中,所以这个速度飞快。
如果你的业务体量并不大,那这样的架构模型基本可以满足你的需求。是不是很简单?
随着时间的推移,你的业务体量逐渐发展起来了,Redis 中存储的数据也越来越多,此时你的业务应用对 Redis 的依赖也越来越重。
但是,突然有一天,你的 Redis 因为某些原因宕机了,这时你的所有业务流量,都会打到后端 MySQL 上,这会导致你的 MySQL 压力剧增,严重的话甚至会压垮 MySQL。
这时你应该怎么办?
我猜你的方案肯定是,赶紧重启 Redis,让它可以继续提供服务。
但是,因为之前 Redis 中的数据都在内存中,尽管你现在把 Redis 重启了,之前的数据也都丢失了。重启后的 Redis 虽然可以正常工作,但是由于 Redis 中没有任何数据,业务流量还是都会打到后端 MySQL 上,MySQL 的压力还是很大。
这可怎么办?你陷入了沉思。
有没有什么好的办法解决这个问题?
既然 Redis 只把数据存储在内存中,那是否可以把这些数据也写一份到磁盘上呢?
如果采用这种方式,当 Redis 重启时,我们把磁盘中的数据快速恢复到内存中,这样它就可以继续正常提供服务了。
是的,这是一个很好的解决方案,这个把内存数据写到磁盘上的过程,就是「数据持久化」。
数据持久化:有备无患
现在,你设想的 Redis 数据持久化是这样的:
但是,数据持久化具体应该怎么做呢?
我猜你最容易想到的一个方案是,Redis 每一次执行写操作,除了写内存之外,同时也写一份到磁盘上,就像这样:
没错,这是最简单直接的方案。
但仔细想一下,这个方案有个问题:客户端的每次写操作,既需要写内存,又需要写磁盘,而写磁盘的耗时相比于写内存来说,肯定要慢很多!这势必会影响到 Redis 的性能。
如何规避