Redis常见数据类型(1)

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

预备知识: 几个全局命令, 数据结构和内部编码, 单线程机制解析.

5种数据类型的特点, 命令使用, 应用场景示例.

键遍历, 数据库管理.

话不多说, 我们来开始认识一下吧.

 预备知识

在正式介绍5种数据类型之前, 了解一下Redis的全局命令, 数据类型和内部编码, 单线程命令的处理机制是十分重要的.

主要体现在两个方面:

(1)Redis的命令有上百个, 如果纯靠死记硬背比较困难, 但是如果理解Redis的一些机制, 会发现这些机制有很强的通用性.

(2)Redis不是万金油, 有些数据结构的命令必须在特定场景下使用, 一旦使用不当可能对Redis本身或者应用本身造成致命伤害.

基本全局命令

最最最最基本的一定要记下了, 否则哥们就这么说吧, 你不知道这相当于没学redis.

set key value; (设定键值对, key是String类型的, value可以是多种数据类型).

get key; (获得键对应的值)

 

KEYS

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

h?llo 匹配hello, hallo, hxllo(?表示的是任意一个字符)

h*llo 匹配hllo, heeeeeello(*匹配的是任意数目的字符,包括0) 

h[ae]llo 匹配hallo, hello(匹配的是a或e)

h[^e]llo 匹配hallo, hbllo...... 但不匹配hello(表示不匹配什么)

h[a-e] 匹配hallo, hbllo...... (匹配的是a-e范围内的字符)

语法:

keys pattern 

时间复杂度: O(N)

返回值: 匹配pattern的所有key 

使用展示:

 

特别注意, 一定要谨慎使用形如keys *这种查询的数据体量非常大的命令, 它可能会导致奔溃!

特别注意, 一定要谨慎使用形如keys *这种查询的数据体量非常大的命令, 它可能会导致奔溃!

特别注意, 一定要谨慎使用形如keys *这种查询的数据体量非常大的命令, 它可能会导致奔溃!

EXISTS

判断某个key是否存在.

语法: 

 exists key [key....]

时间复杂度O(1)

返回值: key存在的个数.

使用展示:

注:第二条hcllo, hdllo不存在, 因此只返回了三个. 

DEL

删除指定的key.

 语法:

DEL key [key...]

时间复杂度:O(1)

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

使用展示:

EXPIRE

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

语法:

EXPIRE key seconds

时间复杂度: O(1)

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

使用展示:

TTL

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

语法:

TTL key 

时间复杂度: O(1)

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

EXPIRE和TTL命令都有对应的支持毫秒为单位的版本: PEXPIRE, PTTL, 详细用法不再展示. 

关于键的过期机制, 如图所示:

TYPE

返回key对应的数据类型.

语法:

TYPE key 

时间复杂度O(1)

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

使用展示:

数据结构和内部编码

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

实际上Redis针对每种数据结构都有自己的底层内部代码实现, 而且是多种实现, 这种Redis会在合适的场景选择合适的内部编码.(我保证一定有这些数据结构的效果, 但我不一定这样实现). 

raw: 长字符串. int: 整数. embstr: 短字符串. 

hashtable:  最基本的哈希表. ziplist:当元素相对较少时, 会使用列表

linkedlist: 链表. intset: 只存整数的集合

skiplist:跳表, 类似于链表, 但每个结点上有多个指针,巧妙地搭配这些指针域的指向, 就可以做到从跳表上查询元素的时间复杂度是O(logN).

注: 从redis3.2开始, 引入了新的实现方式 ->quicklist. 同时兼顾了linkedlist和ziplist的优点, quicklist就是一个链表, 每个元素又是一个ziplist, 把空间和效率都折衷地兼顾到.

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

 

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

Redis这样设计有两个好处:

(1)可以改进内部编码, 而对外的数据类型和命令没有任何影响, 这样一旦开发出更优秀的代码, 无需改动外部数据类型和指令.

(2)多种内部编码实现可以在不同场景下发挥各自的优势. 比如在hash中, 数据量庞大可以使用hashtable提高性能, 而数据量比较小的情况下, 可以使用ziplist以节省内存. 

 单线程架构

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去执行命令的, 但微观角度, 这些命令还是使用线性方式去执行的, 只是原则上命令的执行顺序是不确定的.

这就好比上高中时, 中午准备放学, 大家迫不及待地去食堂干饭, 下课铃一响, 大家都会同时向食堂"冲锋"(客户端同时要求Redis去执行命令的), 虽然是同时去, 但实际到了餐厅后还是要在 窗口排队(微观角度,用线性方式去执行的). 

