目录
一、Redis服务
1、什么是redis
NoSQL内存数据库(非关系型的数据库)是最近兴起的新型数据库,它的特点就是把数据放在内存中操作,数据处理速度相对于磁盘提高了好几个量级,因此,通过把经常访问的数据转移到内存数据库中,不但可以缓解Oracle的访问压力,而且可以极大提高数据的访问速度,提高用户体验。
redis是一个开源的、使用C语言编写的、支持网络交互的、可基于内存也可持久化的键值对(Key-Value)数据库。Redis 通常被称为数据结构服务器,因为值(value)可以是字符串(String)、哈希(Hash)、列表(list)、集合(sets)和有序集合(sorted sets)等类型。
Redis是一个内存型数据库。不限于此,Redis也可以把数据持久化到磁盘中,或者把数据操作指令追加了一个日志文件,把它用于持久化。也可以用Redis容易的搭建master-slave架构用于数据复制。
2、redis的安装
redis软件下载: https://redis.io/download
解压redis安装包,并进入目录
编译 安装
由于之前安装数据库等已经解决过依赖性,因此在原有数据库集群上搭建不再需要解决依赖性,但如果全新的环境安装,要解决依赖性,可看我之前博客依赖性的解决方式。
创建
vim install_server.sh 注释掉本地连接
创建成功
再次创建只需要更改端口即可
不想要了直接关闭
此时6379只有内部回环接口可以访问,因此要更改配置文件, 监听端口改为0.0.0.0,使得所有用户接口都可访问
重启服务生效
查看服务开启端口为6379
3、主从复制搭建
Redis支持将数据同步到多台从库上,这种特性对提高读取性能非常有益。
当设置好 slave 服务器后,slave 会建立和 master 的连接,然后发送 sync命令。无论是第一次同步建立的连接还是连接断开后的重新连接,master 都会启动一个后台进程,将数据库快照保存到文件中,同时 master 主进程会开始收集新的写命令并缓存起来。后台进程完成写文件后,master 就发送文件给 slave,slave 将文件保存到磁盘上,然后加载到内存恢复数据库快照到 slave 上。接着 master 就会把缓存的命令转发给 slave。而且后续 master 收到的写命令都会通过开始建立的连接发送给slave。从master到slave的同步数据的命令和从客户端发送的命令使用相同的协议格式。当 master 和 slave 的连接断开时 slave 可以自动重新建立连接。如果 master 同时收到多个 slave 发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有 slave。
此时通过该指令发现,此时为master端,没有slave
创建slave端
将编译后的包直接整个复制到要设置成slave的主机,省去编译的步骤,可以之间安装。
进到目录中make install
以脚本形式创建redis,由于所有文件都是复制过来的,所以本地连接已经注释掉,可直接运行install_server.sh脚本
编辑6379的配置文件,修改监听端口为0.0.0.0
监听端口0.0.0.0
此时查看server2也为master
编辑配置文件,加上master的ip
再次查看状态更改为slave
在server1上查看,已经识别到slave为server2的ip
测试
在server1中写入:set name westos
定义key值为name,value值为westos,get name
可以获取value值。
server数据同步,但是slave端不可写,只读
redis集群部署时,不需要手动去保持数据同步,只要设置成slave连接成功master后,会将自己的数据全部删掉,自动同步master数据,极其方便。
server3进行和server2相同的操作,成为第二个slave端。
server3设置好后查看server1 上slave为2了
redis-cli
> info
二、Redis 的 Sentinel 分布式系统(高可用)
基于sentinel哨兵模式,哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
Redis 的 Sentinel 分布式系统:
监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器。
原先的主从复制也断开了,客户端和损坏的主节点也断开了。从节点被提升为新的主节点,其它从节点开始和新的主节点建立复制关系。客户端通过新的主节点继续进行交互。
redis常用指令:
config get * //查看配置
select 1 //选择数据库
flushdb //清空当前数据库
flushall //清空所有数据库
move key 1 //移动key
del key //删除
rename oldkey newkey //改名
expire key 10 //设置过期时间
persist key //设置持久化
keys user* //查询
exists key //判断是否存在
以下两个信息,当不满足时,便会认为master错误,此时客户端便不可以往里写,以确保不会有数据丢失
第一个是确保连接数最少为2,否则认为出错。
这个是从节点健康延迟时间:延迟时间超过该值的从节点判断为有问题。
但是这种修改只有此时生效,如果想永久生效,需要写入配置文件。
Sentinel 主从切换
sentinel monitor mymaster 172.25.254.1 6379 2 #master为server1,2表示需要两票通过
sentinel down-after-milliseconds mymaster 10000 #连接超时为10s
修改完以后,在启动之前,将文件拷贝给server2和server3
然后server1上执行
redis-sentinel /etc/redis/sentinel.conf ##启动sentinel
在server2上
redis-sentinel /etc/redis/sentinel.conf ##启动sentinel
在server3上
redis-sentinel /etc/redis/sentinel.conf ##启动sentinel
此时有三个sentinel
测试:关闭server1的redis
此时server3成为master,server2指向server3,server1也成为了slave但是down
测试重新打开server1
查看server1状态,变为slave
查看配置文件:
三、Cluster 集群
Cluster 集群简介
Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的内容。
其结构特点:
1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
2、节点的fail是通过集群中超过半数的节点检测失效时才生效。
3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。
4、redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。
5、Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。
集群内部划分为16384个数据分槽,分布在三个主redis中。
从redis中没有分槽,不会参与集群投票,也不会帮忙加快读取数据,仅仅作为主机的备份。
三个主节点中,每个节点中不会存有有重复数据,仅仅有自己的从机帮忙冗余。
Redis Cluster搭建
停掉redis服务(redis服务本身监听的端口是6379
端口)
数据库也停掉。
启动redis Cluster对应的6个节点。(默认是6个,可以修改,相当于建了6个节点)
ps ax 查看进程,已经被创建,并且都支持cluster,但此时还不是集群。
redis-cluster
创建集群
(集群中的主从节点是随机的),节点全部启动后,每个节点目前只能识别出自己的节点信息,彼此之间并不知道对方的存在;实现集群的快速搭建,需要使用redis-cluster
来创建集群
此时一主一从,6个节点3组。
redis-cli用来进行集群交互,客户端连接任意一个节点,使用-c表示以集群方式登陆,-p指定端口。
30001为master
测试:
根据redis cluster的key值分配,name被分配到节点30002上,我们查看name的值,上面显示了redis cluster自动从30001跳转到30002上
Redis cluster集群的故障迁移
将节点30002挂掉
检查集群,看到30004变成新的master
重新 启动集群
查看状态会发现30002变成了slave ,指向30004
先把4停掉,2又变回master
此时再把2停掉,哈希槽不完整,集群不能用了。
再重新起起来,就会自动恢复。
添加节点和分配哈希槽
在配置文件中修改节点个数为8
此时集群已经建立了,发现7和8并不在集群里面。
需要往集群中添加这两个节点。
redis-cli --cluster check 127.0.0.1:30001 #查看集群30007变为master
添加节点 30008到指定的master端30007
再次查看,8已成为7的slave, 但此时7上面没有哈希槽
我们需要迁移一点过来
How many slots do you want to move (from 1 to 16384)? 1000 ##想要移动的插槽数量
What is the receiving node ID? ##接收节点的ID
Source node #1: all ##从哪些节点获取这些资源,all指的是从每个组中都获取一些
查看结果:分别从30001,30001,30003获得1000个哈希槽,共3000个
清除集群节点
四、Redis 持久化
Redis 提供了不同级别的持久化方式:
- RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.
- AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.
- 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
- 你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
- 最重要的事情是了解RDB和AOF持久化方式的不同,让我们以RDB持久化方式开始
RDB的优点
- RDB是一个非常紧凑的文件,它保存了某个时间点得数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
- RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.
- RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
- 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.
-
RDB的缺点
- 如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据.
- RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.
-
AOF 优点
- 使用AOF 会让你的Redis更加耐久: 你可以使用不同的fsync策略:无fsync,每秒fsync,每次写的时候fsync.使用默认的每秒fsync策略,Redis的性能依然很好(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据.
- AOF文件是一个只进行追加的日志文件,所以不需要写入seek,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用redis-check-aof工具修复这些问题.
- Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。
- AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。
-
AOF 缺点
- 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。
-
如何选择使用哪种持久化方式?
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
Note: 因为以上提到的种种原因, 未来我们可能会将 AOF 和 RDB 整合成单个持久化模型。 (这是一个长期计划。) 接下来的几个小节将介绍 RDB 和 AOF 的更多细节。