Redis.conf配置
包含(多个配置文件集成)
网络
# bind 127.0.0.1 绑定的IP *通配
protected-mode no #是否受保护
port 6379 默认端口
通用 GENERAL general
daemonize yes #以守护进程方式运行 默认是no
supervised no 管理守护进程的,不用动
pidfile /var/run/redis_6379.pid #如果以后台方式运行,我们就需要指定一个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) :类似debug
# notice (moderately verbose, what you want in production probably) :通知:部分重要通知,仅适用于生产环境
# warning (only very important / critical messages are logged) :警告 非常关键的信息才会打印
loglevel notice
logfile "" 日志生成的文件位置名 空位标准输出
databases 16 默认数据库数量
always-show-logo no 是否显示logo
SNAPSHOTTING 快照 snapshotting
redis 是内存数据库,不持久化的话数据就会丢
持久化:在规定的时间内,执行了多少次操作,会持久化到文件 .rdb .aof
save 3600 1 如果1小时内,至少一个key进行了修改,我们就进行持久化操作
save 300 100 如果300s(5分钟)内,至少10 个key进行了修改,我们就进行持久化操作
save 60 10000 如果60s(1分钟)内,至少10000 个key进行了修改,我们就进行持久化操作
stop-writes-on-bgsave-error yes 持久化出现错误后,是否继续进行工作
rdbcompression yes 是否压缩rdb文件 压缩就会消耗CPU资源
rdbchecksum yes 保存时,是否校验rdb文件
dir ./ rdb文件保存的目录 默认当前文件下
REPLICATION 主从复制 replicatioon
# replicaof <masterip> <masterport> 配置主机ip 主机端口
# masterauth <master-password> 配置主机密码
SECURITY 安全 security
config get requirepass 获取密码指令 启动Redis后
config set requirepass "123455" 设置密码指令
auth "123455" 验证密码,获取权限
CLIENTS 客户端限制 clients
# maxclients 10000 设置能连接上Redis的最大客户端的数量
MEMORY MANAGEMENT 内存设置 memory management
# maxmemory <bytes> redis配置设置最大内存容量
# maxmemory-policy noeviction 内存达到上限之后的处理策略
移除过期的key 报错
LRU:最近最久未使用
1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)
2、allkeys-lru : 删除lru算法的key
3、volatile-random:随机删除即将过期key
4、allkeys-random:随机删除
5、volatile-ttl : 删除即将过期的
6、noeviction : 永不过期,返回错误
APPEND ONLY MODE(append only mode) AOF的设置
AOF 第二种持久化方式
appendonly no 默认不开启AOF,默认使用RDB方式持久化
appendfilename "appendonly.aof" 持久化的文件的名字
# appendfsync always 每次修改都会同步,速度慢,消耗性能
appendfsync everysec 每秒执行一次sync同步,(宕机)可能会丢失这1s的数据
# appendfsync no 不同步 这个时候操作系统自己同步数据,速度最快
Redis持久化
RDB(Redis DataBase)
在主从复制中,rdb就是在从机上面备用的,不占用主机内存,aof几乎不使用
在指定的时间间隔内将内存的数据集体写入磁盘,也就是snapshot快照
恢复时将快照文件读到内存里
Redis会单独创建一个(fork)子进程来进行持久化,会先将数据写入一个临时RDB文件中,
再用临时文件替换上次持久化完成的文件
整个过程主进程不进行任何io操作,保证了性能,如果进行大规模数据恢复,RDB和AOP都可以进行数据恢复,RDB数据恢复完整性不敏感,RDB更加高效,缺点时最后一次持久化后的数据可能丢失,默认使用的就是RDB,一般情况不需要修改这个配置
RDB保存的文件是dump.rdb
AOF保存的文件是appendonly.aof
配置快照在snapshots配置区域下
触发机制
1.save规则触发
2.执行flushall命令
3.关闭redis shutdown命令
会自动生成dump.rdb文件
如何恢复RDB文件
只要将rdb文件放在Redis启动目录下,redis启动时会自动检查dump.rdb文件恢复数据com
config get dir 查看dump.rdb文件的位置
优点:
1.父进程处理客户端请求,子进程进行持久化,效率很高
2.适合大规模数据恢复,如果服务器宕机了,不要删除rdb文件,重启自然在目录下,自动读取
缺点:
1.需要一定的时间间隔去操作
2.fork进程的时候,会占用一定的空间
3.如果redis意外宕机,最后一次的修改数据会丢失
在生产环境下,会将这个文件进行备份
AOF(Append Only File) 追加文件
AOF:以日志形式记录所有写操作,恢复时再执行一次。如果是大数据就需要写很久
aof默认是文件无限追加,大小会不断扩张
在主从复制中,rdb是备用的,在从机上使用,aof一般不使用
1.fork分支出子进程
2.根据内存中的数据子进程创建临时aof文件
3.父进程执行的命令存放在缓存中,并且写入原aof文件
4.子进程完成新aof文件通知父进程
5.父进程将缓存中的命令写入临时文件
6.父进程用临时文件替换旧aof文件并重命名
7.后面的命令都追加到新的aof文件中
开启AOF
appendonly no
#默认关闭appendonly 手动设置yes开启
appendfilename "appendonly.aof"
#默认名字
# appendfsync always
appendfsync everysec
# appendfsync no
#每次都进行修改
#每秒钟都进行修改
#不进行修改
no-appendfsync-on-rewrite no
#是否进行重写
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
#percentage重写百分比
#重写时文件最小的体积
#一般保持默认,一般只需要开启
修复AOF
用redis-check-aof修复 AOF
[root@iZ8vbgai5w4b6pa3r1mpdiZ bin]# redis-check-aof --fix appendonly.aof
修复后数据可能丢失
# appendfsync always 每次修改都会同步,速度慢,消耗性能
appendfsync everysec 每秒执行一次sync同步,(宕机)可能会丢失这1s的数据
# appendfsync no 不同步 这个时候操作系统自己同步数据,速度最快
优点:
1.每一次修改都同步,文件完整性更好
2.每秒同步一次,可能会丢失1S的数据
3.从不同步,效率是最高的
缺点:
1.相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢
2.aof运行效率比rdb慢,所以默认是rdb
重写规则说明:文件大小如果超过64MB,frok一个新的进程,来讲我们的文件进行重写
扩展
1.rdb持久化方式能够在指定的时间间隔内对数据进行快照存储
2.aof持久化方式记录每次对服务器写的操作,服务器重启时,重新执行命令来恢复原始数据,追加在文件末尾,能对aof文件进行重写,避免体积过大
3.==如果只做缓存不需要使用任何持久化==
4.同时开启两种持久化
1.redis重启时,会优先载入aof文件,来恢复原始数据,aof文件比rdb文件完整
2.rdb数据不实时,所以服务器重启也只会找aof文件,但是不推荐只用aof,推荐使用rdb备份数据库,能快速重启,而且不会有aof可能潜在的bug,以防万一
5.性能建议
1.rdb文件只做后备用途,建议只在slave(从机)上持久化rdb文件,15分钟备份一次,比如:只使用save 900 1 规则
2.使用aof,即便在最恶劣的环境下也不会丢失超过2秒的数据
1.代价:持续的io
2.AOF rewrite的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的
所以,只要硬盘允许,尽量减少rewrite的频率 重写大小默认64M,可以设到5G以上,默认超过原100%大小也可以释放更改
3.不使用aof,也可以通过Master-Slave Replication 实现高可用性也可以,能省去一大笔io,减少rewrite带来的系统波动
代价:如果Master-Slave 同时倒掉(主丛断电),会丢失十几分钟的数据,启动脚本也要比较Master-Slave中的rdb文件,选择最新的文件,载入新的,微博就是这种架构
Redis发布订阅
Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息
微信、微博、关注系统、朋友圈
Redis 客户端(一个人)可以订阅任意数量的频道
订阅消息发布图:
第一个:消息发送者 第二个:频道(队列) 第三个:消息订阅者!
使用场景:
1.实时消息系统!
2.实时聊天!
3.订阅关注系统
稍微负责的场景,就需要使用 消息中间级那MQ(KAFUKA)
Redis主从复制
一个Master有多个slave,将一台redis服务器数据,复制到其他的redis服务器,前者称为主节点(master/leader),后者称为从节点(slave、follower),数据是单向的,只能从主节点到从节点,Master以写为主,Slave以读为主 主从复制,读写分离!!80%都在读,最低配都是1主2从,哨兵模式,会选举,所以要至少2个从机
主从复制作用包括:
- -数据冗余-
- 实现了数据的热备份,是持久化之外的一种数据冗余方式
- -故障恢复-
- 主节点出现问题,从节点可以提供服务,实现快速的故障恢复,实际上是一种服务的冗余
- -负载均衡-
- 在主从复制的基础上,配合读写分离,主节点提供写服务,从节点提供读服务,写redis数据时连接主节点,读redis数据连接从节点,分担服务器负载,尤其在写少读多的场景下通过,多个从节点分担负载,可以提高redis性能
- -高可用(集群)基石-
- 哨兵、集群,能够实施的基础,主从复制时高可用的基础
为什么使用集群
- 从结构上来说,单台Redis服务器会发生单点故障,处理所有请求负载,压力较大
- 从容量上来说,单台服务器内存容量有限(就算256G)。单台Redis最大使用内存不应该超过20G
- 通常的电商网站都是一次上传吗,无数次浏览,读多写少
环境配置(单机多集群)
- 只配置从库,不用配置主库!
127.0.0.1:6379> info replication //查看当前库的信息
# Replication
role:master //默认角色 master
connected_slaves:0 //没有从机
master_failover_state:no-failover
master_replid:4d7723377ff8793e81a41cd6a57a6d7928ca6581
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
- 复制3个配置文件,然后修改对应的信息
1.端口号:port port 6381
2.pid 名字 pidfile /var/run/redis_6381.pid
3.log 文件名字 logfile "6381.log"
4. dump.rdb名字 dbfilename dump6381.rdb
查看进程信息
[root@iZ8vbgai5w4b6pa3r1mpdiZ bin]# ps -ef|grep redis
root 14516 1 0 15:58 ? 00:00:00 redis-server 127.0.0.1:6379
root 14551 1 0 15:59 ? 00:00:00 redis-server 127.0.0.1:6380
root 14591 1 0 15:59 ? 00:00:00 redis-server 127.0.0.1:6381
root 14659 13336 0 16:00 pts/6 00:00:00 grep --color=auto redis
[root@iZ8vbgai5w4b6pa3r1mpdiZ bin]#
- 一主二从
默认情况下,每一台Redis服务器都是主节点
127.0.0.1:6381> info replication 查看信息
一主(79)二从(80、81)
127.0.0.1:6380> slaveof 127.0.0.1 6379 认老大
127.0.0.1:6381> slaveof 127.0.0.1 6379
127.0.0.1:6381> info replication
# Replication
role:slave //从机
master_host:127.0.0.1
master_port:6379
主机中会显示从机的配置
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=602,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=602,lag=1
master_replid:3f9a8d15d0e7a2b3978ad8e6cfc1d8fc490b464e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:602
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:602
127.0.0.1:6379>
真实的主从配置,应该在配置文件中配置,这样的话是永久的,这里使用的命令,暂时的。
细节
主机可以设置值,从机不能设置
如果使用命令行来配置主从,这个时候重启了,就会变回主机
但只要变为从机,立马就会从主机中获取值
slave启动成功连接到master后会发送一个sync同步命令
master接到命令,启动后台的存盘进程,同时收集所接收到的用于修改数据集命令,后台执行完毕之后,
master将传送==整个数据文件到slave,并完成一次完全同步=
==专有名词==
全量复制
slave服务在接受到数据库文件数据后,将其存盘并加载到内存中
增量复制
master继续将新的所有收集到的修改命令依次传给slave,完成同步,叫增量复制,即后来增加的
只要重新连接master,一次完全同步(全量复制)将被自动执行,数据一定能在从机中看到
结构
层层链路,工作中都不会使用。。。
如果主机断开了连接,可以使用“slaveof no one” 让自己变成主机,其他的节点就可以手动连接到这个最新的主节点
就算老大节点修复了,也是光杆司令,要重新配置, 哨兵出来之后就可以自动选老大
哨兵模式
(自动选举老大的模式)
概述
主从切换的方法是,当master服务器宕机后,需要人工切换,费事,更多时候选择优先考虑是哨兵模式,redis2.8 开始正确提供sentinel(哨兵 ) 谋朝篡位自动版
哨兵能够监控后台的主机是否故障,如果出现故障,根据投票数,自动将从库专为主库
哨兵模式是一种特殊模式,首先Redis提供了哨兵命令。哨兵是一个独立的进程,作为进程,它会独立运行,原理是哨兵通过发请求,等待redis服务器响应,从而监控多个redis实例
基本模型
哨兵向每台发送信息确定主机是否存活,优点类似于springcloud的心跳检测
上图称为单机哨兵,当然单个哨兵也有宕机风险,我们可以创建多个哨兵,互相监控,形成多哨兵模式
当哨兵模式检测到master宕机,会自动将slave切换成master,通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机
多哨兵模式
- 假设master宕机,sentinel先检测到这个结果,系统并不会马上进行failover(故障转移)这个现象称为主观下线
- 当后面的哨兵也检测到主服务器不可用,sentinel之间会发起一次投票,投票的结果由随机一个sentinel发起,进行failover(故障转移)操作,
- 得到sentinel票数多的slave能成功切换为master,切换成功后,通过发布订阅模式,让各个哨兵把自己监控的服务器实现切换主机,这个过程称为客观下线
在bin目录下,有redis-sentinel(哨兵)文件
1.vim sentinel.config //创建配置文件 在lconfig文件夹中
sentinel monitor(监视) mymaster 127.0.0.1 6379 1 // 1:至少1个哨兵判断主机挂了后,执行投票机制
//# sentinel monitor <master-name> <ip> <redis-port> <quorum>
//#quorum(法定人数)至少需要<quorum>个哨兵同意的情况下,能确定处于客观关闭状态
//#(Objectively Down) state only if at least <quorum> sentinels agree.
2.启动哨兵
redis-sentinel lconfig/sentinel.config
选举机制:采用加权轮询算法
如果主机此时回来了,只能归并到新的主机下,当做从机
哨兵模式的优缺点
优点:
- 基于集群、基于主从复制,所有主从配置的优点都有
- 主从可以切换,故障可以切换,系统的可用性提高
- 哨兵模式就是主从模式的升级,手动到自动,更加健壮
缺点:
- Redis不好在线扩容,集群容量一旦达到上限,在线扩容就十分麻烦
- 哨兵模式需要很多配置
- 多哨兵,多端口配置复杂,一般也由运维来配置
哨兵模式的全部配置:
缓存穿透、击穿和雪崩
服务的高可用问题
缓存穿透(查不到)
- 在默认情况下,用户请求数据时,会先在缓存(Redis)中查找,若没找到即缓存未命中,再在数据库中进行查找,数量少可能问题不大,可是一旦大量的请求数据(例如秒杀场景)缓存都没有命中的话,就会全部转移到数据库上,造成数据库极大的压力,就有可能导致数据库崩溃。这就叫缓存穿透。
- 网络安全中也有人恶意使用这种手段进行攻击被称为洪水攻击。
解决方案
- 布隆过滤器
- 对所有可能查询的参数以Hash的形式存储,以便快速确定是否存在这个值,在控制层先进行拦截校验,校验不通过直接驳回,减轻了存储系统的查询压力。
- 缓存空对象
- 一次请求若在缓存和数据库中都没找到,就在缓存中放一个空对象用于处理后续这个请求。
- - 这样做存在两个问题:
- 如果空值都能被缓存起来,就意味着缓存中会存储很多的空键。解决这个缺陷的方式就是设置较短过期时间
- 即使对空值设置了过期时间,但是缓存层和存储层的数据还会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。
缓存击穿(查询量太大、缓存过期)
微博服务器,比如60s 过期 60.1s 把它恢复了 这0.1
- 概念
- 缓存击穿,是指一个key非常热点,在不停的扛着大并发,大并发集中对着一个点进行冲击,当在key失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,导致服务区宕机。
- 比如热搜排行上,一个热点新闻被同时大量访问就可能导致缓存击穿。
- 解决方案
-
1.设置热点数据永不过期
从缓存层面看,可以解决缓存击穿的问题
-
2.加互斥锁(分布式锁)
分布式锁:使用分布式锁。保证对于每个key,同一时间只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大。
缓存雪崩
某一个时间段,缓存集中过期失效。Redis集群宕机(停电)。
在双12零点,假设将一波商品放入缓存,时限为1小时。到凌晨1点的时候,缓存的商品就过期了,这时候对商品的查询请求,都落在了数据库上。会产生周期性的压力波峰,存储层的调用量会暴增,数据库会挂掉
双十一:防止雪崩,服务降级
解决方案:
-
redis高可用
这个思想的含义是,既然redis有可能挂掉,那我多增设几台redis,这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。(异地多活!)
-
限流降级
这个解决方案的思想是,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
-
数据预热(测试)
数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。