【Redis】网络模型

news2024/12/29 8:20:33

图片

前言

Redis(Remote Dictionary Server)是一个开源的高性能键值对存储系统,广泛用于各种网络应用中作为数据库、缓存和消息代理。Redis的网络模型是其高性能的关键因素之一,它涉及到多个方面,包括内存管理、事件处理、网络协议等。了解Redis的网络模型有助于更好地利用其功能,优化系统的性能和可靠性。

Redis具有的特点:

  1. 高性能:Redis采用内存存储和异步IO机制,能够实现高速读写,读写性能优越。

  2. 数据持久化:Redis支持多种数据持久化方式,包括RDB和AOF两种方式。RDB方式会将内存中的数据定时写入磁盘,AOF方式则会将每个命令追加到磁盘中的AOF文件。

  3. 多种数据结构:Redis提供了多种数据结构,包括字符串、哈希表、列表、集合和有序集合等,可满足不同场景下的需求。

  4. 分布式:Redis提供了分布式支持,能够通过主从复制和集群两种方式实现数据的分布式操作。

  5. 原子性操作:Redis的所有操作都是原子性,支持事务,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行。

  6. 高可用性:Redis支持哨兵机制(master-slave模式)和redis cluster高可用两种高可用方式。

  7. 发布与订阅的消息机制:Redis也支持发布与订阅的消息机制,但不建议使用Redis来做消息中间件。

  8. 简单事务:Redis支持简单事务。

Redis的应用场景:

  1. 会话管理:利用Redis的持久化功能,可以存储和跟踪用户的会话信息。这对于保持用户在网站上的活动以及个性化体验非常重要。

  2. 缓存:由于Redis的高性能和持久化特性,它经常被用作缓存系统。缓存热门数据或频繁访问的数据可以减少数据库的负载,提高应用程序的响应时间。

  3. 排行榜和积分系统:Redis提供了有序集合数据类型,可以轻松实现各种复杂的排行榜应用,例如商品按时间的上新排行榜、京东的月度销量榜单等。

  4. 计数器:例如电商网站商品的浏览量、视频网站视频的播放量等,可以使用Redis的incre命令实现计数器功能。内存操作使得性能非常好,适用于这些计数场景。

  5. 分布式锁:在许多互联网公司中都使用了分布式技术,Redis提供的分布式锁功能可以帮助开发者解决分布式系统中的并发访问问题。

  6. 社交网络功能:点赞、踩、关注/被关注、共同好友等功能是社交网络的基本功能。Redis提供的哈希、集合等数据结构能很方便的实现这些功能。

  7. 消息队列:虽然RabbitMQ、Kafka等专业的消息队列服务对消息队列支持更全面,但Redis的发布/订阅功能也可以用于简单的消息队列场景。

  8. 日志管理:Redis可以用来存储和管理应用程序的日志数据,特别是对于需要实时处理和分析日志数据的场景。

  9. 实时数据分析:Redis提供了丰富的数据结构和操作,可以用于实时数据分析,如统计网站的独立访客、页面浏览量等。

  10. 地理位置服务:利用Redis存储地理位置信息,如经纬度坐标,可以快速查询和定位用户或物品的位置。

Redis的网络模型主要包括以下几个方面:

  1. 内存存储:Redis使用内存作为其主要存储介质,数据直接存储在内存中,避免了磁盘I/O操作的开销,从而实现了极高的数据读写速度。

  2. Reactor模式:Redis采用了一种称为Reactor模式的事件处理机制。在这种模式下,Redis使用一个主循环来监听客户端的连接请求,并将连接请求分配给一个或多个工作线程进行处理。

  3. 单线程模型与多线程模型:根据使用的版本和配置,Redis可以运行在单线程或多线程模式下。在单线程模式下,所有的读写操作都在一个线程中执行。多线程模式允许多个线程同时处理客户端的请求,提高了系统的并发处理能力。

  4. 网络协议:Redis使用自定义的网络协议与客户端进行通信。客户端和Redis服务器之间通过TCP连接进行通信,使用二进制格式的数据传输,具有高效的数据传输性能。

图片

Redis内存存储

