简介(高效率缓存数据库)
Redis是一个key_value的nosql产品,使用的是C语言编写,它存储的value类型相对更加丰富,包括string(字符串)、list(链表)、set(集合)、sorted set(有序集合)和hash。为了保证高效率,数据都是缓存在内存中,在内存中加载的效率比在硬盘上的会更加的快速,区别的是redis会周期性的把内存中的数据写入硬盘中,同时由于redis支持的value类型众多,也被称为结构化的nosql数据库。(not only sql)
缓存有两种类型:数据缓存、页面缓存
缓存的作用:使用缓存减轻数据库的负载。
在开发网站的时候如果有一些数据再短时间之内不会发生变化,而它们还要被频繁访问,为了提高用户的请求速度和降低网站的负载,就把这些数据放到一个读取速度更快的介质上(或者是通过较少的计算量就可以获得该数据),该行为就称为对该数据的缓存。
缓存的两种形式:
1.页面缓存经常用在CMS内存管理系统中
2.数据缓存经常用在页面的具体数据中
Redis和Memcache比较
1.Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
2.Redis支持master-slave主从复制。
3.Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启时可以再次加载进行使用。
4.Redis单个value的最大限制是1GB,memcache只能保存1MB的数据
Redis和Memcache区别
1.Redis只使用单核,而Memcache使用多核;即Redis属于单线程操作,而Memcache属于多线程操作。也就是说在多个用户请求时,Redis是处理完一个请求后在处理另一个请求,而Memcache可以同时处理多个请求。
2.数据结构:Redis不仅仅支持简单的K/V类型的数据,同时还提供list、set、hash等数据结构的存储。
3.数据安全性:Redis和Memcache都是将数据存储在内存中,都属于内存数据库。Memcache属于纯内存数据库,服务器宕机或重启后,数据不可恢复;Redis服务器宕机或重启后可以恢复,因为Redis可以做持久化,将内存数据定期保存到磁盘中,而且提供了两种持久策略,默认支持的是RDM持久化,还有需要手动开启的AOF持久化。而Memcache仅仅将数据存储在内存中。
4.数据备份:Redis支持数据备份,即需要开启master-slave策略
5.过期策略:Memcache在set时就指定了过期时间;而Redis可以通过expire设定key的过期时间
6.内存回收:Memcache有内存回收机制,就是当程序里给它设定的内存大小,一旦存储的数据超过该分配的内存大小的时候,就会去自动回收,也就是释放,不然就会出现内存溢出的情况,因为Memcache的数据都是存储在内存中的,但是Redis不会,因为Redis可以将数据持久化到磁盘上。
Nosql产品的两个非常显著特点
1.nosql产品一般不使用严格的表结构(行和列的组成形成一个表)
2.nosql产品的数据的查询一般都不使用sql查询
常见的nosql产品比较
在window下启动redis服务(默认端口6379)
Redis-server.exe
简单操作(使用redis的客户端命令来连接redis的服务器端,必须保持服务器端开启状态)
Redis-cli.exe 默认连接本机的redis服务
Redis-cli.exe –h 服务器ip地址 –p 服务器端口
Redis-key类型
1.key的命名规则不同于一般语言,键盘上除了空格、\n换行外其他的大部分字符都可以使用。
像“my key”和“mykey\n”这样包含空格和换行的key是不允许的。
2.我们在使用的时候可以自己定义一个key的格式。
3.例如object-type:id:field
4.key不要太长,占内存、查询慢。
5.key不要太短,像u:1000:pwd 就不如 user:1000:password 可读性好
redis数据库下标从0开始,0-15
配置日志文件
Redis有个api,可以通过help @xx来查找需要使用的命令,比如查找关于string操作的
也可以直接查找单个命令,通过help xx
String类型
string是redis最基本的类型
redis的string可以包含任何数据。包括jpg图片或者序列号的对象
单个value值最大上限是1G字节
如果只用string类型,redis就可以被看做加上持久化特性的memcache
字符串追加append key value
键的命名
因为redis数据库不能出现两个同名的键,所以我们通过使用field1::field2::field3这样的格式来区分同一类型的多个字符串键。比如,像上面提交用户那样,这样大家用户的email地址就不会冲突了。一个更复杂的例子,就是user::10086::info这个可能是Id使10086的用户的信息,new::sport::cache这个可能是新闻类网站体育分类的缓存,message::123321::content,这个可能就是Id为123321消息的内容,两个冒号是大众习惯的分隔符,你也可以用自己习惯的分隔符来命名键。
索引
字符串的索引以0为开始,从字符串的开头向字符串的结尾依次递增,字符串每一个字符的索引为0,字符串最后一个字符的索引为N-1,其他N为字符串的长度。举个例子,这里有个字符串值叫,"hello"有5个字符组成,它的索引分别是1,2,3,4,从0至4,除了正数索引之外,字符串还有负数索引:负数索引以-1开始,从字符串的结尾向字符串的开头依次递减,字符串的最后一个字符的索引为-N,其中N为字符串的长度。
范围设置
因为有了索引,两个字符直接就会有个范围,譬如刚才这里我们说0到3,这就是索引范围,这就对应着h,e,l,l这四个字符,负数索引是-3到-1,这也是一个范围,涵盖了l,l,o这三个字符。
通过SETRANGE命令我们可以从索引index开始,用你想写入的value值替换掉给定key所存储的字符串的部分,等于做手术般切开病人的胳膊,我们再接上新的胳膊一样,当然这里只接受正数索引。命令返回替换之后字符串值得长度,比如:我们将key为msg的值设为"hello",然后调用SETRANGE命令,然后键为msg,给定的索引为1,也就是字符的第二个字符开始,也就是从第二个开始我们把字符逐个改写为a,p,p,y,也就是变成了happy,我们现在再用get msg的话就会返回happy。
GETRANGE
返回key存储的字符串值中,位于start和end两个索引之间的内容,左右都闭区间!和SETRANGE只接受正数索引不同,GETRANGE的索引可以是正数也可以是负数。
比如:如果将set msg “hello world”,GETRANGE给定索引值0,4,就可以获得字符串h,e,l,l,o这五个字符的内容,因为GETRANGE还能接受负数,同样我们获取范围-5到-1的字符,我们也可以获得5个字符,w,o,r,l,d,只需要注意一点就是,这里索引是闭区间,给定0的时候这个字符会包含在内,给定4的时候这个字符也会包含在内。
INCR:increament 增长
该指令可以对key进行累加1操作,默认是累加1,类型i++
该指令可以针对新key或已有key进行操作(已有key的信息值类型要求必须为整型的)
1.设置值
2.获取值
3.incr做自增操作,可以对某个key的value进行+1操作
4.decr做自减操作,可以对某个key的value进行-1操作
5.incrby指定自增的数字
6.decrby指定自减的数字
7.获取redis所有的key(keys *)
Hash类型
设置单个值(类似于userInfo:{name:asion})
获取值
设置多个值
获取key中的某个值
获取某个key中的所有值(hgetall)
清空当前库所有数据 flushdb
清空所有库的数据 flushall
查看key还剩多少存活时间 ttl key
如果返回-1 代表key存在但没有设置ttl,也可能是曾经存在,但是现在消亡了
如果返回毫秒数,代表key存在,还剩多少存活时间
Hash的用途
节约内存空间
每创建一个ky,它都会为这个key储存一些附加的管理信息,比如这个key的类型,这个key最后一次被访问的时间等等
所以数据库里面的key越多,redis数据库服务器在储存附加管理信息方面耗费的内存就越多,花在管理数据库key上的cpu也会越多在字段对应的值上进行浮点数的增量计算
List类型
Redis中把list类型称为链表类型
list类型其实就是一个双向链表,通过push,pop操作从链表的头部或者尾部添加删除元素,这使list既可以用作栈,也可以用作队列。
应用场合示例:
获得最新的10个登录用户信息:select * from user order by logintime desc limit 10
以上sql语句可以实现用户需求,但是数据多的时候,全部数据都有受到影响,对数据库的负载比较高,必要情况还需要给关键字(id或logintime)设置索引,索引页比较耗费系统资源。
如果通过list链表实现以上功能,可以在list链表中只保留最新的10个数据,每进来一个新数据就删除一个旧数据,每次就可以从链表中直接获得需要的数据,极大节省各方面资源消耗。
特点:
1.基于Linked List实现
2.元素是字符串类型
3.列表头尾增删快,中间增删慢,增删元素是常态
4.元素可以重复出现
5.最多包含2^32-1个元素
列表的索引
从左至右是从0开始的,从右至左是从-1开始的
设置一个链表 newlogin 放了5个用户
队列:先进先出,就跟进隧道一样
栈:先进后出,往瓶子里放东西
向链表的头部放数据
向链表的尾部放数据
获取链表中的数据
删除某一链表左侧的数据(lpop)
删除某一链表右侧的数据(rpop)
链表的应用
Set类型(无序集合)
关于set集合类型除了基本的添加删除操作,其他有用的操作还包含集合的取并集(union),交集(intersection),差集(difference)。通过这些操作可以很容易的实现sns中的好友推荐功能。
注意:每个集合中的元素不可重复。
该类型应用场合:qq好友推荐。
tom朋友圈(与某某是好友):mary jack xiaoming wang5 wang6
linken朋友圈(与某某是好友):yuehan daxiong luce wang5 wang6
redis里面的set类型被称为集合类型
集合是数学里面常见的一个概念,可以理解是一类数据的集合。
集合满足三个特点:
a.无序性:集合里面的数据是没有顺序之分
b.唯一性:集合里面的数据彼此是不能重复
c.确定性:集合里面的数据的个数是确定的
1.往set集合里面添加元素
2.获取集合里面的元素(关键字smembers)
3.删除集合中的某个元素(srem)
4.spop随机删除一个元素
5.set的实际使用
一般redis里面的集合被用在社交类型的网站里面做好友关系展示。比如实现好友的推荐,共同好友。。。
C:求取好友关系
Zset类型(sort-set)
Redis里面的zset类型被称为有序集合,意味有序集合里面的元素是排好序的,也满足唯一性和确定性。
每个元素都关联着一个浮点数分值(score),并按照分值从小到大排列集合中的元素,分值可以相同
增加一个或多个元素
zadd key score member [score member...]
如果元素已经存在,则使用新的score
举例
zadd fruits 3.2 香蕉
zadd fruits 2.0 西瓜
zadd fruits 4.0 番石榴 7.0 梨 6.8 芒果
3.获取集合内容时,查询权重信息
增加或减少分值
ZINCRBY key increment member
increment 为负数就是减少
举例
ZINCRBY fruits 1.5 西瓜
ZINCRBY fruits 0.8 香蕉
Redis的安全问题
在操作redis的时候,默认是不需要客户端提供认证信息,不需要使用密码即可对redis实现操作,本身是很危险,所以有必要开启redis的认证功能。
Redis的持久化功能
redis的持久化方式之一:Snapshotting(快照)方式
默认文件名为dump.rdb
save 900 1 //900秒超过1个key被修改,发起快照保存
save 300 10 //60秒超过10000个key被修改,发起快照保存
save 60 10000 //60秒超过10000个key被修改,发起快照保存
redis为了本身数据的安全和完整性,会把内存中的数据按照一定的方法同步到电脑的磁盘上面,这个过程被称为持久化操作,下次再次启动redis服务的时候,会把磁盘上面保存的数据重新加载到内存里面。
常见的持久化方式有两种:
a.基于快照的方式:redis会按照一定的周期把内存里面的数据同步到磁盘文件里面
b.基于日志文件的追加:redis会把redis数据造成更改的命令记录到日志文件里面,然后在一次重启的时候,执行一下日志文件里面对redis写的操作。达到数据的还原。
Rdb存的是真实数据,aof存的是命令操作
- 因为redis服务器将数据储存在内存里面,而一旦服务器被关闭、或者运行服务器的主机本身被关闭的话,储存在内存里面的数据就会消失不见。
- 如果我们仅仅是将redis用作缓存的话,那么这种数据丢失带来的问题并不是非常大,我们只需要重启机器,然后再次将数据放到缓存里面就可以了,但如果我们将redis用作数据库的话,那么这种数据丢失就不能接受了。
- 为了在redis服务器关闭时,仍然保留数据库中的数据,redis提供了RDB和AOF两种持久化功能,这两种功能可以将储存在内存里面的数据库数据以文件形式保存到硬盘里面,这样的话,即使服务器关闭,已经保存到硬盘里面的数据也不会丢失。
- 除此之外,服务器也可以在重新启动时,通过载入持久文件来还原服务器在关闭之前的数据库数据。或者使用持久化文件来进行数据备份、数据迁移等工作。
- RDB持久化功能可以将服务器包含的所有数据库数据以二进制文件的形式保存到硬盘里面。
- 在redis服务器创建RDB文件的情况中,以下三种最常见的:
1.服务器执行客户端发送的save命令
2.服务器执行客户端发送的bgsave命令
3.使用save配置选项设置的自动保存条件被满足,服务器自动执行bgsave
- 这三种创建RDB文件的情况中,前两种需要用户手动执行,而第三种情况则是由redis服务器自动执行。
手动创建RDB文件,也就是手动发送save命令或者bgsave命令
- 通过使用客户端向服务器发送save命令,可以命令服务器去创建一个新的RDD文件:
- redis>save
- 在执行save命令的过程中(也即时创建RDB文件的过程中),redis服务器将被阻塞,无法处理客户端发送的命令请求,只有在save命令执行完毕之后(也即时RDB文件创建完毕之后),服务器才会重新开始处理客户端发送的命令请求。
- 如果RDB文件已经存在,那么服务器将自动使用新的RDB文件去代替旧的RDB文件。
- 执行BGSAVE命令同意可以创建一个新的RDB文件,这个命令和SAVE命令的区别在于,BGSAVE不会造成redis服务器阻塞:在执行BGSAVE命令的过程中,redis服务器仍然可以正常的处理其他客户端发送的命令请求。
- BGSAVE命令不会造成服务器阻塞的原因在于:
1、当redis服务器接受到BGSAVE命令的时候,他不会自己来创建RDB文件,而是通过fork()来生成一个子进程,然后由子进程负责创建RDB文件,而自己则继续处理客户端的命令请求
2、当子进程创建好RDB文件并退出时,他会向父进程(也即是负责处理命令请求的redis服务器)发送一个信号,告知他RDB文件已经创建完毕
3、最后redis服务器(父进程)接受子进程创建的RDB文件BGSAVE执行完毕
- 创建子进程,会消耗额外的内存,因为需要创建子进程,会耗费额外的内存,所以SAVE创建RDB文件的速度会比BGSAVE快,可以集中资源来创建RDB文件,SAVE和BGSAVE没有孰好孰坏之分,你要考虑的就是哪个更适合你,那比如说你的数据库正在上线当中呢,那当然就是使用BGSAVE,另外相反如果你要维护,在凌晨3点中,那么你最好使用SAVE,比如维护需要停机一个或半个小时,那你就使用SAVE命令,这时系统被阻塞了也没有关系,使用SAVE命令会好一点。
自动的去创建RDB文件
- 比如save 300 10
- 表示“如果距离上一次创建RDB文件已经过去了300秒,并且服务器的所有数据库总共已经发生了不少于10次修改,那么执行BGSAVE命令”。
- 而设置为save 60 10000
- 则表示“如果距离上一次创建RDB文件已经过去了60秒,并且服务器的所有数据库总共已经发生了不少于10000次修改,那么执行BGSAVE命令”。
- 另外,用户还可以设置多个save选项来设置多个自动保存条件,当任意一个条件被满足时,服务器就会自动执行BGSAVE命令。
- save 900 1;save 300 10;save 60 10000
- 只要三个条件中的任意一个被满足时,服务器就会执行BGSAVE
- 每次创建RDB文件之后,服务器为实现自动持久化而设置的时间计数器和次数计数器就会被清零。并重新开始计数,所以多个保存条件的效果是不会叠加的。
总结
- redis提供RDB持久化和AOF持久化这两种持久化功能。用于将储存在内存里面的数据库数据以文件形式保存到硬盘里面,以免数据因为服务器关闭而丢失。
- RDB文件是一个二进制文件,他保存了redis服务器在创建RDB文件时,所有数据库的数据。
- 三种最常见的创建RDB文件的方法是:1.执行save命令;2.执行BGSAVE命令;3.使用SAVE选项设置保存条件,让服务器自动执行BGSAVE,第三种配置在redis.conf中
- 服务器在执行SAVE命令时会被阻塞,导致无法处理客户端发送的命令请求。
BGSAVE在执行时不会阻塞服务器,因为创建RDB文件的操作是由子进程执行的,这也使得执行BGSAVE会比执行SAVE耗费更多内存,并且创建RDB文件的速度也会比SAVE更慢一些。
用户可以设置多个save选项,当任意一个保存条件被满足时,BGSAVE就会被执行。
RDB持久化的缺点
那就是因为创建RDB文件需要将服务器所有的数据库的数据都保存起来,这是一个非常耗费资源和时间的操作,所以服务器需要隔一段时间才创建一个新的RDB文件,也就是说,创建RDB文件的操作不能执行得过于频繁,否则就会严重得影响服务器的性能。
但是好消息是:可以同时使用两种持久化,根据需要来使用,还原数据优先使用AOF文件。所以说redis数据库安全性比不上sql数据库的安全性是个误解,当使用always模式下运行时,redis持久化和一般的sql数据库的持久化方式是一样的
做一个测试,测试快照持久化
基于日志文件的持久化(AOF)
appendfsync everysec:每1s中进行一次对redis数据造成更改的操作,都记录到磁盘文件。
appendfsync no:完全交给操作系统来完成,意思就是操作系统不繁忙的时候会对redis进行数据造成更改的操作,都记录到磁盘文件上,这种操作最不可靠。
持久化运行原理
- AOF持久化保存数据库的方法是:每当有修改的数据库的命令被执行时,服务器就会将执行的命令写入到AOF文件的末尾
- 因为AOF文件里面储存了服务器执行过的所有数据库修改的命令,所以给定一个AOF文件,服务器只要重新执行一遍AOF文件里面包含的所有命令,就可以达到还原数据库的目的
安全性问题
虽然服务器执行一个修改数据库的命令,就会将执行的命令写入到AOF文件,但这并不意味着AOF文件持久化不会丢失任何数据。
在目前常见的操作系统中,执行系统调用write函数,将一些内容写入到某个文件里面时,为了提高效率,系统通常不会直接将内容写入硬盘里面,而是先将内容放入一个内存缓冲区(buffer)里面,等到缓冲区被填满,或者用户只需fsync调用和fdatasync调用时才将储存在缓冲区里的内容真正的写入到硬盘里。
对于AOF持久化来说,当一条命令真正的被写入到硬盘里面时,这条命令才不会因为停机而意外丢失。
因此,AOF持久化在遭遇停机时丢失命令的数量,取决于命令被写入到硬盘的时间:
越早将命令写入到硬盘,发生意外停机时丢失的数据就越少;而越迟将命令写入到硬盘,发生意外停机时丢失的数据就越多。
为了控制redis服务器在遇到意外停机,redis为AOF持久化提供了appendfsync选项,这个选项的值可以是always、everysec或者no,这些值所代表的含义为:
always:服务器每写入一个命令,就调用一次fdatasync,将缓冲区里面的命令写入到硬盘里面,在这种模式下,服务器即使遭遇意外停机,也不会丢失任何自己已经成功执行的命令数据。
everysec:服务器每一秒调用一次fdatasync,将缓冲区里面的命令写入到硬盘里面,在这种模式下,服务器即使遭遇意外停机时,最多丢失一秒钟内的执行的命令数据,在性能和持久化方面做了很好的折中,推荐
no:服务器不主动调用fdatasync,由操作系统决定任何将缓冲区里面的命令写入到硬盘里面。在这种模式下,服务器遭遇意外停机时,丢失命令的数量是不确定的,持久化没保证。
运行速度:always的速度慢,everysec和no都很快。
默认值:everysec
这时候发现基于文件追加方式的日志文件已经存在
redis持久化的相关指令
- bgsave 异步保存数据到磁盘(快照保存)
- lastsave 返回上次成功保存到磁盘的unix时间戳
- shutdown 同步保存到服务器并关闭redis服务器
- bgrewriteaof 当日志文件过长时优化AOF日志文件的存储
- ./redis-cli bgrewriteaof
- ./redis-cli bgsave
- ./redis-cli -h 127.0.0.1 -p 6379 bgsave //手动发起快照
Redis主从模式
1.主从复制
- 一个redis服务可以有多个该服务的复制品,这个redis服务称为master,其他复制品称为slaves
- 只要网络连接正常,master会一直将自己的数据更新同步给slaves,保持主从同步
- 只有master可以执行命令,slaves只能执行读命令
- 从服务器执行客户端发送的读命令,比如GET、LRANGE、SMEMMBERS、HGET、ZRANGE等等
- 客户端可以连接slaves执行读请求,来降低master的读压力
2.主从复制创建
- redis-server --slaveof
配置当前服务称为某redis服务的slave redis-server --port 6380 --slaveof 127.0.0.1 6379
- slaveof host port命令,将当前服务器状态从master修改为别的服务器的slave
slaveof 192.168.1.1 6379,将服务器转换为slave
slaveof no one,将服务器重新恢复成master,不会丢失已同步的数据
- 配置方式:启动时,服务器读取配置文件,并自动成为指定服务器的从服务器
slaveof
slaveof 127.0.0.1 6379
为了降低每个redis服务器的负载,可以多设置几个,并做主从模式。
一个服务器负责“写”数据,其他服务器负责“读”数据
主服务器数据会“自动”同步给从服务器
Redis哨兵
1.主从复制可能引发的问题
- 一个master可以有多个slaves
- slave下线,只是读请求的处理性能下降
- master下线,写请求无法执行
- 其中一台slave使用slaveof no one命令成为master,其他slaves执行slaveof命令指向这个新的master,从它这里同步数据
以上过程为手动,也可以实现自动,这就需要sentinel哨兵,实现故障转移操作
2.监控Monitoring
- sentinel会不断检查master和slaves是否正常
- 每一个sentinel可以监控任意多个master和该master下的slave
3.Sentinel网络
监控同一个master的sentinel会自动连接,组成一个分布式的sentinel网络,互相通信并交换彼此关于被监测服务器的信息
下图就是3个sentinel监控着s1和它的2个slave
这里涉及到一个投票机制,如果超过一半的哨兵认为主服务器挂了,那么就会提升一个从服务器为主,所以这里一般会把哨兵个数设置为奇数
4.服务器下线
- 当一个sentinel认为被监视的服务器已经下线时,它会向网络中的其他sentinel进行确认,判断该服务器是否真的已经下线
- 如果下线的服务器为主服务器,那么sentinel网络将对下线主服务器进行自动故障转移通过将下线主服务器的某个从服务器提升为新的主服务器,并让其从服务器转为复制新的主服务器,以此来让系统重新回到上线的状态
- 当原来挂掉的主服务器重新启动后,那么哨兵会将它设置为从服务器。
5.sentinel配置文件
- 至少包含一个监控配置选项,用于指定被监控master的相关信息
- sentinel monitor
比如:sentinel monitor mymaster 127.0.0.1 6379 2
监视mymaster的主服务器,服务器ip和端口,将这个主服务器判断为下线失效至少需要2个sentinel同意,如果多数sentinel同意才会执行故障转移
6.sentinel总结
- 主从复制,解决了读请求的分担,从节点下线,会使得读请求能力有所下降
- master只有一个,写请求单点问题
- sentinel会在master下线后自动执行故障转移操作,提升一台slave为master,并让其它slaves重新成为新master的slaves
- 主从复制+哨兵sentinel只解决了读性能和高可用问题,但是没有解决写性能问题
Redis集群
- redis3.0以上支持集群模式
- 由多个redis服务器组成的分布式网络服务集群
- 每一个redis服务器称为节点node,节点之间会互相通信,两两相连
- redis集群无中心节点,集群中没有主从概念,都是两两通信,构成一个大的网状,缺点就是消耗网络io太多,所以设置节点的数据不要太多,不然太消耗io
redis集群节点复制
- redis集群的每个节点都有两种角色可选:主节点master node、从节点slave node。其中主节点用于存储数据,而从节点则是主节点的复制品
- 当用户需要处理更多请求的时候,添加从节点可以扩展系统的读性能,因为redis集群重用了单机redis复制特性的代码,所以集群的复制行为和之前介绍的单机复制特性的行为是完全一样的
- 一般集群做6个节点,其中3个做集群,另外3个做前3个的从,进行复制
redis集群故障转移
- redis集群的主节点内置了类似redis sentinel的节点故障检测和自动故障转移功能,当集群中的某个主节点下线时,集群中的其他在线节点会注意到这一点,并对已下线的主节点进行故障转移
- 集群进行故障转移的方法和redis sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中其他在线的主节点负责进行的,所以集群不必另外使用redis sentinel
redis集群分片
- 集群将整个数据库分为16384个槽位,所有key都属于这些slot中的一个,key的槽位计算公式为slot number = crc16(key)%16384,其他crc16为16位的循环冗余校验和函数
- 集群中的每个主节点都可以处理0至16383个槽,当16384个槽都有某个节点在负责处理时,集群进入上线状态,并开始处理客户端发送的数据命令请求。
举例
- 三个主节点7000、7001、7002平均分片16384个slot槽位
- 节点7000指派的槽位为0到5460
- 节点7001指派的槽位为5461到10922
- 节点7002指派的槽位为10923到16383
redis集群redirect转向
- 由于redis集群无中心节点,请求会发给任意主节点
- 主节点只会处理自己负责槽位的命令请求,其他槽位的命令请求,该主节点会返回客户端一个转向错误
- 客户端根据错误中包含的地址和端口重新向正确的负责的主节点发起命令请求
集群搭建步骤(三主三从)
- 创建redis-cluster,然后在下面分别创建文件夹1001-1006
- 把redis.conf文件分别拷贝到6个文件夹下,修改内容daemonize yes //后台启动
- port 1001 //这里设置为文件夹名100*进行模拟每个机器端口号
- cluster-enabled yes //启动集群模式
- appendonly yes //持久化模式AOF
- cluster-node-timeout 5000 //节点超时时间
- dir /xx/xxx/redis-cluster/100* //指定数据文件存在位置,指定不同位置,不然会丢失数据
- 由于redis集群需要使用ruby命令,所以需要安装ruby
- yum install ruby
- yum install rubygems
- gem install reids //安装redis和ruby的接口
- 分别启动6个redis实例,并检查是否启动成功
/root/redis/bin/redis-server /root/redis/redis-cluster/100*/redis-conf
ps –ef |grep redis //检查是否服务都启动了
- 切换到redis安装包的src目录下,使用
./redis-trib.rb create –replicas 1 端口号:100* 端口号:100* 端口号:100* 端口号:100* 端口号:100* 端口号:100*
如果如上图所示,那么代表集群就搭建成功!!!
/root/redis/bin/redis-cli –p 1001 –c
注意:因为redis的集群没有中心节点,所以连接哪个节点都可以,-c代表是集群模式
把一个主服务给杀死,验证该主的从服务器是否变为了主服务器,以验证集群的哨兵
centos 7 redis远程连接
1.conf/redis.conf 里面的
bind 127.0.0.1 ::1 这一行注释掉。
这里的bind指的是只有指定的网段才能远程访问这个redis。 注释掉后,就没有这个限制了。
或者bind 自己所在的网段
2.conf/redis.conf里面
protected-mode 要设置成no (默认是设置成yes的, 防止了远程访问,在redis3.2.3版本后)