[Redis] Redis 安装部署

简介

Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的API。

它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Hash), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。本文主要介绍 Redis 启动配置参数含义、主从、哨兵模式的环境搭建方式。


手机用户请横屏获取最佳阅读体验,REFERENCES中是本文参考的链接,如需要链接和更多资源,可以关注公众号后加入『知识星球』获取长期知识分享服务。

windows 下安装

下载地址: https://github.com/MicrosoftArchive/redis/releases

linux & mac 下安装

下载 & 编译

$ wget https://download.redis.io/releases/redis-6.0.8.tar.gz
$ tar xzf redis-6.0.8.tar.gz
$ cd redis-6.0.8
$ make

启动

$ src/redis-server

在这里插入图片描述

访问

$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
  • cp -R /Users/xiazhaoyang/Ashe/plugin/redis/redis-6.0.8 /usr/local/bin/redis-6.0.8
  • cd /usr/local/bin/redis-6.0.8
yi:bin xiazhaoyang$ cd redis-6.0.8/
yi:redis-6.0.8 xiazhaoyang$ ls
00-RELEASENOTES		README.md		runtest-sentinel
BUGS			TLS.md			sentinel.conf
CONTRIBUTING		deps			src
COPYING			redis.conf		tests
INSTALL			runtest			utils
MANIFESTO		runtest-cluster
Makefile		runtest-moduleapi
yi:redis-6.0.8 xiazhaoyang$ redis-cli
127.0.0.1:6379> get x
"1"
127.0.0.1:6379>

参数配置

BASIC

绑定的主机地址

bind 127.0.0.1

redis3.2 版本后新增 protected-mode 配置,默认是 yes,即开启。设置外部网络连接 redis 服务,设置方式:

1、关闭 protected-mode 模式,此时外部网络可以直接访问

2、开启 protected-mode 保护模式,需配置 bind ip 或者设置访问密码

protected-mode yes

指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上 MERZ 对应的号码,而 MERZ 取自意大利歌女 Alessia Merz 的名字

port 6479

设置数据库的数量,默认数据库为0,可以使用SELECT 命令在连接上指定数据库id

databases 16

指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合。

save <seconds> <changes>

# 分别表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改。
save 900 1
save 300 10
save 60 10000

指定 Redis 最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis新的 vm 机制,会把Key存放内存,Value 会存放在 swap 区

maxmemory <bytes>

RDB

指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大

rdbcompression yes

指定本地数据库文件名,默认值为 dump.rdb

dbfilename dump.rdb

是否校验rdb文件。从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和。这跟有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗,所以如果你追求高性能,可以关闭该配置。

rdbchecksum no

指定本地数据库存放目录

dir ./

当 RDB持久化出现错误后,是否依然进行继续进行工作,

yes:不能进行工作,

no:可以继续进行工作

可以通过info中的rdb_last_bgsave_status了解RDB持久化是否有错误

stop-writes-on-bgsave-error yes

AOF

指定是否在每次更新操作后进行日志记录,

  • Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为 no 。
  • 开启 append only 模式之后,redis 会把所接收到的每一次写操作请求都追加到 appendonly.aof 文件中,当 redis 重新启动时,会从该文件恢复出之前的状态。但是这样会造成 appendonly.aof 文件过大,所以 redis 还支持了 BGREWRITEAOF 指令,对 appendonly.aof 进行重新整理。默认是不开启的。

appendonly no

指定更新日志文件名,默认为appendonly.aof

appendfilename appendonly.aof

指定更新日志条件(设置 aof 的同步频率),共有3个可选值:
no:表示等操作系统进行数据缓存同步到磁盘(快)
always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
everysec:表示每秒同步一次(折衷,默认值)

appendfsync everysec

指定是否在后台 aof 文件 rewrite 期间调用 fsync,默认为 no,表示要调用 fsync(无论后台是否有子进程在刷盘)。Redis 在后台写 RDB 文件或重写 aof 文件期间会存在大量磁盘 IO,此时,在某些 linux 系统中,调用 fsync 可能会阻塞。

no-appendfsync-on-rewrite no

指定 Redis 重写 aof 文件的条件,默认为 100,表示与上次 rewrite 的 aof 文件大小相比,当前 aof 文件增长量超过上次 aof 文件大小的 100% 时,就会触发 background rewrite。若配置为0,则会禁用自动 rewrite。