Redis使用内存作为其主要存储介质。所有的数据都存储在内存中,这意味着读写操作的速度非常快,避免了磁盘I/O操作的开销。Redis提供了多种数据结构,如字符串、哈希表、列表、集合等,这些数据结构在内存中以特定的方式进行存储,以便快速地进行读取和修改。为了优化内存使用,Redis还实现了内存回收和内存压缩机制。通过合理配置和优化Redis的内存使用,可以进一步提高系统的性能和可靠性。

Reactor模式

Reactor模式是一种事件处理机制,广泛应用于网络编程。在这种模式下,一个单独的线程或一组线程等待多个事件的发生,一旦事件发生,就立即处理该事件。Redis使用Reactor模式来处理客户端的连接请求和读写事件。Redis的主循环负责监听客户端的连接请求,并将请求分配给一个或多个工作线程进行处理。每个工作线程负责处理一部分连接,这使得多个CPU核心可以同时工作,从而提高了系统的整体性能。通过合理配置Reactor模式下的线程数量和工作负载分布,可以进一步优化Redis的性能和并发处理能力。

 Reactor模式读写流程:

  •  Reactor:负责响应事件,将事件分发到绑定了对应事件的Handler,如果是连接事件,则分发到Acceptor。

  • Handler:事件处理器,负责执行对应事件对应的业务逻辑。

  • Acceptor:绑定了connect事件,当客户端发起connect请求时,Reactor会将accept事件分发给Acceptor处理。

单线程模型

在早期版本中,Redis采用单线程模型。redis网络IO模型底层使用IO多路复用,通过reactor模式实现的。这意味着所有的读写操作都在一个线程中执行。虽然这种模型简单且易于实现,但它无法充分利用多核CPU的性能。为了解决这个问题,Redis引入了多线程模型。

图片

多线程模型

Redis6.0 版本之后,Redis 正式在核心网络模型中引入了多线程,也就是所谓的 I/O threading,至此 Redis 真正拥有了多线程模型,这对应了主从Reactor多线程模型的Reactor设计模式。多线程模型允许多个线程同时处理客户端的请求。每个线程负责处理一部分连接,这使得多个CPU核心可以同时工作,从而提高了系统的整体性能。然而,多线程模型也带来了线程管理和同步的问题,需要谨慎处理以避免竞态条件和死锁。

图片

例子1:多个线程并发访问Redis

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class RedisMultiThreadDemo {
    public static void main(String[] args) {
        // 创建JedisPoolConfig对象,设置IO线程数为4
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(4);
        config.setMaxIdle(4);
        config.setMinIdle(0);
        config.setTestOnBorrow(true);
        config.setTestOnReturn(true);
        config.setTestWhileIdle(true);

        // 创建JedisPool对象,连接到Redis服务器
        JedisPool jedisPool = new JedisPool(config, "localhost", 6379);

        // 创建多个线程并发访问Redis
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try (Jedis jedis = jedisPool.getResource()) {
                    jedis.set("key" + Thread.currentThread().getId(), "value");
                    System.out.println("Set key" + Thread.currentThread().getId() + ": " + jedis.get("key" + Thread.currentThread().getId()));
                }
            }).start();
        }
    }
}

网络协议

Redis的网络协议是一种基于文本的协议,使用基于文本的命令请求和响应格式。客户端通过TCP协议与Redis服务器建立连接,然后发送命令请求,服务器接收到命令请求后执行相应的操作,并将结果作为响应返回给客户端。

命令请求和响应都是以回车换行符(CRLF)为结束标记的字符串,其中命令请求是由一个或多个命令组成的字符串序列,每个命令以回车换行符(CRLF)结束;响应则是由一个或多个响应组成的字符串序列,每个响应也是以回车换行符(CRLF)结束。

除了基本的文本协议外,Redis还支持一种二进制安全的数据协议(Binary-Safe),该协议允许客户端发送二进制数据作为命令请求和响应。这种协议可以更好地处理非文本的数据,例如图像、音频、视频等。

另外,Redis还支持一种称为“请求-响应协议”的通信协议,该协议允许客户端发送多个命令请求并接收多个响应。这种协议可以提高通信效率,减少网络延迟和阻塞。

总之,Redis的网络协议是一种简单、高效、可靠的通信协议,能够满足各种应用场景的需求。

图片

例子2:连接Redis服务器并执行一些基本操作

import redis.clients.jedis.Jedis;

