已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
如何正确地使用Redis1. Redis特性介绍1.1 Redis概述Redis是一款依据BSD开源协议发行的高性能,使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value存储系统(cache and store),并提供多种语言的API。它起步较晚,发展迅速,目前已被许多大型机构采用。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(hashes), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。1. 性能极高 Redis能支持超过 100K 每秒的读写频率。2. 丰富的数据类型 Redis支持二进制案例的 Strings, Lists, Hashes, Sets及 Sorted Sets数据类型操作。3. 原子 Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行,我们能非常方便得实现事务。4. Redis支持 publish/subscribe, 通知, key 过期等重要特性。5. Redis内存中的数据支持实时持久化,非常安全。6. 新版本Redis支持集群。Redis在最近发布了3.0.6稳定版,我把最新的3.0.6稳定版的配置翻译了一遍,获益匪浅,基本上对这个版本的Redis的很多细节清晰了很多,下面针对一些重要配置介绍下Redis的相关特性。1.2 Redis配置花了三天时间,把REDIS 3.0.6英文版大部分都翻译过来了,地址:/?/article/191.3 内存快照某个时间点Redis服务器内存中的内容我们称之为快照,Redis会自动快照保存到磁盘,调用BGSAVE能手动触发快照保存,保存快照的动作是后台进程完成的,保存快照期间其他客户端仍然和可以读写REDIS服务器。后台保存快照到磁盘会占用大量内存。如果调用SAVE命令保存内存中的数据到磁盘,将阻塞客户端请求,直到保存完毕。调用SHUTDOWN命令,Redis服务器会先调用SAVE,所有数据持久化到磁盘之后才会真正退出。在Redis的配置文件中可以配置内存数据持久化的触发条件# save # 两个条件同时满足,发生一次落地本地磁盘动作,下面三个配置是或的关系# 如果不想落地内存中的数据,直接注释掉下面三个配置即可# 如果配置成save ,之前落地的数据都可能被删除save 900 1save 300 10save 60 100001.4 主从同步 用slaveof的配置来设置本机的Redis作为从实例,实时从主实例读取数据,成为其镜像。主要是高可用场景需要本功能。以下是Redis主从同步的一些特性:1. 同一个Master可以同步多个Slaves;2. Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。因此我们可以将Redis的Replication架构视为图结构;3. Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求;4. Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据;5. 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成。即便如此,系统的伸缩性还是得到了很大的提高;6. Master可以将数据快照保存操作交给Slaves完成,从而避免了在Master中要有独立的进程来完成此操作,减轻Master的压力;7. Redis的数据同步是异步进行的,你可以配置主实例在和从实例断掉连接的时候停止接受客户端发过来的写请求,从而保证数据的一致性。8. 同步是自动完成的,不需要人工干预。主从之间的网络短暂的断开后,从再次连上主之后,会自动从上次断开的时候同步数据。9. 当新的从实例连入主实例,或者从实例断开连接时间比较长,再连入主实例的时候,为了保证数据一致,主实例会将全量数据同步给从实例。这种主要有两种模式:文件模式:主实例创建一个任务去写DB文件到磁盘,文件创建完毕后,主实例增量方式读取文件中的数据传输给从实例;使用Disk-backed模式同步数据有个好处就是,这个文件一旦生成,多个slave实例过来全量同步,都可以重用这一个文件;网络模式:主实例创建一个任务把全量数据直接写入从实例的socket连接上,数据不落地。;使用Diskless模式同步全量数据,一旦一个全量同步行为开始了,其他slave实例的同步请求过来时,只能先排到队列里面去等下一次全量同步开始。 使用diskless的数据同步时,master实例会等一会(时间可配),看看这段时间内是否有多个slave实例同时请求全量同步,好凑齐了一块给所有实例传输数据。在网络带宽充裕的情况下,diskless的同步避免了磁盘io,性能会好很多。10. Redis提供一个叫Redis Sentinel的监控程序做主从监控和主从切换工作。他主要有以下功能:监控(Monitoring): Redis Sentinel实时监控主服务器和从服务器运行状态。提醒(Notification):当被监控的某个 Redis 服务器出现问题时, Redis Sentinel 可以向系统管理员发送通知, 也可以通过 API 向其他程序发送通知。自动故障转移(Automatic failover): 当一个主服务器不能正常工作时,Redis Sentinel 可以将一个从服务器升级为主服务器, 并对其他从服务器进行配置,让它们使用新的主服务器。当应用程序连接到 Redis 服务器时, Redis Sentinel会告之新的主服务器地址和端口。Redis Sentinel 是一个分布式系统, 你可以在架构中运行多个 Sentinel 进程,这些进程通过相互通讯来判断一个主服务器是否断线,以及是否应该执行故障转移。在配置Redis Sentinel时,至少需要有1个Master和1个Slave。当Master失效后,Redis Sentinel会报出失效警告,并通过自动故障转移将Slave提升为Master,并提供读写服务;当失效的Master恢复后,Redis Sentinel会自动识别,将Master自动转换为Slave并完成数据同步。1.5 安全Redis可以在配置内设置访问密码,如果设置,那么在运行任何命令前,必须先输入密码。如果你的内网环境有不信任的主机在运行,那么你需要设置这个密码。如果你的内网是安全的,那么不建议设置本密码。Redis允许客户端每秒尝试15万次密码匹配,如果你密码不够强,很容易被破解。Redis还有一招挺绝的,就是修改高级别的命令的指令名。比如把CONFIG修改成b840fc02d524045429941cc15f59e41cb7be6c52,基本上就可以避免外部人员调用本命令了。Redis也可以屏蔽一些命令名,使用rename-command命令将命令的指令名设置为空字符串即可。需要注意的是,这些对命令名的修改也会同步到AOF文件中,或者传输给从实例中,引起其他问题。1.6 内存限制及LRU自动清理KeyRedis可以使用maxmemory来配置内存的使用上限,一旦Redis使用的内存达到设置的上限,那么会出现两种情况:1. 按照LRU算法自动清理过期Key来释放内存;2. 拒绝所有客户端发上来的写请求;Redis有个配置叫maxmemory-policy,这个配置决定了Redis内存触限后的处理策略:1. volatile-lru :根据LRU算法删除过期Key2. allkeys-lru :根据LRU算法删除所有Key3. volatile-random :随机删除过期数据4. allkeys-random :随机删除任意数据5. volatile-ttl :根据最近过期时间来删除(辅以TTL)6. noeviction:不删除任何数据,拒绝客户端写请求如果Reids在当前策略下找不到可以删除的key,那么Redis会拒绝所有客户端的写请求。写请求的命令包括:set setnx setex append incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby getset mset msetnx exec sort本配置项默认值为 : maxmemory-policy noeviction1.7 AOF模式持久化1.7.1 AOF持久化细节默认情况下Redis会异步落地内存快照数据到磁盘,这种模式对于很多场景是够用的。但这种模式有个缺点就是对于突发情况,比如突然停电,落地的文件数据会丢失几分钟数据,极端情况丢数据这事对于普通应用程序可能可以接收,但对于类似银行这种机构是苟能容忍的。因此Redis提供一种更可靠的模式来保证数据的安全,AOF是一种可选的更安全的持久化模式,能很好地解决上面说的数据丢失的问题。默认配置下,AOF模式在意外故障发生时最多丢失一秒钟的数据。AOF和内存快照两种持久化模式能同时启动,不会互相影响。如果AOF模式生效了,那么Redis启动的时候会首先载入AOF文件来保证数据的可靠性。AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令,有比较好的可读性。AOF日志也不是完全按客户端的请求来生成日志的,比如命令 INCRBYFLOAT 在记AOF日志时就被记成一条SET记录, 因为浮点数操作可能在不同的系统上会不同,所以为了避免同一份日志在不同的系统上生成不同的数据集,所以这里只将操作后的结果通过SET来记录。每一条写命令都生成一条日志,所以AOF文件会很大。Redis在落地AOF文件的时候,有三种模式1. appendfsync always : 每次有客户端发送写操作,都需要落地到磁盘,性能最差,但最安全。2. appendfsync everysec : 顾名思义,每秒写一次,均衡模式。3. appendfsync no : 操作系统在需要的时候才落地数据到磁盘,性能最好,但可能有数据丢失风险。对大多数Linux操作系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。Redis实用的默认模式是everysec,这是一种均衡的模式。在AOF同步文件同步模式设置为always或者everysec的时候,会有一个后台线程去做这个事,同时产生大量磁盘IO。这些IO操作经常会阻塞后台内存快照落地线程和AOF日志重写线程,甚至导致整个Redis被阻塞,目前没有很好的解决方案。为了缓解这个问题,Redis增加了AOF阻塞机制,生成AOF文件之前会先检查BGSAVE或者BGREWRITEAOF是否在运行,如果是,那么就先阻止AOF操作。这就意味这在BGSAVE或者BGREWRITEAOF时,Redis不会去写AOF,可能会因此丢掉30秒以内的数据。如果你因为AOF写入产生延迟问题,可以将AOF阻塞机制的相关配置no-appendfsync-on-rewrite设置为yes。该配置设置为no为最安全,最不可能丢失数据的方式.1.7.2 AOF重写在AOF文件增长到足够大超过配置的百分比的时候,Redis提供AOF重写功能,AOF重写会聚合Key的所有操作,目的是让一个KEY只有一条记录留在AOF文件中,从而大大缩小AOF文件的尺寸。AOF重写是重新生成一份AOF文件,新的AOF文件中一条记录的操作只会有一次,而不像一份老文件那样,可能记录了对同一个值的多次操作。其生成过程和RDB类似,也是fork一个进程,直接遍历数据,写入新的AOF临时文件。 在写入新文件的过程中,所有的写操作日志还是会写到原来老的 AOF文件中,同时还会记录在内存缓冲区中。当重完操作完成后,会将所有缓冲区中的日志一次性写入到临时文件中。然后调用原子性的rename命令用新的 AOF文件取代老的AOF文件。重写后,AOF文件变成一个非常小的全量文件命令:BGREWRITEAOF, 我们应该经常调用这个命令来来重写Redis会自动重写AOF,当然你也可以配置它不自动AOF重写。Redis数据结构详解Redis并不是简单的key-value存储,实际上他是一个数据结构服务器,支持不同类型的值。也就是说,你不必仅仅把字符串当作键所指向的值。下列这些数据类型都可作为值类型。二进制安全的 字符串 string二进制安全的 字符串列表 list of string二进制安全的 字符串集合 set of string,换言之:它是一组无重复未排序的element。可以把它看成JAVA中的 HashSet。有序集合sorted set of string,类似于集合set,但其中每个元素都和一个浮点数score(评分)关联。element根据score排序。可以把它看成JAVA的HashMap其key等于element,value等于score,但元素总是按score的顺序排列,无需额外的排序操作。1.8 KeyRedis key值是二进制安全的,这意味着可以用任何二进制序列作为key值,比如”foo”的简单字符串到一个JPEG文件的内容都可以。空字符串也是有效key值。关于key的几条规则:太长的键值不是个好主意,例如1024字节的键值就不是个好主意,不仅因为消耗内存,而且在数据中查找这类键值的计算成本很高。太短的键值通常也不是好主意,如果你要用”u:1000:pwd”来代替”user:1000:password”,这没有什么问题,但后者更易阅读,并且由此增加的空间消耗相对于key object和value object本身来说很小。当然,没人阻止您一定要用更短的键值节省一丁点儿空间。最好坚持一种模式。例如:”object-type:id:field”就是个不错的注意,像这样”user:1000:password”。1.9 Strings这是最简单Redis类型。如果你只用这种类型,Redis就像一个可以持久化的memcached服务器(注:memcache的数据仅保存在内存中,服务器重启后,数据将丢失)。我们来玩一下字符串类型。1.9.1 操作$ redis-cli set mykey my binary safe valueOK$ redis-cli get mykeymy binary safe value正如你所见到的,通常用SET command 和 GET command来设置和获取字符串值。值可以是任何种类的字符串(包括二进制数据),例如你可以在一个键下保存一副jpeg图片。值的长度不能超过1GB。虽然字符串是Redis的基本值类型,但你仍然能通过它完成一些有趣的操作。例如:原子递增:$ redis-cli set counter 100OK $ redis-cli incr counter(integer) 101$ redis-cli incr counter(integer) 102$ redis-cli incrby counter 10(integer) 112INCR 命令将字符串值解析成整型,将其加一,最后将结果保存为新的字符串值,类似的命令有INCRBY, DECR and DECRBY。实际上他们在内部就是同一个命令,只是看上去有点不同。INCR是原子操作意味着什么呢?就是说即使多个客户端对同一个key发出INCR命令,也决不会导致竞争的情况。例如如下情况永远不可能发生:客户端1和客户端2同时读出“10”,他们俩都对其加到11,然后将新值设置为11。最终的值一定是12,read-increment-set操作完成时,其他客户端不会在同一时间执行任何命令。对字符串,另一个的令人感兴趣的操作是GETSET命令,顾名思义:他为key设置新值并且返回原值。这有什么用处呢?例如:你的系统每当有新用户访问时就用INCR命令操作一个Redis key。你希望每小时对这个信息重置一次。你就可以GETSET这个key并给其赋值0并读取原值。1.9.2 使用场景UserId的生成,我们直接使用Redis的Strings数据结构,主要用到了INCR的原子性和Redis的全局性两个特点。内容变更不频繁的对象,直接用protobuff序列化之后,以字符串的形式写入Redis,需要的时候把字符串从Redis中取出,然后反序列化成对象后使用。比如用户基本信息的缓存我们就用这种形式存储。这种做法的好处是:存储、获取的时候代码很简单,不容易出错;对于这种对象,如果对象内容发生变更,一般的处理都是在变更时直接删除Redis中的对象对应的字符串,下次需要使用该对象的时候生成字符串写入Redis。1.10 Lists1.10.1 操作一般意义上讲,列表就是有序元素的序列:10,20,1,2,3就是一个列表。但用数组实现的List和用Linked List实现的List,在属性方面大不相同。Redis lists基于Linked Lists实现。这意味着即使在一个list中有数百万个元素,在头部或尾部添加一个元素的操作,其时间复杂度也是非常小。用LPUSH 命令在十个元素的list头部添加新元素,和在千万元素list头部添加新元素的速度相同。那么,坏消息是什么?在数组实现的list中利用索引访问元素的速度极快,而同样的操作在linked list实现的list上没有那么快。Redis Lists用linked list实现的原因是:对于数据库系统来说,至关重要的特性是:能非常快的在很大的列表上添加元素。另一个重要因素是,正如你将要看到的:Redis lists能在非常短时间取得常数长度。LPUSH 命令可向list的左边(头部)添加一个新元素,而RPUSH命令可向list的右边(尾部)添加一个新元素。最后LRANGE 命令可从list中取出一定范围的元素$ redis-cli rpush messages Hello how are you?OK$ redis-cli rpush messages Fine thanks. Im having fun with RedisOK$ redis-cli rpush messages I should look into this NOSQL thing ASAPOK$ redis-cli lrange messages 0 21. Hello how are you?2. Fine thanks. Im having fun with Redis3. I should look into this NOSQL thing ASAP注意LRANGE 带有两个索引,一定范围的第一个和最后一个元素。这两个索引都可以为负来告知Redis从尾部开始计数,因此-1表示最后一个元素,-2表示list中的倒数第二个元素,以此类推。1.10.2 使用场景List最大的优点就是你可以每次都以原先添加的顺序访问数据。对于只需要顺序批量读取,不需要按照特定值检索的数据,我们使用Lists数据结构。比如IM系统中的未读消息,就可以存在Lists中,每次读出来后就可以删除。Blog系统里面的Feed列表,也可以存储在List中,使用LRANGE可以实现分页。每个Feed的评论也可以单独存储一个List,写入读取都很方便。一些网站 的一些访问量比较大的内容,比如推荐文章,热门用户等内容都比较适合使用Lists结构来存储。1.11 Hashes1.11.1 操作Redis拥有一个键值对的数据结果,类似Java中的HashMap hmset user:1000 username antirez birthyear 1977 verified 1OK hget user:1000 usernameantirez hget user:1000 birthyear1977 hgetall user:10001) username2) antirez3) birthyear4) 19775) verified6) 1Hahes数据结构用来存储对象非常方便,基本上你想存储多少个字段到对象中都可以(除非超过内存限制)。HMSET可以设置多个键值对到Hashes对象中去,HGET只能获取一个键值对出来。HMGET可以获取多个键值对出来。 hmget user:1000 username birthyear no-such-field1) antirez2) 19773) (nil)HINCRBY之类的命令可以针对Hashes对象中的某一个键值对进行计算操作: hincrby user:1000 birthyear 10(integer) 1987 hincrby user:1000 birthyear 10(integer) 1997需要提醒大家的是,比较小的Hashes对象(拥有的元素少)被专门优化过,会得到一个非常好的性能。1.11.2 使用场景对于需要经常变更的对象,我们使用Hashes结构来存储。好处显而易见,第一你可以给一个对象存储任意多的字段,第二访问很方便,不用频繁序列化和反序列化。在IM系统中,用户在线状态就推荐用Hashes结果来存储。keepalive的时候会非常高效,IM的keepalive的请求量是非常大的。对于一些列配置类的数据,也比较适合用Hashes来缓存。比如会员的相关配置就可以都存在一个Hashes结构中,取起来很方便。1.12 Sets1.12.1 操作Redis集合是未排序的集合,其元素是二进制安全的字符串。SADD命令可以向集合添加一个新元素。和sets相关的操作也有许多,比如检测某个元素是否存在,以及实现交集,并集,差集等等。一例胜千言:$ redis-cli sadd myset 1(integer) 1$ redis-cli sadd myset 2(integer) 1$ redis-cli sadd myset 3(integer) 1$ redis-cli smembers myset1. 32. 13. 2我向集合中添加了三个元素,并让Redis返回所有元素。如你所见它们是无序的。现在让我们检查某个元素是否存在:$ redis-cli sismember myset 3(integer) 1$ redis-cli sismember myset 30(integer) 0“3是这个集合的成员,而“30”不是。集合特别适合表现对象之间的关系。例如用Redis集合可以很容易实现标签功能。下面是一个简单的方案:对每个想加标签的对象,用一个标签ID集合与之关联,并且对每个已有的标签,一组对象ID与之关联。例如假设我们的新闻ID 1000被加了三个标签tag 1,2,5和77,就可以设置下面两个集合:$ redis-cli sadd news:1000:tags 1(integer) 1$ redis-cli sadd news:1000:tags 2(integer) 1$ redis-cli sadd news:1000:tags 5(integer) 1$ redis-cli sadd news:1000:tags 77(integer) 1$ redis-cli sadd tag:1:objects 1000(integer) 1$ redis-cli sadd tag:2:objects 1000(integer) 1$ redis-cli sadd tag:5:objects 1000(integer) 1$ redis-cli sadd tag:77:objects 1000(integer) 1要获取一个对象的所有标签,如此简单:$ redis-cli smembers news:1000:tags1. 52. 13. 774. 2而有些看上去并不简单的操作仍然能使用相应的Redis命令轻松实现。例如我们也许想获得一份同时拥有标签1, 2, 10和27的对象列表。这可以用SINTER命令来做,他可以在不同集合之间取出交集。因此为达目的我们只需:$ redis-cli sinter tag:1:objects tag:2:objects tag:10:objects tag:27:objects. no result in our dataset composed of just one object ;) .在命令参考文档中可以找到和集合相关的其他命令,令人感兴趣的一抓一大把。一定要留意SORT命令,Redis集合和list都是可排序的。1.12.2 使用场景需要经常判断值是否在列表中,比如系统黑名单,被屏蔽的图片,在线列表等等,我们用Sets结构存储效率最高。1.13 Sorted Sets集合是使用频率很高的数据类型,但是对许多问题来说他们也有点儿太不讲顺序了;因此Redis1.2引入了有序集合。他和集合非常相似,也是二进制安全的字符串集合,但是这次带有关联的score,以及一个类似LRANGE的操作可以返回有序元素,此操作只能作用于有序集合,它就是,ZRANGE 命令。基本上有序集合从某种程度上说是SQL世界的索引在Redis中的等价物。例如在上面提到的例子中,并没有提到如何根据用户投票和时间因素将新闻组合生成首页。我们将看到有序集合如何解决这个问题,但最好先从更简单的事情开始,阐明这个高级数据类型是如何工作的。让我们添加几个黑客,并将他们的生日作为“score”。$ redis-cli zadd hackers 1940 Alan Kay(integer) 1$ redis-cli zadd hackers 1953 Richard Stallman(integer) 1$ redis-cli zadd hackers 1965 Yukihiro Matsumoto(integer) 1$ redis-cli zadd hackers 1916 Claude Shannon(integer) 1$ redis-cli zadd hackers 1969 Linus Torvalds(integer) 1$ redis-cli zadd hackers 1912 Alan Turing(integer) 1对有序集合来说,按生日排序返回这些黑客易如反掌,因为他们已经是有序的。有序集合是通过一个dual-ported 数据结构实现的,它包含一个精简的有序列表和一个hash table,因此添加一个元素的时间复杂度是O(log(N)。这还行,但当我们需要访问有序的元素时,Redis不必再做任何事情,它已经是有序的了:$ redis-cli zrange hackers 0 -11. Alan Turing2. Claude Shannon3. Alan Kay4. Richard Stallman5. Yukihiro Matsumoto6. Linus Torvalds你知道Linus比Yukihiro年轻吗无论如何,我想反向对这些元素排序,这次就用 ZREVRANGE 代替 ZRANGE 吧:$ redis-cli zrevrange hackers 0 -11. Linus Torvalds2. Yukihiro Matsumoto3. Richard Stallman4. Alan Kay5. Claude Shannon6. Alan Turing大家需要注意,ZSets只是有一个“默认的”顺序,但你仍然可以用 SORT 命令对有序集合做不同的排序(但这次服务器要耗费CPU了)。要想得到多种排序,一种可选方案是同时将每个元素加入多个有序集合。有序集合之能不止于此,他能在区间上操作。例如获取所有1950年之前出生的人。我们用 ZRANGEBYSCORE 命令来做:$ redis-cli zrangebyscore hackers -inf 19501. Alan Turing2. Claude Shannon3. Alan Kay我们请求Redis返回score介于负无穷到1950年之间的元素(两个极值也包含了)。也可以删除区间内的元素。例如从有序集合中删除生日介于1940到1960年之间的黑客。$ redis-cli zremrangebyscore hackers 1940 1960(integer) 2ZREMRANGEBYSCORE 这个名字虽然不算好,但他却非常有用,还会返回已删除的元素数量。2 Redis的高可用实现“高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。Redis有比较完备的主从同步机制,一个主可以配置多个从,并且Redis有自己原生的主从监控程序Redis Sentinel,一旦主挂了,该程序会根据从的配置,把优先级最高的从选举为主,并且通知管理员并调用订阅了该变更的应用程序的API,让应用程序调用从的IP来继续使用Redis。这一切看起来都不错,但是仔细想想,其实有两个不完美的地方:1 需要所有调用Redis的程序对Redis开放一个监听API才能同步切换主从;2 需要Redis遍历通知一遍应用才能完全生效,如果应用比较多,这个过程比较慢;得出的结论是,Reids原生的主从同步机制不错,但原生的高可用切换方案在大型系统中不实用。实际上我们生产环境会使用KeepAliveD来做Redis的主从切换。KeepAliveD实时监控主和从的健康状态,一旦主出现问题,就立刻把虚拟IP切换到从主机的网络地址,通过切换虚拟IP的方式来切换主从,从网络底层就把活给干了,应用程序不需要做任何事情,任然继续访问虚拟IP。细节描述:主从两台资源服务器上都部署了Redis和KeepaliveD,两台服务器上的主从Redis之间会实时同步数据,每台主服务的KeepAliveD都会用IP欺骗的方法使用广播APR包虚拟出这些有一个对外的IP,这样所有的应用服务器会认为主服务器占用了该虚拟Ip,所有的读写请求都会落地到主服务器上去。两台服务器的Keepalived会实时监控本服务器的Redis的健康情况,并且两台服务器的KeepAlivedD之间也会并通过VRRP协议互通监控情况。一旦主服务器出现故障,主服务器的KeepAliveD会:广播ARP包告诉大家,这台故障的服务器不再拥有这个虚拟IP,而是另一台健康的资源服务器才是这个虚拟IP的真正归属。这样所有发送给故障服务的请求就发送给另外一台资源服务器了。从服务器上的KeepAliveD会调用之前准备好的Shell脚本,见本服务器的Redis切换成主模式,继续接收应用服务器发送过来的读写请求。两台服务器上的KeepAliveD的配置:! Configuration File for keepalivedglobal_defs router_id cu_vitural_routervrrp_script chk_redis_a script /home/keepalived/scripts/redis_check.sh 6391 eth1 interval 2 #2秒检查一次 timeout 2 #2秒不响应算超时 fall 3 #连续错误三次开始切换vrrp_instance redis_a state BACKUP # 主也配置为SLAVE interface eth1 #绑定虚拟IP的网络接口 virtual_router_id 101 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组 priority 150 #节点的优先级(1-254之间),备用节点必须比主节点优先级低 nopreempt # 不抢占,注意加上 advert_int 1 #组播信息发送间隔,两个节点设置必须一样 authentication #设置验证信息,两个节点必须一致 auth_type PASS auth_pass cu1030 virtual_ipaddress 43/24 track_script chk_redis_a #需要成为master的时候执行的脚本 notify_master /home/keepalived/scripts/redis_be_master.sh 6391#需要成为slave的时候执行的脚本 notify_backup /home/keepalived/scripts/redis_be_slave.sh 91 6391#检查Redis的时候返回错误 notify_fault /home/keepalived/scripts/redis_fault.sh 6391#Keepalived停止的时候记录日志 notify_stop /home/keepalived/scripts/redis_stop.sh 6391下面是五个shell脚本的实现细节:redis_check.sh#!/bin/bash ALIVE=/usr/local/bin/redis-cli -p $1 PING GATE=route -n | grep $2 | grep UG | awk print $2LOGFILE=/var/log/keepalived/redis-check-$1.log echo CHECK $LOGFILEdate $LOGFILEping -w 1 -c 1 $GATE/dev/nullret=$?if $ALIVE = PONG -a $ret -eq 0 ;then echo Success: redis-cli -p $1 PING $ALIVE $LOGFILE 2&1 exit 0 else echo Failed:redis-cli -p $1 PING $ALIVE $LOGFILE 2&1 exit 1 firedis_be_master.sh:成为主,不从任何从同步数据;#!/bin/bash REDISCLI=/usr/local/bin/redis-cli -p $1 LOGFILE=/var/log/keepalived/redis-state-$1.log echo be master $LOGFILE date $LOGFILE echo Being SLAVEOF NO ONE . $LOGFILE $REDISCLI SLAVEOF NO ONE $LOGFILE 2&1exit(0)redis_be_slave:成为从,从主同步数据;#!/bin/bash REDISCLI=/usr/local/bin/redis-cli -p $2 LOGFILE=/var/log/keepalived/redis-state-$2.log echo be slave $LOGFILE date $LOGFILE echo Being SLAVEOF $1 $2. $LOGFILE 2&1$REDISCLI SLAVEOF $1 $2 $LOGFILEexit(0)redis_fault.sh#!/bin/bash LOGFILE=/var/log/keepalived/redis-state-$1.logecho fault $LOGFILEdate $LOGFILEnotify_stop#!/bin/bash LOGFILE=/var/log/keepa
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026江苏无锡鑫山北投资管理有限公司招聘2人备考题库(培优)附答案详解
- 2026广东省广晟控股集团有限公司总部管理人员岗位选聘4人备考题库及参考答案详解【完整版】
- 2026广东广州市天河区东风实验小学招聘小学高年段语文教师备考题库含答案详解【a卷】
- 2026浙江台州市中医院招聘120驾驶员编外人员1人备考题库【全优】附答案详解
- 2026北京师范大学东营实验学校人才引进教师6人备考题库(山东)及答案详解(基础+提升)
- 2026上半年四川成都市大邑县医疗卫生事业单位考核招聘高层次人才23人备考题库含完整答案详解(网校专用)
- 2026年宁夏财经职业技术学院单招职业适应性测试题库含答案详细解析
- 2026年四川省乐山市高职单招综合素质考试题库附答案详细解析
- 2026年陕西能源职业技术学院单招综合素质考试题库及答案详细解析
- 2026年山西省晋城市高职单招综合素质考试题库有答案详细解析
- 水稻幼穗发育
- 皮肤科常见疾病康复
- GB/T 4925-2008渔网合成纤维网片强力与断裂伸长率试验方法
- GB/T 39363-2020金银花空气源热泵干燥通用技术要求
- 复工复产安全检查表
- 第三章表面活性剂的功能与应用
- 心理学主要理论流派课件讲义
- 延1024井马五层酸化压裂设计
- 采矿学I第四章-矿石的损失和贫化课件
- 部编版六年级下册道德与法治全册优秀课件
- 中国经典广告案例评析之公益广告课件
评论
0/150
提交评论