宏观(同时要求):

围观(有次序地执行): 

Redis的单线程模型:

 

为什么单线程这么快?

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

1.redis访问内存, 其它数据库访问硬盘

2.redis核心功能, 比其它数据库的核心功能简单 (数据库对于数据的插入删除查询等都有更复杂的功能支持. 这样的功能势必要花费更大的开销. 比如针对插入删除, 数据库的各种约束, 都会使数据库额外工作, redis因为活少, 因此功能提供的比mysql少, 但够用).

3.避免了不必要的竞争开销(它的每个基本操作都是短平快, 不是什么特别消耗CPU的操作).

4.处理网络IO的时候, 使用了epoll这样的IO多路复用的机制.

什么是IO的多路复用?

简单来说, 就是通过一个线程, 管理多个socket.

针对TCP来说, 服务器这边每次要服务一个客户端,都要安排一个socket. 

一个服务器服务多个客户端, 同时就有很多个socket, 这些socket上都是无时不刻地在传输数据吗?

不是的, 很多情况下, 每个客户端和服务器之间的通信也没有那么频繁. 此时这么多socket大部分时间都是静默的, 上面是没有数据需要传输的. (同一时刻, 只有少数socket是活跃的).

最开始介绍TCP服务器的时候, 有个版本就是给每个客户端分配一个线程, 客户端多了, 线程多了, 系统开销就大了.

这时, 就可以通过IO多路复用, 用一个线程处理多个socket.

那么怎么通过epoll实现IO多路复用呢?

epoll是目前IO多路复用最高效的机制.

它的工作就类似比如说, 我晚上去小吃摊买饺子, 米线, 煎饼果子三样食物. 由于制作需要时间,因此买完不能直接拿. 而最低效的方法就是买一个等一个, 这样有点慢了. 我换了一个方法, 先把三个都一点, 然后哪个好了我去取(老板叫我取就类似epoll事件通知机制). 这个显然要高效地多. 此时就能让我一个线程同时做到三件事(有一个前提: 这三件事都不频繁, 大部分时间都在等).

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

03-SparkSQL入门

0 Shark Spark 的一个组件,用于大规模数据分析的 SQL 查询引擎。Shark 提供了一种基于 SQL 的交互式查询方式,可以让用户轻松地对大规模数据集进行查询和分析。Shark 基于 Hive 项目,使用 Hive 的元数据存储和查询语法,并基于Hiv…

信号的小波包能量谱计算(以轴承振动信号为例,Python环境)

小波分析是近30年来发展起来的数学分支,是Fourier分析划时代发展的结果,由法国工程师Morlet首先提出,后广泛应用于信号处理、图像处理与分析、地震勘探、故障诊断、自动控制等领域,小波就是小的波形,所谓“小”是指它具…

备忘录导出的HTML文档转换MarkDown尝试记录

备忘录导出的HTML文档转换MarkDown尝试记录 1. pandoc命令行2. HTML转换MARKDOWN3. MD导入CSDN记录过长报错及压缩尝试参考 本地备忘录写了些旅游攻略,想做个纪念,导出为长图片ok,导出为HTML,也可以。但是导出图片是base64格式的&…

2、事件修饰符、双向绑定、style样式使用、v-for循环遍历、v-if 和 v-show

一、事件修饰符 1、.stop 阻止冒泡事件 给谁加了阻止冒泡事件&#xff0c;谁下面的盒子就不会执行了 <div id"app"><div class"parent" click"log3"><div class"child" click"log2"><button click.…

厨师上门服务小程序开发与运营指南

随着移动互联网的普及&#xff0c;各种生活服务类APP应运而生。厨师上门服务小程序作为一种新型的服务模式&#xff0c;为用户提供了便捷、个性化的餐饮服务。本文将为您介绍厨师上门服务小程序的开发与运营方法&#xff0c;帮助您快速搭建起一款实用的小程序。 一、小程序开发…

MyEclipse打开文件跳转到notepad打开问题

问题描述 windows系统打开README.md文件&#xff0c;每次都需要右键选择notepad打开&#xff0c;感觉很麻烦&#xff0c;然后就把README.md文件打开方式默认选择了notepad&#xff0c;这样每次双击就能打开&#xff0c;感觉很方便。 然后某天使用MyEclipse时&#xff0c;双击RE…

Linux系统——硬件命令

