爬梯:Redis全解析(二)

学习资源整理自:B站《狂神说》
书接上回

11、Redis配置文件详解

redis.conf以下都是默认配置

######### INCLUDES #########
# 包含,可以想properties一样包含其他配置文件
# include /path/to/local.conf
# include /path/to/other.conf
######### NETWORK ##########
# 绑定地址,可以接收请求的链接,改成 0.0.0.0 或者 * 表示通配
bind 127.0.0.1

# 保护模式,非本机访问需要将其关闭
protected-mode yes

port 6379 # 监听端口
######### GENERAL ########
# 以守护进程的方式运行,默认no,意思是是否可以后台运行redis
daemonize no

# 如果以后台方式运行,我们需要制定一个pid文件
pidfile /var/run/redis_6379.pid

# 日志级别
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably) 生产环境适用
# warning (only very important / critical messages are logged)
loglevel notice

logfile "" # 日志文件名

databases 16 # 数据库数量,默认16个

#是否显示logo,就是运行redis-server的时候那个redis logo
always-show-logo yes

########## SNAPSHOTTING  ########
# 快照 

# 持久化的执行规则,复合条件则执行一次数据持久化 .rdb .aof
# 如果900秒内,有至少1个key修改过
# 如果300秒内,有至少10个key修改过
# 如果60秒内,至少有10000个key修改过
save 900 1
save 300 10
save 60 10000

# 持久化出错,是否继续工作
stop-writes-on-bgsave-error yes

rdbcompression yes # 是否压缩rdb文件(压缩会消耗cpu资源)

rdbchecksum yes # 保存rdb文件的时候,进行错误的检查校验

dbfilename dump.rdb # rdb文件名

dir ./   # rdb文件保存的目录 

########## SECURITY #########
# 密码,默认是注释掉,没有密码的
# requirepass foobared
# 也可以通过命令修改密码:config set requirepass 123

######### CLIENTS ##########
# 最大连接数,默认不限制,指的是同时存活的redis客户端
# maxclients 10000

######## MEMORY MANAGEMENT ########
# 最大内存容量
# maxmemory <bytes>

# 内存满了之后的处理策略
# maxmemory-policy 六种方式
# 1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
# 2、allkeys-lru : 删除lru算法的key   
# 3、volatile-random:随机删除即将过期key   
# 4、allkeys-random:随机删除   
# 5、volatile-ttl : 删除即将过期的   
# 6、noeviction : 永不过期,返回错误
# maxmemory-policy noeviction

####### APPEND ONLY MODE #######
# aof
# 默认不开启aof模式,默认使用rdb模式
appendonly no    
    
# aof持久化文件名
appendfilename "appendonly.aof"
    
# aof同步模式 
# appendfsync always  # 每次修改都会 sync,比较消耗性能
appendfsync everysec  # 每秒执行一次sync,可能会丢失1秒的数据
# appendfsync no # 不执行 sync,操作系统自己同步数据

12、Redis持久化

概念

Redis是内存数据库,数据属于断电既失的情况,所以需要持久化的能力。

redis有两种持久化策略 rdb 和 aof,默认使用rdb模式。

触发机制:

1、save规则,满足则执行rdb持久化

2、执行flushall

3、退出redis

数据恢复:

当redis启动的时候,会自动检查redis.conf中配置的持久化规则,去寻找是否有对应的持久化文件,如果有则会回复文件中的数据。

rdb

redis database

在指定持久化条件符合时,将内存中的数据集写入磁盘中。

redis会创建一个fork子进程来进行持久化操作:

1、首先将数据写入一个临时文件中;

2、等到全部数据都写入临时文件后,再用这个临时的rdb文件替代上一次持久化的rdb文件,成为正式rdb文件。

在整个持久化过程中,全部io操作都由fork进程完成,确保了主进程的高性能。

在这里插入图片描述

redis.conf

dbfilename dump.rdb # rdb文件名
dir ./   # rdb文件保存的目录 

优点:高性能、适合大规模恢复数据

缺点:可能会丢失最后一次持久化的数据(持久化过程中宕机等情况)、fork进程会占用一定的系统资源

aof

append only file 将命令追加到文件

