Redis全面梳理

2020-03-27  本文已影响0人  雨后桥前

一、什么是Redis:

Redis是一款高速缓存数据库,使用C语言编写,是key-value存储系统(键值存储系统);支持多种数据类型,如:string、list、set、zset、hash。可用于缓存、事件发布或订阅、高速队列等场景。基于内存并可做持久化处理

二、Redis常见数据类型

三、Redis持久化(重启恢复数据 AOF优先于RDB)

1、RDB快照:保存某个时间点的完整数据快照

自动备份 :save seconds number(多久至少有多少个key发生改变)

RDB备份规则.png

手动备份 :save 或 bgsave

2、AOF:增量保存操作记录(append到文件末尾)

自动备份:
开启aof备份: appendonly yes

AOF备份规则.png

手动备份:bgwriteaof

AOF重写规则:
当aof文件达到一定大小:auto-aof-rewrite-min-size 64mb 达到64M重写
当aof文件大小增大百分比:auto-aof-rewrite-percentage 100 增达达到100%

四、主从同步

Redis主从复制原理总结

1. 环境搭建(同一台机器)复制两份redis.conf配置文件 并修改如下项 redis6380.conf 和 redis6381.conf
配置文件列表.png
port 6380    #当前Redis使用端口号
pidfile /var/run/redis/redis6380.pid  #进程文件
logfile /usr/local/redis/var/redis6380.log  #日志文件
dbfilename dump6381.rdb  #RDB持久化
replicaof 127.0.0.1 6379  #主Redis地址和端口

如果主Redis如果需要密码 
masterauth <master-password>  
2.启动redis6380和redis6381服务
redis-server ./redis6380.conf
redis-server ./redis6381.conf
3.查看主从服务信息(命令行中输入info )
info   
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
info
# Replication
role:master
connected_slaves:2  #连接的从Redis数量
slave0:ip=127.0.0.1,port=6380,state=online,offset=15463,lag=0  #从Redis 地址 端口 状态 信息
slave1:ip=127.0.0.1,port=6381,state=online,offset=15463,lag=0

四、Redis Sentinel(哨兵)架构下的高可用

参考帖子一
参考帖子二

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

1. 配置Sentinel (新建配置文件sentinel.conf 并写入以下内容)
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
2. 启动模拟环境
#启动Redis
redis-server ./redis.conf   #端口6379默认master
redis-server ./redis6380.conf  #端口6380
redis-server ./redis6381.conf  #端口6381
redis-server ./redis6382.conf  #端口6382
#启动sentinel
redis-sentinel ./sentinel.conf
image.png
3. 模拟master 6379宕机情况
shutdown
image.png

四、Redis cluster集群

五、内存淘汰策略

1.最大内存设置
maxmemory 1048576
1.选择策略
# volatile-lru -> 从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
# allkeys-lru -> 从数据集中挑选最近最少使用的数据淘汰
# volatile-lfu ->从已设置过期时间的数据集挑选使用频率最低的数据淘汰。
# allkeys-lfu -> 从数据集中挑选使用频率最低的数据淘汰
# volatile-random -> 从已设置过期时间的数据集中任意选择数据淘汰。
# allkeys-random ->从数据集中任意选择数据淘汰
# volatile-ttl -> 从已设置过期时间的数据集中挑选将要过期的数据淘汰。
# noeviction -> 默认策略 不淘汰数据

五、Redis的单线程及其优点(处理每秒几十万的请求)

1. Redis的高并发和快速原因
2. 为什么Redis是单线程的

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了

Redis的数据结构并不全是简单的Key-Value,还有list,hash等复杂的结构,这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在hash当中添加或者删除
一个对象。这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加。
总之,在单线程的情况下,就不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗。

单线程的威力实际上非常强大,每核心效率也非常高,多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的。
所以单线程、多进程的集群不失为一个时髦的解决方案。

采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU。
但是如果CPU成为Redis瓶颈,或者不想让服务器其他CUP核闲置,那怎么办?
可以考虑多起几个Redis进程,Redis是key-value数据库,不是关系数据库,数据之间没有约束。只要客户端分清哪些key放在哪个Redis进程上就可以了。

Redis是纯内存数据库,一般都是简单的存取操作,线程占用的时间很多,时间的花费主要集中在IO上,所以读取速度快。
再说一下IO,Redis使用的是非阻塞IO,IO多路复用,使用了单线程来轮询描述符,将数据库的开、关、读、写都转换成了事件,减少了线程切换时上下文的切换和竞争。
Redis采用了单线程的模型,保证了每个操作的原子性,也减少了线程的上下文切换和竞争。
另外,数据结构也帮了不少忙,Redis全程使用hash结构,读取速度快,还有一些特殊的数据结构,对数据存储进行了优化,如压缩表,对短数据进行压缩存储,再如,跳表,使用有序的数据结构加快读取的速度。
还有一点,Redis采用自己实现的事件分离器,效率比较高,内部采用非阻塞的执行方式,吞吐能力比较大。

六、故障处理(缓存雪崩、缓存穿透、缓存击穿)

https://zhuanlan.zhihu.com/p/100706208

1、缓存穿透:在高并发下,查询一个不存在的值时,缓存不会被命中,导致大量请求直接落到数据库上,如活动系统里面查询一个不存在的活动。(1️⃣布隆过滤器解决,拦截一个一定不存在的值;2️⃣直接缓存一个NULL值
2、缓存击穿:在高并发下,对某一热点数据进行查询,但是这个时候缓存正好过期了,缓存没有命中,导致大量请求直接落到数据库上,如活动系统里面查询活动信息,但是在活动进行过程中活动缓存突然过期了。(首先get Key是否为null ,是的话,使用SETNX加锁,查库并set key,其余查询sleep(10)等待后再重新调用
3、 缓存雪崩:在高并发下,大量的缓存key在同一时间失效,导致大量的请求落到数据库上,如活动系统里面同时进行着非常多的活动,但是在某个时间点所有的活动缓存全部过期。(设定随机过期时间

解决方案

上一篇 下一篇

猜你喜欢

热点阅读