redis和memached

redis 的 setex( key, expir, value) 创建一个有过期时间的值,expire不能为0,否则返回false,设置失败。setnx 当key不存在时,执行该方法。

 

随着业务数据量的不断增加,传统mysql + memcached架构遇到的问题

1. mysql需要不断进行拆库拆表,memcached也要不断扩容。

2. memcached与mysql的数据库数据一致性问题

3. memcached数据命中率低或宕机,引起的访问直接穿透到DB,mysql无法支撑。

4. 跨机房memcached同步问题

 

redis的有点:

1. redis不仅支持key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

2. redis支持数据的备份,即master-slave模式的数据备份。

3. redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载使用。

 

redis的内部设计:

在redis中。并不是所有的数据都一直存储在内存中的,这是和memcached相比最大的区别,redis只会缓存所有的key的信息,如果redis发现内存的使用量超过设置的一个阀值,将触发swap的操作,redis根据“swappability = age*log(size_in_memory)”计算出哪些key对应的value需要swap到磁盘,然后再将这些key对应的value持久化到磁盘中,同时在内存中清除,这种特性使得redis可以保持超过其计算机本身内存大小的数据,当然,机器本身的内存必须能够保存所有的key,毕竟这些数据是不会进行swap操作的,同时由于redis将内存中的数据swap到磁盘中的时候,提供服务的主线程和进行swap操作的子线程会共享这部分内存,所以如果更新需要swap的数据,redis将阻塞这个操作,直到子线程完成swap操作后才可以修改。

 

当从redis中读取数据的时候,如果读取的key对应的value不在内存中,那么redis就需要从swap文件中加载相应的数据,然后再返回给请求方。这里就存在一个I/o进程池的问题,在默认情况下,redis会出现阻塞,即完成所有的swap文件加载后才会响应,这种策略在客户端的数量较小,进行批量操作的时候比较合适,但如果将redis应用在一个大型网站应用程序中,这显然是无法满足大并发的情况的,所以redis运行我们设置的I/o线程池的大小,对需要从swap文件中加载相应数据的读取请求进行并发操作,减少阻塞时间。

所以说redis使用的最佳方式是全部数据in-memory。

 

memcached和redis的比较

1. 网络IO模型。

memcached是多线程,非阻塞IO复用的网络模型,分为监听主线程和子线程,监听线程监听网络连接,接受请求后,将连接描述字pipe传递给worker线程,进行读写IO,网络层使用libevent封装的事件库,多线程可以发挥多线程的作用。

redis使用单线程的IO复用模型,对于单纯只有IO操作来说,单线程可以将速度优势发挥到最大,但是redis提供的一些计算功能会严重影响单线程的整体吞吐量,CPU计算过程中,整个IO是阻塞的。

 

2. 内存管理方面。

memcached使用预分配内存池的方式(优先按照配置文件分配好内存块儿)使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除。

redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache

 

3. 数据一致性问题。

memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。redis没有提供cas命令,并不能保证这点,不过redis提供了事务,可以保证一串命令的原子性,中间操作不被打断。

(memcached的原子性讨论:

场景:如原来MEMCACHED中的KES的内容为A,客户端C1和客户端C2都把A取了出来,C1往准备往其中加B,C2准备往其中加C,这就会造成C1和C2执行后的CACHE KEYS要么是AB要么是AC,而不会出现我们期望的ABC。这种情况,如果不是在集群环境中,而只是单机服务器,可以通过在写CACHE KEYS时增加同步锁,就可以解决问题,可是在集群环境中,同步锁是显然解决不了问题的。

memcached是原子的吗?宏观

         所有的被发送到memcached的单个命令是完全原子的。如果您针对同一份数据同时发送了一个set命令和一个get命令,它们不会影响对方。它们将被串行化、先后执行。即使在多线程模式,所有的命令都是原子的;命令序列不是原子的。如果您通过get命令获取了一个item,修改了它,然后想把它set回memcached,我们不保证这个item没有被其他进程(process,未必是操作系统中的进程)操作过。在并发的情况下,您也可能覆写了一个被其他进程set的item。

memcached 1.2.5以及更高版本,提供了gets和cas命令,它们可以解决上面的问题。如果您使用gets命令查询某个key的item,memcached会 给您返回该item当前值的唯一标识。如果您覆写了这个item并想把它写回到memcached中,您可以通过cas命令把那个唯一标识一起发送给 memcached。如果该item存放在memcached中的唯一标识与您提供的一致,您的写操作将会成功。如果另一个进程在这期间也修改了这个 item,那么该item存放在memcached中的唯一标识将会改变,您的写操作就会失败。

memcache为了避免一些竞争,加入了一些特殊原子操作:add cas incr decr

4. 存储方式以及其他方面

memacached基本上只支持kv存储,不支持枚举,持久化和复制等功能

redis除了kv之外,还有list,set,zset,hash等数据结构,还提供了keys枚举操作,但不能在线上使用,如果需要枚举线上数据,redis提供了工具可以直接扫描dump文件,枚举出所有数据。

由以上可以看出当我们不希望数据被剔除,或者需要除kv数据类型时,或者需要数据落地功能时,使用redis比memacached合适。

总结:

1. redis使用最佳方式是全部数据in-memory

2. redis更多使用场景是mamcached的替代者

3. 当需要除kv以外的更多数据类型时,redis更合适

4. 当数据不能剔除,数据需要落地时,redis更合适

 

memcached和redis的简介

1. mamcached简介。

我们首先需要安装libevent,然后从获取源码,make && make install即可。默认情况下,Memcached的服务器启动程序会安装到/usr/local/bin目录下。在启动Memcached时,我们可以为其配置不同的启动参数。

1.1 Memcache配置

Memcached服务器在启动时需要对关键的参数进行配置,下面我们就看一看Memcached在启动时需要设定哪些关键参数以及这些参数的作用。

1)-p <num> Memcached的TCP监听端口,缺省配置为11211;