aof策略是指,将每一条写指令以日志的形式存入aof文件,在需要恢复时redis会将aof文件中的写指令逐行执行

aof文件修复:

如果aof文件遭到破坏,aof模式的redis将无法启动。使用redis-check-aof工具修复:

redis-check-aof --fix appendonly.aof

在这里插入图片描述

redis.conf

##### APPEND ONLY MODE #####
# 默认不开启,修改为yes重启生效
appendonly no
appendfilename "appendonly.aof"

# appendfsync always
appendfsync everysec
# appendfsync no

# 是否不需要重写aof文件
no-appendfsync-on-rewrite no

# 当aof文记达到64兆的100%时,重写一个新的文件来继续存储指令
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

优点

1、数据的完整性会更好

2、最多丢失1秒的数据

3、不需要同步则不需要fork进程周期进行持久化

缺点

1、aof的文件远大于rdb的文件大小

2、数据恢复的速度慢于rdb

持久化总结扩展

  1. RDB持久化方式能够在指定的时间间隔内对数据进行快照存储
  2. AOF持久化方式记录每次对服务器的写操作,当服务器重启的时候会重新执行这些命令来恢复原始数据,AOF命令以Redis协议追加保存命令到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大;
  3. 制作缓存,如果你只希望你的数据在服务器运行的时候存在,你也可以不做任何持久化
  4. 同时开启两种缓存的方式
    • 在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的更完整;
    • RDB的数据不实时,同事使用两者时服务器重启也只会找AOF文件,即便如此,也不是说仅仅只开启AOF模式就可以,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不能保证AOF不会出现语句错误,留一个后手;
  5. 性能建议
    • 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次即可,只保留900 1的规则;
    • 如果开启AOF,好处是在恶劣情况下也只会丢失不超过两秒的数据,启动脚本较简单只load AOF文件就可以,代价是:1.带来持续的IO 2、AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成阻塞几乎是不可避免的,所以只要硬盘大小允许,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认为64m太小了,可以设置到5G以上,默认超过原始大小100%时重写可以改到适当值;
    • 如果不启动AOF,仅靠Master-Slave Replication 实现 高可用也可以,能节省大部分IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave同事崩掉,会丢失十几分钟的数据,启动脚本也要比较两个Master/Slave中的RDB文件,载入较新的那个(微博使用这种架构)。

14、Redis发布订阅

引用菜鸟资料
在这里插入图片描述
订阅/发布消息图
在这里插入图片描述

演示

订阅端:

127.0.0.1:6379> subscribe ssxChennel
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "ssxChennel"
3) (integer) 1
#进入等待阶段,等待频道消息推送
1) "message" 	#消息
2) "ssxChennel" #频道名
3) "helloCust" 	#消息内容

发送端:

127.0.0.1:6379> publish ssxChennel helloCust
(integer) 1

应用场景

  1. 实时消息系统

  2. 实时聊天(频道当作聊天室,将信息回显给聊天的人)

  3. 订阅,关注系统

    稍微复杂的场景使用消息队列实现。

15、Redis主从复制

概念

主从复制是指将一台Redis服务器的数据,复制到其它的Redis服务器。前者称为主节点(Master/Leader),后者称为从节点(Slave/Follower)。数据的复制是单向的,只能由主节点到从节点(主从复制、读写分离)Master以写为主、Slave以读为主。

PS:默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有),而一个从节点只能由一个主节点。

主从复制的作用主要包括:

  1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的数据冗余方式;
  2. 故障恢复:当主节点出问题时,可以由从节点提供服务,实现快速的故障恢复(服务冗余);
  3. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载;一般系统是读的压力更大可以通过多个从节点分担“读”的压力;
  4. 高可用:主从复制还是哨兵和集群能够实现的基础,因此说主从复制是Redis高可用的基础。

在这里插入图片描述

一般生产环境是不可以使用单台Redis;

环境配置

默认情况下,每台Redis服务器都是主节点

127.0.0.1:6379> info replication
# Replication
role:master #主节点
connected_slaves:0
master_replid:d1ca96e10d765ebb85d9db44475211bade81534d
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

配置集群:

