本文采用 VMware Workstation 来搭建虚拟化安装 CentOS 7 系统,Redis-3.2.3大家可以根据自己的实际情况来选择合适的版本。
使用 VMware 创建虚机我这边是使用的本地系统 iso来创建的,其他步骤这里就不详细说明了,可以看相关的教程来学习使用 VMware
Redis 这里我使用本地的安装包 redis-3.2.3.tar.gz,通过 WinSCP工具将本地安装包传至虚拟机中,除此之外您如果虚拟机能够连通外部网络的话也可以直接下载redis安装包
安装 Redis 所需命令如下:
通过网络下载安装包(前提是您的主机具备连通公网)
wget http://download.redis.io/releases/redis-3.2.3.tar.gz
1、解压上传的安装包
tar -zxvf redis-3.2.3.tar.gz
2、进入解压后的目录进行编译和安装
make
make install
3、安装完成测试启动redis
./redis-server
当前我们具备三台虚拟机,三个 Redis 单实例节点,按照一主两从三哨兵的思路进行大致设计
检查服务器防火墙状态
查看防火墙当前状态
systemctl status firewalld
如正在运行我们先将其关闭避免后续影响端口连通,您同样也可以采用开放所需端口达到此效果
systemctl stop firewalld
分配说明
简要说明将会提到的主从节点 ip、服务端口、哨兵端口的分配情况
IP(master) | port |
---|---|
192.168.8.116(server) | 6379 |
192.168.8.116(sentinel) | 26379 |
IP(slave 1) | port |
---|---|
192.168.8.117(server) | 6379 |
192.168.8.117(sentinel) | 26379 |
IP(slave 2) | port |
---|---|
192.168.8.120(server) | 6379 |
192.168.8.120(sentinel) | 26379 |
结合了一些网上材料对 redis.conf 中一些基本或默认的配置进行了描述,如下配置根据您的个人需要来选择(尽管有些啰嗦还是值得没事看下嚎)
#关闭保护模式
protected-mode no
#redis端口默认6379
port 6379
#默认511,此参数确定了TCP连接中已完成队列(完成三次握手之后)的长度
tcp-backlog 511
#client 空闲多少秒之后关闭连接(0表示永不关闭)
timeout 0
#用来定时向client发送tcp_ack包来探测client是否存活的。默认不探测,官方建议值为300秒
tcp-keepalive 300
#默认情况下 redis 不是作为守护进程运行的,如果你想让它在后台运行,你就把它改成 yes。
#当redis作为守护进程运行的时候,它会写一个 pid 到 /var/run/redis.pid 文件里面
daemonize yes
#可以通过upstart和systemd管理Redis守护进程
#选项:
# supervised no - 没有监督互动
# supervised upstart - 通过将Redis置于SIGSTOP模式来启动信号
# supervised systemd - signal systemd将READY = 1写入$ NOTIFY_SOCKET
# supervised auto - 检测upstart或systemd方法基于 UPSTART_JOB或NOTIFY_SOCKET环境变量
supervised no
#配置PID文件路径,当redis作为守护进程运行的时候,它会把 pid 默认写到 /var/redis/run/redis_6379.pid 文件里面
pidfile "/var/run/redis_6379.pid"
#定义日志级别。
# 可以是下面的这些值:
# debug(记录大量日志信息,适用于开发、测试阶段)
# verbose(较多日志信息)
# notice(适量日志信息,使用于生产环境)
# warning(仅有部分重要、关键信息才会被记录)
loglevel notice
#日志文件的位置,当指定为空字符串时,为标准输出,如果redis已守护进程模式运行,那么日志将会输出到/dev/null
logfile ""
#设置数据库的数目。默认的数据库是DB 0 ,可以在每个连接上使用
#select 命令选择一个不同的数据库,dbid是一个介于0到databases - 1 之间的数值。
databases 16
#如果用户开启了RDB快照功能,那么在redis持久化数据到磁盘时如果出现失败,默认情况下,redis会停止接受所有的写请求。
# 这样做的好处在于可以让用户很明确的知道内存中的数据和磁盘上的数据已经存在不一致了。
# 如果redis不顾这种不一致,一意孤行的继续接收写请求,就可能会引起一些灾难性的后果。
# 如果下一次RDB持久化成功,redis会自动恢复接受写请求。
# 如果不在乎这种数据不一致或者有其他的手段发现和控制这种不一致的话,可以关闭这个功能,
# 以便在快照写入失败时,也能确保redis继续接受新的写请求。
stop-writes-on-bgsave-error yes
#对于存储到磁盘中的快照,可以设置是否进行压缩存储。
# 如果是的话,redis会采用LZF算法进行压缩。如果你不想消耗CPU来进行压缩的话,
# 可以设置为关闭此功能,但是存储在磁盘上的快照会比较大。
rdbcompression yes
#在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,
# 如果希望获取到最大的性能提升,可以关闭此功能。
rdbchecksum yes
#设置快照的文件名
dbfilename "dump.rdb"
#设置快照文件存储位置
dir "/home/admin"
# 当一个 slave 与 master 失去联系,或者复制正在进行的时候,
# slave 可能会有两种表现:
# 1) 如果为 yes ,slave 仍然会应答客户端请求,但返回的数据可能是过时,
# 或者数据可能是空的在第一次同步的时候
# 2) 如果为 no ,在你执行除了 info he salveof 之外的其他命令时,
# slave 都将返回一个 "SYNC with master in progress" 的错误
slave-serve-stale-data yes
#你可以配置一个 slave 实体是否接受写入操作。
# 通过写入操作来存储一些短暂的数据对于一个 slave 实例来说可能是有用的,
# 因为相对从 master 重新同步数而言,据数据写入到 slave 会更容易被删除。
# 但是如果客户端因为一个错误的配置写入,也可能会导致一些问题。
# 从 redis 2.6 版起,默认 slaves 都是只读的。
slave-read-only yes
#主从数据复制是否使用无硬盘复制功能。
# 新的从站和重连后不能继续备份的从站,需要做所谓的“完全备份”,即将一个RDB文件从主站传送到从站。
# 这个传送有以下两种方式:
# 1)硬盘备份:redis主站创建一个新的进程,用于把RDB文件写到硬盘上。过一会儿,其父进程递增地将文件传送给从站。
# 2)无硬盘备份:redis主站创建一个新的进程,子进程直接把RDB文件写到从站的套接字,不需要用到硬盘。
# 在硬盘备份的情况下,主站的子进程生成RDB文件。一旦生成,多个从站可以立即排成队列使用主站的RDB文件。
# 在无硬盘备份的情况下,一次RDB传送开始,新的从站到达后,需要等待现在的传送结束,才能开启新的传送。
# 如果使用无硬盘备份,主站会在开始传送之间等待一段时间(可配置,以秒为单位),希望等待多个子站到达后并行传送。
# 在硬盘低速而网络高速(高带宽)情况下,无硬盘备份更好。
repl-diskless-sync no
#当启用无硬盘备份,服务器等待一段时间后才会通过套接字向从站传送RDB文件,这个等待时间是可配置的。
# 这一点很重要,因为一旦传送开始,就不可能再为一个新到达的从站服务。从站则要排队等待下一次RDB传送。因此服务器等待一段
# 时间以期更多的从站到达。
# 延迟时间以秒为单位,默认为5秒。要关掉这一功能,只需将它设置为0秒,传送会立即启动。
repl-diskless-sync-delay 5
#同步之后是否禁用从站上的TCP_NODELAY
# 如果你选择yes,redis会使用较少量的TCP包和带宽向从站发送数据。但这会导致在从站增加一点数据的延时。
# Linux内核默认配置情况下最多40毫秒的延时。
# 如果选择no,从站的数据延时不会那么多,但备份需要的带宽相对较多。
# 默认情况下我们将潜在因素优化,但在高负载情况下或者在主从站都跳的情况下,把它切换为yes是个好主意。
repl-disable-tcp-nodelay no
#从站优先级是可以从redis的INFO命令输出中查到的一个整数。当主站不能正常工作时
# redis sentinel使用它来选择一个从站并将它提升为主站。
# 低优先级的从站被认为更适合于提升,因此如果有三个从站优先级分别是10,
# 100,25,sentinel会选择优先级为10的从站,因为它的优先级最低。
# 然而优先级值为0的从站不能执行主站的角色,因此优先级为0的从站永远不会被redis sentinel提升。
# 默认优先级是100
slave-priority 100
#设置redis连接密码(弱密码请勿效仿)
requirepass "123456"
#默认redis使用的是rdb方式持久化,这种方式在许多应用中已经足够用了。但是redis如果中途宕机,
#会导致可能有几分钟的数据丢失,根据save来策略进行持久化,Append Only File是另一种持久化方式,
#可以提供更好的持久化特性。Redis会把每次写入的数据在接收后都写入appendonly.aof文件,
#每次启动时Redis都会先把这个文件的数据读入内存里,先忽略RDB文件。
appendonly no
#aof文件名
appendfilename "appendonly.aof"
#aof持久化策略的配置
# no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快。
# always表示每次写入都执行fsync,以保证数据同步到磁盘。
# everysec表示每秒执行一次fsync,可能会导致丢失这1s数据
appendfsync everysec
# 在aof重写或者写入rdb文件的时候,会执行大量IO,此时对于everysec和always的aof模式来说,
# 执行fsync会造成阻塞过长时间,no-appendfsync-on-rewrite字段设置为默认设置为no。
# 如果对延迟要求很高的应用,这个字段可以设置为yes,否则还是设置为no,这样对持久化特性来说这是更安全的选择。
# 设置为yes表示rewrite期间对新写操作不fsync,暂时存在内存中,等rewrite完成后再写入,默认为no,建议yes。
# Linux的默认fsync策略是30秒。可能丢失30秒数据。
no-appendfsync-on-rewrite no
#aof自动重写配置,当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,
#即当aof文件增长到一定大小的时候,Redis能够调用bgrewriteaof对日志文件进行重写。
#当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。
auto-aof-rewrite-percentage 100
#设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写
auto-aof-rewrite-min-size 64mb
#aof文件可能在尾部是不完整的,当redis启动的时候,aof文件的数据被载入内存。
#重启可能发生在redis所在的主机操作系统宕机后,尤其在ext4文件系统没有加上data=ordered选项,出现这种现象
#redis宕机或者异常终止不会造成尾部不完整现象,可以选择让redis退出,或者导入尽可能多的数据。
#如果选择的是yes,当截断的aof文件被导入的时候,会自动发布一个log给客户端然后load。
#如果是no,用户必须手动redis-check-aof修复AOF文件才可以。
aof-load-truncated yes
#如果达到最大时间限制(毫秒),redis会记个log,然后返回error。当一个脚本超过了最大时限。
lua-time-limit 5000
#slog log是用来记录redis运行中执行比较慢的命令耗时。
#当命令的执行超过了指定时间,就记录在slow log中,slog log保存在内存中,所以没有IO操作。
#执行时间比slowlog-log-slower-than大的请求记录到slowlog里面,单位是微秒,所以1000000就是1秒。
#注意,负数时间会禁用慢查询日志,而0则会强制记录所有命令。
slowlog-log-slower-than 10000
#慢查询日志长度。当一个新的命令被写进日志的时候,最老的那个记录会被删掉,这个长度没有限制。
# 只要有足够的内存就行,你可以通过 SLOWLOG RESET 来释放内存
slowlog-max-len 128
#延迟监控功能是用来监控redis中执行比较缓慢的一些操作,用LATENCY打印redis实例在跑命令时的耗时图表。
# 只记录大于等于下边设置的值的操作,0的话,就是关闭监视。
# 默认延迟监控功能是关闭的,如果你需要打开,也可以通过CONFIG SET命令动态设置。
latency-monitor-threshold 0
#键空间通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了 Redis 数据集的事件。因为开启键空间通知功能需要消耗一些 CPU ,所以在默认配置下,该功能处于关闭状态。
#notify-keyspace-events 的参数可以是以下字符的任意组合,它指定了服务器该发送哪些类型的通知:
# K 键空间通知,所有通知以 __keyspace@__ 为前缀
# E 键事件通知,所有通知以 __keyevent@__ 为前缀
# g DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知
# $ 字符串命令的通知
# l 列表命令的通知
# s 集合命令的通知
# h 哈希命令的通知
# z 有序集合命令的通知
# x 过期事件:每当有过期键被删除时发送
# e 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
# A 参数 g$lshzxe 的别名
# 输入的参数中至少要有一个 K 或者 E,否则的话,不管其余的参数是什么,都不会有任何 通知被分发。
notify-keyspace-events ""
#hash类型的数据结构在编码上可以使用ziplist和hashtable。
#ziplist的特点就是文件存储(以及内存存储)所需的空间较小,在内容较小时,性能和hashtable几乎一样。
#因此redis对hash类型默认采取ziplist。如果hash中条目的条目个数或者value长度达到阀值,将会被重构为hashtable。
#这个参数指的是ziplist中允许存储的最大条目个数,,默认为512,建议为128
hash-max-ziplist-entries 512
#ziplist中允许条目value值最大字节数,默认为64,建议为1024
hash-max-ziplist-value 64
#当取正值的时候,表示按照数据项个数来限定每个quicklist节点上的ziplist长度。比如,当这个参数配置成5的时候,表示每个quicklist节点的ziplist最多包含5个数据项。
#当取负值的时候,表示按照占用字节数来限定每个quicklist节点上的ziplist长度。这时,它只能取-1到-5这五个值,每个值含义如下:
# -5: 每个quicklist节点上的ziplist大小不能超过64 Kb。(注:1kb => 1024 bytes)
# -4: 每个quicklist节点上的ziplist大小不能超过32 Kb。
# -3: 每个quicklist节点上的ziplist大小不能超过16 Kb。
# -2: 每个quicklist节点上的ziplist大小不能超过8 Kb。(-2是Redis给出的默认值)
# -1: 每个quicklist节点上的ziplist大小不能超过4 Kb。
list-max-ziplist-size -2
#这个参数表示一个quicklist两端不被压缩的节点个数。
#注:这里的节点个数是指quicklist双向链表的节点个数,而不是指ziplist里面的数据项个数。
#实际上,一个quicklist节点上的ziplist,如果被压缩,就是整体被压缩的。
#参数list-compress-depth的取值含义如下:
# 0: 是个特殊值,表示都不压缩。这是Redis的默认值。
# 1: 表示quicklist两端各有1个节点不压缩,中间的节点压缩。
# 2: 表示quicklist两端各有2个节点不压缩,中间的节点压缩。
# 3: 表示quicklist两端各有3个节点不压缩,中间的节点压缩。
#由于0是个特殊值,很容易看出quicklist的头节点和尾节点总是不被压缩的,以便于在表的两端进行快速存取。
list-compress-depth 0
#数据量小于等于set-max-intset-entries用intset,大于set-max-intset-entries用set
set-max-intset-entries 512
#数据量小于等于zset-max-ziplist-entries用ziplist,大于zset-max-ziplist-entries用zset
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
#value大小小于等于hll-sparse-max-bytes使用稀疏数据结构(sparse)
#大于hll-sparse-max-bytes使用稠密的数据结构(dense),一个比16000大的value是几乎没用的,
#建议的value大概为3000。如果对CPU要求不高,对空间要求较高的,建议设置到10000左右
hll-sparse-max-bytes 3000
#Redis将在每100毫秒时使用1毫秒的CPU时间来对redis的hash表进行重新hash,可以降低内存的使用。
#当你的使用场景中,有非常严格的实时性需要,不能够接受Redis时不时的对请求有2毫秒的延迟的话,把这项配置为no。
#如果没有这么严格的实时性要求,可以设置为yes,以便能够尽可能快的释放内存
activerehashing yes
#对客户端输出缓冲进行限制可以强迫那些不从服务器读取数据的客户端断开连接,用来强制关闭传输缓慢的客户端。
client-output-buffer-limit normal 0 0 0
#对于slave client和MONITER client,如果client-output-buffer一旦超过256mb,又或者超过64mb持续60秒,那么服务器就会立即断开客户端连接。
client-output-buffer-limit slave 256mb 64mb 60
#对于pubsub client,如果client-output-buffer一旦超过32mb,又或者超过8mb持续60秒,那么服务器就会立即断开客户端连接。
client-output-buffer-limit pubsub 32mb 8mb 60
#redis执行任务的频率
hz 10
#在aof重写的时候,如果打开了aof-rewrite-incremental-fsync开关,系统会每32MB执行一次fsync。
#这对于把文件写入磁盘是有帮助的,可以避免过大的延迟峰值
aof-rewrite-incremental-fsync yes
在master配置的基础上加上如下配置即可
slaveof 192.168.8.116 6379
启动三台Redis服务指向配置文件,然后密码登入master的client查看当前状态会发现此时有有两个从节点已接入
插入数据测试读写状态,在master中插入数据并读取
分别登入两个slave的client尝试读取数据和插入数据,如下图所示从节点只具备读的权限
Redis-Sentinel:
(1)监测:监测Redis主从节点是否按照预期正常运行
(2)提示:如果Redis运行出现问题可以按照配置文件中的配置项通知客户端或者集群管理员
(3)故障转移:当主节点下线之后,哨兵可以从主节点的多个从节点中选出一个为主节点,并更新配置文件和其他从节点的主节点信息
# 哨兵sentinel实例运行的端口 默认26379
port 26379
# 哨兵sentinel的工作目录
dir "/home/admin"
# 告诉sentinel去监听地址为ip:port的一个master,这里的master-name可以自定义,quorum是一个数字
# 指明当有多少个sentinel认为一个master失效时,master才算真正失效。master-name只能包含英文字母,数字,和“.-_”这三个字符需要注意的是master-ip 要写真实的ip地址而不要用回环地址(127.0.0.1)
sentinel monitor mymaster 192.168.8.116 6379 2
# 这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
sentinel down-after-milliseconds mymaster 5000
#同一个sentinel对同一个master两次failover之间的间隔时间。
#当一个slave从一个错误的master那里同步数据开始计算时间。直到slave被纠正为向正确的master那里同步数据时。
#当想要取消一个正在进行的failover所需要的时间。
#当进行failover时,配置所有slaves指向新的master所需的最大时间。不过,即使过了这个超时,slaves依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了。
sentinel failover-timeout mymaster 30000
#设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码
#因此master和slave的密码应该设置相同(弱密码请勿效仿)。
sentinel auth-pass mymaster 123456
#redis3.2版本后新增protected-mode配置,默认是yes,即开启。设置外部网络连接redis服务,设置方式如下:
# 1、关闭protected-mode模式,此时外部网络可以直接访问
# 2、开启protected-mode保护模式,需配置bind ip或者设置访问密码
protected-mode no
从master开始依次启动哨兵,查看主节点哨兵状态
测试故障转移关闭master服务
查看从节点状态是否推选出新的master,从如下图中可以看IP:192.168.8.117已经被选举为新的master
本文主要讲解了下redis整体的搭建思路和相关配置文件的讲解为大家提供一个参考方向实际还需动手实践,文章也存在着一些不足之处,还请诸位批评指正,谢谢。