auto-aof-rewrite-percentage 100

指定触发 rewrite 的 aof 文件大小。若 aof 文件小于该值,即使当前文件的增量比例达到 auto-aof-rewrite-percentage 的配置值,也不会触发自动 rewrite。即这两个配置项同时满足时,才会触发 rewrite。

允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写

auto-aof-rewrite-min-size 64mb

aof rewrite 过程中,是否采取增量文件同步策略,默认为 “yes”。当 child 进程在 rewrite AOF 文件,每 32M 数据进行一次文件同步,这样可以减少 aof 大文件写入对磁盘的操作次数

aof-rewrite-incremental-fsync yes

aof文件可能在尾部是不完整的,当 redis启动的时候,aof文件的数据被载入内存。重启可能发生在 redis 所在的主机操作系统宕机后,尤其在 ext4文件系统没有加上 data=ordered 选项(redis宕机或者异常终止不会造成尾部不完整现象。)

出现这种现象,可以选择让 redis退出,或者导入尽可能多的数据。

如果选择的是yes,当截断的 aof文件被导入的时候,会自动发布一个log给客户端然后load。

如果是no,用户必须手动 redis-check-aof 修复 AOF 文件才可以。

aof-load-truncated yes

VM

指定是否启用虚拟内存机制,默认值为no,简单的介绍一下,VM 机制将数据分页存放,由Redis将访问量较少的页即冷数据 swap 到磁盘上,访问多的页面由磁盘自动换出到内存中。

vm-enabled no

虚拟内存文件路径,默认值为/tmp/redis.swap,不可多个Redis实例共享

vm-swap-file /tmp/redis.swap

将所有大于 vm-max-memory 的数据存入虚拟内存,无论 vm-max-memory 设置多小,所有索引数据都是内存存储的( Redis 的索引数据 就是keys),也就是说,当 vm-max-memory 设置为 0 的时候,其实是所有 value 都存在于磁盘。默认值为 0

vm-max-memory 0

Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page大小最好设置为32或者64bytes;如果存储很大大对象,则可以使用更大的page,如果不 确定,就使用默认值

vm-page-size 32

设置swap文件中的page数量,由于页表(一种表示页面空闲或使用的bitmap)是在放在内存中的,,在磁盘上每8个pages将消耗1byte的内存。

vm-pages 134217728

设置访问swap文件的线程数,最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为4

vm-max-threads 4

设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启

glueoutputbuf yes

指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件

include /path/to/local.conf

Client

按键通知事件

键空间通知使得客户端可以通过订阅频道或模式,来接收那些以某种方式改动了 Redis 数据集的事件。因为开启键空间通知功能需要消耗一些 CPU ,所以在默认配置下,该功能处于关闭状态。

notify-keyspace-events 的参数可以是以下字符的任意组合,它指定了服务器该发送哪些类型的通知:

  1. K 键空间通知,所有通知以 keyspace@ 为前缀
  2. E 键事件通知,所有通知以 keyevent@ 为前缀
  3. g DEL 、 EXPIRE 、 RENAME 等类型无关的通用命令的通知
  4. $ 字符串命令的通知
  5. l 列表命令的通知
  6. s 集合命令的通知
  7. h 哈希命令的通知
  8. z 有序集合命令的通知
  9. x 过期事件:每当有过期键被删除时发送
  10. e 驱逐(evict)事件:每当有键因为 maxmemory 政策而被删除时发送
  11. A 参数 g$lshzxe 的别名
  12. 输入的参数中至少要有一个 K 或者 E,否则的话,不管其余的参数是什么,都不会有任何 通知被分发。详细使用可以参考 http://redis.io/topics/notifications

notify-keyspace-events ""

LUA

一个 Lua 脚本最长的执行时间,单位为毫秒,如果为0或负数表示无限执行时间,默认为5000

lua-time-limit 5000

SlAVE

当slave服务器和master服务器失去连接后,或者当数据正在复制传输的时候,如果此参数值设置yes,slave服务器可以继续接受客户端的请求,否则,会返回给请求的客户端如下信息SYNC with master in progress

slave-serve-stale-data yes

指定 slave 的优先级。在不只1个 slave 存在的部署环境下,当 master 宕机时,Redis Sentinel 会将 priority值最小的 slave 提升为 master。需要注意的是,若该配置项为 0,则对应的 slave 永远不会自动提升为master