三份配置文件:实例:6379 6380 6381

  1. 端口:port 6379

  2. 后台服务:daemonize yes

  3. pid文件 :pidfile /var/run/redis_6379.pid

  4. rdb文件:dbfilename dump.rdb

  5. 日志文件:logfile “6379.log”

  6. 分别启动三个redis
    在这里插入图片描述

集群配置:一主二从

让从机去认老大
在这里插入图片描述

使用命令配置主从集群

配置6380:

127.0.0.1:6380> slaveof 127.0.0.1 6379	#配置主机的host和port  (我使用localhost能连接成功,但主机没找到从机....)
OK
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:2
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:d507237df1352cd264dfe399b439c2872dca4977
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0

主机6379:

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=14,lag=1
master_replid:d507237df1352cd264dfe399b439c2872dca4977
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:14
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:14

一般生产环境直接在配置文件中配置,永久配置

# replicaof <masterip> <masterport>
# masterauth <master-password>

主写 从读

#主机写入
127.0.0.1:6379> set key1 v1
OK

#从机读取
127.0.0.1:6380> get key1
"v1"
127.0.0.1:6380> set key2 v2
(error) READONLY You can't write against a read only replica. #从机不能进行写操作

主机宕机重连

127.0.0.1:6379> shutdown
not connected> exit

此时关闭了主机
在这里插入图片描述
然后主机重启 设值

[root@localhost redis-5.0.8]# src/redis-server redis.conf
[root@localhost redis-5.0.8]# src/redis-cli -p 6379
127.0.0.1:6379> set key2 v2
OK

从机读取值

127.0.0.1:6380> get key2  
"v2"   #还是可以读取到,意味着恢复了主从链接关系

从机宕机重连

如果使用命令配置的主从关系,从机重启会失去关联主机(重启不能恢复主从结构)

但如果再使用命令关联到主机 slaveof,此时会将主机中的数据全部恢复过来从机。

复制原理

Slave启动成功连接到Master后会发送一个sync同步命令。

Master接到命令后,启动后台存盘进程,收集所有接收到的写命令,在后台进程执行完毕之后,Master将传送整个文件到Slave完成一次数据同步;

官方名词:

  • 全量复制:Slave服务器接收到数据文件后,将其存盘并全数加载到内存中;
  • 增量复制:Master在接收到写命令时,依次将命令发送给Slave完成同步;

只有Slave重新连接到Master,就会完成一次全量复制。

集群配置:链路集群

这种模式下,当Master宕机之后,需要手动执行命令让Slave1成为老大:

slaveof on one

此时如果Master回来了,需要手动配置集群结构。
在这里插入图片描述

16、Redis哨兵模式

自动选取老大

概述

主从切换技术的方法是:当主服务器宕机后,手动把一台从服务器切换为主服务器,需要人工干预,耗时费力并且会造成一段时间内服务不可用情况。这不是一种推荐的方法,更多时候我们优先考虑哨兵模式。Redis2.8开始正式提供Sentinel(哨兵)架构来解决这个问题。

谋朝篡位自动版,能够后台监控主机是否故障,如果故障了将根据投票决定自动将一台从机转换为主机

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程。进程原理:哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。

单哨兵模式

在这里插入图片描述

多哨兵模式

在这里插入图片描述

  1. 当主服务器宕机后,假设哨兵1先检测到这个结果,此时这个主服务会被判定为“主观下线”,不会立刻进行failover(故障转移)操作。
  2. 当另外的哨兵都检测到主服务器宕机并且数量达到一定值后,那么哨兵之间就会进行一次投票,投票的行为由其中一台哨兵发起,即进行failover操作。
  3. 切换成功后,会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机操作,这个过程成为“客观下线”。

实操

目前集群结构为:一主二从

  1. 配置哨兵文件 sentinel.conf
#sentinel monitor 监听名 host port 票数
sentinel monitor myredis 127.0.0.1 6379 2

后面的票数代表主机挂了之后,Slave投票让谁成为主机,票数多的成为主机。

  1. 启动哨兵进程
    在这里插入图片描述
    当主机宕机,一定时间后会由哨兵进行选举另外一台作为主机。

