【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…

centos7 yum install 失败,mirrorlist.centos.org连接不上

由于centos7停止支持,导致mirrorlist.centos.orgdns解析都是失效啦,yum命令没法安装程序. 换一个镜像源就好 sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/…

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

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

JVM 常见面试题及解析(2024)

目录 一、JVM 基础概念 二、JVM 内存结构 三、类加载机制 四、垃圾回收机制 五、性能调优 六、实战问题 七、JVM 与其他技术结合 八、JVM 内部机制深化 九、JVM 相关概念拓展 十、故障排查与异常处理 一、JVM 基础概念 1、什么是 JVM?它的主要作用是…

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

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

鸿蒙一次开发,多端部署,响应式布局

鸿蒙一次开发,多端部署,响应式布局 一、定义屏幕相关常量 BreakpointConstants.ets import BreakpointType from ../bean/BreakpointType export default class BreakPointConstants{/*** 小屏幕设备的Breakpoints 标记*/static readonly BREAKPOINT_…

ubuntu防火墙入门(一)——设置服务、关闭端口

本机想通过git clone gitgithub.com:skumra/robotic-grasping.git下载代码,firewall-config中需要为当前区域的防火墙开启SSH服务吗 是的,如果你想通过 git clone gitgithub.com:skumra/robotic-grasping.git 使用 SSH 协议从 GitHub 下载代码&#xff0…

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

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

js:函数

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

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

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

前端网络安全分析

前端常见的网络安全包括:xss(跨站脚本攻击)、csrf(跨站请求伪造)、sql注入攻击等。 1)跨站脚本攻击(xss) 原理: 攻击者往web页面中注入恶意 script 代码(或…

【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项目资产到当前项目 - 不用另外打开资产项目查看资产,迁移资产(麻烦) 插件官网插件文档插…

macOS 桌面悬浮窗口

开发一个 macOS 桌面悬浮窗口(类似悬浮工具条、任务管理器等)可以使用 macOS 的 AppKit 框架,通过配置窗口属性,使窗口始终显示在其他应用窗口的上方。以下是开发的详细步骤: 关键点 窗口类型 使用 NSWindow 创建悬浮窗口。将窗口设置为浮动窗口,使其始终显示在其他窗口上…

GitLab/GitHub 多环境配置SSH密钥

需求: 代码有多个仓库,需要配置不同的密钥。 生成密钥(有的可以跳过) ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" -f ~/.ssh/id_rsa_custom_name-t rsa 指定使用 RSA 算法。-b 4096 指定密钥长度为 4096 位…

力扣整理版十:动态规划(待更新)

动态规划:每一个状态由上一个状态推导出来。 --------------------------- (1) 509 斐波那契数 (2) 70 爬楼梯 (3) 746 使用最小花费爬楼梯 --------------------------- 一、基础题目 1、509 斐波那契数 509. 斐波那契数 - 力扣(LeetCode&#…

黑马2024AI+JavaWeb开发入门Day02-JS-VUE飞书作业

视频地址&#xff1a;哔哩哔哩 讲义作业飞书地址&#xff1a;飞书 一、作业1 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">&l…

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

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