slave-priority 100

设置当本机为 slave服务时,设置 master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步

slaveof <masterip> <masterport>

是否允许 slave 服务器节点只提供读服务。

作为从服务器,默认情况下是只读的(yes),可以修改成NO,用于写(不建议)。

slave-read-only yes

REPL

是否使用socket方式复制数据。目前redis复制提供两种方式,disk和socket。如果新的slave连上来或者重连的slave无法部分同步,就会执行全量同步,master会生成rdb文件。有2种方式:disk方式是 master 创建一个新的进程把 rdb 文件保存到磁盘,再把磁盘上的 rdb文件传递给 slave。socket 是 master创建一个新的进程,直接把rdb文件以socket的方式发给slave。disk方式的时候,当一个 rdb 保存的过程中,多个 slave 都能共享这个rdb文件。socket的方式就的一个个slave顺序复制。在磁盘速度缓慢,网速快的情况下推荐用 socket方式。

repl-diskless-sync no

diskless复制的延迟时间,防止设置为0。一旦复制开始,节点不会再接收新slave的复制请求直到下一个rdb传输。所以最好等待一段时间,等更多的slave连上来。

repl-diskless-sync-delay 5

slave根据指定的时间间隔向服务器发送ping请求。时间间隔可以通过 repl_ping_slave_period 来设置,默认10秒。

repl-ping-slave-period 5

复制连接超时时间。master和slave都有超时时间的设置。master检测到slave上次发送的时间超过repl-timeout,即认为slave离线,清除该slave信息。slave检测到上次和master交互的时间超过repl-timeout,则认为master离线。需要注意的是repl-timeout需要设置一个比repl-ping-slave-period更大的值,不然会经常检测到超时。

repl-timeout 60

指定向 slave 同步数据时,是否禁用 socket 的 NO_DELAY 选 项。

  • 若配置为 yes,则禁用 NO_DELAY,则 TCP 协议栈会合并小包统一发送,这样可以减少主从节点间的包数量并节省带宽,但会增加数据同步到 slave 的时间。
  • 若配置为 no,表明启用 NO_DELAY,则 TCP 协议栈不会延迟小包的发送时机,这样数据同步的延时会减少,但需要更大的带宽。 通常情况下,应该配置为 no降低同步延时,但在主从节点间网络负载已经很高的情况下,可以配置为 yes

repl-disable-tcp-nodelay no

复制缓冲区大小,这是一个环形复制缓冲区,用来保存最新复制的命令。这样在slave离线的时候,不需要完全复制master的数据,如果可以执行部分同步,只需要把缓冲区的部分数据复制给slave,就能恢复正常复制状态。缓冲区的大小越大,slave离线的时间可以更长,复制缓冲区只有在有slave连接的时候才分配内存。没有slave的一段时间,内存会被释放出来,默认1m。

repl-backlog-size 32mb

master没有slave一段时间会释放复制缓冲区的内存,repl-backlog-ttl用来设置该时间长度。单位为秒。

repl-backlog-ttl 3600

监控

执行日志

指定日志记录级别,Redis总共支持四个级别:

debug、verbose、notice(生产环境)、warning,默认为verbose

loglevel notice

日志记录方式,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null

logfile "6479.log"

延迟监控

延迟监控功能是用来监控redis中执行比较缓慢的一些操作,用 LATENCY 打印 redis实例在跑命令时的耗时图表。只记录大于等于下边设置的值的操作。0的话,就是关闭监视。默认延迟监控功能是关闭的,如果你需要打开,也可以通过CONFIG SET命令动态设置。

latency-monitor-threshold 0

慢日志

slow 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

安全

当master服务设置了密码保护时,slave服务连接 master的密码

masterauth <master-password>

设置Redis连接密码,如果配置了连接密码,客户端在连接Redis时需要通过AUTH <password> 命令提供密码,默认关闭

requirepass foobared

存储结构

Redis 的 List 内部是通过 quicklist 实现的(Redis 3.2 开始使用),quicklist 是一个双向链表。 quicklist 的每个节点都是一个 ziplist。list-max-ziplist-size 就是用于配置 quicklist 中的每个节点的 ziplist 的大小。 当这个值配置为正数时表示 quicklist 每个节点的 ziplist 所包含的元素个数是一个确定的数量。 当 list-max-ziplist-size 为负数时表示限制每个 ziplist 的大小,具体有以下含义:

  • -5:最大 64 kb 正常环境不推荐
  • -4:最大 32 kb 不推荐
  • -3:最大 16 kb 可能不推荐
  • -2:最大 8 kb 不错
  • -1:最大 4kb 不错

