redis单点-主从-哨兵-集群
参考文档
https://blog.csdn.net/miss1181248983/article/details/90056960
https://blog.csdn.net/miss1181248983/article/details/82011884
https://www.cnblogs.com/jaycekon/p/6237562.html
https://blog.csdn.net/liuxiao723846/article/details/86715614
详解cluster逻辑
环境
Linux iZ8vb47604rgqewujsb9kbZ 3.10.0-1062.9.1.el7.x86_64 #1 SMP Fri Dec 6 15:49:49 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
CentOS Linux release 7.7.1908 (Core)
redis5.0.7
编译安装redis以及安装完成后的一些配置持久化等(单点)
安装扩展依赖:yum install gcc
下载稳定版本redis
解压缩
tar zxf redis-5.0.7.tar.gz
进入解压缩目录编译
cd redis-5.0.7
yum install gcc #安装依赖
make MALLOC=libc
如果未报错,执行安装
make install PREFIX=/jesong/cluster/redis
创建数据存放目录
mkdir -p /jesong/cluster/redis/{conf,data,log}
复制主配置文件到安装目录
cp /root/redis-5.0.7/redis.conf /jesong/cluster/redis/conf/
cp /root/redis-5.0.7/sentinel.conf /jesong/cluster/redis/conf/
bind 172.26.103.65 #绑定ip
requirepass 123456 #设置连接密码
port 6379
dir /jesong/cluster/redis/data/ #缓存文件存放位置
appendonly yes #开启aof持久化
appendfsync everysec #指定aof持久化模式(everysec:每一秒,always:每一次,no:系统随机)
logfile "/jesong/cluster/redis/log/redis.log"
pidfile /var/run/redis_6379.pid
daemonize yes #设置后台启动
loglevel notice #设置log日志的级别
save 900 1 #设置rdb持久化,900秒内至少有1个key被改变则做一次快照
save 300 10 #设置rdb持久化,300秒内至少有300个key被改变则做一次快照
save 60 10000 #设置rdb持久化,60秒内至少有10000个key被改变则做一次快照
添加环境变量
echo 'export PATH=$PATH:/jesong/cluster/redis/bin' >>/etc/profile
source /etc/profile
启动
/jesong/cluster/redis/bin/redis-server /jesong/cluster/redis/conf/redis.conf
主从模式
主从模式介绍
* 主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库
* 从数据库一般都是只读的,并且接收主数据库同步过来的数据
* 一个master可以拥有多个slave,但是一个slave只能对应一个master
* slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来
* master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务
* master挂了以后,不会在slave节点中重新选一个master
工作机制
当slave启动后,主动向master发送SYNC命令。master接收到SYNC命令后在后台保存快照(RDB持久化)和缓存保存快照这段时间的命令,然后将保存的快照文件和缓存的命令发送给slave。slave接收到快照文件和命令后加载快照文件和缓存的执行命令。
复制初始化后,master每次接收到的写命令都会同步发送给slave,保证主从数据一致性。
master节点在主从模式中唯一,若master挂掉,则redis无法对外提供写服务
按照(单点配置)配置主节点
配置redis从服务,修改配置文件(两从节点)
如果主redis已经启动过了,那么复制的数据务必要删除缓存文件和日志文件
cp -a /jesong/cluster/redis/ /jesong/cluster/redis2
cp -a /jesong/cluster/redis/ /jesong/cluster/redis3
修改redis从服务配置文件
vim redis.conf
port 6380 #不能与主冲突 93行
pidfile /var/run/redis_6380.pid #pid文件不能相同 159行
logfile "/var/log/redis2.log" #日志文件不能相同 172行
dir /data/redis2 #dir不能相同 264行
replicaof 127.0.0.1 6379 #说明它是哪个的从,salveof 主IP 主服务端口 287行
masterauth 123123 #设置从连接主的密码,假设主的密码为123123 294行
启动从数据库
/jesong/cluster/redis2/bin/redis-server /jesong/cluster/redis2/conf/redis.conf
登录主数据库查看主从状态
redis-cli -h 127.0.0.1 -p 6379
auth 123456
info replication
测试是否同步
添加数据
set ceshi test
在各节点查询数据
get ceshi
删除测试数据
del ceshi
Sentinel模式(哨兵模式)
当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。
哨兵模式介绍
主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因此sentinel应运而生。
sentinel中文含义为哨兵,顾名思义,它的作用就是监控redis集群的运行状况,特点如下:
* sentinel模式是建立在主从模式的基础上,如果只有一个Redis节点,sentinel就没有任何意义
* 当master挂了以后,sentinel会在slave中选择一个做为master,并修改它们的配置文件,其他slave的配置文件也会被修改,比如slaveof属性会指向新的master
* 当master重新启动后,它将不再是master而是做为slave接收新的master的同步数据
* sentinel因为也是一个进程有挂掉的可能,所以sentinel也会启动多个形成一个sentinel集群
* 多sentinel配置的时候,sentinel之间也会自动监控
* 当主从模式配置密码时,sentinel也会同步将配置信息修改到配置文件中,不需要担心
* 一个sentinel或sentinel集群可以管理多个主从Redis,多个sentinel也可以监控同一个redis
* sentinel最好不要和Redis部署在同一台机器,不然Redis的服务器挂了以后,sentinel也挂了
* master下线后再次启动,会自动变成当前master的从库,并且会自动更改配置文件,无需手动变更。
工作机制
* 每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令
* 如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线。
* 如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态
* 当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线
* 在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令
* 当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次
* 若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;
若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除
* 当使用sentinel模式的时候,客户端就不要直接连接Redis,而是连接sentinel的ip和port,由sentinel来提供具体的可提供服务的Redis实现,这样当master节点挂掉以后,sentinel就会感知并将新的master节点提供给使用者。
在主从的基础上,修改哨兵配置文件
vim sentinel.conf
port 26379
daemonize yes
pidfile /var/run/redis-sentinel.pid
logfile "/jesong/cluster/redis/log/sentinel.log"
dir /jesong/cluster/redis/data
sentinel monitor mymaster 172.26.103.68 6379 2 #mymaster:自定义的集群名字 2:有多少个哨兵就可以决定是否下线
sentinel auth-pass mymaster 123456
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
启动哨兵
/jesong/cluster/redis/bin/redis-sentinel /jesong/cluster/redis/conf/sentinel.conf
把主节点干掉测试一下
查看哨兵日志,看看是否切换成功
tailf /jesong/cluster/redis/log/sentinel.log
测试新的主节点是否可以写入数据
info replication
set ceshi test
get ceshi
查看从节点是否同步了数据
keys *
cluster集群模式
https://blog.csdn.net/liuxiao723846/article/details/86715614
详解cluster,数据访问,集群链接,客户端访问等
不能绑定多个ip,否则创建集群会报错
cluster模式介绍
代码连接cluster吧主从所有六个ip和端口都写上
sentinel模式基本可以满足一般生产的需求,具备高可用性。但是当数据量过大到一台服务器存放不下的情况时,主从模式或sentinel模式就不能满足需求了,这个时候需要对存储的数据进行分片,将数据存储到多个Redis实例中。cluster模式的出现就是为了解决单机Redis容量有限的问题,将Redis的数据根据一定的规则分配到多台机器。
cluster可以说是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。
使用集群,只需要将redis配置文件中的cluster-enable配置打开即可。每个集群中至少需要三个主数据库才能正常运行,新增节点非常方便。
集群特点
* 多个redis节点网络互联,数据共享
* 所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用
* 不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,
并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为
* 支持在线增加、删除节点
* 客户端可以连接任何一个主节点进行读写
redisCluster的缺陷(虚拟槽分区的缺点)
a,键的批量操作支持有限,比如mset, mget,如果多个键映射在不同的槽,就不支持了
b,键事务支持有限,当多个key分布在不同节点时无法使用事务,同一节点是支持事务
c,键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点
d,不支持多数据库,只有0,select 0
e,复制结构只支持单层结构,不支持树型结构。
在(单点)的基础上,修改配置文件(不能绑定多个ip,否则创建集群会报错)
三台服务器:每台服务器上安装两个redis 所有的节点都是一主一从(也可以是一主多从)每个集群中至少需要三个主数据库才能正常运行
修改三台服务器上的redis配置文件
第一台: port 7000 port 7001
第二台: port 7002 port 7003
第三台:port 7004 port 7005
不能绑定多个ip,否则创建集群会报错
vim redis.conf
masterauth 123456
requirepass 123456
cluster-enabled yes
cluster-node-timeout 15000 #15秒超时
cluster-config-file nodes_7001.conf #会存放在dir 指定的目录下
port 7000 #不能与其他redis冲突 93行
pidfile /var/run/redis_6379.pid #pid文件路径不能相同 159行
logfile "/var/log/redis.log" #日志文件路径不能相同 172行
dir /data/redis2 #dir不能相同 264行
修改完配置文件后,启动各服务器redis
/jesong/cluster/redis/bin/redis-server /jesong/cluster/redis/conf/redis.conf
查看端口是否启动
ss -lntup
创建集群(3主3从)
redis-cli -a 123456 --cluster create 172.26.103.68:7000 172.26.103.68:7001 172.26.103.67:7002 172.26.103.67:7003 172.26.103.66:7004 172.26.103.66:7005 --cluster-replicas 1
出现下列为成功,老版本得redis创建集群需要安装ruby
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.26.103.67:7003 to 172.26.103.68:7000
Adding replica 172.26.103.66:7005 to 172.26.103.67:7002
Adding replica 172.26.103.68:7001 to 172.26.103.66:7004
M: f449cc610cfa32c1c64091195d0f86c0e862ff30 172.26.103.68:7000
slots:[0-5460] (5461 slots) master
S: c8ad1ea097b7466f4c4db1d972740ca7816085e3 172.26.103.68:7001
replicates 8c70e48b9c5b73654e698f22cb0caf76c83a3383
M: 4ec55ab4a64a0894e591ddf23482a470f3edd73a 172.26.103.67:7002
slots:[5461-10922] (5462 slots) master
S: 9cd8ed44964086b7f7e56a13a825ce8c43a6ae5f 172.26.103.67:7003
replicates f449cc610cfa32c1c64091195d0f86c0e862ff30
M: 8c70e48b9c5b73654e698f22cb0caf76c83a3383 172.26.103.66:7004
slots:[10923-16383] (5461 slots) master
S: 36d471bf1b6bcd3a532c2162ee4151c97b39b444 172.26.103.66:7005
replicates 4ec55ab4a64a0894e591ddf23482a470f3edd73a
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 172.26.103.68:7000)
M: f449cc610cfa32c1c64091195d0f86c0e862ff30 172.26.103.68:7000
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: c8ad1ea097b7466f4c4db1d972740ca7816085e3 172.26.103.68:7001
slots: (0 slots) slave
replicates 8c70e48b9c5b73654e698f22cb0caf76c83a3383
S: 9cd8ed44964086b7f7e56a13a825ce8c43a6ae5f 172.26.103.67:7003
slots: (0 slots) slave
replicates f449cc610cfa32c1c64091195d0f86c0e862ff30
M: 4ec55ab4a64a0894e591ddf23482a470f3edd73a 172.26.103.67:7002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 36d471bf1b6bcd3a532c2162ee4151c97b39b444 172.26.103.66:7005
slots: (0 slots) slave
replicates 4ec55ab4a64a0894e591ddf23482a470f3edd73a
M: 8c70e48b9c5b73654e698f22cb0caf76c83a3383 172.26.103.66:7004
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
登陆集群
redis-cli -c -h 172.26.103.68 -p 7000 -a 123456 # -c,使用集群方式登录
列出节点信息
cluster nodes
测试集群
192.168.30.128:7001> set key111 aaa
-> Redirected to slot [13680] located at 192.168.30.130:7005 #说明数据到了192.168.30.130:7005上
OK
192.168.30.130:7005> set key222 bbb
-> Redirected to slot [2320] located at 192.168.30.128:7001 #说明数据到了192.168.30.128:7001上
OK
192.168.30.128:7001> set key333 ccc
-> Redirected to slot [7472] located at 192.168.30.129:7003 #说明数据到了192.168.30.129:7003上
OK
192.168.30.129:7003> get key111
-> Redirected to slot [13680] located at 192.168.30.130:7005
"aaa"
192.168.30.130:7005> get key333
-> Redirected to slot [7472] located at 192.168.30.129:7003
"ccc"
redis常用命令
https://blog.csdn.net/miss1181248983/article/details/82011884
cluster集群命令(redis-cli -c -p port)
集群
cluster info :打印集群的信息
cluster nodes :列出集群当前已知的所有节点( node),以及这些节点的相关信息。
节点
cluster meet <ip> <port> :将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
cluster forget <node_id> :从集群中移除 node_id 指定的节点。
cluster replicate <node_id> :将当前节点设置为 node_id 指定的节点的从节点。
cluster saveconfig :将节点的配置文件保存到硬盘里面。
redis存储hash(散列操作)
赋值/取值 单个操作
hset key field value : 为指定的key设定field/value对 (键值对)
172.26.103.66:7005> hset user03 name zhangsan
(integer) 1
172.26.103.66:7005> hset user03 age 16
(integer) 1
hget key field:返回指定的key种的field值
172.26.103.66:7005> hget user03 name
"zhangsan"
172.26.103.66:7005> hget user03 age
"16"
7.2.1 赋值/取值 同时设置多个字段
hget key field:返回指定的key中的field的值
hmget key fields:获取key中的多个filed的值
hgetall key:获取key中的所有field-vaule
172.26.103.68:7001> hmset user02 city shanghai email zhangsan@163.com
OK
172.26.103.68:7001> hmget user02 city email
1) "shanghai"
172.26.103.68:7001> hgetall user02
1) "city"
2) "shanghai"
3) "email"
增加,判断,获取keys
hincrby key field increment: 设置key中field的值增加increment 如age 增加20
172.26.103.66:7005> hincrby user04 age 23
(integer) 43
hexists key field : 判断指定的key中的filed是否存在(返回0不存在,返回1存在)
172.26.103.66:7005> hexists user04 city
(integer) 0
172.26.103.66:7005> hexists user04 name
(integer) 1
hlen key :获取key所包含的field的数量
172.26.103.66:7005> hlen user04
(integer) 2
hkeys key:获取所有的key
hvals key :获取所有的value
172.26.103.66:7005> hkeys user04
1) "age"
2) "name"
172.26.103.66:7005> hvals user04
1) "43"
2) "wxd"
删除
hdel key field:可以删除一个或多个字段,返回值是被删除的字段个数
del key: 删除整个list
172.26.103.68:7001> hdel user02 city email
(integer) 2
172.26.103.68:7001> hgetall user02
(empty list or set)
172.26.103.68:7001> del user02
(integer) 0
172.26.103.68:7001> keys *
1) "test11"
客户端登录命令(非集群,集群加上 -c)
./redis-cli -p 6379
验证密码
auth password
创建一个key value
redis> set foo bar
OK
redis> get foo
"bar"
查看主从状态
info replication
查看redis种所有的key
keys *
切换数据库(redis默认有16个库,在配置文件内配置,cluster不支持多库)
select 2 #切换到第二个库