Redis拾遗

本文深入解析Redis与Memcache区别,探讨Redis高速运行原理,介绍其数据类型及底层实现,讲解如何使用Redis进行分布式锁、异步队列操作,以及RDB、AOF持久化策略,最后阐述Redis的同步机制与Sentinel功能。
  • 本文整理自剑指Java面试-Offer直通车

  • 主流应用架构

  • Memcache和Redis的区别

    • Memcache

      • 代码层次类似Hash

      • 支持简单数据类型

      • 不支持数据持久化存储

      • 不支持主从

      • 不支持分片

    • Redis

      • 数据类型丰富

      • 支持数据磁盘持久化存储

      • 支持主从

      • 支持分片(Redis3.0+) 

  • 为什么Redis能这么快

    • 完全基于内存,绝大部分请求是纯粹的内存啊哦做,执行效率高

    • 数据结构简单,对数据操作也简单

    • 采用单线程,单线程也能处理高并发请求,想多核也可启动多实例

    • 使用多路I/O复用模型,非阻塞IO

  • 多路I/O复用模型

    • FD

      • File Descriptor,文件描述符

      • 一个打开的文件通过为疑似的描述符进行引用,该描述符是打开文件的元数据到文件本身的映射

    • 传统的阻塞I/O模型

    • epoll/kqueue/evport/select

      • Redis根据不同的操作系统,选择不同的多路复用函数

      • 优先选择时间复杂度为O(1)的I/O多路复用函数作为底层实现

      • 以时间复杂度为O(n)的select作为保底

      • 基于react设计模式监听I/O事件

      • Select系统调用

  • 说说你用过的Redis的数据类型

    • String

      • 最基本的数据类型

      • 二进制安全

        • 可以包含任何数据,比如JPG图片或者序列化的对象

      • 最大512M

    • Hash

      • String元素组成的字典,适合用于存储对象

    • List

      • 列表,按照String元素插入顺序排序

      • 大约能存储40亿个成员

    • Set

      • String元素组成的无需集合,通过哈希表实现,不允许重复

    • Sorted Set

      • 通过分数来为集合中的成员进行从小到大的排序

    • HyperLogLog

      • 用于计数

    • Geo

      • 支持存储地理位置信息

    • 底层数据类型基础

      • 简单动态字符串

      • 链表

      • 字典

      • 跳跃表

      • 整数集合

      • 压缩列表

      • 对象

  • 从海量Key里查询出某一固定前缀的Key

    • KEYS pattern

      • 查找所有复核给定模式pattern的key

      • 一次性返回左右匹配的key

      • 键的数量过大会导致服务器卡顿

    • SCAN cursor [MATCH pattern] [COUNT count]

      • 基于游标的迭代器,需要基于上一次的游标延续之前的迭代过程

      • 以0作为游标开始一次新的迭代,知道命令返回游标0完成一次遍历

      • 不保证每次执行都返回某个给定数量的元素(甚至会返回0个,只要游标不为0,就不应该结束迭代),支持模糊查询

      • 一次返回的数量不可控,只能是大概率复核count参数 

      • 有可能会返回重复Key

  • 如何通过Redis实现分布式锁

    • 分布式锁需要解决的问题

      • 互斥性

        • 只能有一个客户端获得锁

      • 安全性

        • 锁只能被持有锁的客户端删除

      • 死锁

        • 获取锁的客户端未能释放锁,其他客户端再也无法获取该锁

      • 容错

        • 当部分Redis节点宕机时,客户端应依然能够获取锁

    • SETNX key value

      • 如果key不存在,则创建并赋值

      • 时间复杂度,O(1)

      • 设置成功返回1,设置失败返回0

      • SETNX设置的key将长期存在,分开设置EXPIRE无法满足原子性

    • SET key value [EX seconds] [PX milliseconds] [NX|XX]

        • EX seconds,设置键的过期时间为seconds秒

        • PX millisecond,设置键的过期时间为milliseconds毫秒

        • NX,只在键不存在时,才对键进行设置操作

        • XX,只在键已存在时,才对键进行设置操作

        • SET操作完成时,返回OK,否则返回nil

    • 大量的key同时过期的注意事项

      • 集中过期,由于清除大量的key很耗时,会出现短暂的卡顿现象

      • 解决方法,在key的过期时间上加上一个随机值

  • 如何使用Redis做异步队列

    • 使用List作为队列,RPUSH生产消息,LPOP消费消息

      • 缺点,没有等待队列里有值就直接消费

      • 弥补,可以通过在应用层引入Sleep机制去调用LPOP重试

    • BLPOP key [key...] timeout

      • 阻塞直到队列有消息或者超时

      • 缺点,只能供一个消费者消费

    • 使用pub/sub,主题订阅者模式

      • 发送者pub发送消息,订阅者sub接收消息

      • 订阅者可以订阅任意数量的频道

      • subscribe 频道

      • publish 频道 消息

      • 缺点,消息发布是无状态的,无法保证可达,若发送消息时,没有消费者在线,消息就丢失了

  • Redis如何做持久化

    • RDB(快照)持久化,保存某个时间点的全量数据快照

      • 优点,全量数据快照,文件小,恢复快

      • 缺点,无法保存最近一次快照之后的数据

      • SAVE命令

        • 在主线程中保存快照,阻塞Redis的服务器进程,知道RDB文件被创建完毕

      • BGSAVE命令

        • Fork一个子进程来创建RDB文件,不阻塞服务器进程

      • LASTSAVE

        • 返回上次执行save的时间

        • BGSAVE保存成功后,才会更新此时间

      • 自动化出发RDB持久化

        • redis.conf

          • save 900 1

            • 900秒内有1条写入指令,则产生一次快照

          • save 300 10

            • 300秒内有10条写入指令,则产生一次快照

          • save 60 10000

            • 60秒内有10000条写入指令,则产生一次快照

          • stop-writes-on-bgsave-error yes

            • 当备份进程出错时,主进程停止接受写入操作

          • rdbcompression yes

            • 在备份时,将rdb压缩后再保存,建议设置为no

          • save ""

            • 禁用rdb配置

        • 主从复制时,主节点自动触发

        • 执行Debug Reload时

        • 执行Shutdown且没有开启AOF持久化

      • 缺点

        • 内存数据的全量同步,数据量大会由于I/O而严重影响性能

        • 可能会因为Redis挂掉而丢失从当前至最近一次快照期间的数据

    • AOF(Append-Only-File)持久化,保存写状态

      • 优点,可读性高,适合保存增量数据,数据不易丢失

        • 缺点,文件体积大,恢复时间长 

      • 记录下除了查询以外的所有变更数据库状态的指令

      • 以append的形式追加保存到AOF文件中(增量)

      • redis.conf

        • appendonly yes

          • 开启AOF

        • appendfilename "appendonly.aof"

          • AOF文件的名字

        • appendfsync always/everysec/no

          • 立即写入/每秒写入/交由操作系统决定(一般等到缓存区填满才同步数据到磁盘中)

          • 推荐everysec

      • 日志重写解决AOF文件大小不断增大的问题

        • 调用fork(),创建一个子进程

        • 子进程把新的AOF写到一个临时文件里,不依赖原来的AOF文件

        • 主进程持续将新的变动同时写到内存和原来的AOF里

        • 主进程获取子进程重写AOF的完成信号,往新AOF同步增量变动

        • 使用新的AOF文件替换掉旧的AOF文件

    • RDB-AOF混合持久化方式,4.0后默认

      • BGSZVE做镜像全量持久化,AOF做增量持久化

    • Redis数据的恢复

      • RDB和AOF文件共存情况下的恢复流程,AOF优先

  • 使用Pipeline的好处

    • Pipeline和Linux的管道类似

    • Redis基于请求/响应模型,单个请求处理需要一一应答

    • Pipeline批量执行指令,节省多次IO往返时间

    • 有顺序依赖的指令建议分批发送

  • Redis的同步机制

    • 全同步过程

      • Slave发送sync命令到Master

      • Master启动一个后台进程,将Redis中的数据快照保存到文件中

      • Master将保存数据快照期间接收到的写命令缓存起来

      • Master完成写文件操作后,将该文件发送给Slave

      • 使用新的AOF文件替换掉旧的AOF文件

      • Master将这期间收集的增量写命令发送给Slave端进行回放

    • 增量同步过程

      • Master接收到用户的操作指令,判断是否需要传播到Slave

      • 将操作记录追加到AOF文件

      • 将操作传播到其他Slave

        • 对齐主从库,确保从数据库是该操作所对应的数据库

        • 将命令和参数按照Redis的格式写入到响应Slave的缓存中

      • 将缓存中的数据发送给Slave  

  • Redis Sentinel(Redis哨兵)

    • 解决主从同步Master宕机后的主从切换问题

      • 监控,检查主从服务器是否运行正常  

      • 提醒,通过API向管理员或其他应用程序发送故障通知

      • 自动故障迁移,主从切换

  • 流言协议Gossip

    • 每个节点都随机地与对方通信,最终所有节点的状态达成一致

    • 种子节点定期随机向其他节点发送街店列表以及需要传播的消息

    • 不保证信息一定会传递给所有的节点,但是最终会趋于一致  

 