2)-U <num> Memcached的UDP监听端口,缺省配置为11211,为0时表示关闭UDP监听;

3)-s <file> Memcached监听的UNIX套接字路径;

4)-a <mask> 访问UNIX套接字的八进制掩码,缺省配置为0700;

5)-l <addr> 监听的服务器IP地址,默认为所有网卡;

6)-d 为Memcached服务器启动守护进程;

7)-r 最大core文件大小;

8)-u <username> 运行Memcached的用户,如果当前为root的话需要使用此参数指定用户;

9)-m <num> 分配给Memcached使用的内存数量,单位是MB;

10)-M 指示Memcached在内存用光的时候返回错误而不是使用LRU(Least Recently Used)算法移除数据记录;

11)-c <num> 最大并发连数,缺省配置为1024;

12)-v –vv –vvv 设定服务器端打印的消息的详细程度,其中-v仅打印错误和警告信息,-vv在-v的基础上还会打印客户端的命令和相应,-vvv在-vv的基础上还会打印内存状态转换信息;

13)-f <factor> 用于设置chunk大小的递增因子;

14)-n <bytes> 最小的chunk大小,缺省配置为48个字节;

15)-t <num> Memcached服务器使用的线程数,缺省配置为4个;

16)-L 尝试使用大内存页;

17)-R 每个事件的最大请求数,缺省配置为20个;

18)-C 禁用CAS,CAS模式会带来8个字节的冗余;

 

 

 

2. redis简介

1. 安装和配置

Redis的安装非常方便,只需从http://redis.io/download获取源码,然后make && make install即可。默认情况下,Redis的服务器启动程序和客户端程序会安装到/usr/local/bin目录下。在启动Redis服务器时,我们需要为其指定一个配置文件,缺省情况下配置文件在Redis的源码目录下,文件名为redis.conf。

2.1 Redis配置文件

为了对Redis的系统实现有一个直接的认识,我们首先来看一下Redis的配置文件中定义了哪些主要参数以及这些参数的作用。

1)daemonize no 默认情况下,redis不是在后台运行的。如果需要在后台运行,把该项的值更改为yes;

2)pidfile /var/run/redis.pid当Redis在后台运行的时候,Redis默认会把pid文件放在/var/run/redis.pid,你可以配置到其他地址。当运行多个redis服务时,需要指定不同的pid文件和端口;

3)port 6379指定redis运行的端口,默认是6379;

4)bind 127.0.0.1 指定redis只接收来自于该IP地址的请求,如果不进行设置,那么将处理所有请求。在生产环境中最好设置该项;

5)loglevel debug 指定日志记录级别,其中Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose。debug表示记录很多信息,用于开发和测试。verbose表示记录有用的信息,但不像debug会记录那么多。notice表示普通的verbose,常用于生产环境。warning 表示只有非常重要或者严重的信息会记录到日志;

6)logfile /var/log/redis/redis.log 配置log文件地址,默认值为stdout。若后台模式会输出到/dev/null;

7)databases 16 可用数据库数,默认值为16,默认数据库为0,数据库范围在0-(database-1)之间;

8)save 900 1保存数据到磁盘,格式为save <seconds> <changes>,指出在多长时间内,有多少次更新操作,就将数据同步到数据文件rdb。相当于条件触发抓取快照,这个可以多个条件配合。save 900 1就表示900秒内至少有1个key被改变就保存数据到磁盘;

