【Redis】Redis 预备知识

目录

1. 基本全局命令 

KEYS

EXISTS

DEL

EXPIRE

TTL

TYPE

2. 数据结构和内部编码

3. 单线程架构


        Redis 提供了5种数据结构,理解每种数据结构的特点对于 Redis 开发运维非常重要,同时掌握每种数据结构的常见命令,会在使用 Redis 的时候做到游刃有余。本章内容如下:

  1. 预备知识:几个全局(generic)命令,数据结构和内部编码,单线程式机制分析。
  2. 5 种数据结构的特点、命令使用、应用场景示例。
  3. 键遍历、数据库管理。

       在正式介绍5种数据结构之前,了解一下 Redis 的一些全局命令、数据结构和内部编码、单线程命令处理机制是十分必要的,它们能为后面内容的学习打下一个良好的基础.
主要体现在两个方面:
1) Redis 的命令有上百个,如果纯靠死记硬背比较困难,但是如果理解 Redis 的一些机制,会发现这些命令有很强的通用性。
2) Redis不是万金油,有些数据结构和命令必须在特定场景下使用,一旦使用不当可能对 Redis 本身或者应用本身造成致命伤害。

1. 基本全局命令 

Redis有5种数据结构,但它们都是键值对种的值,对于键来说有一些通用的命令。

KEYS

返回所有满足样式 (pattern) 的 key。支持如下统配样式。

语法

KEYS pattern

时间复杂度:0(N)

返回值:匹配 pattern 的所有 key。

示例:

127.0.0.1:6379> keys *name*
1) "lastname"
2) "firstname"
127.0.0.1:6379> keys a??
1) "age"
127.0.0.1:6379> keys *
1) "lastname"
2) "age"
3) "firstname"

EXISTS

判断某个 key 是否存在。

语法:

EXISTS key [key ...]

返回值:key存在的个数。

时间复杂度:0(1)

示例:

127.0.0.1:6379> set key1 "hello"
OK
127.0.0.1:6379> exists key1
(integer) 1
127.0.0.1:6379> exists nosuchkey
(integer) 0
127.0.0.1:6379> set key2 "world"
OK
127.0.0.1:6379> exists key1 key2 nosuchkey
(integer) 2

DEL

删除指定的 key。

语法:

DEL key [key ...]

返回值:删除掉的 key 的个数。

时间复杂度:0(1)

示例:

127.0.0.1:6379> set key1 "hello"
OK
127.0.0.1:6379> set key2 "world"
OK
127.0.0.1:6379> del key1 key2 key3
(integer) 2

EXPIRE

为指定的 key 添加秒级的过期时间(Time To Live TTL)

语法:

EXPIRE key seconds

时间复杂度:0O(1)

返回值:1表示设置成功。0表示设置失败。

示例:

127.0.0.1:6379> set key "hello"
OK
127.0.0.1:6379> expire key 10
(integer) 1
127.0.0.1:6379> ttl key
(integer) 8

TTL

获取指定 key 的过期时间,秒级。

语法:

TTL key

时间复杂度:0(1)

返回值:剩余过期时间。-1表示没有关联过期时间,-2 表示 key不存在。

示例:

127.0.0.1:6379> flushall
OK
127.0.0.1:6379> set key "hello"
OK
127.0.0.1:6379> expire key 10
(integer) 1
127.0.0.1:6379> ttl key
(integer) 9
127.0.0.1:6379> ttl nokey
(integer) -2

关于键过期机制,可以参考下图所示。

键的过期机制

Redis 的 key 的过期删除策略是怎样的?

惰性过期

        只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

定期过期

       每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
       expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。

Redis 中同时使用了惰性过期和定期过期两种过期策略:

  • 每隔 100ms 就随机抽取一定数量的key来检查和删除的。
  • 在获取某个key的时候,redis 会检查一下,这个key如果设置了过期时间并且已经过期了,此时就会删除。 

 

TYPE

返回 key 对应的数据类型。

语法:

TYPE key

时间复杂度:0(1)

