• Redis基础整理1.1


    概述

    redis基础知识整理

    正文

    Redis为什么要选择单线程
    1.Redis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,因此多线程并不会带来巨大的性能提升
    2.多线程回导致过多的上下文切换,带来不必要的开销
    3.引入多线程回面临线程安全问题,必然要引入线程锁,这样回导致实现复杂度增高,而且性能也会大打折扣

    IO多路复用是指利用单个线程来同时监听多个FD(File Descriptor)–文件描述符,再某个FD可读、可写时得到通知,去处理

    IO多路复用的实现方式:select、poll、epoll

    IO多路复用-select

    select执行流程
    创建fd_set集合
    设定监听对象
    执行select

    将数据拷贝到内核空间

    遍历fd_set
    没有就绪,则休眠
    等待数据就绪被唤醒或超时

    将就绪集合返回用户空间

    拷贝回用户空间,遍历找到就绪的

    在这里插入图片描述
    select模式存在的问题
    需要将整个fd_set从用户空间拷贝到内核空间,select结束还要 再次拷贝回用户空间
    select无法得知具体哪个fd就绪,需要遍历整个fd_set
    fd_set监听的fd数量不能超过1024

    IO多路复用-poll

    polldf在内核中采用链表,理论上无上限
    监听FD越多,每次遍历消耗时间也越久,性能反而会下降

    select和poll实现方案,只会通知用户进程由FD就绪,但不确定具体是哪个FD就绪,需要用户进程一个个的遍历FD确定就绪文件

    IO多路复用-epoll
    epoll是对select和epoll的改进,
    在这里插入图片描述
    epoll_create 创建epoll实例
    rb_root:红黑树
    list_head:链表

    epoll_ctl():添加fd
    将fd添加到红黑树 给fd添加ep_poll_callback回调函数,就绪了添加到list_head链表中

    epoll_wait:等待fd就绪
    events:空数组

    执行epol_wait

    检查就绪列表,有直接返回epoll_wait,否则等待

    events:接收就绪fd

    rb_root 添加所以的,设置回调函数,就绪将就绪fd到list_head ,结果将list_head–就绪拷贝会events中

    epoll_create的好处:
    基于epoll实例中的红黑树保存要监听的FD,增删查改效率都非常高,性能不会随监听的FD数量增多而下降
    每个FD只需要执行一次epoll_ctl添加到红黑树,以后每次epoll_wait无需传任何参数,无需重复拷贝FD到内核空间
    内核会将就绪的FD直接拷贝到用户空间的指定位置,用户进程无需遍历所有FD就能知道就绪的FD是谁

    缓存穿透、缓存雪崩、缓存击穿

    缓存穿透是指客户端请求的数据再缓存和数据库中都不存在,这些请求都打到数据库

    常见解决方案
    布隆过滤器

    在这里插入图片描述

    缓存雪崩是指某一时段大量的缓存key同时失效或者Redis服务宕机,导致大量请求打到数据库,导致数据库压力激增

    解决方案:
    Key的同时失效问题(给不同的Key添加随机值) 缓存预热
    Redis宕机(利用集群–主从、哨兵机制–主从中选一个,提高服务的可用性)
    给缓存业务添加降级、限流(sentinel、)

    缓存击穿也叫热点key问题,就说一个被高并发访问的key突然失效了,大量请求在瞬间打到数据库带来巨大压力

    解决方案:
    互斥锁
    逻辑过期(不给设置逻辑过期)

    Redis的过期策略有哪些?

    惰性清理:每次查找key时判断是否过期,如果过期则删除

    定期清理:定期抽样部分key,判断是否过期,如果过期则删除 不断的循环遍历数据库中的每一个key,每次抽一部分,过期清理,随着时间推进,多起的迟早被删除

    定期清理的两种模式:
    SLOW模式执行频率默认为10,每次不超过25ms
    FAST模式执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms

    Redis有哪些内存淘汰策略?

    任何命令执行之前,检查内存是否够,不够根据内存淘汰策略对key进行内存淘汰

    8种淘汰策略
    noeviction:不淘汰任何key,但是内存满时不允许写入性数据,默认就是这种策略
    volatitle-ttl:对设置了过期时间的key进行淘汰,比较key的剩余TTL值,TTL越小越先被淘汰 存活时间小的将被淘汰
    allkeys-random:对全体key,随机进行淘汰,页就是最直接从db->dict中随机挑选 再过期时间里的key你挑
    volatile-random:对设置了TTL的key,随机淘汰。也就是从设置了过期时间的key进行淘汰
    allkeys-lru:对全体key,基于LRU算法进行淘汰
    volatile-lru:对设置了过期时间的KEY基于最少最近使用进行淘汰
    allkeys-lfu:对全体key,基于最少频率使用进行淘汰
    volatile-lfu:对设置了TTL的key,基于最少频率使用算法进行淘汰

    LRU(Least Recently Used),最少最近使用。用当前时间减去最后一次访问时间,值越大则淘汰优先级越高 太长时间没用,
    LFU(Least Frequently Used),最少频率使用,统计每个key的访问频率,值越小淘汰优先级越高 访问频率低 优先淘汰

    在配置文件中配置内存淘汰策略

  • 相关阅读:
    案例驱动,手把手教你学PyTorch(一)
    uniapp制作——交友盲盒
    tkinter-TinUI-xml实战(7)PDF分页与合并
    Spring Security 自定义资源服务器实践
    Linux编译安装libmodbus库
    Tomcat HTTP Status 404 tomcat 404问题解决
    系列五、线程间通信
    全套3D游戏建模自学资料
    Multisim14.0仿真(十四)电压跟随器
    Django报错:RuntimeError at /home/ 解决办法
  • 原文地址:https://blog.csdn.net/weixin_40598838/article/details/125438824