深入剖析Redis系列 – Redis数据结构与全局命令概述

作者 : 开心源码 本文共3505个字,预计阅读时间需要9分钟 发布时间: 2022-05-12 共169人阅读

前言

Redis?提供了?5?种数据结构。了解每种数据结构的特点,对于?Redis?的?开发运维?非常重要,同时掌握?Redis?的?单线程命令解决?机制,会使?数据结构?和?命令?的选择事半功倍。

接下来的几篇文章,将从如下几个方面详情?Redis?的几种数据结构,命令使用及其应用场景。

预备知识:几个简单的?全局命令数据结构?和?内部编码单线程命令?解决机制分析。

数据结构特性:5?种?数据结构?的特点、命令使用应用场景

数据管理键管理遍历键数据库管理

正文

1. 预备知识

在详情?5?种?数据结构?之前,需要先理解?Redis?的少量?全局命令数据结构?和?内部编码单线程命令解决机制

Redis?的命令有?上百个,了解?Redis?的少量机制,会发现这些命令有很强的?通用性

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

2. 全局命令

Redis?有?5?种?数据结构,它们是?键值对?中的?,对于??来说有少量通用的命令。

2.1. 查看所有键

keys *

下面插入了?3?对字符串类型的键值对:

127.0.0.1:6379>?set?hello?world?OK?127.0.0.1:6379>?set?java?jedis?OK?127.0.0.1:6379>?set?python?redis-py?OK?复制代码

命令会将所有的键输出:

127.0.0.1:6379>?keys?*?1)?”python”?2)?”java”?3)?”hello”?复制代码

2.2. 键总数

dbsize

下面插入一个?列表类型?的?键值对(值是?多个元素?组成):

127.0.0.1:6379>?rpush?mylist?a?b?c?d?e?f?g?(integer)?7?复制代码

dbsize?命令会返回当前数据库中?键的总数

127.0.0.1:6379>?dbsize?(integer)?4?复制代码

dbsize?命令在?计算键总数?时?不会遍历?所有键,而是直接获取?Redis?内置的键总数变量,所以?dbsize?命令的?时间复杂度?是?O(1)。而?keys?命令会?遍历?所有键,所以它的?时间复杂度?是?O(n),当?Redis?保存了?大量键?时,线上环境?禁止?使用。

2.3. 检查键能否存在

exists key

假如键存在则返回?1,不存在则返回?0:

127.0.0.1:6379>?exists?java?(integer)?1?127.0.0.1:6379>?exists?not_exist_key?(integer)?0?复制代码

2.4. 删除键

del key

del?是一个?通用命令,无论值是什么?数据结构?类型,del?命令都可以将其?删除

127.0.0.1:6379>?del?java?(integer)?1?127.0.0.1:6379>?exists?java?(integer)?0?127.0.0.1:6379>?del?not_exist_key?(integer)?0?127.0.0.1:6379>?exists?not_exist_key?(integer)?0?复制代码

返回结果为?成功删除?的?键的个数,假设删除一个?不存在?的键,就会返回?0。

2.5. 键过期

expire key seconds

Redis?支持对??增加?过期时间,当超过过期时间后,会?自动删除键,例如为键?hello?设置?10?秒过期时间:

127.0.0.1:6379>?set?hello?world?OK?127.0.0.1:6379>?expire?hello?10??(integer)?0?复制代码

ttl?命令会返回键的?剩余过期时间,它有?3?种返回值:

大于等于?0?的整数:表示键?剩余?的?过期时间

返回?-1:?没设置?过期时间

返回?-2:?不存在。

可以通过?ttl?命令观察??hello?的?剩余过期时间

#?还剩7秒?127.0.0.1:6379>?ttl?hello(integer)??(integer)?7?…?#?还剩1秒?127.0.0.1:6379>?ttl?hello(integer)??(integer)?1?#?返回结果为-2,说明键hello已经被删除?127.0.0.1:6379>?ttl?hello(integer)??(integer)?-2?127.0.0.1:6379>?get?hello?(nil)?复制代码

2.6. 键的数据结构类型

type key

例如键?hello?是的值?字符串类型,返回结果为?string。键?mylist?的值是?列表类型,返回结果为?list。假如键不存在,则返回?none。

127.0.0.1:6379>?set?a?b?OK?127.0.0.1:6379>?type?a?string?127.0.0.1:6379>?rpush?mylist?a?b?c?d?e?f?g?(integer)?7?127.0.0.1:6379>?type?mylist?list?复制代码

3. 数据结构和内部编码

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

对于每种?数据结构,实际上都有自己底层的?内部编码?实现,而且是?多种实现。这样?Redis?会在合适的?场景?选择合适的?内部编码,如图所示:

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

127.0.0.1:6379>?object?encoding?hello?”embstr”?127.0.0.1:6379>?object?encoding?mylist?”quicklist”?复制代码

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

Redis?这样设计有两个好处:

其一:可以改进?内部编码,而对外的?数据结构?和?命令?没有影响。例如?Redis3.2?提供的?quicklist,结合了?ziplist?和?linkedlist?两者的优势,为?列表类型?提供了一种?更加高效?的?内部编码实现

其二:不同?内部编码?可以在?不同场景?下发挥各自的?优势。例如?ziplist?比较?节省内存,但是在列表?元素比较多?的情况下,性能?会有所?下降,这时候?Redis?会根据?配置,将列表类型的?内部实现?转换为?linkedlist。

4. 单线程架构

Redis?使用了?单线程架构?和?I/O?多路复用模型?来实现?高性能?的?内存数据库服务。那为什么?单线程?还能这么快,下面分析起因:

4.1. 纯内存访问

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

4.2. 非阻塞I/O

Redis?使用?epoll?作为?I/O?多路复用技术?的实现,再加上?Redis?自身的?事件解决模型?将?epoll?中的?连接读写关闭?都转换为?事件,从而不用不在?网络?I/O?上白费过多的时间,如图所示:

4.3. 单线程避免线程切换和竞态产生的消耗

采用?单线程?就能达到如此?高的性能,那么不失为一种不错的选择,由于?单线程?能带来几个好处:

单线程?可以简化?数据结构和算法?的实现,开发人员不需要理解复杂的?并发数据结构

单线程?避免了?线程切换?和?竞态?产生的消耗,对于服务端开发来说,锁和线程切换?通常是性能杀手。

单线程?的问题:对于?每个命令?的?执行时间?是有要求的。假如某个命令?执行过长,会造成其余命令的?阻塞,对于?Redis?这种?高性能?的服务来说是致命的,所以?Redis?是面向?快速执行?场景的数据库。

小结

本文堆?Redis?的几种?数据结构?进行了概述,详情了几个简单的?全局命令数据结构?和?内部编码?以及?单线程命令?解决机制分析。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 深入剖析Redis系列 – Redis数据结构与全局命令概述

发表回复