前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redis知识点

redis知识点

作者头像
用户1558882
发布2023-02-25 09:46:06
4090
发布2023-02-25 09:46:06
举报
文章被收录于专栏:Rgc

通信协议

  • 协议概念: 所谓协议 其实就是 发送和接收 双方约定的数据格式而已;类似于 加密解密; 没有什么神秘; 比如 http协议,双方约定好格式,如何读取url,取参赛,取请求头数据等等;
  • redis传输层协议是TCP
  • redis应用层协议是其自己实现的一种协议,叫 RESP(redis serialization protocol:redis序列化协议); 这种协议 特点在于 实现简单,快速解析,人类易读,
  • 采用这种协议原因是 redis是高性能内存数据库,需要尽可能的减少不必要的计算量及时间,而http是比较复杂的协议;
  • RESP协议只用于 redis客户端与服务端之间的交流;
  • 协议工作流程(以客户端发送一个命令为例):
  • 客户端:原始命令->RESP编码->传输
  • 服务端:接收->RESP解码->原始命令

redis高性能的原因

  • redis是纯内存的操作,性能瓶颈不在cpu上(因为其不读取硬盘数据),而是网络IO时间 和 内存大小 问题上,而且在硬件上基本不涉及磁盘(除了持久化等情况);
  • redis采用单线程模型(指网络事件处理模式(单reactor单线程模型),不是说redis只是单线程程序),因其实现简单,避免多线程频繁上下文切换,及同步机制加锁的开销;
  • redis采用 单Reactor单线程 模式的网络事件处理器,内部使用了 I/O多路复用模型,如linux的epoll,使其能同时连接成千上万个客户端连接;
  • redis基础数据结构简单高效,如链表,字典,整数集合等,在此基础上实现用户能操作的对象:字符串,列表,hash,集合,有序集合等

redis是单线程系统?

  • 常说的redis单线程指其网络事件出来模型 reactor是单线程;
  • 由于 redis瓶颈在于网络IO时间较长,所以在redisV6.0引入了多线程去处理客户端IO读写相应,而redis命令的处理还是在主线程 单线出来;
  • 针对整个redis系统,则一直有其他线程进行异步任务出来,如 AOF,RDB等数据持久化任务;

单Reactor单线程模型

介绍

  • Reactor对象通过epoll监听事件,收到准备就绪的事件后通过dispatch分发,根据事件类型,决定分发到Acceptor(建立客户端连接)或Handler(处理业务的对象)
  • 当是 建立连接事件时,则Acceptor对象会通过 accept方法获取连接,然后建立client对象和socket对象,然后产生read事件,将此事件与 命令出来handler关联,表示后续此socket为可读事件,也就是接收客户端的命令操作;
  • 当接收到客户端命令的读事件时,Reactor的dispatch(分发)将读事件分发给对应的hanlder,handler读取命令,执行完后,生成一个 包含数据的写事件扔给Reacotr,让其再次分发给写事件的handler; 然后此hanler将数据写入socket发送给客户端;

优点

  • 单线程操作,方便管理,没有锁的困扰;

缺点

  • 所有业务操作都在一个线程中执行,如果一个连接的操作耗时较长会导致 所有连接响应延迟;但redis没此问题,因为其是内存操作,瓶颈不在cpu;
  • 随着高并发的增长,网络IO操作耗时越来越明显(read操作,从内核读数据到应用程序,write操作,应用程序中的数据写到内核),而这些操作 都在主线程中执行,由于这些网络IO操作 浪费了CPU资源,所以网络IO就是瓶颈;

缺点解决方案

  • 将 网络IO操作从主线程中 提取到 只负责此功能的IO线程中; 这样 主线程只负责执行命令,充分利用cpu; IO线程只负责 从socket读取写入数据;

redis 单reactor单线程模式+多线程网络IO

示意图

工作方式

  • 网络IO线程 专门负责从socket读取或写入数据,主线程仍然负责执行命令;

优点:此方式解决了网络IO导致的性能瓶颈问题;

redis事件循环(EventLoop)

事件类型

文件事件

  • 和redis客户端的socket进行交互的 读写事件称为文件事件;
  • 读事件: 客户端发送请求时,redis服务端的事件handler读取对应socket中的命令,然后执行;
  • 写事件: redis服务端将命令执行结果 写入socket文件返回给客户端;
  • 当与同一个客户端的socket 读事件 和写事件同时发生时,先执行读事件;

时间事件

  • 在指定时间点运行的事件 称为时间事件; 多个时间事件以无序链表结构保存在服务器中;
  • 时间事件包括 定时执行的事件和 一次性执行的事件;
  • 时间事件 默认每100ms执行一次,每秒执行10次;
时间事件中有一个 默认执行的事件,功能如下
  • 更新服务器各种统计信息,比如时间,内存占用,数据库占用情况
  • 清理数据库中过期的键值对
  • 关闭和清理连接失效的客户端
  • 尝试进行AOF,RDB 持久化操作
  • 如果服务器是主节点,则对附属节点进行同步数据
  • 对不合理的数据库大小进行调整;