9)rdbcompression yes 存储至本地数据库时(持久化到rdb文件)是否压缩数据,默认为yes;

10)dbfilename dump.rdb本地持久化数据库文件名,默认值为dump.rdb;

11)dir ./ 工作目录,数据库镜像备份的文件放置的路径。这里的路径跟文件名要分开配置是因为redis在进行备份时,先会将当前数据库的状态写入到一个临时文件中,等备份完成时,再把该临时文件替换为上面所指定的文件。而这里的临时文件和上面所配置的备份文件都会放在这个指定的路径当中,AOF文件也会存放在这个目录下面。注意这里必须指定一个目录而不是文件;

12)slaveof <masterip> <masterport> 主从复制,设置该数据库为其他数据库的从数据库。设置当本机为slave服务时,设置master服务的IP地址及端口。在Redis启动时,它会自动从master进行数据同步;

13)masterauth <master-password> 当master服务设置了密码保护时(用requirepass制定的密码)slave服务连接master的密码;

14)slave-serve-stale-data yes 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:如果slave-serve-stale-data设置为yes(默认设置),从库会继续相应客户端的请求。如果slave-serve-stale-data是指为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误"SYNC with master in progress";

15)repl-ping-slave-period 10从库会按照一个时间间隔向主库发送PING,可以通过repl-ping-slave-period设置这个时间间隔,默认是10秒;

16)repl-timeout 60 设置主库批量数据传输时间或者ping回复时间间隔,默认值是60秒,一定要确保repl-timeout大于repl-ping-slave-period;

17)requirepass foobared 设置客户端连接后进行任何其他指定前需要使用的密码。因为redis速度相当快,所以在一台比较好的服务器下,一个外部的用户可以在一秒钟进行150K次的密码尝试,这意味着你需要指定非常强大的密码来防止暴力破解;

18)rename-command CONFIG "" 命令重命名,在一个共享环境下可以重命名相对危险的命令,比如把CONFIG重名为一个不容易猜测的字符:# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52。如果想删除一个命令,直接把它重命名为一个空字符""即可:rename-command CONFIG "";

19)maxclients 128设置同一时间最大客户端连接数,默认无限制。Redis可以同时打开的客户端连接数为Redis进程可以打开的最大文件描述符数。如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis会关闭新的连接并向客户端返回max number of clients reached错误信息;

20)maxmemory <bytes> 指定Redis最大内存限制。Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,Redis同时也会移除空的list对象。当此方法处理后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。注意:Redis新的vm机制,会把Key存放内存,Value会存放在swap区;

 

21)maxmemory-policy volatile-lru 当内存达到最大值的时候Redis会选择删除哪些数据呢?有五种方式可供选择:volatile-lru代表利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used ),allkeys-lru代表利用LRU算法移除任何key,volatile-random代表移除设置过过期时间的随机key,allkeys_random代表移除一个随机的key,volatile-ttl代表移除即将过期的key(minor TTL),noeviction代表不移除任何key,只是返回一个写错误。

注意:对于上面的策略,如果没有合适的key可以移除,写的时候Redis会返回一个错误;

 

22)appendonly no 默认情况下,redis会在后台异步的把数据库镜像(RDB)备份到磁盘,但是该备份是非常耗时的,而且备份也不能很频繁。如果发生诸如拉闸限电、拔插头等状况,那么将造成比较大范围的数据丢失,所以redis提供了另外一种更加高效的数据库备份及灾难恢复方式。开启append only模式之后,redis会把所接收到的每一次写操作请求都追加到appendonly.aof文件中。当redis重新启动时,会从该文件恢复出之前的状态,但是这样会造成appendonly.aof文件过大,所以redis还支持了BGREWRITEAOF指令对appendonly.aof 进行重新整理,你可以同时开启asynchronous dumps 和 AOF;

23)appendfilename appendonly.aof  AOF文件名称,默认为"appendonly.aof";

24)appendfsync everysec  Redis支持三种同步AOF文件的策略: no代表不进行同步,系统去操作,always代表每次有写操作都进行同步,everysec代表对写操作进行累积,每秒同步一次,默认是"everysec",按照速度和安全折中这是最好的。

 

25)slowlog-log-slower-than 10000 记录超过特定执行时间的命令。执行时间不包括I/O计算,比如连接客户端,返回结果等,只是命令执行时间。可以通过两个参数设置slow log:一个是告诉Redis执行超过多少时间被记录的参数slowlog-log-slower-than(微妙),另一个是slow log 的长度。当一个新命令被记录的时候最早的命令将被从队列中移除,下面的时间以微妙微单位,因此1000000代表一分钟。注意制定一个负数将关闭慢日志,而设置为0将强制每个命令都会记录;