优点

  1. 哨兵集群,基于主从复制模式,所有的主从配置优点
  2. 主从可以自动切换,故障自动转移,Redis实现高可用
  3. 从手动模式的主从模式升级,更加健壮实时

缺点

  1. Redis不好进行在线扩容,集群容量一旦达到上限后,在线扩容十分麻烦
  2. 实现哨兵模式的全套配置较为麻烦

哨兵模式全套配置:

bind 172.31.11.235
port 26380
daemonize yes
logfile "/usr/local/redis-4.0.9/sentinel.log.26380"

#master1
# 哨兵监控这个master,在至少1个哨兵实例都认为master down后把master标记为odown
sentinel monitor master1 172.31.11.235 6380 1#多少毫秒后,sentinel 认定redis master 服务器已掉线sentinel down-after-milliseconds master1 5000
# 若sentinel在该配置值内未能完成failover操作(即故障时master/slave自动切换),则认为本次failover失败
sentinel failover-timeout master1 10000
#sentinel can-failover master1 yes
sentinel parallel-syncs master1 2
# Generated by CONFIG REWRITE
dir "/usr/local/redis-4.0.9"
sentinel auth-pass master1 xxxxx

17、Redis缓存穿透、击穿和雪崩

Redis缓存的使用极大的提升了性能和效率,特别是数据查询方面。但是也带来了一些问题,其中最致命的是数据一致性问题,从严格意义上讲这个问题无解。如果对数据一致性要求较高,那么就不能使用缓存。

另外一些典型问题如:缓存穿透、缓存雪崩和缓存击穿。

缓存穿透

(某类绕过缓存查询数据库的数据)

缓存穿透的意思是,当用户想要查询一个数据,然后Redis中并没有,于是缓存没有命中,那么就会进入持久层中去数据库查,发现也没有,于是本次查询失败。

然后当这类查询被无数次执行时(恶意攻击、秒杀等),一直无法存入缓存,一直向数据库进行查询,则会造成数据库被攻击的现象,这就叫做 缓存击穿。
在这里插入图片描述

布隆过滤器

布隆过滤器是一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询攻击。
在这里插入图片描述

缓存空对象

当存储层不命中后,即使返回的空对象也将其缓存起来,同时设置一个过期时间,之后再访问这个数据会从缓存中获取,保护了后端数据源
在这里插入图片描述
存在两个问题:

  1. 如果空值被存储存储起来,也意味着使用了更多的内存空间;
  2. 虽然对空值设置了过期时间,还是会存在缓存层和存储层会有一段时间数据不一致问题,此时业务对一致性要求较高时则会造成不必要的影响。

缓存击穿

(某个热点缓存持续高并发查询)

指的是一个key非常热门,一直在被大并发集中查询,然后当这个key瞬间过期失效时,持续的大并发就会穿透缓存,直接冲击到数据库(类似于一堵墙,在一个空被穿出一个洞)

设置热点数据不过期

从缓存层面来看,没有设置过期时间,所以不会出现热点key过期问题,避免了缓存击穿

加互斥锁

分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其它线程没有获得分布式锁的权限不能去查询。这种实现方式将高并发的压力转移到分布式锁上,因此对分布式锁的考验较大。

缓存雪崩

指的是缓存在某一个时间点,集体失效。(Redis宕机、集体过期)

比如:双十一的时候,热门商品被放入缓存中,过期设置1小时,那么凌晨一点时,缓存集体过期,那么就会对数据库造成一个压力波峰,极有可能将持久层冲垮;
在这里插入图片描述
集中过期还不是非常危险,更为致命的是缓存服务器某个节点宕机断网,将全部压力直接卸到持久层上。

Redis高可用

redis集群,当一台挂了还会有别的redis顶上。(异地多活)

限流降级

  • 分布式锁限流,控制只能有一个或几个线程可以访问后台;
  • 降级:临时关闭其他不紧急的服务,来为主服务让出服务器资源;

数据预热

意思是在正式启用之前,先把可能访问的数据预先访问一遍,让大部分数据先存入缓存中。

在即将发生大并发访问前,手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点分布均匀。

猜你喜欢

转载自blog.csdn.net/qq845484236/article/details/108251135