Redis主从复制架构
主从复制
主从复制架构解决数据冗余备份的问题,从节点用来同步数据。
无法解决:主节点出现故障宕机。
搭建一个一主二从。
复制3份配置文件,让3个redis服务分别加载对应的配置文件启动。
读写分离
主节点:既可以读,又可以写。
从节点:只能读,不能写。
从redis2.6版本以后,从节点默认是只读的,我们可以把从节点改成可读可写,但是无法同步。不建议从节点可读可写。
虽然说主节点宕机后,从节点无法重新建立主从架构,从节点一直在请求连接主节点。
如果主节点重新上线,从节点会自动连接到主节点,就可以正常的进行主从复制!
哨兵机制
Sentinel
Sentinel是redis的高可用性解决方案,可以有一个或多个Sentinel实例组成的Sentinel系统监视多个主服务器,以及这些主服务器属下的从服务器,并在监测到主服务器下线时,自动将下线的主服务器下的从服务器升级成主服务器。可以让普通的主从架构升级成可以自动进行故障转移的主从架构。
如果原来的主服务器有恢复运行,它会成为一个新的从服务器。
无法解决:1.单节点并发压力的问题 2.单节点内存和磁盘上线
配置哨兵,在sentinel.conf
文件中填入以下内容
sentinel monitor 被监控的数据库的名字(自己起名字) ip port 票数
当主机宕机下线后,它下属的所有的从机开始进行投票选举,当有一个台从机的票数达到设置的票数,则该从机为新的主机。
配置文件需要编译才能生效。
一般情况下,哨兵也是要搭建集群的,要有多个哨兵。
面试
穿透
Redis中本身就没有这个请求的数据。
数据库中都没有这个记录。
解决方案:
-
在redis中缓存null。
-
白名单
-
实时监控
-
key加密
击穿
某一个key过期了,该key的访问量巨大。
解决方案:
-
预先设定
-
现场调整
-
后台刷新数据
-
二级缓存
-
加锁,分布式锁
雪崩
向redis中保存数据要设置过期时间,流量很高的情况下,redis中的大量的key同时过期,大量的请求涌入数据库,数据库宕机。
解决方案:
-
给不同key设置不同的过期时间,在基本时间的基础上,添加一个随机数。
-
使用布隆过滤器。
-
让页面静态化。
-
ehcache缓存+Nginx缓存+redis缓存
-
Mysql监控
-
热点数据设置永久key
-
定期维护
-
加锁(不推荐)
Redis持久化机制
redis是用来做缓存。
持久化:数据从内存->磁盘
Redis官方提供了两种持久化机制。
-
快照(SNAPSHOT)RDB
-
AOF(Append Only File)只追加日志文件
快照
特点:这种方式可以把某一时刻所有数据存入硬盘中,Redis默认的持久化机制保存的文件是以rdb形式保存。
快照的生成方式
-
客户端指令:BGSAVE或SAVE指令
-
服务器配置自动触发
-
配置文件中的触发策略
-
关闭redis服务
-
rdb文件就是快照持久化的核心,定期备份rdb文件。
AOF持久化
保存执行的命令。把操作数据的指令保存到一个aof文件里,Redis默认是不开启AOF持久化。
需要我们手动开启AOF持久化。
AOF持久化会自动忽略读指令,只记录写指令。
日志追加频率
-
always:每个redis写的命令同步,降低redis效率。
-
everysec:每秒执行一次同步,有延迟。
-
no:由操作系统决定何时同步。
如果AOF持久化和RDB持久化同时开启,会以AOF为准。
AOF文件具备了一个自我修复的能力。
./redis-check-aof --fix appendonly.aof
AOF文件重写
# This base size is compared to the current size. If the current size is # bigger than the specified percentage, the rewrite is triggered. Also # you need to specify a minimal size for the AOF file to be rewritten, this # is useful to avoid rewriting the AOF file even if the percentage increase # is reached but it is still pretty small. # # Specify a percentage of zero in order to disable the automatic AOF # rewrite feature. auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
如果当前aof文件的大小已经比64mb大了100%,自动指定重写AOF文件的指令。
Redis事务
Redis的事务是不支持回滚的。
开启事务:
MULTI
提交事务:
EXEC
放弃事务:
DISCARD
悲观锁:顾名思义,就是很悲观,每次去拿数据的时候都会认为别人要修改,每次拿数据时都会上锁,别人想拿这个数据,就会被锁住,直到另外一方释放锁。在传统的关系型数据库中用到了很多的悲观锁,比如行锁,表锁,读锁,写锁。
乐观锁:顾名思义,就是很乐观,每次去拿数据的时候会认为别人不会修改,所以不会上锁。由于在开发中,所有的删除都是逻辑删除,都是修改操作,version版本号。当执行修改操作时,要提交的版本号必须大于当前版本号才能执行更新。
数据删除与淘汰策略
Redis中数据的特征
Redis是一种内存级数据库,所有数据都是存在内存中,内存中的数据可以通过TTL
获取器状态。
TTL
返回的值三种情况:
-
正数:代表该数据在内存中还能存活的时间
-
-1:永久有效的数据
-
-2:已经过期的数据或被删除的数据或未定义的数据
删除策略就是针对已过期数据的处理策略,已过期的数据是不是真的就立即删除了?
其实也不是,我们实际上有多种删除策略。
时效性数据的存储
所有的过期数据会存放在一块独立的存储空间,Hash结构,key就是内存地址,value是过期时间,保存了所有的key的过期描述,在最终进行过期处理的时候,对该空间的数据进行监测。
数据删除策略
目标:在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成redis性能的下降,甚至引发服务器宕机或内存泄漏。
-
1.定时删除
-
2.惰性删除
-
3.定期删除
定时删除
创建一个定时器,当key设置了过期时间,且过期时间到达时,由定时器任务立即执行对键的闪出去操作。
-
优点:节约内存,到时就删除,快速释放不必要的内存占用。
-
缺点:CPU压力很大,无论CPU此时负载量多高,占用CPU,会影响redis的响应时间。
-
总结:用CPU性能换取存储空间。
惰性删除
数据到达过期时间,不做处理。等下次访问该数据时,我们需要判断:
-
如果未过期,返回数据
-
如果过期,删除,返回不存在
-
优点:节约CPU性能,必须删除的时候才删除
-
缺点:内存压力很大,出现长期占用内存的资源
-
总结:用存取空间换取CPU性能
定期删除
其实是上两种策略的折中方案!
-
Redis启动服务器初始化的时候,读取一个配置,
server.hz
,默认是10 -
每秒中实行一次配置。
set类型和zset类型
set
特点:Set类型类似于Set集合,元素无序,不可重复。
-
sadd:为集合添加元素
-
smembers:显示集合中的所有元素,无序
-
scard:返回集合中元素的个数
-
spop:随机返回一个元素,并将元素在集合中删除
-
smove:从一个集合中向另一个集合中移动元素,必须都是set类型
-
srem:从集合中删除一个元素
-
sismember:判断一个集合中是否含有这个元素
-
srandmember:随机获取n个元素
-
sdiff:去掉第一个集合中其他集合含有的相同元素,返回一个新的结果,原有的集合中的数据不会真正删除。
-
sinter:求交集
-
sunion:求并集,求合集
zset
特点:可排序的set集合,不可以重复。
-
zadd:为集合添加元素,添加元素的同时要指定元素的分数,最终根据分数来排序。
-
zcard:返回集合元素的个数
-
zrange:按照分数的升序排列,可以选择带有score查询
-
zrevrange:按照分数的降序排列。
-
zrangebyscore:按照分数查找一个范围内的元素,可以分页。
-
zrank:返回排名
-
zrevrank:倒序排名
-
zscore:查看某一个元素的分数
-
zrem:删除某个元素
-
zincrby:给某一个特定的元素加分
hash类型
特点:value是一个map结构。key无序的
-
hset:创建一个hash
-
hget:获取一个key对应的value
-
hgetall:获取所有的k-v对
-
hdel:删除某一个k-v对
-
hexists:判断一个key是否存在
-
hkeys:获取所有的key
-
hvals:获得所有的value
-
hmset:设置多个k-v
-
hmget:获得多个key的value
-
hsetnx:设置一个不存在的k-v值
-
hincrby:为value自增
-
hincrbyfloat:为value自增,浮点数
redis远程连接
远程连接redis:
1、开放端口号
firewall-cmd --zone=public --add-port=7000/tcp --permanent firewall-cmd --zone=public --add-port=6379/tcp --permanent systemctl restart firewalld
2、配置redis允许远程连接
vim ../redis.conf
可以使用/搜索关键字
把bind改成0.0.0.0