26)hash-max-zipmap-entries 512 && hash-max-zipmap-value 64 当hash中包含超过指定元素个数并且最大的元素没有超过临界时,hash将以一种特殊的编码方式(大大减少内存使用)来存储,这里可以设置这两个临界值。Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不同实现。这个Hash的成员比较少时Redis为了节省内存会采用类似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap。当成员数量增大时会自动转成真正的HashMap,此时encoding为ht;

27)list-max-ziplist-entries 512 list数据类型多少节点以下会采用去指针的紧凑存储格式;

28)list-max-ziplist-value 64数据类型节点值大小小于多少字节会采用紧凑存储格式;

29)set-max-intset-entries 512 set数据类型内部数据如果全部是数值型,且包含多少节点以下会采用紧凑格式存储;

30)zset-max-ziplist-entries 128 zsort数据类型多少节点以下会采用去指针的紧凑存储格式;

31)zset-max-ziplist-value 64 zsort数据类型节点值大小小于多少字节会采用紧凑存储格式。

32)activerehashing yes Redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存;

 

2. redis常用的数据类型

1)String

常用命令:set/get/decr/incr/mget等;

应用场景:String是最常用的一种数据类型,普通的key/value存储都可以归为此类;

实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr、decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。

2)Hash

常用命令:hget/hset/hgetall等

应用场景:我们要存储一个用户信息对象数据,其中包括用户ID、用户姓名、年龄和生日,通过用户ID我们希望获取该用户的姓名或者年龄或者生日;

3)List

常用命令:lpush/rpush/lpop/rpop/lrange等;

应用场景:Redis list的应用场景非常多,也是Redis最重要的数据结构之一,比如twitter的关注列表,粉丝列表等都可以用Redis的list结构来实现;

实现方式:Redis list的实现为一个双向链表(可以进行堆栈操作,也可以进行队列操作),即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销,Redis内部的很多实现,包括发送缓冲队列等也都是用的这个数据结构。

4)Set

常用命令:sadd/spop/smembers/sunion等;

应用场景:Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的;

实现方式:set 的内部实现是一个 value永远为null的HashMap,实际就是通过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的原因。

5)Sorted Set

常用命令:zadd/zrange/zrem/zcard等;

应用场景:Redis sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,并且是插入有序的,即自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以发表时间作为score来存储,这样获取时就是自动按时间排好序的。

实现方式:Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

3. redis的数据落地持久化。

redis提供两种主要的持久化策略:RDB快照和AOF日志。

RDB的原理:

Redis借助了fork命令的copy on write机制。在生成快照时,将当前进程fork出一个子进程,然后在子进程中循环所有的数据,将数据写成为RDB文件。你也可以通过Redis的CONFIG SET命令在Redis运行时设置规则,不需要重启Redis。

Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的,当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件,这样在任何时候出现故障,Redis的RDB文件都总是可用的。同时,Redis的RDB文件也是Redis主从同步内部实现中的一环。

RDB有他的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了

AOF(append only file)日志:

AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令。当然,并不是发送发Redis的所有命令都要记录到AOF日志里面,只有那些会导致数据发生修改的命令才会追加到AOF文件。

appendfsync设置项的三个策略:

1. appendfsync no。

Redis不会主动调用fsync去将AOF日志内容同步到磁盘,所以这一切就完全依赖于操作系统的调试了(操作系统有定期将cache中的数据swap到磁盘的机制)。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上

2. appendfsync everysec

当设置appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。但是当这一次的fsync调用时长超过1秒时。Redis会采取延迟fsync的策略,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就不管会执行多长时间都会进行。这时候由于在fsync时文件描述符会被阻塞,所以当前的写操作就会阻塞。

3. appednfsync always

每一次写操作都会调用一次fsync,这时数据是最安全的,但影响性能。

 

4. redis和memacached集群(cluster)的实现。

1. memcached的分布式。

Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希(现在客户端计算出数据在哪台上,再连接哪台服务器)这样的分布式算法来实现Memcached的分布式存储。

2. redis的分布式

相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储Redis开发版(3.0)中已经具备了Redis Cluster的基本功能。

 

Redis在3.0版正式引入了集群这个特性。Redis集群是一个分布式(distributed)、容错(fault-tolerant)的 Redis内存K/V服务, 集群可以使用的功能是普通单机 Redis 所能使用的功能的一个子集(subset),比如Redis集群并不支持处理多个keys,select的命令,因为这需要在不同的节点间移动数据,从而达不到像Redis那样的性能,在高负载的情况下可能会导致不可预料的错误。