2种事件在事件循环中的处理顺序

  • 2种事件必须有先后顺序,无法抢占CPU资源,中断某个事件
  • 当2种事件类型都有需要执行的事件时,先执行 文件事件(客户端的命令) 等执行完后,再执行时间事件;
  • 在事件循环中 文件时间的等待时间(epoll函数等待有就绪的socket时间) 由 距离到达时间最短的时间事件决定; 如 最近时间事件在2s后执行,则 文件时间的等待时间最多为2s;
  • 基于如上特点,会导致 时间事件 实际的执行时间可能会晚于设定的执行时间;因为 无法抢占执行,且 文件事件 优先执行直到完成为止;

redis事件循环(EventLoop)整体流程

  • 先初始化redis服务
  • 再是一个大的while循环,里面执行如下步骤
代码语言:javascript
复制
def process_event():
    # 获取执行时间最接近现在的一个时间事件(过去的事件和未来要执行的事件 中找离现在最近的事件时间)
    te = get_nearest_time_event(server.time_event_linked_list)

    # 检查该事件的执行时间和现在时间之差
    # 如果值 <= 0 ,说明至少有一个时间事件已到达
    # 如果值 > 0 ,说明目前没有任何时间事件到达
    nearest_te_remaind_ms = te.when - now_in_ms()

    if nearest_te_remaind_ms <= 0:
        # 若有时间事件已达,则调用不阻塞的文件事件等待函数
        poll(timeout=None)
    else:
        # 若时间事件还没到达,则阻塞的最大时间不超过 te 的到达时间
        poll(timeout=nearest_te_remaind_ms)

    # 优先处理已就绪的文件事件
    process_file_events()

    # 再处理已到达的时间事件
    process_time_event()
  • 最后关闭时 清理服务器;

持久化相关

RDB快照方式

简介

  • RDB是通过快照方式完成持久化,一次性将所有数据都持久化到磁盘中;

执行频率

在配置文件中设置,配置命令如下

代码语言:javascript
复制
save 3600 1; // 3600s内有1个key变化就执行持久化
save 300 100
save 60 1000

或者 用户手动执行命令,如下 save命令: 同步快照方式,此方式会阻塞redis服务主进程对客户端命令的执行,不推荐; bgsave命令: 异步快照方式,此方法会 fork一个子进程 在后台执行,不影响主进程的效率;

优缺点

  • 优点:快照方式 适用于备份和灾难恢复,且恢复速度比如AOF快(因为RDB是直接记录数据最终结果,而AOF记录的是每次操作日志,恢复时相当于重新执行命令);
  • 缺点:因为是快照,频率过高会导致 资源浪费严重,但是频率低又会导致 宕机时数据丢失严重(最后一次快照后的数据都丢失);

BGSAVE命令的快照方式实现细节

涉及知识点
  • linux fork()函数: 系统内核中的此函数会从父进程 生成一个完全相同的子进程;代码,内存数据都相同;
  • Copy On Write(写时复制)机制: 此机制 是为了解决 fork时,将父进程的所有数据都复制一份到子进程造成的瞬间内存压力及资源消耗问题; 此机制会在fork后,子进程访问内存时将内存空间指向父进程,也就是 子进程共享父进程的内存数据; 只有在 父或子进程对 内存数据进行写入时,才会触发将 父进程的内存空间中对应写的内存页数据复制一份给子进程,然后再写入; 这种方式 节约了内存空间等资源;
实现过程
  • 当触发词任务时,主进程通过fork()函数创建一个 包含相同代码,内存数据的 基本完全相同的子进程(除了进程ID等);
  • 子进程 通过 Copy On Write机制 开始 访问父进程共享的内存数据,执行持久化任务直到结束即可;
  • 由于总体上,redis操作的读操作多于写操作(不会因为写时复制机制 总是触发复制情况,造成性能下降),所以 此实现性能还可以;

AOF(Append On File)持久化方式

简介

这种持久化方式是 将 执行命令追加到文件中;

实现流程

  • 写命令的数据先缓存到 内存中;
  • 主进程fork出子进程,根据用户设置的 将缓存同步到磁盘的频率,进行同步即可;
  • 当AOF文件过大时,触发重写机制(直接读取内存中现有的键值对,然后用一条写命令记录这些键值对,达到压缩文件大小的目的);

AOF文件重写流程

优点

  • 基本设置都是每秒同步一次,能保证数据最多丢失1s;

缺点

  • 文件体积比RDB的大;
  • 恢复数据时,耗时比RDB长;
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 通信协议
  • redis高性能的原因
  • redis是单线程系统?
  • 单Reactor单线程模型
    • 介绍
      • 优点
        • 缺点
          • 缺点解决方案
            • redis 单reactor单线程模式+多线程网络IO
              • 示意图
              • 工作方式
              • 优点:此方式解决了网络IO导致的性能瓶颈问题;
          • redis事件循环(EventLoop)
            • 事件类型
              • 文件事件
              • 时间事件
            • 2种事件在事件循环中的处理顺序
              • redis事件循环(EventLoop)整体流程
              • 持久化相关
                • RDB快照方式
                  • 简介
                  • 执行频率
                  • 优缺点
                  • BGSAVE命令的快照方式实现细节
                • AOF(Append On File)持久化方式
                  • 简介
                  • 实现流程
                  • AOF文件重写流程
                  • 优点
                  • 缺点
              相关产品与服务
              云数据库 Redis®
              腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档