默认值为 -2,也是官方最推荐的值,当然你可以根据自己的实际情况进行修改。

list-max-ziplist-size -2

quicklist 中的 ziplist 节点会被压缩。为了 push/pop 操作的高效性,quicklist 的头和尾节点永远都不会被压缩。 list-compress-depth 选项用于控制 quicklist 中压缩的节点的深度,下面的示例中加了中括号的节点表示未压缩。

  • 0 表示不对节点进行压缩,这是默认的值
  • 1 表示对头和尾节点外的其他节点进行压缩, [head]->node->node->…->node->[tail]
  • 2 [head]->[next]->node->node->…->node->[prev]->[tail]
  • 3 [head]->[next]->[next]->node->node->…->node->[prev]->[prev]->[tail]
  • 依次类推

list-compress-depth 0

数据量

entries <= list-max-ziplist-entries用 ziplist,

entries > list-max-ziplist-entries用 list。

hash-max-ziplist-entries 512
hash-max-ziplist-value 64

数据量

entries <= set-max-intset-entries 用 iniset,

entries > set-max-intset-entries 用 set。

set-max-intset-entries 512

数据量

entries <= zset-max-ziplist-entries 用 ziplist
entries > zset-max-ziplist-entries 用 zset

zset-max-ziplist-entries 128

value <= zset-max-ziplist-value 用 ziplist,
value > zset-max-ziplist-value 用 zset

zset-max-ziplist-value 640

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 表进行 rehash,可以降低内存的使用。当你的使用场景中,有非常严格的实时性需要,不能够接受 Redis 时不时的对请求有2毫秒的延迟的话,把这项配置为 no。如果没有这么严格的实时性要求,可以设置为 yes,以便能够尽可能快的释放内存。

activerehashing yes

指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法

hash-max-zipmap-entries 64

hash-max-zipmap-value 512

连接

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

maxclients 128

当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

timeout 0

tcp keepalive参数。如果设置不为 0,就使用配置 tcp 的 SO_KEEPALIVE 值,使用 keepalive有两个好处:

  • 检测挂掉的对端。降低中间设备出问题而导致网络看似连接却已经与对端端口连接异常的问题。
  • 在Linux内核中,设置了 keepalive,redis 会定时给对端发送 ack。检测到对端关闭需要两倍的设置值。

如果值非0,单位是秒,表示将周期性的使用 SO_KEEPALIVE 检测客户端是否还处于健康状态,避免服务器一直阻塞,官方给出的建议值是 60 S。

tcp-keepalive 0

此参数确定了TCP连接中已完成队列(完成三次握手之后)的长度, 当然此值必须不大于Linux系统定义的/proc/sys/net/core/somaxconn值,默认是511,而Linux的默认参数值是128。当系统并发量大并且客户端速度缓慢的时候,可以将这二个参数一起参考设定。

tcp-backlog 511

对客户端输出缓冲进行限制可以强迫那些不从服务器读取数据的客户端断开连接,用来强制关闭传输缓慢的客户端。

参数说明:

client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>

class可以为以下:

  • normal -> normal clients including MONITOR clients

  • slave -> slave clients

  • pubsub -> clients subscribed to at least one pubsub channel or pattern

当 hard限制到了会立即被关闭客户端。如果 soft 限制到了,会等 soft 秒。比如硬限制是32m,soft是16m,10 secs。到32m就立即断,或者在16m以上停止了10 secs。设置成0就是关闭。

示例:

  • 对于 normal client,第一个0表示取消 hard limit,第二个0和第三个0表示取消 soft limit,normal client 默认取消限制,因为如果没有寻问,他们是不会接收数据的。

  • 对于 slave client 和 MONITER client,如果 client-output-buffer一旦超过 256 mb,又或者超过 64mb 持续 60秒,那么服务器就会立即断开客户端连接。

  • 对于 pubsub client,如果 client-output-buffer一旦超过 32mb,又或者超过 8mb 持续 60 秒,那么服务器就会立即断开客户端连接。

client-output-buffer-limit normal 0 0 0

