《Redis核心技术与实战》学习总结(三)
mhr18 2024-11-18 14:39 20 浏览 0 评论
Redis的单线程认知
一个基本事实
我们通常说的Redis单线程,主要是指:Redis 6.0 之前版本的 网络I/O 和 键值对读写 是由一个线程来完成的。
除了网络I/O 和 键值对读写 之外的其他功能,大多都是由额外的线程执行的。比如:持久化、异步删除、集群数据同步 等操作。
Note:Redis 6.0之后对网络I/O改为使用多线程,但是,仍然使用单线程处理 键值对的读写操作。
Why 单线程?
因为 多线程开发会不可避免地带来并发控制的问题。
系统中通常会存在被多线程同时访问的共享资源,比如一个共享的数据结构。而当多个线程要修改这个共享资源的时候,为了保证共享资源的正确性,就需要有额外的机制进行保证。
以Redis为例,它提供了List数据类型,我们可以拿它来做队列,入队(LPOP)和出队(LPUSH)就是两个基本操作。如果采用多线程设计,那么当两个线程同一时间一个操作LPOP一个操作LPUSH,为了保证队列长度的正确性,Redis就需要保证串行执行。而要保证串行执行,可能就需要一些额外的开销,比如我们常见的加锁。但在Redis的使用场景下,简单地加锁可能并不能得到理想的效果,会导致大部分线程在等待获取互斥锁,并行变串行,从而降低吞吐率。此外,多线程开发一般也还会引入同步源于来保护共享资源的并发访问,这也会降低系统代码的易调试性和可维护性。
综上所述,为了避免这些问题,尽可能保证简单高效,Redis直接采用了单线程模式。
Redis的单线程效率
我们都知道,Redis公开出来的数据:Redis使用单线程也可以达到每秒10万级的处理能力。
前提条件:在一定的服务器配置下才能达到。
Why 这么高效?
核心原因有两个:
(1)Redis的大部分操作都在内存上完成 + 采用了高效的数据结构
eg. 哈希表、跳表 等。如果你对数据结构还不熟悉,可以阅读 Redis学习总结(1)。
(2)Redis采用了多路复用机制,使其在网络I/O操作中能够并发处理大量的客户端请求,从而实现高吞吐率。
其中,原因(2)是Redis单线程高效率的重点,它避免了accept() 和 send()/recv() 潜在的网络I/O操作的阻塞点。
如果不想了解细节,那么知道这几个核心的原因就够了。
而要理解多路复用模型的优势,就得了解一下基本的IO模型。
基本的IO模型
在网络处理程序中,都会存在一些潜在的阻塞点,比如:常见服务端Socket程序中的accept() 和 recv() 函数。比如服务端监听到一个客户端有连接请求,但是一直没有能够成功建立连接,就会阻塞在accept()函数中,导致其他客户端无法和服务端建立连接,这就可能会导致服务端的线程阻塞。
那么,有没有不阻塞的IO模型?
别急,我们从阻塞IO模型看起。我们也不看什么原理,举个例子-买火车票场景来理解。
阻塞式IO模型
老周去火车站买票,排队三天才买到一张退票。
开销:在车站吃喝拉撒睡 3天,其他事一件没干。
非阻塞式IO模型
老周去火车站买票,隔12小时去火车站问有没有退票,三天后买到一张票。
开销:往返车站6次,路上6小时,其他时间做了好多事。
IO多路复用模型
对于IO多路复用,不同的操作系统平台有不同的系统调用实现,主要以select/poll 和 epoll 最为人知。
(1)select/poll
老周去火车站买票,委托黄牛,然后每隔6小时电话黄牛询问,黄牛三天内买到票,然后老李去火车站交钱领票。
开销:往返车站2次,路上2小时,黄牛收取手续费100元,打电话17次。
(2)epoll
老周去火车站买票,委托黄牛,黄牛买到后即通知老李去领,然后老李去火车站交钱领票。
开销:往返车站2次,路上2小时,黄牛手续费100元,无需打电话。
信号驱动IO模型
老周去火车站买票,给售票员留下电话,有票后,售票员电话通知老李,然后老李去火车站交钱领票。
开销:往返车站2次,路上2小时,免黄牛费100元,无需打电话。
异步IO模型
老周去火车站买票,给售票员留下电话,有票后,售票员电话通知老李并快递送票上门。
开销:往返车站1次,路上1小时,免黄牛费100元,无需打电话。
Redis IO模型
Redis在设计中基于Linux的IO多路复用机制实现了自己的IO模型,如下图所示:
上图中的多个FD就是多个套接字(Socket),Redis的网络框架通过调用epoll让内核监听这些套接字。此时,Redis线程不会阻塞在某一个特定的监听 或 已连接的套接字上。因此,Redis可以同时和多个客户端连接并处理请求,从而提升并发性。
正如刚刚的例子中提到,黄牛买到票后会通知老周去领票,为了在请求到达时能够通知到Redis线程,epoll提供了基于事件的回调机制,即针对不同事件的发生,调用响应的处理函数。
Note:比如 连接请求对应Accept事件,读取数据对应 Read事件。Redis会分别对这两个事件注册 accept 和 get 回调函数。
这些事件会被放进一个事件队列,Redis单线程会对该队列不断地进行处理:如果Linux内核监听到有实际请求时,就会触发对应事件,然后Linux内核就会回调Redis对应的函数开始处理。
因此,Redis不用一直阻塞等待是否有实际请求发生,避免CPU资源浪费,进而提高吞吐率。
Note:IO 模型的演进,其实就是时代的变化,倒逼着操作系统将更多的功能加到自己的内核。
End总结
本文总结了Redis单线程的几个核心要点:
(1)Redis单线程的基本认知,即Redis只是对网络I/O和数据读写采用了单线程。
(2)Redis为何要使用单线程,即Redis为了避免多线程开发中的并发控制问题。
(3)Redis单线程为何很高效,即Redis使用了高性能的多路复用IO模型。
参考资料
极客时间,蒋德钧《Redis核心技术与实战》
博客园,Tree《IO原理(下)》,https://www.cnblogs.com/liujiaqi1101/p/14855322.html
相关推荐
- 【推荐】一个开源免费、AI 驱动的智能数据管理系统,支持多数据库
-
如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!.前言在当今数据驱动的时代,高效、智能地管理数据已成为企业和个人不可或缺的能力。为了满足这一需求,我们推出了这款开...
- Pure Storage推出统一数据管理云平台及新闪存阵列
-
PureStorage公司今日推出企业数据云(EnterpriseDataCloud),称其为组织在混合环境中存储、管理和使用数据方式的全面架构升级。该公司表示,EDC使组织能够在本地、云端和混...
- 对Java学习的10条建议(对java课程的建议)
-
不少Java的初学者一开始都是信心满满准备迎接挑战,但是经过一段时间的学习之后,多少都会碰到各种挫败,以下北风网就总结一些对于初学者非常有用的建议,希望能够给他们解决现实中的问题。Java编程的准备:...
- SQLShift 重大更新:Oracle→PostgreSQL 存储过程转换功能上线!
-
官网:https://sqlshift.cn/6月,SQLShift迎来重大版本更新!作为国内首个支持Oracle->OceanBase存储过程智能转换的工具,SQLShift在过去一...
- JDK21有没有什么稳定、简单又强势的特性?
-
佳未阿里云开发者2025年03月05日08:30浙江阿里妹导读这篇文章主要介绍了Java虚拟线程的发展及其在AJDK中的实现和优化。阅前声明:本文介绍的内容基于AJDK21.0.5[1]以及以上...
- 「松勤软件测试」网站总出现404 bug?总结8个原因,不信解决不了
-
在进行网站测试的时候,有没有碰到过网站崩溃,打不开,出现404错误等各种现象,如果你碰到了,那么恭喜你,你的网站出问题了,是什么原因导致网站出问题呢,根据松勤软件测试的总结如下:01数据库中的表空间不...
- Java面试题及答案最全总结(2025版)
-
大家好,我是Java面试陪考员最近很多小伙伴在忙着找工作,给大家整理了一份非常全面的Java面试题及答案。涉及的内容非常全面,包含:Spring、MySQL、JVM、Redis、Linux、Sprin...
- 数据库日常运维工作内容(数据库日常运维 工作内容)
-
#数据库日常运维工作包括哪些内容?#数据库日常运维工作是一个涵盖多个层面的综合性任务,以下是详细的分类和内容说明:一、数据库运维核心工作监控与告警性能监控:实时监控CPU、内存、I/O、连接数、锁等待...
- 分布式之系统底层原理(上)(底层分布式技术)
-
作者:allanpan,腾讯IEG高级后台工程师导言分布式事务是分布式系统必不可少的组成部分,基本上只要实现一个分布式系统就逃不开对分布式事务的支持。本文从分布式事务这个概念切入,尝试对分布式事务...
- oracle 死锁了怎么办?kill 进程 直接上干货
-
1、查看死锁是否存在selectusername,lockwait,status,machine,programfromv$sessionwheresidin(selectsession...
- SpringBoot 各种分页查询方式详解(全网最全)
-
一、分页查询基础概念与原理1.1什么是分页查询分页查询是指将大量数据分割成多个小块(页)进行展示的技术,它是现代Web应用中必不可少的功能。想象一下你去图书馆找书,如果所有书都堆在一张桌子上,你很难...
- 《战场兄弟》全事件攻略 一般事件合同事件红装及隐藏职业攻略
-
《战场兄弟》全事件攻略,一般事件合同事件红装及隐藏职业攻略。《战场兄弟》事件奖励,事件条件。《战场兄弟》是OverhypeStudios制作发行的一款由xcom和桌游为灵感来源,以中世纪、低魔奇幻为...
- LoadRunner(loadrunner录制不到脚本)
-
一、核心组件与工作流程LoadRunner性能测试工具-并发测试-正版软件下载-使用教程-价格-官方代理商的架构围绕三大核心组件构建,形成完整测试闭环:VirtualUserGenerator(...
- Redis数据类型介绍(redis 数据类型)
-
介绍Redis支持五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)及Zset(sortedset:有序集合)。1、字符串类型概述1.1、数据类型Redis支持...
- RMAN备份监控及优化总结(rman备份原理)
-
今天主要介绍一下如何对RMAN备份监控及优化,这里就不讲rman备份的一些原理了,仅供参考。一、监控RMAN备份1、确定备份源与备份设备的最大速度从磁盘读的速度和磁带写的带度、备份的速度不可能超出这两...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)