`

Redis复制与可扩展集群搭建

 
阅读更多

 

 
 

Redis主从复制策略是通过其持久化的rdb文件来实现的,其过程是先dump出rdb文件,将rdb文件全量传输给slave,然后再将dump后的操作实时同步到slave中。下面是一篇介绍Redis复制原理的文章,文章作者为新浪微博的田琪同学(@摇摆巴赫)。

本文会讨论一下Redis的复制功能以及Redis复制机制本身的优缺点以及集群搭建问题。

Redis复制流程概述

Redis的复制功能是完全建立在之前我们讨论过的基于内存快照的持久化策略基础上的,也就是说无论你的持久化策略选择的是什么,只要用到了Redis的复制功能,就一定会有内存快照发生,那么首先要注意你的系统内存容量规划,原因可以参考我上一篇文章中提到的Redis磁盘IO问题。

Redis复制流程在Slave和Master端各自是一套状态机流转,涉及的状态信息是:

Slave 端:

REDIS_REPL_NONE
REDIS_REPL_CONNECT
REDIS_REPL_CONNECTED

Master端:

REDIS_REPL_WAIT_BGSAVE_START
REDIS_REPL_WAIT_BGSAVE_END
REDIS_REPL_SEND_BULK
REDIS_REPL_ONLINE

整个状态机流程过程如下:

  • 1.Slave端在配置文件中添加了slave of指令,于是Slave启动时读取配置文件,初始状态为REDIS_REPL_CONNECT。
  • 2.Slave端在定时任务serverCron(Redis内部的定时器触发事件)中连接Master,发送sync命令,然后阻塞等待master发送回其内存快照文件(最新版的Redis已经不需要让Slave阻塞)。
  • 3.Master端收到sync命令简单判断是否有正在进行的内存快照子进程,没有则立即开始内存快照,有则等待其结束,当快照完成后会将该文件发送给Slave端。
  • 4.Slave端接收Master发来的内存快照文件,保存到本地,待接收完成后,清空内存表,重新读取Master发来的内存快照文件,重建整个内存表数据结构,并最终状态置位为 REDIS_REPL_CONNECTED状态,Slave状态机流转完成。
  • 5.Master端在发送快照文件过程中,接收的任何会改变数据集的命令都会暂时先保存在Slave网络连接的发送缓存队列里(list数据结构),待快照完成后,依次发给Slave,之后收到的命令相同处理,并将状态置位为 REDIS_REPL_ONLINE。

整个复制过程完成,流程如下图所示:

Redis复制机制的缺陷

从上面的流程可以看出,Slave从库在连接Master主库时,Master会进行内存快照,然后把整个快照文件发给Slave,也就是没有象MySQL那样有复制位置的概念,即无增量复制,这会给整个集群搭建带来非常多的问题。

比如一台线上正在运行的Master主库配置了一台从库进行简单读写分离,这时Slave由于网络或者其它原因与Master断开了连接,那么当Slave进行重新连接时,需要重新获取整个Master的内存快照,Slave所有数据跟着全部清除,然后重新建立整个内存表,一方面Slave恢复的时间会非常慢,另一方面也会给主库带来压力。

所以基于上述原因,如果你的Redis集群需要主从复制,那么最好事先配置好所有的从库,避免中途再去增加从库。

Cache还是Storage

在我们分析过了Redis的复制与持久化功能后,我们不难得出一个结论,实际上Redis目前发布的版本还都是一个单机版的思路,主要的问题集中在,持久化方式不够成熟,复制机制存在比较大的缺陷,这时我们又开始重新思考Redis的定位:Cache还是Storage?

如果作为Cache的话,似乎除了有些非常特殊的业务场景,必须要使用Redis的某种数据结构之外,我们使用Memcached可能更合适,毕竟Memcached无论客户端包和服务器本身更久经考验。

如果是作为存储Storage的话,我们面临的最大的问题是无论是持久化还是复制都没有办法解决Redis单点问题,即一台Redis挂掉了,没有太好的办法能够快速的恢复,通常几十G的持久化数据,Redis重启加载需要几个小时的时间,而复制又有缺陷,如何解决呢?

Redis可扩展集群搭建

1. 主动复制避开Redis复制缺陷。

既然Redis的复制功能有缺陷,那么我们不妨放弃Redis本身提供的复制功能,我们可以采用主动复制的方式来搭建我们的集群环境。

所谓主动复制是指由业务端或者通过代理中间件对Redis存储的数据进行双写或多写,通过数据的多份存储来达到与复制相同的目的,主动复制不仅限于用在Redis集群上,目前很多公司采用主动复制的技术来解决MySQL主从之间复制的延迟问题,比如Twitter还专门开发了用于复制和分区的中间件gizzard(https://github.com/twitter/gizzard) 。

主动复制虽然解决了被动复制的延迟问题,但也带来了新的问题,就是数据的一致性问题,数据写2次或多次,如何保证多份数据的一致性呢?如果你的应用对数据一致性要求不高,允许最终一致性的话,那么通常简单的解决方案是可以通过时间戳或者vector clock等方式,让客户端同时取到多份数据并进行校验,如果你的应用对数据一致性要求非常高,那么就需要引入一些复杂的一致性算法比如Paxos来保证数据的一致性,但是写入性能也会相应下降很多。

通过主动复制,数据多份存储我们也就不再担心Redis单点故障的问题了,如果一组Redis集群挂掉,我们可以让业务快速切换到另一组Redis上,降低业务风险。

2. 通过presharding进行Redis在线扩容。

通过主动复制我们解决了Redis单点故障问题,那么还有一个重要的问题需要解决:容量规划与在线扩容问题。

我们前面分析过Redis的适用场景是全部数据存储在内存中,而内存容量有限,那么首先需要根据业务数据量进行初步的容量规划,比如你的业务数据需要100G存储空间,假设服务器内存是48G,那么根据上一篇我们讨论的Redis磁盘IO的问题,我们大约需要3~4台服务器来存储。这个实际是对现有业务情况所做的一个容量规划,假如业务增长很快,很快就会发现当前的容量已经不够了,Redis里面存储的数据很快就会超过物理内存大小,那么如何进行Redis的在线扩容呢?

Redis的作者提出了一种叫做presharding的方案来解决动态扩容和数据分区的问题,实际就是在同一台机器上部署多个Redis实例的方式,当容量不够时将多个实例拆分到不同的机器上,这样实际就达到了扩容的效果。

拆分过程如下:

  • 1.在新机器上启动好对应端口的Redis实例。
  • 2.配置新端口为待迁移端口的从库。
  • 3.待复制完成,与主库完成同步后,切换所有客户端配置到新的从库的端口。
  • 4.配置从库为新的主库。
  • 5.移除老的端口实例。
  • 6.重复上述过程迁移好所有的端口到指定服务器上。

以上拆分流程是Redis作者提出的一个平滑迁移的过程,不过该拆分方法还是很依赖Redis本身的复制功能的,如果主库快照数据文件过大,这个复制的过程也会很久,同时会给主库带来压力。所以做这个拆分的过程最好选择为业务访问低峰时段进行。

Redis复制的改进思路

我们线上的系统使用了我们自己改进版的Redis,主要解决了Redis没有增量复制的缺陷,能够完成类似Mysql Binlog那样可以通过从库请求日志位置进行增量复制。

我们的持久化方案是首先写Redis的AOF文件,并对这个AOF文件按文件大小进行自动分割滚动,同时关闭Redis的Rewrite命令,然后会在业务低峰时间进行内存快照存储,并把当前的AOF文件位置一起写入到快照文件中,这样我们可以使快照文件与AOF文件的位置保持一致性,这样我们得到了系统某一时刻的内存快照,并且同时也能知道这一时刻对应的AOF文件的位置,那么当从库发送同步命令时,我们首先会把快照文件发送给从库,然后从库会取出该快照文件中存储的AOF文件位置,并将该位置发给主库,主库会随后发送该位置之后的所有命令,以后的复制就都是这个位置之后的增量信息了。

Redis与MySQL的结合

目前大部分互联网公司使用MySQL作为数据的主要持久化存储,那么如何让Redis与MySQL很好的结合在一起呢?我们主要使用了一种基于MySQL作为主库,Redis作为高速数据查询从库的异构读写分离的方案。

为此我们专门开发了自己的MySQL复制工具,可以方便的实时同步MySQL中的数据到Redis上。

(MySQL-Redis 异构读写分离)

总结:

  • 1.Redis的复制功能没有增量复制,每次重连都会把主库整个内存快照发给从库,所以需要避免向在线服务的压力较大的主库上增加从库。
  • 2.Redis的复制由于会使用快照持久化方式,所以如果你的Redis持久化方式选择的是日志追加方式(aof),那么系统有可能在同一时刻既做aof日志文件的同步刷写磁盘,又做快照写磁盘操作,这个时候Redis的响应能力会受到影响。所以如果选用aof持久化,则加从库需要更加谨慎。
  • 3.可以使用主动复制和presharding方法进行Redis集群搭建与在线扩容。

本文加上之前的2篇文章基本将Redis的最常用功能和使用场景与优化进行了分析和讨论,实际Redis还有很多其它辅助的一些功能,Redis的作者也在不断尝试新的思路,这里就不一一列举了,有兴趣的朋友可以研究下,也很欢迎一起讨论,我的微博(http://weibo.com/bachmozart ) @摇摆巴赫。

http://blog.nosqlfan.com/html/3153.html

分享到:
评论

相关推荐

    redis的集群搭建与简单使用

    ### Redis集群搭建与简单使用详解 #### 一、概述 Redis 集群是一种通过分区数据来实现高可用性和水平扩展的技术。通过将数据分布在多个 Redis 实例中,集群能够提供更高的性能和更大的数据存储容量。本文档将详细...

    Redis集群搭建教程(含搭建文档和所需软件).zip

    1. **添加主节点**:当需要扩展集群时,可以使用`redis-cli --cluster add-node`命令向现有集群添加新的主节点。 2. **添加副本节点**:同样使用`redis-cli --cluster add-node`命令,但需指定一个现有的主节点作为...

    redis-5.0.4集群环境搭建

    Redis是一个开源的高性能键值存储数据库,通常被称为数据结构服务器。它被广泛用于构建各种类型的缓存系统或数据库,包括数据库、消息中间件等。...希望这些资料能够帮助学习者更好地理解和掌握Redis集群的搭建与维护。

    Redis集群搭建工具及教程

    Redis集群通过分片(Sharding)技术将数据分散到多个节点上,实现数据的冗余和负载均衡,从而提高系统的可扩展性和可用性。每个节点负责一部分数据,当某个节点故障时,其他节点可以接管其责任,确保服务的连续性。 ...

    Redis集群搭建.zip

    本资料"Redis集群搭建.zip"提供了真实项目环境下的Redis集群配置,旨在帮助用户快速搭建并投入使用。以下是对Redis集群搭建及相关知识点的详细解释: 1. **Redis集群的基本概念**: - **主从复制(Replication)**...

    Redis4基于CentOS6集群搭建1

    总之,搭建Redis集群需要细心的配置和初始化步骤,通过正确安装依赖、配置实例、启动服务和创建集群,可以实现高可用和可扩展的数据存储解决方案。在实践中,不断优化和调整配置,以适应不断变化的业务需求。

    14_redis搭建集群1

    Redis 集群(Cluster)是其提供的一种分布式解决方案,可以将数据分散存储在多个节点上,实现数据的高可用性和水平扩展。在 CentOS 6.7 系统上搭建 Redis 集群时,我们需要遵循一定的步骤来完成配置。 首先,确保...

    redis教程及主从配置和集群搭建

    ### Redis 教程及主从配置和集群搭建 #### Redis 基础知识与应用场景 **Redis**(Remote Dictionary Server)是一种开源的键值(Key-Value)存储系统,使用 C 语言编写,以其高性能和丰富的数据结构而闻名。Redis ...

    redis集群搭建步骤

    Redis 集群搭建是指将多个 Redis 服务器组合成一个集群,以提高系统的可用性和可扩展性。在这个步骤中,我们将详细介绍如何搭建一个 Redis 集群,包括虚拟机的准备、主从关系配置和查看集群信息。 虚拟机的准备 在...

    redis集群搭建以及脚本启动

    Redis 集群搭建与脚本启动是分布式缓存系统中的一个重要话题,它涉及到如何配置多个Redis实例以实现数据的高可用性和可扩展性。在本文中,我们将深入探讨Redis集群的基本概念、搭建过程以及使用脚本自动化启动的方法...

    windowsredis集群搭建

    在Windows环境下搭建Redis集群是一项技术性的工作,涉及到多个Redis实例的配置和协调,以实现数据的高可用性和可扩展性。以下将详细讲解这个过程。 首先,我们需要了解Redis集群的基本概念。Redis Cluster是Redis...

    Redis集群-Redis安装、Redis主从复制、哨兵、Redis集群

    Redis集群是Redis的一种高可用性解决方案,通过主从复制、哨兵和集群三大技术模块来实现高可用性和可扩展性。本文将对Redis集群进行详细的介绍,包括Redis安装、主从复制、哨兵和集群的配置和实现。 一、Redis安装 ...

    redis集群搭建相关文件

    总结来说,Redis集群提供了一种高效、可扩展的解决方案,通过分片和复制技术保证了高可用性和数据一致性。在搭建过程中,了解集群的基本原理和配置步骤至关重要,同时在实际应用中也要注意监控和维护集群的稳定运行...

    Redis分布式集群配置文档

    为了提高Redis的可靠性和可扩展性,需要对其进行分布式集群配置。本文档将详细介绍Redis分布式集群的配置过程。 一、Redis集群安装 1. 安装Redis 使用ssh工具连接服务器,下载和解包Redis安装包。然后,编译安装...

    spring + redis集群

    本文将深入探讨如何使用Spring Data Redis构建一个Redis集群,以及如何通过Spring框架来操作Redis集群,存储对象集合,并提供一个基于Maven的可运行项目示例。 首先,Spring Data Redis是Spring框架的一个模块,它...

    redis主从复制集群

    通过搭建主从复制集群,可以有效避免单点故障问题,并且能够满足读多写少的应用场景需求。 **主从复制的好处包括:** 1. **避免单点故障:** 通过构建多个从节点,即使主节点发生故障,应用仍然可以从其他节点读取...

Global site tag (gtag.js) - Google Analytics