(一)主从复制
一.几个基本概念
- 概念:一台redis服务器的数据,复制到其他redis服务器上。前者称为主节点(master/leader),后者称为从节点(slave/follower)。
- 复制特点:
1.数据的复制是单向的,只能由主节点到从节点。
2.master以写为主,slave以读为主。 - 结构特点:
1.默认情况下,每台redis服务器是一个主节点。
2.主节点可以有多个从节点,但从节点只能有一个主节点。 - 连接结构:
1.链表形式:注意中间节点仍然是从节点属性。
2.分叉形式
使用说明:
一般情况下,项目中使用redis,应该避免只用一台。原因:
1.从结构上,单个redis服务器会发生单点故障,并且一台服务器处理所有请求,压力太大。
2.从容量上,单个redis服务器内存容量有限,就算一台的内存容量有256G,但也不能将所有内存当作存储内存。一般来说,单个redis服务器最大使用内存不应超过20G。
基于以上原因,故而要采用以下架构:
二.测试基本命令和配置
1.配置
- 增加多个不同名的redis.conf配置文件
[root@hadoop1 etc] ls
redis.conf
[root@hadoop1 etc] cp redis.conf redis79.conf #cp为复制操作,即复制redis.conf到新文件redis79.conf
[root@hadoop1 etc] cp redis.conf redis80.conf
[root@hadoop1 etc] cp redis.conf redis81.conf
[root@hadoop1 etc] ls
redis79.conf redis80.conf redis81.conf redis.conf
- 修改配置文件(以下端口皆为示例)
1.端口
port 6379(6380/6381)
2.pid名
pidfile /var/run/redis_6379(6380/6381).pid
3.log文件名
logfile "6379(6380/6381).log"
4.dump.rdb名
dbfilename dump6379(6380/6381).rdb
2.命令
- slaveof (host) (port) (称为指定主机的从机)
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:0
master_link_down_since_seconds:-1
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:03b0103ad5496d7313d9a981db82bcc246618d9c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
- info replication(查看当前库的信息)
127.0.0.1:6379> info replication
# Replication
role:master #当前库的角色
connected_slaves:0 #当前库的从节点
master_failover_state:no-failover
master_replid:2385ee57189b2c6a6540942c25dd0b7fecfb769a
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
- slaveof no one(设定自己为主机)
127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_failover_state:no-failover
master_replid:b7f98e4ac51099240eb370c3ee06b387c1332fe1
master_replid2:fc78cfcfea97b4021f96c7c50a2ff50d4fb65c91
master_repl_offset:224
second_repl_offset:225
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:224
3.原理
- slave启动成功连接到master后会发送一个同步命令,master接到命令会启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,master会将整个数据文件传送到slave,并完成一次完全同步。
- 全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存。
- 增量复制:master继续将新的所有收集到的修改命令依次传到slave,完成同步。
注意: 只要重新连接master,就会自动执行一次全量复制。
(二)哨兵模式
1.概述
- 使用原因:当主服务器宕机时,为避免手动操作费事,利用哨兵(sentinel)模式,监控主机,并可以自动替换掉主服务器。
- 运行原理:哨兵通过发送命令到服务器,等待响应,从而监控服务器。图解如下:
2.作用
- 哨兵发送命令到服务器,通过响应监控服务器。
- 当监控到master宕机,自动替换为slave,然后通过发布订阅模式通知其他服务器修改配置,并切换主机。
- 为防止单哨兵进程出现问题,故而采用多哨兵互相监控模式,示例如下:
- 主观下线:单个哨兵检测的服务器不可用,而且不会failover[故障转移]。
- 客观下线:检测到同一个不可用服务器的哨兵数量到达一定数量,哨兵之间对剩余可用服务器进行投票,票数多者为新主机,并通过发布订阅模式,让各哨兵监控的服务器主从切换。
3.测试
- 创建并配置哨兵配置文件sentinel.conf(与主从服务器的conf在同一目录)
#sentinel monitor 被监控名 host post 1
sentinel monitor myradis 127.0.0.1 6379 1
- 启动
[root@hadoop1 bin] redis-sentinel /usr/local/redis-6.2.4/etc/sentinel.conf
- 关闭主服务器后的哨兵响应代码如下(举例主为6379,从为6380和6381):
3673:X 10 Jul 2021 18:46:57.774 * +failover-state-send-slaveof-noone slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:57.876 * +failover-state-wait-promotion slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:57.889 # +promoted-slave slave 127.0.0.1:6381 127.0.0.1 6381 @ myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:57.889 # +failover-state-reconf-slaves master myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:57.953 * +slave-reconf-sent slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:58.904 * +slave-reconf-inprog slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:58.904 * +slave-reconf-done slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:58.979 # +failover-end master myredis 127.0.0.1 6379
3673:X 10 Jul 2021 18:46:58.979 # +switch-master myredis 127.0.0.1 6379 127.0.0.1 6381
3673:X 10 Jul 2021 18:46:58.979 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ myredis 127.0.0.1 6381
3673:X 10 Jul 2021 18:46:58.979 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381
3673:X 10 Jul 2021 18:47:28.991 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381
3673:X 10 Jul 2021 18:50:25.350 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ myredis 127.0.0.1 6381
#再次更新主机为6381
- 重新连接原来的服务器,此时它只能当新的主服务器的从机。
(三)缓存穿透和雪崩
1.缓存穿透
- 概述:许多用户请求缓存(redis)和持久层(mysql)中没有的数据,导致持久层压力过大。
2.缓存击穿
- 概述:大并发下集中访问热点,当热点出于设置的过期时间时,大并发会击穿缓存,直接访问数据库。
- 解决方案:
1.设置热点数据永不过期。缺点是会一直占用空间,而且redis空间也是有限的,考虑占满空间时会清理key则不太合适。
2.使用分布式锁,对于每一个key同时只能有一个线程去请求后端服务,但将高并发的压力转移到了分布式锁上,对分布式锁考验很大。
3.缓存雪崩
- 概述:某一时间段,缓存集中过期失效,redis宕机。即缓存过期,导致对数据的访问任务落到了数据库上,进而调用量暴增,数据库挂掉。
- 解决方案:
1.redis高可用:即搭建集群
2.限流降级:通过加锁和队列来限制读数据库写缓存的线程数量。
3.数据预热:在大并发之前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间尽量均匀。