Redis作为一款性能优异的内存数据库,支撑着亿级数据量的社交平台,也成为很多互联网公司的标配。这里将以Redis Cluster 集群为核心,基于最新的Redis5版本,从原理到实战,玩儿转Redis集群。

常见的Redis集群方案

在介绍Redis Cluster集群方案之前,为了方便对比,先简单了解一下业界常见的Redis集群方案:

  • 1 基于客户端分片

    Redis Sharding是Redis Cluster出来之前,业界普遍使用的多Redis实例集群方法。其主要思想是基于哈希算法,根据Redis数据的key的哈希值对数据进行分片,将数据映射到各自节点上。

    优点在于实现简单,缺点在于当Redis集群调整,每个客户端都需要更新调整

  • 2 基于代理服务器分片

    客户端发送请求到独立部署代理组件,代理组件解析客户端的数据,并将请求转发至正确的节点,最后将结果回复给客户端。

    优点在于透明接入,容易集群扩展,调整Redis集群只需要更新代理即可,缺点在于多了一层代理转发,性能有所损耗

  • 3 Redis Sentinel(哨兵)

    Redis Sentinel是官方从Redis 2.6版本提供的高可用方案,在Redis主从复制集群的基础上,增加Sentinel集群监控整个Redis集群。当Redis集群master节点发生故障时,Sentinel进行故障切换,选举出新的master,同时Sentinel本身支持高可用集群部署。

    优点在于支持集群高可用,高性能读写,缺点在于没有实现数据分片,每个节点需要承载完整数据集,负载能力受当个Redis服务器限制,仅支持通过增加机器内存实现垂直扩容,不支持水平扩展

Redis Cluster设计

  • 1 整体设计

    Redis Cluster 是 在 3.0 版本正式推出的高可用集群方案,相比Redis Sentinel,Redis Cluster方案不需要额外部署Sentinel集群,而是通过集群内部通信实现集群监控,故障时主从切换;同时,支持内部基于哈希实现数据分片,支持动态水平扩容

    整体架构如下:

    集群中有多个主节点,每个主节点有多个从节点,主从节点间数据一致,最少需要3个主节点,每个主节点最少需要1个从节点

    • 高可用:当master节点故障时,自动主从切换
    • 高性能:主节点提供读写服务,从节点只读服务,提高系统吞吐量
    • 可扩展性:集群的数据分片存储,主节点间数据各不同,各自维护对应数据,可以为集群添加节点进行扩容,也可以下线部分节点进行水平缩容
  • 2 数据分片
    将整个数据集按照一定规则分配到多个节点上,称为数据分片,Redis Cluster采用的分片方案是哈希分片

    基本原理如下: Redis Cluster首先定义了编号0 ~ 16383的区间,称为槽,所有的键根据哈希函数映射到0 ~ 16383整数槽内,计算公式:slot=CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据

    槽是 Redis 集群管理数据的基本单位,集群扩容收缩就是槽和数据在节点之间的移动

    槽与节点映射关系如下:

    • 每个集群节点维护着一个16384 bit (2kB)的位数组,每个bit对应相同编号的槽,用 0 / 1标识对于某个槽自己是否拥有
    • 集群节点同时还维护着槽到集群节点的映射,是由长度为16384,数组下标代表槽编号,值为节点信息的数组

  • 3 集群扩容
    Redis Cluster支持不影响集群对外服务的情况下,对集群进行动态扩容或缩容,当Redis 新节点加入现有集群后,需要为其迁移槽和数据,确保迁移后每个节点负责相似数量的槽,使数据分布均匀在各节点上

    整个数据迁移涉及系列操作,Redis提供了集群管理工具,包括基于Ruby的redis-trib.rb,还Redis5新提供的基于C语言redis-cli,下面的介绍以redis-cli为例

    源节点将指定slot数据迁移到目标节点,基本流程如下:

  • (1) redis-cli设置目标节点指定slot状态importing,让目标节点准备迁入slot数据

  • (2) redis-cli设置源节点指定slot状态migrating,让让源节点准备迁出slot的数据

  • (3) redis-cli批量迁移源节点指定slot中的数据到目标节点

  • (4) 数据迁移完后 redis-cli向集群所有主节点通知槽被分配给目标节点,主节点更新slot与节点映射关系信息

    通常情况下,如果客户端请求的数据不在节点上,节点会回复 MOVED 重定向信息,客户端根据该信息再请求正确的节点。对于正在迁移的slot数据,保证客户端仍然能正常访问的设计如下:

    • (1) 迁移完成后才更新slot与节点映射关系信息,如果迁移进行中的映射信息保持与迁移前一致
    • (2) 如果客户端访问源节点,访问的key尚未迁出,则正常的处理该key
    • (3) 如果客户端访问源节点,访问的key尚已迁出,源节点返回ASK重定向信息
    • (4) 客户端根据ASK 重定向异常提取出目标节点信息,先向目标节点发送ASKING命令请求操作,再执行键命令

    ASK 和 MOVED 这2个重定向控制有如下区别:

    ASK 重定向说明集群正在进行 slot 数据迁移,客户端无法知道什么时候迁移完成,因此只能是临时性的重定向,客户端不会更新 slot 到 Redis 节点的映射缓存。
    MOVED 重定向说明键对应的slot 已经明确指定到新的节点,因此需要更新 slot 到 Redis 节点的映射缓存

  • 4 CAP取舍
    CAP包括:一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance),系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须在C和A之间做出选择

    Redis Cluster选择了AP架构,为了保证可用性,Redis并不保证强一致性,在特定条件下会出现数据不一致甚至丢失写操作

    第一个原因是:为了在性能和一致性上做出权衡,主从节点间数据同步是异步复制的,当客户端成功写入master节点,master返回成功,master节点才将写操作异步复制给slave节点
    另外一个原因是,当集群发送网络分区,集群可能会分为两部分:多数派和少数派,假如masterA节点位于少数派,如果网络分区发生时间较短,那么集群将会继续正常运作;如果分区的时间足够长,让多数派中选举为新的master替代matsterA,那么分区期间写入masterA的数据就丢失了
    在网络分区期间, 客户端可以向matsterA发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(cluster-node-timeout),是 Redis集群的一个重要的配置选项