public class RedisDemo {
    public static void main(String[] args) {
        // 创建Jedis对象,连接到Redis服务器
        Jedis jedis = new Jedis("localhost", 6379);

        // 设置一个键值对
        jedis.set("key", "value");

        // 获取键对应的值
        String value = jedis.get("key");
        System.out.println("Value of key: " + value);

        // 关闭连接
        jedis.close();
    }
}

结语

Redis的网络模型是其高性能的关键因素之一。通过使用Reactor模式和多线程模型,Redis能够高效地处理大量并发连接,并提供快速的数据读写操作。了解并合理配置Redis的网络模型对于提高系统的性能和可靠性至关重要。在实际应用中,根据系统的需求和资源限制,可以选择适合的网络模型并进行相应的优化配置。

图片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1407318.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LeetCode 14.最长公共前缀(python版)

需求 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”] 输出&#xff1a;“fl” 示例 2&#xff1a; 输入&#xff1a;strs [“dog”,“race…

Python使用pip命令安装外部库-项目内安装外部库-全局安装外部库

一、前言 在进行Python项目开发时需要安装一些外部库来扩展项目功能&#xff0c;因此需要了解pip命令的详细使用。 二、基本语法 1.安装库 pip install 包名 2.安装特定版本 pip install 包名版本号 3.升级库 pip install --upgrade 包名 4.卸载库 pip uninstall 包名 5.查看已…

智能调光芯片 PWM调光 模拟调光36V 48V 60V 72V-H5119SL

智能调光芯片是一种用于控制光照系统的集成电路&#xff0c;其主要功能是根据环境条件和用户需求智能调整光照强度。以下是智能调光芯片的基本工作原理&#xff1a; 传感器输入&#xff1a;智能调光芯片通常集成光感应传感器&#xff0c;用于检测周围环境的光照强度。传感器会…

2023 工业 AR 关键词:纵深和开拓

2023 年&#xff0c;以虚实融合、工业元宇宙为代表的“新数字化”升级在工业制造领域达成共识。 ▲五部委联合印发元宇宙行动计划 通过发展元宇宙赋能新型工业化 而相对过去几年的行业渗透广、落地场景多样的 AR 业务拓展与合作&#xff0c;#纵深和#开拓&#xff0c;成为 2023…

Pandas.DataFrame.idxmin() 最小值索引 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本&#xff1a; 本文基于 pandas2.2.0 编写。 关于本文内容更新&#xff1a; 随着pandas的stable版本更迭&#xff0c;本文持续更新&#xff0c;不断完善补充。 传送门&#xff1a; Pandas API参考目录 传送门&#xff1a; Pandas 版本更新及新特性 传送门&…

C#用DateTime.Now静态属性返回日期的星期信息

目录 一、使用的方法 1.Now属性 2.ToString方法 二、示例 使用DateTime结构的Now静态属性&#xff0c;可以方便地获取系统日期信息。调用时间对象的ToString方法&#xff0c;在该方法的参数中添加适当的格式化字符串&#xff0c;将返回日期的星期信息。 一、使用的方法 1…

网络电视盒子哪个好?博主分享超高性价比网络电视盒子推荐

电视盒子是我们使用最多的数码产品&#xff0c;年货节很多朋友在纠结网络电视盒子哪个好&#xff0c;我这次的测评产品就是电视盒子&#xff0c;按照18款电视盒子的深度测评结果整理了网络电视盒子推荐&#xff0c;想知道网络电视盒子哪个好可以看看下面这五款电视盒子。 一&am…

【数学建模】插值与拟合

文章目录 插值插值方法用Python解决插值问题 拟合最小二乘拟合数据拟合的Python实现 适用情况 处理由试验、测量得到的大量数据或一些过于复杂而不便于计算的函数表达式时&#xff0c;构造一个简单函数作为要考察数据或复杂函数的近似 定义 给定一组数据&#xff0c;需要确定满…

ArcEngine添加点要素、线要素、面要素及学习总结

基于C#的ArcEngine二次开发教程&#xff08;13&#xff09;&#xff1a;点、线、面要素的绘制_arcengine onmousedown-CSDN博客 https://www.cnblogs.com/cannel/p/11074343.html ArcEngine绘制点、线、多边形、矩形、圆形、椭圆的代码_arcengine 开发 生成矩形-CSDN博客 https…

keil5 查看stm32 寄存器的值

