Redis深度历险-简单的原理技术

本文探讨了Redis中的IO模型,如何通过多路复用和描述符管理并发请求,以及RDB和AOF两种持久化方法。还涉及了Redis的通信协议、事务处理、发布订阅机制和内存优化,如小对象压缩及内存分配库的选择。
摘要由CSDN通过智能技术生成

IO模型

  • 使用多路复用IO模型
    • 一次接收多个读写描述符,并且每一个描述符提供一个timeout超时参数
      • 通过描述符要读取的内容和大小,去进行IO读写
      • 一旦timeout超时才会将事件标记为处理完成,并且将结果返回。
      • 如果没有超时,线程会继续循环为每一个事件IO读写
  • 使用指令队列排序客户端指令
    • redis会将每个客户端套接字都关联一个指令队列,客户端的指令通过队列来排队进行顺序处理,先到先得。
  • 使用响应队列排序响应结果
    • 和指令队列相似,将指令队列响应的结果返回给客户端的队列。

通信协议

RESP(Redis Serialization Protocol)

  • Redis序列化协议,实现过程简单,解析性能极好
  • 将传输的结构数据分为5种最小单元类型,单元结束统一加上换行回车\r\n
  • 每个最小单元类型都有不同的开头和结构

客户端与服务端通信

  • 客户端向服务器发送指令使用多行字符串数组
    • 一个set指令 set author codehole序列化如下
      • *3\r\n$3\r\nset\r\n$6\r\nauthor\r\n$8\r\ncodehole\r\n
  • 服务端向客户端发送指令和RESP通信序列化协议结构类似

持久化

  • RDB快照
    • 是一种全量备份
    • 存储上非常紧凑
    • 使用操作系统的多进程COW(Copy On Write)机制实现快照持久化
    • 子进程只负责循环读取内存中的数据,而父进程在响应客户端请求时如果对数据进行了修改,就会将使用写时复制技术
  • AOF增量日志
    • 记录内存数据修改的指令记录文本
    • 需要定时重写瘦身
      • bgrewriteaof指令用于AOF文件瘦身,就是合并AOF中的无用的指令操作,替代原本的AOF文件

混合持久化

  • RDB和AOF各有优缺点,所以Redis4.0提供了一个新的持久化选项——混合持久化
  • 大概就是:RDB不是因为不能随时或者短时间频繁持久化吗,因为每次都会消耗大量的资源,那就就必定会有一段时间的数据可能会丢失,那么我就使用AOF来存储你这部分时间的增量指令。
    • ![[Pasted image 20231106140904.png]]

管道

  • 管道并不是Redis服务器提供的技术,而是客户端提供的
  • 类似与Mysql的merge insert,将读写操作都进行合并,避免多次请求的发出
  • 客户端的write本质上就是将数据放到套接字发送缓冲区,将缓冲区数据发送到网卡,网卡在通过路由交换机将数据发送到服务器
  • 客户端的read本质就是,发送请求后,等待套接字返回数据到缓冲区,再从缓冲区拿取数据

事务

  • 事务指令为
    • multi表示事务开始
    • exec表示事务指令
    • discard表示事务丢弃
  • exec才代表事务中的命令开始执行
  • Redis的事务执行时不具备原子性,只是满足了事务的隔离性的串行化。
  • 提供discard指令,用于在exec执行之前取消multi排队

发布订阅

  • 消息多播的概念:将生产者生产的消息有中间件发送到多个消息队列,是分布式系统常用的解耦方式
  • redis为了消息多播,不再依赖原本的5种基本数据类型,而是使用PubSub来支持消息多播
  • 消费者订阅主题必须明确指定主题的名称,Redis提供了模型订阅功能,解决了多个主题一次一次订阅的麻烦,可以一次性订阅多个主题

小对象压缩

  • 为了节约Redis的内存,防止Redis崩溃,Redis作者增加了许多优化点来优化数据结构的内存占用
  • Redis很多类型都有小对象压缩技术
    • ziplist
    • u64在可以的时候可以压缩到u16
  • 但是当压缩的对象不能存储新加入的数据时,就会将整个存储转变为正常大小

内存使用

  • redis中删除了1GB的key后却发现redis占用的内存没有变化,因为操作系统回收是以页为单位回收内存,删除的1GB的key并不是都在同一个页中
  • 可以想象如果使用标记整理回收算法,那么就不会出现这种情况,因为标记整理可以腾出大量的连续空间,但是由于Redis的内存结构并不是单纯的堆,而是根据hash槽存储key和value的结构,所以使用标记整理是不合理的
  • redis的内存分配是使用的第三方内存分配库实现,目前使用的是jemalloc(fackbook)库,可以切换到tcmalloc(google)库
  • 32
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值