client-output-buffer-limit slave 256mb 64mb 60

client-output-buffer-limit pubsub 32mb 8mb 60

redis执行任务的频率为1s除以hz。 redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,越大则调度频率越高。设置成100以上会对CPU造成大压力除非你对线上实时性要求很高。可以在1~500之间。

hz 10

Tips

  • windows 下不支持 daemonzise no

Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
# NOT SUPPORTED ON WINDOWS daemonize no
  • windows 下不支持 pidfile /var/run/redis.pid

当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

# Creating a pid file is best effort: if Redis is not able to create it
# nothing bad happens, the server will start and run normally.
# NOT SUPPORTED ON WINDOWS pidfile /var/run/redis.pid

运行模式

单机模式

拷贝 redis.conf 副本进行修改

cp redis.conf redis.single.conf
vim redis.single.conf

绑定 IP

bind 127.0.0.1

修改 port

port 6479

设置主服务器密码

# --- SECURITY WARNING ---
#
# If you plan to put Redis on the internet in a publicly accessible address
# to server Gopher pages MAKE SURE TO SET A PASSWORD to the instance.
# Once a password is set:
#
#   1. The Gopher server (when enabled, not by default) will still serve
#      content via Gopher.
#   2. However other commands cannot be called before the client will
#      authenticate.
#
# So use the 'requirepass' option to protect your instance.

# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the replica to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the replica request.

# IMPORTANT NOTE: starting with Redis 6 "requirepass" is just a compatiblity
# layer on top of the new ACL system. The option effect will be just setting
# the password for the default user. Clients will still authenticate using
# AUTH <password> as usually, or more explicitly with AUTH default <password>
# if they follow the new protocol: both will work.

requirepass 123456

开启守护进程

# deamonize yes|no 杀掉进程后自动重启
deamonize yes

由于本地通过 brew 安装了4.0版本的 redis,因此需要修改下端口后启动

