本文转自互联网
本系列文章将整理到我在GitHub上的《Java面试指南》仓库,更多精彩内容请到我的仓库里查看
喜欢的话麻烦点下Star哈
文章首发于我的个人博客:
www.how2playlife.com
本文是微信公众号【Java技术江湖】的《探索Redis设计与实现》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客内容,引用其中了一些比较好的博客文章,如有侵权,请联系作者。
该系列博文会告诉你如何从入门到进阶,Redis基本的使用方法,Redis的基本数据结构,以及一些进阶的使用方法,同时也需要进一步了解Redis的底层数据结构,再接着,还会带来Redis主从复制、集群、分布式锁等方面的相关内容,以及作为缓存的一些使用方法和注意事项,以便让你更完整地了解整个Redis相关的技术体系,形成自己的知识框架。
如果对本系列文章有什么建议,或者是有什么疑问的话,也可以关注公众号【Java技术江湖】联系作者,欢迎你参与本系列博文的创作和修订。
转自http://blog.720ui.com/2016/redis_action_04_cluster/#Replication%EF%BC%88%E4%B8%BB%E4%BB%8E%E5%A4%8D%E5%88%B6%EF%BC%89
下面介绍Redis的集群方案。
Replication(主从复制)
Redis的replication机制允许slave从master那里通过网络传输拷贝到完整的数据备份,从而达到主从机制。为了实现主从复制,我们准备三个redis服务,依次命名为master,slave1,slave2。
配置主服务器
为了测试效果,我们先修改主服务器的配置文件redis.conf的端口信息
1. port 6300
配置从服务器
replication相关的配置比较简单,只需要把下面一行加到slave的配置文件中。你只需要把ip地址和端口号改一下。
1. slaveof 192.168.1.1 6379
我们先修改从服务器1的配置文件redis.conf的端口信息和从服务器配置。
1. port 6301
2. slaveof 127.0.0.1 6300
我们再修改从服务器2的配置文件redis.conf的端口信息和从服务器配置。
1. port 6302
2. slaveof 127.0.0.1 6300
值得注意的是,从redis2.6版本开始,slave支持只读模式,而且是默认的。可以通过配置项slave-read-only来进行配置。
此外,如果master通过requirepass配置项设置了密码,slave每次同步操作都需要验证密码,可以通过在slave的配置文件中添加以下配置项
1. masterauth
测试
分别启动主服务器,从服务器,我们来验证下主从复制。我们在主服务器写入一条消息,然后再其他从服务器查看是否成功复制了。
Sentinel(哨兵)
主从机制,上面的方案中主服务器可能存在单点故障,万一主服务器宕机,这是个麻烦事情,所以Redis提供了Redis-Sentinel,以此来实现主从切换的功能,类似与zookeeper。
Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-Sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。
它的主要功能有以下几点
- 监控(Monitoring):不断地检查redis的主服务器和从服务器是否运作正常。
- 提醒(Notification):如果发现某个redis服务器运行出现状况,可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover):能够进行自动切换。当一个主服务器不能正常工作时,会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
Redis Sentinel 兼容 Redis 2.4.16 或以上版本, 推荐使用 Redis 2.8.0 或以上的版本。
配置Sentinel
必须指定一个sentinel的配置文件sentinel.conf,如果不指定将无法启动sentinel。首先,我们先创建一个配置文件sentinel.conf
1. port 26379
2. sentinel monitor mymaster 127.0.0.1 6300 2
官方典型的配置如下
1. sentinel monitor mymaster 127.0.0.1 6379 2
2. sentinel down-after-milliseconds mymaster 60000
3. sentinel failover-timeout mymaster 180000
4. sentinel parallel-syncs mymaster 1
5.
6. sentinel monitor resque 192.168.1.3 6380 4
7. sentinel down-after-milliseconds resque 10000
8. sentinel failover-timeout resque 180000
9. sentinel parallel-syncs resque 5
配置文件只需要配置master的信息就好啦,不用配置slave的信息,因为slave能够被自动检测到(master节点会有关于slave的消息)。
需要注意的是,配置文件在sentinel运行期间是会被动态修改的,例如当发生主备切换时候,配置文件中的master会被修改为另外一个slave。这样,之后sentinel如果重启时,就可以根据这个配置来恢复其之前所监控的redis集群的状态。
接下来我们将一行一行地解释上面的配置项:
1. sentinel monitor mymaster 127.0.0.1 6379 2
这行配置指示 Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的 IP 地址为 127.0.0.1 , 端口号为 6300, 而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意,只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行。
不过要注意, 无论你设置要多少个 Sentinel 同意才能判断一个服务器失效, 一个 Sentinel 都需要获得系统中多数(majority) Sentinel 的支持, 才能发起一次自动故障迁移, 并预留一个给定的配置纪元 (configuration Epoch ,一个配置纪元就是一个新主服务器配置的版本号)。换句话说, 在只有少数(minority) Sentinel 进程正常运作的情况下, Sentinel 是不能执行自动故障迁移的。sentinel集群中各个sentinel也有互相通信,通过gossip协议。
除了第一行配置,我们发现剩下的配置都有一个统一的格式:
1. sentinel
接下来我们根据上面格式中的option_name一个一个来解释这些配置项:
- down-after-milliseconds 选项指定了 Sentinel 认为服务器已经断线所需的毫秒数。
- parallel-syncs 选项指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。
启动 Sentinel
对于 redis-sentinel 程序, 你可以用以下命令来启动 Sentinel 系统
1. redis-sentinel sentinel.conf
对于 redis-server 程序, 你可以用以下命令来启动一个运行在 Sentinel 模式下的 Redis 服务器
1. redis-server sentinel.conf --sentinel
以上两种方式,都必须指定一个sentinel的配置文件sentinel.conf, 如果不指定将无法启动sentinel。sentinel默认监听26379端口,所以运行前必须确定该端口没有被别的进程占用。
测试
此时,我们开启两个Sentinel,关闭主服务器,我们来验证下Sentinel。发现,服务器发生切换了。
当6300端口的这个服务重启的时候,他会变成6301端口服务的slave。
Twemproxy
Twemproxy是由Twitter开源的Redis代理, Redis客户端把请求发送到Twemproxy,Twemproxy根据路由规则发送到正确的Redis实例,最后Twemproxy把结果汇集返回给客户端。
Twemproxy通过引入一个代理层,将多个Redis实例进行统一管理,使Redis客户端只需要在Twemproxy上进行操作,而不需要关心后面有多少个Redis实例,从而实现了Redis集群。
Twemproxy本身也是单点,需要用Keepalived做高可用方案。
这么些年来,Twenproxy作为应用范围最广、稳定性最高、最久经考验的分布式中间件,在业界广泛使用。
但是,Twemproxy存在诸多不方便之处,最主要的是,Twemproxy无法平滑地增加Redis实例,业务量突增,需增加Redis服务器;业务量萎缩,需要减少Redis服务器。但对Twemproxy而言,基本上都很难操作。其次,没有友好的监控管理后台界面,不利于运维监控。
Codis
Codis解决了Twemproxy的这两大痛点,由豌豆荚于2014年11月开源,基于Go和C开发、现已广泛用于豌豆荚的各种Redis业务场景。
Codis 3.x 由以下组件组成:
- Codis Server:基于 redis-2.8.21 分支开发。增加了额外的数据结构,以支持 slot 有关的操作以及数据迁移指令。具体的修改可以参考文档 redis 的修改。
- Codis Proxy:客户端连接的 Redis 代理服务, 实现了 Redis 协议。 除部分命令不支持以外(不支持的命令列表),表现的和原生的 Redis 没有区别(就像 Twemproxy)。对于同一个业务集群而言,可以同时部署多个 codis-proxy 实例;不同 codis-proxy 之间由 codis-dashboard 保证状态同步。
- Codis Dashboard:集群管理工具,支持 codis-proxy、codis-server 的添加、删除,以及据迁移等操作。在集群状态发生改变时,codis-dashboard 维护集群下所有 codis-proxy 的状态的一致性。对于同一个业务集群而言,同一个时刻 codis-dashboard 只能有 0个或者1个;所有对集群的修改都必须通过 codis-dashboard 完成。
- Codis Admin:集群管理的命令行工具。可用于控制 codis-proxy、codis-dashboard 状态以及访问外部存储。
- Codis FE:集群管理界面。多个集群实例共享可以共享同一个前端展示页面;通过配置文件管理后端 codis-dashboard 列表,配置文件可自动更新。
- Codis HA:为集群提供高可用。依赖 codis-dashboard 实例,自动抓取集群各个组件的状态;会根据当前集群状态自动生成主从切换策略,并在需要时通过 codis-dashboard 完成主从切换。
- Storage:为集群状态提供外部存储。提供 Namespace 概念,不同集群的会按照不同 product name 进行组织;目前仅提供了 Zookeeper 和 Etcd 两种实现,但是提供了抽象的 interface 可自行扩展。
Codis引入了Group的概念,每个Group包括1个Redis Master及一个或多个Redis Slave,这是和Twemproxy的区别之一,实现了Redis集群的高可用。当1个Redis Master挂掉时,Codis不会自动把一个Slave提升为Master,这涉及数据的一致性问题,Redis本身的数据同步是采用主从异步复制,当数据在Maste写入成功时,Slave是否已读入这个数据是没法保证的,需要管理员在管理界面上手动把Slave提升为Master。
Codis使用,可以参考官方文档https://github.com/CodisLabs/codis/blob/release3.0/doc/tutorial_zh.md
Redis 3.0集群
Redis 3.0集群采用了P2P的模式,完全去中心化。支持多节点数据集自动分片,提供一定程度的分区可用性,部分节点挂掉或者无法连接其他节点后,服务可以正常运行。Redis 3.0集群采用Hash Slot方案,而不是一致性哈希。Redis把所有的Key分成了16384个slot,每个Redis实例负责其中一部分slot。集群中的所有信息(节点、端口、slot等),都通过节点之间定期的数据交换而更新。
Redis客户端在任意一个Redis实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。
Redis 3.0集群,目前支持的cluster特性
- 节点自动发现
- slave->master 选举,集群容错
- Hot resharding:在线分片
- 集群管理:cluster xxx
- 基于配置(nodes-port.conf)的集群管理
- ASK 转向/MOVED 转向机制
如上图所示,所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。节点的fail是通过集群中超过半数的节点检测失效时才生效。客户端与redis节点直连,不需要中间proxy层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。redis-cluster把所有的物理节点映射到[0-16383]slot上cluster负责维护node<->slot<->value。
选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超时,认为当前master节点挂掉。
当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误。如果集群任意master挂掉,且当前master没有slave,集群进入fail状态,也可以理解成进群的slot映射[0-16383]不完成时进入fail状态。如果进群超过半数以上master挂掉,无论是否有slave集群进入fail状态。
环境搭建
现在,我们进行集群环境搭建。集群环境至少需要3个主服务器节点。本次测试,使用另外3个节点作为从服务器的节点,即3个主服务器,3个从服务器。
修改配置文件,其它的保持默认即可。
1. # 根据实际情况修改
2. port 7000
3. # 允许redis支持集群模式
4. cluster-enabled yes
5. # 节点配置文件,由redis自动维护
6. cluster-config-file nodes.conf
7. # 节点超时毫秒
8. cluster-node-timeout 5000
9. # 开启AOF同步模式
10. appendonly yes
创建集群
目前这些实例虽然都开启了cluster模式,但是彼此还不认识对方,接下来可以通过Redis集群的命令行工具redis-trib.rb来完成集群创建。
首先,下载 https://raw.githubusercontent.com/antirez/redis/unstable/src/redis-trib.rb。
然后,搭建Redis 的 Ruby 支持环境。这里,不进行扩展,参考相关文档。
现在,接下来运行以下命令。这个命令在这里用于创建一个新的集群, 选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
1. redis-trib.rb create --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
5.3、测试
探索Redis设计与实现13:Redis集群机制及一个Redis架构演进实例的更多相关文章
-
【笔记】《Redis设计与实现》chapter17 集群
17.1 节点 启动节点 Redis服务器启动时会根据cluster-enabled配置选项是否为yes来决定是否开启服务器的集群模式 节点会继续使用redisServer结构来保存服务器的状态,使用 ...
-
Redis在Windows上使用和集群配置
一.什么是Redis Redis是一个开源的,使用C语言编写的面向键值对类型的分布式Nosql数据库系统,功能类似Memcache,但比Memcache功能更丰富.官网地址:https://redis ...
-
实现Redis Cluster并实现Python链接集群
目录 一.Redis Cluster简单介绍 二.背景 三.环境准备 3.1 主机环境 3.2 主机规划 四.部署Redis 4.1 安装Redis软件 4.2 编辑Redis配置文件 4.3 启动R ...
-
redis使用哈希槽实现集群
Redis Cluster集群 一.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper等,但从redis 3.0之后版本支持redis-cluster集群,Re ...
-
Redis主从同步、哨兵、集群
什么是主从同步(复制) 主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器.前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点 ...
-
Redis详解(七)——集群
Redis详解(七)--集群 Redis3.0版本之前,可以通过Redis Sentinel(哨兵)来实现高可用 ( HA ),从3.0版本之后,官方推出了Redis Cluster,它的主要用途是 ...
-
Redis 超详细自动管理Cluster集群工具上手 redis-trib.rb (多图,手把手)
安装介绍 redis-trib.rb是一款由Redis官方提供的集群管理工具,能够大量减少集群搭建的时间. 除此之外,还能够简化集群的检查.槽迁徙.负载均衡等常见的运维操作,但是使用前必须要安 ...
-
redis编译安装、哨兵、集群
编译安装 #下载源代码解压 wget https://download.redis.io/releases/redis-5.0.13.tar.gz -P /home/ tar -xvf /home/r ...
-
关于redis的主从、哨兵、集群
关于redis主从.哨兵.集群的介绍网上很多,这里就不赘述了. 一.主从 通过持久化功能,Redis保证了即使在服务器重启的情况下也不会损失(或少量损失)数据,因为持久化会把内存中数据保存到硬盘上,重 ...
随机推荐
-
金旭亮老师的Scoekt编程摘要
Socket提供了众多的属性,还提供了SetSocketOption方法来设置各种选项,对.NET网络应用程序的数据通讯进行“微调”. Socket的功能出奇地强大,在.NET平台上,它支持以下 ...
-
【原】http缓存与cdn相关技术
摘要:最近要做这个主题的组内分享,所以准备了一个星期,查了比较多的资料.准备的过程虽然很烦很耗时间,不过因为需要查很多的资料,因此整个过程下来,对这方面的知识影响更加深刻.来来来,接下来总结总结 一 ...
-
CentOS7修改服务器主机名方法
CentOS7下修改主机名 第一种:hostname 主机名 01.hostname 主机名称 这种方式,只能修改临时的主机名,当重启机器后,主机名称又变回来了. 第二种:hostnamectl se ...
-
rc.local自启动学习(转)
linux有自己一套完整的启动体系,抓住了linux启动的脉络,linux的启动过程将不再神秘. 本文中假设inittab中设置的init tree为: /etc/rc.d/rc0.d/etc/rc. ...
-
动态设置 GridView 列宽
/// <summary> /// 设置简单评语列的宽度 /// </summary> /// <param name=&quo ...
-
ccflow表机构与运行机制(二次开发必看)
驰骋工作流引擎,工作流程管理系统,表结构与运行机制. ------------------------------------------------------- 前言: 1, ccflow 有自动 ...
-
R语言 apply,sapply,lapply,tapply,vapply, mapply的用法
apply() apply(m,dimcode,f,fargs) m 是一个矩阵. dimcode是维度编号,取1则为对行应用函数,取2则为对列运用函数. f是函数 fargs是f的可选参数集 > ...
-
学JS的心路历程-函式(六)其余参数及预设参数
今天我们要来介绍ES6新增的其余参数及预设参数! 其余参数rest parameter …numbers可以让我们表示不确定数量的参数,并将其视为一个数组: function getVal(…numb ...
-
codeforces 894C - Marco and GCD Sequence - [有关gcd数学题]
题目链接:https://cn.vjudge.net/problem/CodeForces-894C In a dream Marco met an elderly man with a pair o ...
-
C++编译器符号表有哪些内容?
http://blog.csdn.net/wangbingcsu/article/details/48340479 C++编译器符号表有哪些内容? 很早就想写一篇关于符号表的学习小结,可是迟迟不能下笔 ...