1 查看芯片内部寄存器的值&#xff0c;首先是在仿真状态下&#xff0c;首先仿真&#xff0c;程序运行。 2 点击菜单栏的 View -> System viewer &#xff0c;右侧便会出现芯片的所有寄存器(如果没有&#xff0c;需要添加)&#xff0c;点击要查看的寄存器&#xff0c;便会出…

【手撕C语言 第八集】函数栈帧的创建与销毁

文章目录 一、什么是函数栈帧&#xff1f;二、函数栈帧能解决什么问题呢&#xff1f;&#xff08;1&#xff09;局部变量是如何创建的&#xff1f;&#xff08;2&#xff09;为什么局部变量不初始化内容是随机的&#xff1f;&#xff08;3&#xff09;函数调用时参数是如何传递…

使用ffmpeg转换索尼老DV拍摄的VOB文件为mp4

一些背景故事 最近对象想用 CCD 拍照录像&#xff0c;家里刚好有一台快 20 年前的索尼 DV DCR-DVD653E&#xff0c;就是电池老化充不进去电了。 翻出来之后还感慨了一下&#xff1a;当年没有网购&#xff0c;价格不透明&#xff1b;有些地方也没有官方店&#xff0c;只有一两家…

Yuliverse:引领区块链游戏新篇章!

数据源&#xff1a;Yuliverse Dashboard 作者&#xff1a;lesleyfootprint.network 什么是 Yuliverse Yuliverse 是一款元宇宙游戏的先锋&#xff0c;是一款主打 Explore to earn 和 Social to earn 的链游。 这是一款能让你边玩边赚钱的免费区块链游戏&#xff0c;得到 LI…

解决docker desktop 登录不上账号的问题

一、背景 点击“Sign in”&#xff0c;一直卡在Verifying credentials...&#xff0c;重试也没用。 二、解决办法 1、macOS下载并安装Proxifier 2、配置Proxifier 配置Proxies 配置rule 其中的Applications填&#xff1a;"Docker.app"; "Docker"; com.…

机器学习之聚类-2D数据类别划分

无监督学习&#xff08;Unsupervised Learning&#xff09; 机器学习的一种方法&#xff0c;没有给定事先标记过的训练示例&#xff0c;自动对输入的数据进行分类或分群。 方式一&#xff1a;站着或坐着 方式二&#xff1a;全身或半身 方式三&#xff1a;蓝眼球或不是蓝眼球 …

解决TortoiseGit软件Git Show log时显示Too many files to display的问题

1 问题描述 有时代码提交修改的文件比较多&#xff0c;当查看log时无法显示出来修改的文件列表&#xff0c;如下所示&#xff1a; 2 解决方法 将LogTooManyItemsThreshold尽可能配置得大一些。 三 参考资料 https://gitlab.com/tortoisegit/tortoisegit/-/issues/3878

使用 Docker 部署 ServerStatus 服务器监控系统

一、ServerStatus 介绍 GitHub&#xff1a;https://github.com/cppla/ServerStatus ServerStatus 是一个酷炫高逼格的云探针、云监控、服务器云监控、多服务器探针~。 特性 使用 Rust 完全重写 Server、Client&#xff0c;单个执行文件部署支持上下线和简单自定义规则告警 (T…

01. eNSP环境以及VRP基本使用

eNSP的基本使用 1. eNSP的桥连接1.1. 具体操作&#xff08;1&#xff09;创建环回适配器&#xff08;2&#xff09;设置虚拟网卡&#xff08;3&#xff09;使用eNSP桥接计算机 2. 华为VRP系统2.1. 实验1&#xff1a;VRP的基本操作2.2. 实验2&#xff1a;文件命令&#xff08;1&…

mysql 基础(三)

一、多表设计 数据库设计范式 第一范式(确保每列保持原子性) 第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值&#xff0c;就说明该数据库表满足了第一范式。第二范式就是要有主键&#xff0c;要求其他字段都依赖于主键。 没有主键就没有唯一性&…

el-tree勾选后退出再打开显示之前已经勾选的

官网文档 element-ui官网文档有默认展开和默认选中 <el-tree:data"data"show-checkboxnode-key"id":default-expanded-keys"[2, 3]":default-checked-keys"[5]":props"defaultProps"> </el-tree><script>…