Redis 面试宝典系列的其它文章:
Redis 面试宝典之 Redis 内存用完会怎样?
随着业务的不断发展和扩张我们需要更加稳定和高效的 Redis 服务,这是业务发展的必然趋势也是个人能力进阶的最高境界,我们需要一个高可用的 Redis 服务,来支撑和保证业务的正常运行。
我们本文的面试题是,如何设计一个不宕机的 Redis 高可用服务?
典型回答
想要设计一个高可用的 Redis 服务,那么一定要从 Redis 的多机功能来考虑,比如 Redis 的主从、哨兵以及 Redis 集群服务。
主从同步 (主从复制) 是 Redis 高可用服务的基石,也是多机运行中最基础的一个,它是将从前的一台 Redis 服务器,变为一主多从的多台 Redis 服务器,这样我们就可以将 Redis 的读写分离,而这个 Redis 服务器也能承载更多的并发操作。
Redis Sentinel(哨兵模式)使用监控 Redis 主从服务器的,当 Redis 的主从服务器出现问题时,可以利用哨兵模式自动的实现容灾恢复。
Redis Cluster(集群)是 Redis 3.0 版本中推出的 Redis 集群方案,它是将数据分布在不同的服务器上,以此来降低系统对单主节点的依赖,并且可以大大的提高 Redis 服务的读写性能。Redis Cluster 拥有所有主从同步和哨兵的所有优点,并且可以实现多主多从的集群服务,相当于将单台 Redis 服务器的性能平行扩展到了集群中,并且它还有自动容灾恢复的功能。
考点分析
Redis 多机知识是应聘中级和高级必问的知识点,它虽然看起来很高大上,其实它的概念却很好理解,并且 Redis 也提供了方便的多机构建的方案,例如 Redis 只需要一个命令就可以迅速的构建出一个集群服务等。
和此知识点相关的面试题还有以下这些:
- Redis 主从同步如何开启?它的数据同步方式有几种?
- Redis 哨兵模式如何开启?它是如何选择主服务器的?
- Redis 集群是如何创建的?说一说它的故障处理?
知识扩展
1.主从同步
我们可以将多台单独启动的 Redis 服务器设置为一个主从同步服务器,它的设置方式有两种,一种是在运行时将自己设置为目标服务器的从服务器;另一种是启动时将自己设置为目标服务器的从服务器。
运行中设置从服务器
在 Redis 运行过程中,我们可以使用 replicaof host port
命令,把自己设置为目标 IP 的从服务器,执行命令如下:
127.0.0.1:6379> replicaof 127.0.0.1 6380
OK
如果主服务设置了密码,需要在从服务器输入主服务器的密码,使用 config set masterauth 主服务密码
命令的方式,例如:
127.0.0.1:6377> config set masterauth pwd654321
OK
① 执行流程
在执行完 replicaof
命令之后,从服务器的数据会被清空,主服务会把它的数据副本同步给从服务器。
② 测试同步功能
主从服务器设置完同步之后,我们来测试一下主从数据同步,首先我们先在主服务器上执行保存数据操作,再去从服务器查询。
主服务器执行命令:
127.0.0.1:6379> set lang redis
OK
从服务执行查询:
127.0.0.1:6379> get lang
"redis"
可以看出数据已经被正常同步过来了。
启动时设置从服务器
我们可以使用命令 redis-server --port 6380 --replicaof 127.0.0.1 6379
将自己设置成目标服务器的从服务器。
主从同步的数据同步方式有以下三种。
① 完整数据同步
当有新的从服务器连接时,为了保障多个数据库的一致性,主服务器会执行一次 bgsave
命令生成一个 RDB 文件,然后再以 Socket 的方式发送给从服务器,从服务器收到 RDB 文件之后再把所有的数据加载到自己的程序中,就完成了一次全量的数据同步。
② 部分数据同步
在 Redis 2.8 之前每次从服务器离线再重新上线之前,主服务器会进行一次完整的数据同步,然后这种情况如果发生在离线时间比较短的情况下,只有少量的数据不同步却要同步所有的数据是非常笨拙和不划算的,在 Redis 2.8 这个功能得到了优化。 Redis 2.8 的优化方法是当从服务离线之后,主服务器会把离线之后的写入命令存储在一个特定大小的队列中,队列是可以保证先进先出的执行顺序的,当从服务器重写恢复上线之后,主服务会判断离线这段时间内的命令是否还在队列中,如果在就直接把队列中的数据发送给从服务器,这样就避免了完整同步的资源浪费。
小贴士:存储离线命令的队列大小默认是 1MB,使用者可以自行修改队列大小的配置项 repl-backlog-size。
③ 无盘数据同步
从前面的内容我们可以得知,在第一次主从连接的时候,会先产生一个 RDB 文件,再把 RDB 文件发送给从服务器,如果主服务器是非固态硬盘的时候,系统的 I/O 操作是非常高的,为了缓解这个问题,Redis 2.8.18 新增了无盘复制功能,无盘复制功能不会在本地创建 RDB 文件,而是会派生出一个子进程,然后由子进程通过 Socket 的方式,直接将 RDB 文件写入到从服务器,这样主服务器就可以在不创建 RDB 文件的情况下,完成与从服务器的数据同步。
要使用无须复制功能,只需把配置项 repl-diskless-sync 的值设置为 yes 即可,它默认配置值为 no。
2.哨兵模式
使用主从同步的一个致命问题就是出现服务器宕机之后需要手动恢复,而使用哨兵模式之后就可以监控这些主从服务器并且提供自动容灾恢复的功能,哨兵模式构建流程如下图所示: 哨兵模式.pngRedis 哨兵功能保存在 src 目录下,如图所示: image.png小贴士:Redis Sentinel 的最小分配单位是一主一从。
我们需要使用命令 ./src/redis-sentinel sentinel.conf
来启动 Sentinel,可以看出我们在启动它时必须设置一个 sentinel.conf 文件,这个配置文件中必须包含监听的主节点信息 sentinel monitor master-name ip port quorum
例如 sentinel monitor mymaster 127.0.0.1 6379 1
其中:
- master-name 表示给监视的主节点起一个名称;
- ip 表示主节点的 IP;
- port 表示主节点的端口;
- quorum 表示确认主节点下线的 Sentinel 数量,如果 quorum 设置为 1 表示只要有一台 Sentinel 判断它下线了,就可以确认它真的下线了。
注意:如果主节点 Redis 服务器有密码,还必须在 sentinel.conf 中添加主节点的密码,不然会导致 Sentinel 不能自动监听到主节点下面的从节点。 所以如果 Redis 有密码,sentinel.conf 必须包含以下内容:
sentinel monitor mymaster 127.0.0.1 6379 1 sentinel auth-pass mymaster pwd654321
当我们配置好 sentinel.conf 并执行启动命令 ./src/redis-sentinel sentinel.conf
之后,Redis Sentinel 就会被启动,如下图所示:
从上图可以看出 Sentinel 只需配置监听主节点的信息,它会自动监听对应的从节点。
上面我们演示了单个 Sentinel 的启动,但生产环境我们不会只启动一台 Sentinel,因为如果启动一台 Sentinel 假如它不幸宕机的话,就不能提供自动容灾的服务了,不符合我们高可用的宗旨,所以我们会在不同的物理机上启动多个 Sentinel 来组成 Sentinel 集群,来保证 Redis 服务的高可用。
启动 Sentinel 集群的方法很简单,和上面启动单台的方式一样,我们只需要把多个 Sentinel 监听到一个主服务器节点,那么多个 Sentinel 就会自动发现彼此,并组成一个 Sentinel 集群。
我们启动第二个 Sentinel 来试一下,执行结果如下:
网友评论