美文网首页
Redis全面梳理

Redis全面梳理

作者: 雨后桥前 | 来源:发表于2020-03-27 11:42 被阅读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 )
    • 从Redis信息
    info   
    # Replication
    role:slave
    master_host:127.0.0.1
    master_port:6379
    
    • 主Redis信息
    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的高并发和快速原因
    • redis是基于内存的,内存的读写速度非常快;
    • redis是单线程的,省去了很多上下文切换线程的时间;
    • redis使用多路复用技术,可以处理并发的连接。非阻塞IO 内部实现采用epoll,采用了epoll+自己实现的简单的事件框架。epoll中的读、写、关闭、连接都转化成了事件,然后利用epoll的多路复用特性,绝不在io上浪费一点时间。
    • 下面重点介绍单线程设计和IO多路复用核心设计快的原因。
    2. 为什么Redis是单线程的

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

    • 不需要各种锁的性能消耗

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

    • 单线程多进程集群方案

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

    • CPU消耗

    采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 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在同一时间失效,导致大量的请求落到数据库上,如活动系统里面同时进行着非常多的活动,但是在某个时间点所有的活动缓存全部过期。(设定随机过期时间

    解决方案

    • 直接缓存NULL值:当数据不存在时直接缓存NULL,时间不宜过长,60s为宜
    • 限流:常见的限流算法有滑动窗口,令牌桶算法和漏桶算法,或者直接使用队列、加锁等
    • 缓存预热:缓存命中时查看缓存有效期是否小于刷新时间,小于的话就刷新过期时间、可做到永不过期
    • 分级缓存
    • 缓存永远不过期

    相关文章

      网友评论

          本文标题:Redis全面梳理

          本文链接:https://www.haomeiwen.com/subject/hiloyhtx.html