redis 学习笔记(2)
redis-cluster
简介
- redis-cluster是一个分布式、容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式、集群化的目标。
- redis-cluster中不存在中心节点或者代理节点,这样的设计目标是为了实现线性化扩展,也解决了单一中心(或代理)节点带来的性能瓶颈,但是随着集群规模的增大,节点之间通信的开销也会成指数级的增长,这样的机制也反过来限制了redis-cluster的规模无限扩充的可能。
redis-cluster的容错性采用的基本的主备(1-N)模式,由主节点提供服务,备节点定期与主节点同步数据,且备节点与主节点采用完全一致的配置,只有在主节点异常的情况下才会切换到备用节点。这种简单主备的模式浪费过多资源,不知道是否考虑过节点互为主备的情况(可以保留几台设备作为备机,当然这种情况只在集群故障率较低的情况下使用)
redis-cluster 通信
- redis-cluster中的每一个节点都包含以下信息:1、保存k-v信息;2、记录集群中slot到node的映射信息(因为slot是由key根据固定的算法计算出来的,而且slot数量固定为16384,如果保存key-node映射,则需要大量空间存储映射关系);3、通过Gossip协议与cluster中的其他节点进行通信,自动发现其他节点、识别出工作异常的节点(PING-PONG机制)、传播自身以及获取到的其他节点的信息。4、集群间可以通过PUB/SUB进行分发、订阅事件
- redis-cluster中每个节点都有一个独一无二的ID,这个ID是一个十六进制表示的160位随机数,在节点第一次启动时由/dev/urandom生成。生成的节点ID会保存到配置文件中,只要配置文件存在该节点就会已知沿用这个ID。节点的ip、port都有可能改变,所以用ID来作为集群节点的唯一识别符。当某一结点的ip、port发生变化时,会通过gossip协议将关联信息发送到集群中其他节点:当前的ip、port;标识(flags);负责处理的hash_slot;最后一次使用集群连接发送PING的时间;最后一次收到PONG的时间;被集群标记为下线状态的时间;如果是从节点,会记录主节点的ID,否则主节点ID这一栏值为0000。example:
3886e65cc906bfd9b1f7e7bde468726a052d1dae 127.0.0.1:6380 master - 1318428930 1318428931 connected 1365-2729
- 节点通信:redis-cluster中的节点总是应答来自集群节点的连接请求,并对收到的PING数据包进行回复;对于来自本集群之外的节点的数据包,除了PING之外一概拒绝。这种情况下,集群中添加一个新的节点需要通过以下的步骤:1、新节点向原有节点发送MEET信息,强制接收信息的节点承认该节点是本集群的一份子,但是MEET信息只有在管理员手动执行
CLUSTER MEET ip port
命令时才能发送。2、redis-cluster支持A->B,B->C=A->C,这种传递方式C认识A的方式。 这种添加节点的方式有效防止了多个集群节点的mix,增强了集群的健壮性。 - MOVED和ASK命令:客户端向Node1请求key,如果key存在于Node1上就会直接返回,如果不在该节点上,就会返回
-MOVED *slot addr:port*
给客户端,告知客户端请求的slot所在的Node,然后客户端会重新向新的Node发送请求同时更新本地的slot-node映射缓存;如果请求的key所在的node正在和另一个node进行slot迁移,如果key仍然在当前node上,node会正常返回;否则会返回一个ASK转向命令,客户端收到这个ASK应答后(这里与MOVED的最大区别就是客户端不会去更新本地的slot-node映射缓存,也就是说客户端下次请求依然会指向原来的node),会向新的node节点先发送一个ASKING命令,node节点收到ASKING命令后会设置一个一次性的flag,使得可以接受一次客户端对该node节点的请求,如果没有收到ASKING命令,node节点是拒绝接收任何客户端请求的。
- 节点通信:redis-cluster中的节点总是应答来自集群节点的连接请求,并对收到的PING数据包进行回复;对于来自本集群之外的节点的数据包,除了PING之外一概拒绝。这种情况下,集群中添加一个新的节点需要通过以下的步骤:1、新节点向原有节点发送MEET信息,强制接收信息的节点承认该节点是本集群的一份子,但是MEET信息只有在管理员手动执行
由于redis-cluster没有中心节点或者代理节点,客户端与redis-cluster通信都是采用与节点直接连接发送消息的方式进行的。redis-cluster中的节点采用ASK、MOVED两种机制来解决客户端请求的key不在当前节点的问题,通常情况下只有在新增、删除、主备切换才会出现slot迁移的情况,此时会用到AKS、MOVED机制。为了使客户端可以尽快的找到目标key所在的节点,通常客户端都会缓存一份slot-node映射关系,根据这个映射关系客户端可以直接访问到目标key所在的节点。
集群操作
- redis-cluster支持在运行过程中进行节点的增加、删除操作,而且还不影响集群的正常工作。redis-cluster整个集群总共有16384(16*1024)个slot,所有的key都会指向一个特定的slot,每个node上可以负责其中的一部分,节点的增删,实际上就是slot迁移的过程。slot迁移除了因为主节点down会自动发生主备切换时是自动发生的,其他情况下都需要人工干预,即通过向集群发送命令来进行节点增删、slot迁移,slot迁移(resharding之后的文章会具体介绍)过程中会涉及到ASK、MOVED命令。
- 节点失效检测:当一个节点向另一个节点发送PING消息时,目标节点没有在超时时间内返回PONG,当前节点就会将目的节点标记为PFAIL(possible failure);每次当节点对其他节点发送PING命令的时候,都会随机的广播三个它所知道的节点信息,其中包括已经被标记为PFAIL或者FAIL的节点(如果有的话);当一个节点收到广播的信息,会记下被标记为PFAIL和FAIL的节点;如果节点已经将某个节点标记为PFAIL,并根据节点所收到其他节点关于状态的反馈,如果反馈其为PFAIL的节点数过半,就可以将那个节点标记为FAIL;一旦一个节点被标记为FAIL,其为FAIL的状态信息会很快广播到整个集群。在以下两种情况下节点的FAIL状态会被移除:1、如果被标记的时从节点,那么当这个节点重新上线时,FAIL标记就会被移除,保持从节点的FAIL状态没有任何意义,因为不处理任何slot,只会在主节点发生failover时才会影响其是否能够被提升为主节点;2、如果一个主节点被打上FAIL标记后,结果节点的超时时间的4倍再加10秒钟之后,针对这个主节点的故障slot转移操作仍未完成,并且这个主节点重新上线的话,那么就移除这个节点的FAIL标记。
- 节点failover选举:如果一个主节点进入FAIL状态,如果这个主节点有从节点,那么就会将一个从节点设置为主节点,其他从节点(如果有的话)就会开始从这个节点复制数据。从节点变主节点的条件:1、必须为已下线主节点的从节点;2、原主节点负责的slot数不为0;3、从节点数据被认为是可靠的,即主从节点间复制连接的断线时长不得超过节点超时时限*REDIS_CLUSTER_SLAVE_VALIDITY_MULT常量的乘积。从节点满足条件后,就会向集群中其他的主节点发送授权请求,询问是否能够转换成新的主节点。集群中主节点审核从节点升级主节点的请求时,考虑一下内容:1、发送请求消息的节点目前是从节点状态,其主节点为FAIL状态;2、该从节点在原主节点的所有从节点中,ID最小;3、该从节点没有被标记PFAIL或者FAIL。一旦一个从节点在一定时间内收到大部分的集群主节点的授权,就会开始故障转移操作:1、显式的向集群中所有节点广播一个PONG数据包,表面自身是一个已升级的从节点(promoted slave),目前已经是主节点,接管原有主节点负责处理的所有槽;2、原有主节点的slot全部被更新;3、已下线主节点其他所有的从节点(有的话)接收到promoted标志,开始从当前新的主节点复制数据;4、如果已下线的主节点重新上线,察觉到PROMOTED标志,就会将自身调整为目前主节点的从节点。
- 集群失效检测:每当集群配置发生变化时(slot更新或者slot迁移),集群中的每个节点都会对它所知道的节点进行扫描。配置更新完毕后,集群会根据扫描结果进入不同的状态:1、FAIL:集群不能正常工作,即对每个请求,集群都会返回错误回复;2、集群可以正常工作,负责处理全部16384个槽的节点中,没有一个主节点进入FAIL状态。当集群中的大部分主节点都进入下线状态,即此时大部分为PFAIL,就无法完成FAIL状态确认,因为需要过半数的主节点投票,这种情况下,整个集群就会停止处理客户端的命令请求,并进入到集群FAIL状态。
注:部分内容引用于http://redisdoc.com/topic/cluster-spec.html#id4
redis 学习笔记(2)的更多相关文章
- redis 学习笔记(6)-cluster集群搭建
上次写redis的学习笔记还是2014年,一转眼已经快2年过去了,在段时间里,redis最大的变化之一就是cluster功能的正式发布,以前要搞redis集群,得借助一致性hash来自己搞shardi ...
- Redis学习笔记~目录
回到占占推荐博客索引 百度百科 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合). ...
- Redis学习笔记4-Redis配置详解
在Redis中直接启动redis-server服务时, 采用的是默认的配置文件.采用redis-server xxx.conf 这样的方式可以按照指定的配置文件来运行Redis服务.按照本Redi ...
- Redis学习笔记7--Redis管道(pipeline)
redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis ...
- Redis学习笔记一:数据结构与对象
1. String(SDS) Redis使用自定义的一种字符串结构SDS来作为字符串的表示. 127.0.0.1:6379> set name liushijie OK 在如上操作中,name( ...
- Redis学习笔记之ABC
Redis学习笔记之ABC Redis命令速查 官方帮助文档 中文版本1 中文版本2(反应速度比较慢) 基本操作 字符串操作 set key value get key 哈希 HMSET user:1 ...
- (转)redis 学习笔记(1)-编译、启动、停止
redis 学习笔记(1)-编译.启动.停止 一.下载.编译 redis是以源码方式发行的,先下载源码,然后在linux下编译 1.1 http://www.redis.io/download 先 ...
- Redis学习笔记(二)-key相关命令【转载】
转自 Redis学习笔记(二)-key相关命令 - 点解 - 博客园http://www.cnblogs.com/leny/p/5638764.html Redis支持的各种数据类型包括string, ...
- Redis学习笔记(三)Redis支持的5种数据类型的总结
继续Redis学习笔记(二)来说说剩余的三种数据类型. 三.列表类型(List) 1.介绍 列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的一段片段.列表类型内部是 ...
- Redis学习笔记(二)Redis支持的5种数据类型的总结之String和Hash
引言 在Redis学习笔记(一)中我们已经会安装并且简单使用Redis了,接下来我们一起来学习下Redis支持的5大数据类型. 简介 Redis是REmote DIctionary Server(远程 ...
随机推荐
- 测试一下StringBuffer和StringBuilder及字面常量拼接三种字符串的效率
之前一篇里写过字符串常用类的三种方式<java中的字符串相关知识整理>,只不过这个只是分析并不知道他们之间会有多大的区别,或者所谓的StringBuffer能提升多少拼接效率呢?为此写个简 ...
- 菜鸟Python学习笔记第二天:关于Python黑客。
2016年1月5日 星期四 天气:还好 一直不知道自己为什么要去学Python,其实Python能做到的Java都可以做到,Python有的有点Java也有,而且Java还是必修课,可是就是不愿意去学 ...
- 【热门技术】EventBus 3.0,让事件订阅更简单,从此告别组件消息传递烦恼~
一.写在前面 还在为时间接收而烦恼吗?还在为各种组件间的消息传递烦恼吗?EventBus 3.0,专注于android的发布.订阅事件总线,让各组件间的消息传递更简单!完美替代Intent,Handl ...
- 深入解析Sqlite的完美替代者,android数据库新王者——Realm
写在前面: 又到一年一度七夕虐狗节,看着大家忍受着各种朋友圈和QQ空间还有现实生活中的轮番轰炸,我实在不忍心再在这里给大家补刀,所以我觉得今天不虐狗,继续给大家分享有用的. 如果你比较关心androi ...
- 3种web会话管理的方式
http是无状态的,一次请求结束,连接断开,下次服务器再收到请求,它就不知道这个请求是哪个用户发过来的.当然它知道是哪个客户端地址发过来的,但是对于我们的应用来说,我们是靠用户来管理,而不是靠客户端. ...
- jQuery遮罩层登录对话框
用户登录是许多网站必备的功能.有一种方式就是不管在网站的哪个页面,点击登录按钮就会弹出一个遮罩层,显示用户登录的对话框.这用方式比较灵活方便.而现在扫描二维码登录的方式也是很常见,例如QQ.微信.百度 ...
- XAMARIN.ANDROID SIGNALR 实时消息接收发送示例
SignalR 是一个开发实时 Web 应用的 .NET 类库,使用 SignalR 可以很容易的构建基于 ASP.NET 的实时 Web 应用.SignalR 支持多种服务器和客户端,可以 Host ...
- IOS之Objective-C学习 ARC下的单例模式
单例模式是我常用的一种设计模式,最常见的用途就是用来保存数据并且传递数据.这都归功于单例模式的特性,首先就让我为大家简单介绍一下单例模式的特性. 单例模式的三大特性: 1.某个类只能有一个实例: 2. ...
- 关于sqlmap的使用
好记性不如烂笔头,记录一下. 带cookie的注入 python sqlmap.py -u "http://www.xxx.com?id=1" --cookie="coo ...
- css 填坑常用代码分享
以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 因为提交比较麻烦,后来转置github:https://github.com/jsfront/src/blob/mast ...