返回值: none,string,list, set,zset,hash,stream

示例:

127.0.0.1:6379> set key1 "value"
OK
127.0.0.1:6379> lpush key2 value
(integer) 1
127.0.0.1:6379> sadd key3 value
(integer) 1
127.0.0.1:6379> type key1
string
127.0.0.1:6379> type key2
list
127.0.0.1:6379> type key3
set

本小结只是抛砖引玉,给出几个通用的命令,为5种数据结构的使用做一个热身,后续章节将对
键管理做一个更为详细的介绍。

2. 数据结构和内部编码

type 命令实际返回的就是当前键的数据结构类型,它们分别是:string(字符串)、list(列
表)、hash(哈希)、set(集合)、zset(有序集合),但这些只是Redis 对外的数据结构,如图所示。

Redis的5种数据类型

实际上 Redis 针对每种数据结构都有自己的底层内部编码实现,而且是多种实现,这样 Redis 会
在合适的场景选择合适的内部编码.

Redis 数据结构和内部编码

可以看到每种数据结构都有至少两种以上的内部编码实现,例如 list 数据结构包含了 linkedlist 和
ziplist 两种内部编码。同时有些内部编码,例如 ziplist,可以作为多种数据结构的内部实现,可以通过 object encoding 命令查询内部编码:

127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> lpush mylist a b c
(integer) 3
127.0.0.1:6379> object encoding hello
"embstr"
127.0.0.1:6379> object encoding mylist
"quicklist"

可以看到 hello 对应值的内部编码是 embstr,键 mylist 对应值的内部编码是 ziplist。

Redis 这样设计有两个好处:

1) 可以改进内部编码,而对外的数据结构和命令没有任何影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令,例如 Redis 3.2 提供了 quicklist,结合了 ziplist 和 linkedlist 两者的优势,为列表类型提供了一种更为优秀的内部编码实现,而对用户来说基本无感知。
2) 多种内部编码实现可以在不同场景下发挥各自的优势,例如 ziplist 比较节省内存,但是在列表元素比较多的情况下,性能会下降,这时候 Redis 会根据配置选项将列表类型的内部实现转换为
linkedlist,整个过程用户同样无感知。

3. 单线程架构

Redis 使用了单线程架构来实现高性能的内存数据库服务,本节首先通过多个客户端命令调用的例
子说明 Redis 单线程命令处理机制,接着分析 Redis 单线程模型为什么性能如此之高,最终给出为什么理解单线程模型是使用和运维 Redis 的关键。

引出单线程模型

现在开启了三个 redis-cli 客户端同时执行命令。

客户端1设置一个字符串键值对:

127.0.0.1:6379> set hello world

客户端2 对 counter 做自增操作:

127.0.0.1:6379> incr counter

客户端3对 counter 做自增操作:

127.0.0.1:6379> incr counter

我们已经知道从客户端发送的命令经历了:发送命令、执行命令、返回结果三个阶段,其中我们
重点关注第2步。我们所谓的 Redis 是采用单线程模型执行命令的是指: 虽然三个客户端看起来是同时要求 Redis 去执行命令的,但微观角度,这些命令还是采用线性方式去执行的,只是原则上命令的执行顺序是不确定的,但一定不会有两条命令被同步执行,如图 2-3、2-4、2-5 所示,可以想象 Redis内部只有一个服务窗口,多个客户端按照它们达到的先后顺序被排队在窗口前,依次接受 Redis 的服务,所以两条 incr 命令无论执行顺序,结果一定是2,不会发生并发问题,这个就是 Redis 的单线程执行模型。

2.为什么单线程还能这么快

通常来讲,单线程处理能力要比多线程差,例如有 10000 公斤货物,每辆车的运载能力是每次
200 公斤,那么要 50 次才能完成;但是如果有 50 辆车,只要安排合理,只需要依次就可以完成任
务。那么为什么 Redis 使用单线程模型会达到每秒万级别的处理能力呢? 可以将其归结为三点:

a. 纯内存访问。Redis 将所有数据放在内存中,内存的响应时长大约为 100纳秒,这是 Redis 达到每秒万级别访问的重要基础。

b. 非阻塞 IO。Redis 使用 epoll 作为 I/O 多路复用技术的实现,再加上 Redis 自身的事件处理模型
将 epoll 中的连接、读写、关闭都转换为事件,不在网络 I/O  上浪费过多的时间,如图 2-6所示。

c. 单线程避免了线程切换和竞态产生的消耗。单线程可以简化数据结构和算法的实现,让程序
型更简单: 其次多线程避免了在线程竞争同一份共享数据时带来的切换和等待消耗。

虽然单线程给 Redis 带来很多好处,但还是有一个致命的问题: 对于单个命令的执行时间都是有
要求的。如果某个命令执行过长,会导致其他命令全部处于等待队列中,迟迟等不到响应,造成客户端的阻塞,对于 Redis 这种高性能的服务来说是非常严重的,所以 Redis 是面向快速执行场景的数据库。

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

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

相关文章

【从零开始的LeetCode-算法】3304. 找出第 K 个字符 I

Alice 和 Bob 正在玩一个游戏。最初,Alice 有一个字符串 word "a"。 给定一个正整数 k。 现在 Bob 会要求 Alice 执行以下操作 无限次 : 将 word 中的每个字符 更改 为英文字母表中的 下一个 字符来生成一个新字符串,并将其 追加 到原始的…

软件设计模式复习

一、软件生存周期 二、软件开发过程模型 瀑布模型 特征: 从上一阶段承接的成果物作为本阶段的工作对象; 对上一阶段成果实施本阶段的活动; 给出本阶段的成果,作为下一阶段的输入; 对本阶段的工作进行评审&#xff0c…

搭建文件服务器并使用Qt实现文件上传和下载(带账号和密码)

文章目录 0 背景1 搭建文件服务器2 代码实现文件上传和下载2.1 在pro文件中添加网络支持2.2 创建网络管理类2.3 文件上传2.4 文件下载 3 扩展(其他方法实现文件上传和下载)3.1 python3.2 npm3.3 ftp服务器 4 完整的代码 0 背景 因为需要使程序具备在远程…

自动化运维(k8s)之微服务信息自动抓取:namespaceName、deploymentName等全解析

前言:公司云原生k8s二开工程师发了一串通用性命令用来查询以下数值,我想着能不能将这命令写成一个自动化脚本。 起初设计的 版本一:开头加一条环境变量,执行脚本后,提示输入:需要查询的命名空间&#xff0c…

springboot332基于springboot养老院管理系统pf(论文+源码)_kaic

毕 业 设 计(论 文) 养老院管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计…

js:函数

函数 函数:实现抽取封装,执行特定任务的代码块,方便复用 声明 函数命名规范 尽量小驼峰 前缀应该为动词,如getName、hasName 函数的调用 函数体是函数的构成部分 函数传参 参数列表里的参数叫形参,实际上写的数据叫实…

基于Matlab的图像去噪算法仿真

中值滤波的仿真 本节选用中值滤波法对含有高斯噪声和椒盐噪声的图像进行去噪,并用Matlab软件仿真。 (1)给图像加入均值为0,方差为0.02的高斯噪声,分别选择33模板、55模板和77模板进行去噪 Matlab部分代码&#xff1…

【Linux】-学习笔记06

第二章、时间同步服务器 2.1时间同步服务器的使用 2.1.1系统时区时间的管理 timedatectl set-time "2024-02-13 10:41:55" ##设定系统时间 timedatectl list-timezones ##显示系统的所有时区 timedatectl set-timezone "Asia/Shangh…

UE5_建立自己的资产库

资产库需要用到一个插件: UAsset Browser - 直接在当前项目预览其他UE项目资产(.uasset 文件) - 直接迁移其他UE项目资产到当前项目 - 不用另外打开资产项目查看资产,迁移资产(麻烦) 插件官网插件文档插…

详解登录MySQL时出现SSL connection error: unknown error number错误