Redis集群的几个重要特征:

(1).Redis 集群的分片特征在于将键空间分拆了16384个槽位,每一个节点负责其中一些槽位。

(2).Redis提供一定程度的可用性,可以在某个节点宕机或者不可达的情况下继续处理命令.

(3).Redis 集群中不存在中心(central)节点或者代理(proxy)节点, 集群的其中一个主要设计目标是达到线性可扩展性(linear scalability)。

 

解决的问题:

1.  redis cpu 使用率>80%, 拆分redis实例,修改代码,指向新的redis实例。

2   redis 内存使用超过标准,继续拆分实例!

3   redis 流量增长,拆!

4.  单实例的高可用问题。

 

现在:

只需要 分配一组新的redis实例 加入 cluster, 迁移 slot  即可解决 资源 使用率问题。

 

关于redis cluster的一些信息:

每个在cluster中的redis节点都会监听两个端口,一个是和客户端通讯的TCP端口(6379),一个是用作cluster内部数据传输的,比如错误检测、cluster配置更新、故障转移等等(16379)。这样cluster的通讯问题就解决了,但数据是怎么在cluster中存放的?redis cluster没有采用一致性哈希,而是采用hash slot(哈希槽)。一个redis cluster有固定的16384个hash slot,这么多slot被均匀的分配到cluster中的master节点上,而一个key具体的存储在哪个slot上,则是通过key的CRC16编码对16384取模得出的。上面提到了cluster中的master节点,估计很多人就迷糊了,为了当部分节点失效时,cluster仍能保持可用,Redis 集群采用每个节点拥有 1(主服务自身)到 N 个副本(N-1 个附加的从服务器)的主从模型。

 

例如,你可能有一个 3 个节点的集群,其中

 节点 A 包含从 0 到 5500 的哈希槽。

 节点 B 包含从 5501 到 11000 的哈希槽。

 节点 C 包含从 11001 到 16384 的哈希槽。

这可以让在集群中添加和移除节点非常容易。例如,如果我想添加一个新节点 D,我需要从节点 A,B, C 移动一些哈希槽到节点 D。同样地,如果我想从集群中移除节点 A,我只需要移动 A 的哈希槽到 B 和 C。 当节点 A 变成空的以后,我就可以从集群中彻底删除它。 因为从一个节点向另一个节点移动哈希槽并不需要停止操作,所以添加和移除节点,或者改变节点持有 的哈希槽百分比,都不需要任何停机时间(downtime)。

 

cluster经典架构

170407_pfAT_1384334.png

节点(Node)

一个集群由一个或多个节点组成,其中主节点(master)负责储存键值对数据,而从节点(slave)则负责复制主节点。

注意:从节点不提供任何读写操作

 

redis节点的淘汰和选举

(1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

(2)节点的fail是通过集群中超过半数的节点检测失效时才生效.

(3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可

(4)redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

 

(1)领着选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-node-timeout),认为当前master节点挂掉.

(2):什么时候整个集群不可用(cluster_state:fail),当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误

    a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成进群的slot映射[0-16383]不完成时进入fail状态.

    b:如果进群超过半数以上master挂掉,无论是否有slave集群进入fail状态.

 

redis集群的主从模型

 

为了当部分节点失效时,或者无法与大多数节点通信时仍能保持可用,Redis 集群采用每个节点拥有 1(主 服务自身)到 N 个副本(N-1 个附加的从服务器)的主从模型。 在我们的例子中,集群拥有 A,B,C 三个节点,如果节点 B 失效集群将不能继续服务,因为我们不再 有办法来服务在 5501-11000 范围内的哈希槽。 但是,如果当我们创建集群后(或者稍后),我们为每一个主服务器添加一个从服务器,这样最终的集群 就由主服务器 A,B,C 和从服务器 A1,B1,C1 组成,如果 B 节点失效系统仍能继续服务。 B1 节点复制 B 节点,于是集群会选举 B1 节点作为新的主服务器,并继续正确的运转

集群中nodes负责存储数据,保持集群的状态,包括keys与nodes的对应关系(内部其实为slots与nodes对应关系)。nodes也能够自动发现其他的nodes,检测失效的节点,当某个master失效时还应该能将合适的slave提升为master。

 

Redis Cluster使用异步复制

一个完整的写操作步骤:

1.client写数据到master

2.master告诉client "ok"

3.master传播更新到slave

 

http://www.cnblogs.com/janehoo/p/6119175.html

http://blog.csdn.net/tengdazhang770960436/article/details/49925031

转载于:https://my.oschina.net/shyl/blog/858489

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值