总结

至此,Redis Cluster集群原理介绍到这里,其实还有集群通信协议,内存,数据备份,主从复制等特性值得学习,是设计分布式系统的典范,有机会再展开介绍

转自
作者:一行代码一首诗
链接:https://www.jianshu.com/p/da0a3d36a6ef
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

一篇文章理解Redis集群【转】的更多相关文章

  1. Redis集群的离线安装以及原理理解

    一.本文主要是记录一下Redis集群在linux系统下离线的安装步骤,毕竟在生产环境下一般都是无法联网的,Redis的集群的Ruby环境安装过程还是很麻烦的,涉及到很多的依赖的安装,所以写了一个文章来 ...

  2. redis集群安装2

      概要:本文主要介绍如何在Centos7中单机搭建redis集群三主三从,按照本文绝对可以实现该需求,至于先搭建单机版主要为了方便理解redis集群,为下一步开发或生产上redis集群做铺垫.同时本 ...

  3. Redis 集群规范

    什么是 Redis 集群??Redis 集群是一个分布式(distributed).容错(fault-tolerant)的 Redis 实现,集群可以使用的功能是普通单机 Redis 所能使用的功能的 ...

  4. 认识Redis集群——Redis Cluster

    前言 Redis集群分三种模式:主从模式.sentinel模式.Redis Cluster.之前没有好好的全面理解Redis集群,特别是Redis Cluster,以为这就是redis集群的英文表达啊 ...

  5. redis集群理解

    Redis在3.0中也引入了集群的概念,用于解决一些大数据量和高可用的问题,但是,为了达到高性能的目的,集群不是强一致性的,使用的是异步复制,在数据到主节点后,主节点返回成功,数据被异步地复制给从节点 ...

  6. 【原创】那些年用过的Redis集群架构(含面试解析)

    引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...

  7. 那些年用过的Redis集群架构

    今天我们来谈谈Redis集群这个话题,需要说明的是本文 适合人群:不知道自己生产redis集群架构,以及对Redis集群不了解的人 不适合群: 对自己生产Redis集群架构非常了解的人 本文预计分两个 ...

  8. redis集群架构(含面试题解析)

    老规矩,我还是以循序渐进的方式来讲,我一共经历过三套集群架构的演进! Replication+Sentinel 这套架构使用的是社区版本推出的原生高可用解决方案,其架构图如下! 这里Sentinel的 ...

  9. 【转】那些年用过的Redis集群架构(含面试解析)

    引言 今天是2019年2月12号,也就是大年初八,我接到了高中同学刘有码面试失利的消息. 他面试的时候,身份是某知名公司的小码农一枚,却因为不懂自己生产上Redis是如何部署的,导致面试失败! 人间惨 ...

随机推荐

  1. [linux]查找最大的文件

    查找最大的日志文件,命令: find ./ -type f | xargs -I{} du -m {}|sort -rnk1|head -10 offline一台机器保留限产,其他机器删除日志,命令: ...

  2. Spark编译的三种方式

    有三种编译方式,此文采用make-distribution.sh编译 其余两种为maven 和SBT编译 1.配置jdk 配置maven 配置scala 2.修改spark下make-distribu ...

  3. java(包括springboot)读取resources下文件方式

    1.使用项目内路径读取,该路径只在开发工具中显示,类似:src/main/resources/resource.properties.只能在开发工具中使用,部署之后无法读取.(不通用) File fi ...

  4. 版本问题---keras和tensorflow的版本对应关系

    keras和tensorflow的版本对应关系,可参考: Framework Env name (--env parameter) Description Docker Image Packages ...

  5. Python 基础-> 字符串,数字,变量

    Python 基础:字符串,数字,变量 1. 字符串 (信息的一种表达方式) a. 使用引号创建字符串 b. 单引号,双引号,三引号: ', ", ''', ""&quo ...

  6. 随笔分类 - C++托管(clr)(转)

    c#利用SWIG调用c++dll学习总结[转] 摘要: 开发环境: 操作系统:windows 7 IDE:Microsoft Visual Studio Professional 2015 SWIG: ...

  7. Java动态代理--CGLib实现

    上一篇说了通过JDK实现实现了动态代理,但是用JDK实现代理,要求所代理的类必须实现一个接口.如果我们类不实现接口,这就在无法使用JDK提供的Proxy来实现动态代理,这个时候我们应该怎么办呢?我们找 ...

  8. linux下如何完全删除用户

    1.首先进入系统创建一个用户 [root@localhost /]# useradd haha   #创建用户  haha是用户名 [root@localhost /]# passwd haha    ...

  9. python - django 项目部署 Ubuntu 服务器后接口访问一直 502 问题

    问题描述:最近有了一台 Ubuntu 的服务器,然后准备部署个项目,结果没想到部署的过程跟用 Centos 的时候还有点不一样,最后一步我是卡在了 uwsgi 这里,访问一直502,且可以访问项目的静 ...

  10. RabbitMQ六种队列模式-发布订阅模式

    前言 RabbitMQ六种队列模式-简单队列RabbitMQ六种队列模式-工作队列RabbitMQ六种队列模式-发布订阅 [本文]RabbitMQ六种队列模式-路由模式RabbitMQ六种队列模式-主 ...