课程设计报告:总体方案设计说明 一、软件开发环境配置 本系统采用C++作为核心编程语言,结合Qt 5.12.7框架进行图形用户界面开发。数据库管理系统选用MySQL,用于存储用户数据与小精灵信息。集成开发环境为Qt Creator,操作系统平台为Windows 10。 二、窗口界面架构设计 系统界面由多个功能模块构成,各模块职责明确,具体如下: 1. 起始界面模块(Widget) 作为应用程序的入口界面,提供初始导航功能。 2. 身份验证模块(Login) 负责处理用户登录与账户注册流程,实现身份认证机制。 3. 游戏主大厅模块(Lobby) 作为用户登录后的核心交互区域,集成各项功能入口。 4. 资源管理模块(BagWidget) 展示用户持有的全部小精灵资产,提供可视化资源管理界面。 5. 精灵详情模块(SpiritInfo) 呈现选定小精灵的完整属性数据与状态信息。 6. 用户名录模块(UserList) 系统内所有注册用户的基本信息列表展示界面。 7. 个人资料模块(UserInfo) 显示当前用户的详细账户资料与历史数据统计。 8. 服务器精灵选择模块(Choose) 对战准备阶段,从服务器可用精灵池中选取参战单位的专用界面。 9. 玩家精灵选择模块(Choose2) 对战准备阶段,从玩家自有精灵库中筛选参战单位的操作界面。 10. 对战演算模块(FightWidget) 实时模拟精灵对战过程,动态呈现战斗动画与状态变化。 11. 对战结算模块(ResultWidget) 对战结束后,系统生成并展示战斗结果报告与数据统计。 各模块通过统一的事件驱动机制实现数据通信与状态同步,确保系统功能的连贯性与数据一致性。界面布局遵循模块化设计原则,采用响应式视觉方案适配不同显示环境。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值