• 面渣逆袭:Redis连环五十二问,三万字+八十图详解。


    本文目录:

    1.说说什么是Redis?

    2.Redis可以用来干什么?

    3.Redis 有哪些数据结构?

    4.Redis为什么快呢?

    5.能说一下I/O多路复用吗?

    6. Redis为什么早期选择单线程?

    7.Redis6.0使用多线程是怎么回事?

    8.Redis持久化⽅式有哪些?有什么区别?

    9.RDB 和 AOF 各自有什么优缺点?

    10.RDB和AOF如何选择?

    11.Redis的数据恢复?

    12.Redis 4.0 的混合持久化了解吗?

    13.主从复制了解吗?

    14.Redis主从有几种常见的拓扑结构?

    15.Redis的主从复制原理了解吗?

    16.说说主从数据同步的方式?

    17.主从复制存在哪些问题呢?

    18.Redis Sentinel(哨兵)了解吗?

    19.Redis Sentinel(哨兵)实现原理知道吗?

    20.领导者Sentinel节点选举了解吗?

    21.新的主节点是怎样被挑选出来的?

    22.Redis 集群了解吗?

    23.集群中数据如何分区?

    24.能说说Redis集群的原理吗?

    25.说说集群的伸缩?

    26.什么是缓存击穿、缓存穿透、缓存雪崩?

    27.能说说布隆过滤器吗?

    28.如何保证缓存和数据库数据的⼀致性?

    29.如何保证本地缓存和分布式缓存的一致?

    30.怎么处理热key?

    31.缓存预热怎么做呢?

    32.热点key重建?问题?解决?

    33.无底洞问题吗?如何解决?

    34.Redis报内存不足怎么处理?

    35.Redis的过期数据回收策略有哪些?

    36.Redis有哪些内存溢出控制/内存淘汰策略?

    37.Redis阻塞?怎么解决?

    38.大key问题了解吗?

    39.Redis常见性能问题和解决方案?

    40.使用Redis 如何实现异步队列?

    41.Redis 如何实现延时队列?

    42.Redis 支持事务吗?

    43.Redis和Lua脚本的使用了解吗?

    44.Redis的管道了解吗?

    45.Redis实现分布式锁了解吗?

    46.说说Redis底层数据结构?

    47.Redis 的 SDS 和 C 中字符串相比有什么优势?

    48.字典是如何实现的?Rehash 了解吗?

    49.跳跃表是如何实现的?原理?

    50.压缩列表了解吗?

    51.快速列表 quicklist 了解吗?

    52.假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?

    正文:

    基础

    1.说说什么是Redis?

    Redis图标

    Redis是一种基于键值对(key-value)的NoSQL数据库。

    比一般键值对数据库强大的地方,Redis中的value支持string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、 HyperLogLog、GEO(地理信息定位)等多种数据结构,因此 Redis可以满足很多的应用场景。

    而且因为Redis会将所有数据都存放在内存中,所以它的读写性能非常出色。

    不仅如此,Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者机器故障的时候,内存中的数据不会“丢失”。

    除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。

    总之,Redis是一款强大的性能利器。

    2.Redis可以用来干什么?

    Redis

    1. 缓存

      这是Redis应用最广泛地方,基本所有的Web应用都会使用Redis作为缓存,来降低数据源压力,提高响应速度。

    2. 计数器 Redis天然支持计数功能,而且计数性能非常好,可以用来记录浏览量、点赞量等等。

    3. 排行榜 Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建各种排行榜系统。

    4. 社交网络 赞/踩、粉丝、共同好友/喜好、推送、下拉刷新。

    5. 消息队列 Redis提供了发布订阅功能和阻塞队列的功能,可以满足一般消息队列功能。

    6. 分布式锁 分布式环境下,利用Redis实现分布式锁,也是Redis常见的应用。

     

    Redis的应用一般会结合项目去问,以一个电商项目的用户服务为例:

    • Token存储:用户登录成功之后,使用Redis存储Token

    • 登录失败次数计数:使用Redis计数,登录失败超过一定次数,锁定账号

    • 地址缓存:对省市区数据的缓存

    • 分布式锁:分布式环境下登录、注册等操作加分布式锁

    • ……

    3.Redis 有哪些数据结构?

     

    Redis有五种基本数据结构。

    string

    字符串最基础的数据结构。字符串类型的值实际可以是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能超过512MB。

    字符串主要有以下几个典型使用场景:

    • 缓存功能

    • 计数

    • 共享Session

    • 限速

    hash

    哈希类型是指键值本身又是一个键值对结构。

    哈希主要有以下典型应用场景:

    • 缓存用户信息

    • 缓存对象

    list

    列表(list)类型是用来存储多个有序的字符串。列表是一种比较灵活的数据结构,它可以充当栈和队列的角色

    列表主要有以下几种使用场景:

    • 消息队列

    • 文章列表

    set

    集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的。

    集合主要有如下使用场景:

    • 标签(tag)

    • 共同关注

    sorted set

    有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个权重(score)作为排序的依据。

    有序集合主要应用场景:

    • 用户点赞统计

    • 用户排序

    4.Redis为什么快呢?

    Redis的速度⾮常的快,单机的Redis就可以⽀撑每秒十几万的并发,相对于MySQL来说,性能是MySQL的⼏⼗倍。速度快的原因主要有⼏点:

    1. 完全基于内存操作

    2. 使⽤单线程,避免了线程切换和竞态产生的消耗

    3. 基于⾮阻塞的IO多路复⽤机制

    4. C语⾔实现,优化过的数据结构,基于⼏种基础的数据结构,redis做了⼤量的优化,性能极⾼

     

    5.能说一下I/O多路复用吗?

    引用知乎上一个高赞的回答来解释什么是I/O多路复用。假设你是一个老师,让30个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

    • 第一种选择:按顺序逐个检查,先检查A,然后是B,之后是C、D。。。这中间如果有一个学生卡住,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。

    • 第二种选择:你创建30个分身,每个分身检查一个学生的答案是否正确。这种类似于为每一个用户创建一个进程或者- 线程处理连接。

    • 第三种选择,你站在讲台上等,谁解答完谁举手。这时C、D举手,表示他们解答问题完毕,你下去依次检查C、D的答案,然后继续回到讲台上等。此时E、A又举手,然后去处理E和A。

    第一种就是阻塞IO模型,第三种就是I/O复用模型。

    多路复用模型

    Linux系统有三种方式实现IO多路复用:select、poll和epoll。

    例如epoll方式是将用户socket对应的fd注册进epoll,然后epoll帮你监听哪些socket上有消息到达,这样就避免了大量的无用操作。此时的socket应该采用非阻塞模式。

    这样,整个过程只在进行select、poll、epoll这些调用的时候才会阻塞,收发客户消息是不会阻塞的,整个进程或者线程就被充分利用起来,这就是事件驱动,所谓的reactor模式。

    6. Redis为什么早期选择单线程?

    官方解释:https://redis.io/topics/faq

    官方FAQ表示,因为Redis是基于内存的操作,CPU成为Redis的瓶颈的情况很少见,Redis的瓶颈最有可能是内存的大小或者网络限制。

    如果想要最大程度利用CPU,可以在一台机器上启动多个Redis实例。

    PS:网上有这样的回答,吐槽官方的解释有些敷衍,其实就是历史原因,开发者嫌多线程麻烦,后来这个CPU的利用问题就被抛给了使用者。

    同时FAQ里还提到了, Redis 4.0 之后开始变成多线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 Key 的删除等等。

    7.Redis6.0使用多线程是怎么回事?

    Redis不是说用单线程的吗?怎么6.0成了多线程的?

    Redis6.0的多线程是用多线程来处理数据的读写和协议解析,但是Redis执行命令还是单线程的。

     

    这样做的⽬的是因为Redis的性能瓶颈在于⽹络IO⽽⾮CPU,使⽤多线程能提升IO读写的效率,从⽽整体提⾼Redis的性能。

    持久化

    8.Redis持久化⽅式有哪些?有什么区别?

    Redis持久化⽅案分为RDB和AOF两种。

     

    RDB

    RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发和自动触发。

    RDB⽂件是⼀个压缩的⼆进制⽂件,通过它可以还原某个时刻数据库的状态。由于RDB⽂件是保存在硬盘上的,所以即使Redis崩溃或者退出,只要RDB⽂件存在,就可以⽤它来恢复还原数据库的状态。

    手动触发分别对应save和bgsave命令:

     

    • save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,线上环境不建议使用。

    • bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。

    以下场景会自动触发RDB持久化:

    • 使用save相关配置,如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。

    • 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点

    • 执行debug reload命令重新加载Redis时,也会自动触发save操作

    • 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave。

    AOF

    AOF(append only file)持久化:以独立日志的方式记录每次写命令, 重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

    AOF的工作流程操作:命令写入 (append)、文件同步(sync)、文件重写(rewrite)、重启加载 (load)

     

    流程如下:

    1)所有的写入命令会追加到aof_buf(缓冲区)中。

    2)AOF缓冲区根据对应的策略向硬盘做同步操作。

    3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩 的目的。

    4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

    .............................


    ....博主太懒了字数太多了,不想写了....文章已经做成PDF,有需要的朋友可以私信我免费获取!

     

  • 相关阅读:
    基于Spring Boot+Vue的宠物服务管理系统-计算机毕业设计
    前端工程化精讲第十七课 部署初探:为什么一般不在开发环境下部署代码?
    C语言程序的编译(预处理)概述 —— 上
    vue3自定义全局Loading
    4. 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识wrk、wrk2
    vue:find查找函数实际开发的使用
    Oracle(17)Managing Roles
    学习嵌入式可以胜任哪一些行业?
    XStream常用注解学习
    【Pygame实战】飞机射击大作:宇宙激战一触即发...这款超经典的射击游戏也该拿出来重启了~
  • 原文地址:https://blog.csdn.net/weixin_70730532/article/details/125584184