目录 登录MySQL时出错SSL connection error: unknown error number 出错原因 使用MySQL自带的工具登录MySQL 登陆之后,使用如下命令进行查看 解决方法 找到MySQL8安装目录下的my.ini配置文件 记事本打开my.ini文件,然后按下图所示添加配置 此时再…

深度学习基本单元结构与输入输出维度解析

深度学习基本单元结构与输入输出维度解析 在深度学习领域,模型的设计和结构是理解其性能和应用的关键。本文将介绍深度学习中的基本单元结构,包括卷积神经网络(CNN)、反卷积(转置卷积)、循环神经网络&…

乐鑫发布 esp-iot-solution v2.0 版本

今天,乐鑫很高兴地宣布,esp-iot-solution v2.0 版本已经发布,release/v2.0 分支下的正式版本组件将为用户提供为期两年的 Bugfix 维护(直到 2027.01.25 ESP-IDF v5.3 EOL)。该版本将物联网开发中常用的功能进行了分类整…

面经-综合面/hr面

面经-综合面/hr面 概述1.大学期间遇到的困难,怎么解决的2. 大学期间印象最深/最难忘的是什么3. 大学里面担任了什么职务没?做了什么工作?4. 大学最大的遗憾是什么?5. 对自己的未来规划6. 对自己的评价7. 自己的优缺点8. 对公司的认…

pyspark实现基于协同过滤的电影推荐系统

最近在学一门大数据的课,课程要求很开放,任意做一个大数据相关的项目即可,不知道为什么我就想到推荐算法,一直到着手要做之前还没有新的更好的来代替,那就这个吧。 推荐算法 推荐算法的发展由来已久,但和…

十、Spring Boot集成Spring Security之HTTP请求授权

文章目录 往期回顾:Spring Boot集成Spring Security专栏及各章节快捷入口前言一、HTTP请求授权工作原理二、HTTP请求授权配置1、添加用户权限2、配置ExceptionTranslationFilter自定义异常处理器3、HTTP请求授权配置 三、测试接口1、测试类2、测试 四、总结 往期回顾…

Unity3d C# 实现一个基于UGUI的自适应尺寸图片查看器(含源码)

前言 Unity3d实现的数字沙盘系统中,总有一些图片或者图片列表需要点击后弹窗显示大图,这个弹窗在不同尺寸分辨率的图片查看处理起来比较麻烦,所以,需要图片能够根据容器的大小自适应地进行缩放,兼容不太尺寸下的横竖图…

DVWA 在 Windows 环境下的部署指南

目录预览 一、靶场介绍二、前置准备1. 环境准备2.靶场下载 三、安装步骤1.配置Phpstudy2.配置数据库3.配置DVWA4.登入DVWA靶场 四、参考链接 一、靶场介绍 DVWA 一共包含了十个攻击模块,分别是: Brute Force(暴力(破解&#xff…

微软企业邮箱:安全可靠的企业级邮件服务!

微软企业邮箱的设置步骤?如何注册使用烽火域名邮箱? 微软企业邮箱作为一款专为企业设计的邮件服务,不仅提供了高效便捷的通信工具,更在安全性、可靠性和功能性方面树立了行业标杆。烽火将深入探讨微软企业邮箱的多重优势。 微软…

使用UE5.5的Animator Kit变形器

UE5.5版本更新了AnimatorKit内置插件,其中包含了一些内置变形器,可以辅助我们的动画制作。 操作步骤 首先打开UE5.5,新建第三人称模板场景以便测试,并开启AnimatorKit组件。 新建Sequence,放入测试角色 点击角色右…

应用案例丨坤驰科技双通道触发采集实时FFT数据处理系统

双通道触发采集实时FFT数据处理系统 应用案例 双通道采集,每路通道需要2GSPS的采样率,每2毫秒采集一次,每次采集数据量为65536*2 Sample。采集的信号频率满足奈奎斯特采样定律。采集数据后,每路通道的数据均做运算以及FFT实时处理…