目录 一.网卡带宽 1.查看网卡速率——ethtool 网卡名 2.查看mac地址——ethtool -P 网卡名 二、内存相关 1.显示系统中内存使用情况——free -h 2.显示内存模块的详细信息——dmidecode -t memory 三、CPU相关 1.查看CPU架构信息——lscpu 2.性能模式 四、其他硬件命…

网络:DHCP 协议简介

文章目录 1. 前言2. DHCP 协议简介2.1 DHCP 客户端广播 DHCPDISCOVER 消息2.2 DHCP 服务器回复 DHCPOFFER 消息2.3 DHCP 客户端广播 DHCPREQUEST 消息2.4 DHCP 服务器回复 DHCPACK 消息2.5 剩余的工作 3. 参考资料 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&…

h5增强表单---数据列表和属性

h5增强表单---数据列表 下拉列表 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</ti…

Echarts功能记录

基础配置 工具箱toolbox 对应功能 案例中使用到的第三方脚本

力扣450 删除二叉搜索树中的节点 Java版本

文章目录 题目描述思路代码 题目描述 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;删除…

学生如何帮老师撰写审稿意见

开头先介绍这篇文章做了什么&#xff0c;达到了什么样的目的、有什么创新点、应用&#xff0c;然后第一段最后一句写上&#xff0c;如果你进行了如下补充&#xff0c;明确表达了相关内容等&#xff0c;就能够接收你的文章&#xff08;在我们暂时不想接收他的文章的情况下&#…

JetPack之ViewModel

目录 一、简介1.1 优点1.2 生命周期 二、使用2.1 ViewModel保证数据稳定性demo2.2 ViewModel中如何传递上下文Context 三、注意点 一、简介 ViewModel 组件用于管理界面相关的数据&#xff0c;并且在配置更改&#xff08;如屏幕旋转&#xff09;时保持数据的一致性。ViewModel…

不可变集合及Stream流

若希望某个数据是不可修改的&#xff0c;就可以考虑使用不可变集合&#xff0c;以提高安全性&#xff1b;&#xff08;JKD9之后才有&#xff09; List不可变集合&#xff1a; public static void main(String[] args) {/*创建不可变的List集合"张三", "李四&q…

快速修复找不到msvcp140.dll,无法继续执行此代码问题

在电脑使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“无法找到msvcp140.dll”的错误。那么&#xff0c;msvcp140.dll究竟是什么呢&#xff1f;它为什么会出现这样的错误呢&#xff1f;通过查阅资料和自己的实践经验&#xff0c;我对msvcp140.dll…

odoo 官方常用 widgets 小部件清单

在Odoo中&#xff0c;小部件&#xff08;Widgets&#xff09;是用于构建用户界面的组件&#xff0c;它们决定了表单、列表视图以及更多交互元素的显示和行为方式。虽然无法提供Odoo14及之后所有版本的确切小部件清单&#xff0c;但可以列举一些常见和重要的内置小部件类型&…

11.创建后台系统项目

后台系统项目 兼容性 vite官网&#xff1a;https://vitejs.dev/ vite中文网&#xff1a;https://cn.vitejs.dev/ vite需要node.js版本 >14.0.0&#xff0c;建议16 node -v 查看版本号 创建项目 进入存放目录 执行命令 npm create vitelatest 选择vue框架 选择typescript…

V R元宇宙平台的未来方向|V R主题馆加 盟|游戏体验馆

未来&#xff0c;VR元宇宙平台可能会呈现出以下发展趋势和可能性&#xff1a; 全面融合现实与虚拟世界&#xff1a; VR元宇宙平台将更加无缝地融合现实世界和虚拟世界&#xff0c;用户可以在虚拟环境中进行各种活动&#xff0c;与现实世界进行互动&#xff0c;并且体验到更加逼…

【PostGresql】------ pg多表数据多个条件汇总 使用 union 方法示例代码

1. 示例代码如下&#xff1a; SELECT"ID","DT_DATE","CNAME","RMAN_NAME","DEP_NAME","DEP_ID","INVEST_MAN_NAME","TYPE_NAME","INVEST_LEVEL_NAME","POSITION_NAME",…

详细教程与使用指南助您轻松上手Sora

在2024年2月16日&#xff0c;OpenAI团队宣布了一项革命性的技术突破——推出了首个能够将文本描述转化为视频内容的人工智能模型&#xff0c;名为Sora。这一创新标志着人工智能在多媒体内容创作领域迈出了重要一步。Sora模型不仅能够根据用户的文字描述生成长达60秒的动态视频&…