./src/redis-server redis.single.conf
yi:redis-6.0.8 xiazhaoyang$ ./src/redis-server redis.single.conf
64379:C 20 Oct 2020 08:57:10.556 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
64379:C 20 Oct 2020 08:57:10.556 # Redis version=6.0.8, bits=64, commit=00000000, modified=0, pid=64379, just started
64379:C 20 Oct 2020 08:57:10.556 # Configuration loaded
64379:M 20 Oct 2020 08:57:10.557 * Increased maximum number of open files to 10032 (it was originally set to 256).
                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 6.0.8 (00000000/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6479
 |    `-._   `._    /     _.-'    |     PID: 64379
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'

64379:M 20 Oct 2020 08:57:10.562 # Server initialized
64379:M 20 Oct 2020 08:57:10.563 * Loading RDB produced by version 4.0.14
64379:M 20 Oct 2020 08:57:10.563 * RDB age 242497 seconds
64379:M 20 Oct 2020 08:57:10.563 * RDB memory usage when created 0.95 Mb
64379:M 20 Oct 2020 08:57:10.563 * DB loaded from disk: 0.001 seconds
64379:M 20 Oct 2020 08:57:10.563 * Ready to accept connections

连接

yi:redis-6.0.8 xiazhaoyang$ ./src/redis-cli -p 6479
127.0.0.1:6479> set x 1
(error) NOAUTH Authentication required.
127.0.0.1:6479> auth 123456
OK
127.0.0.1:6479>

主从模式

主机
#演示方便,开放ip连接
bind 0.0.0.0
port 6479
#后台运行
daemonize yes
#pid文件
pidfile /var/run/redis_6479.pid
dbfilename dump-6479.rdb
#日志文件
logfile "6479.log"
从机
bind 0.0.0.0
port 6480
daemonize yes
pidfile /var/run/redis_6480.pid
dbfilename dump-6380.rdb
logfile "6480.log"
#slaveof 表示作为 6479 的从库
slaveof 127.0.0.1 6479
#从库只能读操作
slave-read-only yes
部署
  • 启动主机
./src/redis-server redis.6479.conf
  • 测试主机读写
yi:redis-6.0.8 xiazhaoyang$ ./src/redis-cli -p 6479
127.0.0.1:6479> get x
(nil)
127.0.0.1:6479> set x 1
OK
127.0.0.1:6479> get x
"1"
127.0.0.1:6479>
  • 启动从机
./src/redis-server redis.6480.conf
  • 测试从机数据同步
yi:redis-6.0.8 xiazhaoyang$ ./src/redis-cli -p 6480
127.0.0.1:6480> get x
"1"
127.0.0.1:6480>
  • 测试从机写拒绝
127.0.0.1:6480> set x 2
(error) READONLY You can't write against a read only replica.
info

slave

yi:redis-6.0.8 xiazhaoyang$ ./src/redis-cli -p 6480 info
# Server
redis_version:6.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:5e194b936892759a
redis_mode:standalone
os:Darwin 18.7.0 x86_64
arch_bits:64
multiplexing_api:kqueue
atomicvar_api:atomic-builtin
gcc_version:4.2.1
process_id:74609
run_id:c9b2d4117128abc48bdf1fcc5b5e904b41481bce
tcp_port:6480
uptime_in_seconds:301
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:9679840
executable:/usr/local/bin/redis-6.0.8/./src/redis-server
config_file:/usr/local/bin/redis-6.0.8/redis.6480.conf
io_threads_active:0

//...

# Replication
role:slave
master_host:127.0.0.1
master_port:6479
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:1111
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:1ad59477dd71e3c22d3f85bb909a31402f1e2e34
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1111
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1111

master

yi:redis-6.0.8 xiazhaoyang$ ./src/redis-cli -p 6479 info
# Server
redis_version:6.0.8
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:5e194b936892759a
redis_mode:standalone
os:Darwin 18.7.0 x86_64
arch_bits:64
multiplexing_api:kqueue
atomicvar_api:atomic-builtin
gcc_version:4.2.1
process_id:74394
run_id:5e99d1e4ca23fe8f3824b17cc1fd893f6f039938
tcp_port:6479
uptime_in_seconds:1098
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:9680008
executable:/usr/local/bin/redis-6.0.8/./src/redis-server
config_file:/usr/local/bin/redis-6.0.8/redis.6479.conf
io_threads_active:0

//...

# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6480,state=online,offset=1335,lag=1
master_replid:1ad59477dd71e3c22d3f85bb909a31402f1e2e34
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1335
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1335

Tips:

主从数据同步验证完毕。

哨兵模式(Redis 高可用)

启动命令:redis-sentinel sentinel.conf

sentinel 机制

在这里插入图片描述

过程:

  1. 多个 sentinel 发现并确认 master 有问题
  2. 选举出一个 sentinel 作为领导
  3. 选出一个 slave 作为 master
  4. 通知其余 slave 成为新的 master 的 slave
  5. 通知客户端主从变化
  6. 等待老的 master 复活成为新的 master 的 slave

创建 sentinel.conf 配置文件

1 主 2 从 3 哨兵

  • 主节点
  • 投票(大于1半,至少3个)
  • 主从备份,一个主故障,至少保证主从模式(读写分离),因此 2个从

首先补充一个从节点配置

cp redis.6480.conf redis.6481.conf
vi redis.6481.conf
./src/redis-server redis.6481.conf

redis.6481.conf

bind 0.0.0.0
port 6481
daemonize yes
pidfile /var/run/redis_6481.pid
dbfilename dump-6381.rdb
logfile "6481.log"
loglevel debug
#slaveof 表示作为 6479 的从库
slaveof 127.0.0.1 6479
#从库只能读操作
slave-read-only yes

查看1主2从模式节点信息

# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6480,state=online,offset=13767,lag=0
slave1:ip=127.0.0.1,port=6481,state=online,offset=13767,lag=1
master_replid:1ad59477dd71e3c22d3f85bb909a31402f1e2e34
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:13767
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:13767
配置 sentinel
  • sentine.16479.conf
port 16479
daemonize yes
dir "/private/tmp"
logfile "16479.log"
sentinel monitor mymaster 127.0.0.1 6479 2

同理配置 16480、16481 两个哨兵节点

  • 配置说明

Every long running process should have a well-defined working directory.
For Redis Sentinel to chdir to /tmp at startup is the simplest thing
for the process to don’t interfere with administrative tasks such as
unmounting filesystems.

存储目录

dir

Specify the log file name. Also the empty string can be used to force
Sentinel to log on the standard output. Note that if you use standard
output for logging but daemonize, logs will be sent to /dev/null

日志

logfile "16479.log"

The port that this sentinel instance will run on

端口

port

By default Redis Sentinel does not run as a daemon. Use ‘yes’ if you need it. Note that Redis will write a pid file in /var/run/redis-sentinel.pid when daemonized.

是否守护进程执行

daemonize yes

When running daemonized, Redis Sentinel writes a pid file in
/var/run/redis-sentinel.pid by default. You can specify a custom pid file
location here.

执行文件

pidfile "/var/run/redis-sentinel.16479.pid"

Tells Sentinel to monitor this master, and to consider it in O_DOWN
(Objectively Down) state only if at least sentinels agree.
Note that whatever is the ODOWN quorum, a Sentinel will require to
be elected by the majority of the known Sentinels in order to
start a failover, so no failover can be performed in minority.
Replicas are auto-discovered, so you don’t need to specify replicas in
any way. Sentinel itself will rewrite this configuration file adding
the replicas using additional configuration options.
Also note that the configuration file is rewritten when a
replica is promoted to master.
Note: master name should not include special characters or spaces.
The valid charset is A-z 0-9 and the three characters “.-_”.

监控节点配置

sentinel monitor

运行过后会自动更新位对应的节点 ID

sentinel myid 787c68bbb3e08a19491238c34176fb2ce72430ff

运行状态
yi:note-book xiazhaoyang$ ps -ef|grep redis
  501 67062     1   0 三09下午 ??         0:11.05 /usr/local/opt/redis@4.0/bin/redis-server 127.0.0.1:6379
  501 74394     1   0 12:40下午 ??         0:27.23 ./src/redis-server 0.0.0.0:6479 主
  501 74609     1   0 12:50下午 ??         0:27.32 ./src/redis-server 0.0.0.0:6480 从
  501 77395     1   0  3:27下午 ??         0:01.63 ./src/redis-server 0.0.0.0:6481 从
  501 77574     1   0  3:36下午 ??         0:00.08 ./src/redis-sentinel *:16479 [sentinel] 哨兵
  501 77578     1   0  3:36下午 ??         0:00.05 ./src/redis-sentinel *:16480 [sentinel] 哨兵
  501 77584     1   0  3:36下午 ??         0:00.03 ./src/redis-sentinel *:16481 [sentinel] 哨兵
  501 77586 71911   0  3:36下午 ttys004    0:00.00 grep redis
  501 74522 74515   0 12:47下午 ttys006    0:00.01 ./src/redis-cli -p 6479
高可用

下线主节点

  • 下线主节点 kill -9 74394

  • 查看6480节点状态 ./src/redis-cli -p 6480 info

# Replication
role:slave
master_host:127.0.0.1
master_port:6481
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:56261
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:3d1b0a006e0038ba111dafb6a45754f964626395
master_replid2:1ad59477dd71e3c22d3f85bb909a31402f1e2e34
master_repl_offset:56261
second_repl_offset:51423
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:56261
  • 查看当前主节点 6481 状态 ./src/redis-cli -p 6481 info
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6480,state=online,offset=82126,lag=1
master_replid:3d1b0a006e0038ba111dafb6a45754f964626395
master_replid2:1ad59477dd71e3c22d3f85bb909a31402f1e2e34
master_repl_offset:82392
second_repl_offset:51423
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:13684
repl_backlog_histlen:68709

可以看到完成了主从切换。我们恢复下线的节点 6479,再观察下能否被当前主节点检测到:

再次查看节点 6481 节点信息

# Replication
role:master
connected_slaves:2
# 可以观察到目前 6480、6479 都作为从节点关联道主节点 6481 上了
slave0:ip=127.0.0.1,port=6480,state=online,offset=104514,lag=0
slave1:ip=127.0.0.1,port=6479,state=online,offset=104514,lag=0
master_replid:3d1b0a006e0038ba111dafb6a45754f964626395
master_replid2:1ad59477dd71e3c22d3f85bb909a31402f1e2e34
master_repl_offset:104514
second_repl_offset:51423
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:13684
repl_backlog_histlen:90831

对应的6479节点不能再进行写入操作

127.0.0.1:6479> set x 1
(error) READONLY You can't write against a read only replica.

6481 成为主节点后可以正常写入

yi:redis-6.0.8 xiazhaoyang$ ./src/redis-cli -p 6481
127.0.0.1:6481> set x 2
OK

小结

至此,Redis 安装配置及常见部署方式已经介绍完毕。


REFERENCES

在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