前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Redis 中的数据库

Redis 中的数据库

作者头像
Single
发布于 2019-12-16 03:39:55
发布于 2019-12-16 03:39:55
1.3K00
代码可运行
举报
运行总次数:0
代码可运行

前面我们花了很多的时间介绍了 redis 中基本的数据结构,及其内部的实现情况,这些都是非常基础的东西,可能不经意间你就会用到他们,希望你花点时间了解一下。

接下来,我们将走近 redis 数据库,学习各种操作 redis 的命令,并介绍它的一些实现策略以及集群配置等等内容。

一、redis 中的数据库

server.h/redisServer 结构中有一个字段,db 字段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
redisDb *db;

db 被定义成一个 redisDb 数组,其中 redisDb 的定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
typedef struct redisDb {
    dict *dict;                 
    dict *expires;              
    dict *blocking_keys;        
    dict *ready_keys;          
    dict *watched_keys;         
    int id;                    
    long long avg_ttl;      
} redisDb;

我们经常说 redis 具有十六个数据库,可以切换不通的数据库做数据隔离,这里你就可以将一个 redisDb 实例理解为一个数据库,而 db 指针则可以访问 redis 预定义的所有数据库。

其中,dict 是一个字典结构,用于实际存储数据,expires 也是一个字典结构,它存储的是数据库中所有设置过期时间的键值对,保存他们的过期时间,是一个 UNIX 时间戳。

blocking_keys 存储了被阻塞的键集合,ready_keys 存储的是可以解除阻塞的键集合,watched_keys 存储的是正在被 watch 命令监控的键的集合,id 记录的是当前数据库的一个编号,avg_ttl 收集了所有键剩余存活时间的一个平均值。这一部分的几个字段的值这里不做详细的解释,没有基本的知识储备,不容易理解的,后面我们还会遇到的。

server.h/redisServer 结构中还有一个字段,dbnum 字段:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int dbnum;  /* Total number of configured DBs */

与此同时,redis.conf 配置文件中,默认有这么一项配置。

所以,我们启动 redis-server 的时候,会根据配置文件中给定的配置默认创建 16 个数据库。

1、select 命令

select 命令用于我们切换数据库,例如:

默认连接上 redis-server 的客户端使用 0 号数据库,鉴于 redis 并没有提供给客户端查询当前使用数据库编号的命令,所以建议执行 redis 命令之前,尤其是修改、添加命令,先执行下切换数据库的命令。

2、set 命令

set 命令其实无需过多介绍,它向数据库中添加一个键值对,大部分情况下,键会是一个字符串对象,而值可取我们 redis 的五大对象之一。

因为 redisDb 底层是字典结构,键不允许重复,故而 set 命令同样适用于更新操作。

3、del 命令

del 命令用于删除数据库中一个键值对,标准语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
del [KEY]

例如:

4、get 命令

get 命令用于获取一个键值对的值,标准语法是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
get [KEY]

具体事例就不再演示了,get 命令对应于 set 命令,只能获取由 set 命令添加的字符串对象键值对,而例如一些集合对象,或列表对象需要用类似于 sadd、zadd 等命令进行数据库的添加,自然 get 命令也是无法得到这些键值对对象值的。

5、其他命令

第一个我们介绍 dbsize 命令,它返回当前数据库有多少键值对,基本语法格式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dbsize

第二个我们要介绍的是 flushdb 命令,它用于清空当前数据库,这是一个非常危险的命令,谨慎使用,基本语法格式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
flushdb

第三个我们要介绍一个 kyes 命令,它会返回数据库中所有符合匹配规则的键的集合,这个规则起初我以为是正则表达式,几番操作后发现匹配不上,查阅资料貌似不是正则,并且仅有以下三种规则:

  1. ?:用于匹配单个字符
  2. *:用于匹配零个或者多个字符
  3. []:可以用来指定模式的选择区间

正则表达式中的问号,用于匹配前一个字符出现零次或一次,即要么出现要么不出现,而我们这里的 keys 模式,问号具有不同的意义。

不过 keys 命令这种遍历整个数据库的命令是非常耗 CPU 的,可能会导致 redis 性能下降,不做推荐使用。

最后还有一个简单的命令就是 exists,它用于判断给定的 key 是否存在,返回 0 说明不存在,返回 1 说明存在。

二、过期键

有的时候我们希望给某些键一个过期时间,即希望它存活一段时间就失效,我们 redis 为我们提供了这样的机制。

1、expire

expire 用于设定某个键的过期时间,单位是秒,基本语法格式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
expire [key] [time]

可以看到,五秒后 redis 为我们删除了键 hello。与之对应的有一个命令 pexpire,他会将我们传入的 time 参数解析为毫秒,例如 「pexpire hello 5」会将键通过五毫秒之后删除。

2、expireat

expireat 用于设定某个键在某个具体 Unix 时间戳过期,单位秒,基本语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
expireat [key] [time]

过期键会在我们指定 Unix 时间戳别删除。当然它也有一个对应毫秒单位的命令,pexpireat ,他会解析命令参数时间戳为毫秒,也就是你需要传入的时间戳不再是秒单位的,而是毫秒单位的时间戳。

3、ttl 和 pttl

这两个命令用于查看某个过期键还剩余多少时间,基本语法格式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ttl/pttl [key]

ttl 命令输出的单位是秒,pttl 输出的单位是毫秒,仅此区别。

4、persist

persist 用于移除某个过期键的过期时间,也就是让这个键成为永久有效键。基本语法格式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
persist [key]

以上就是 redis 中过期键相关的命令,之前也说过,redisDb 数据结构中有一个 expires 字典,它存储的就是库中所有过期键以及他们生存截止时间。

那么,你可能会好奇了,redis 只记录了某个过期键的截止有效时间,那么什么时候删除这些过期键呢?

三、过期键删除策略

因为 redis 通过 expires 字典记录所有的过期键以及他们的过期时间(一个 Unix时间戳),那么我们只需要比对当前系统时间戳 Unix 是否大于键的过期时间戳即可判断键是否过期。

我们直接介绍 redis 使用的两种删除策略,定期删除和惰性删除。

  1. 定期删除:redis 每间隔一段时间进行一次小规模,有限时长的删除过期键操作。
  2. 惰性删除:redis 每次读取某个键的时候,会先判断这个键是否过期,如果过期,执行删除操作。

这两个策略,每一个都有缺点,定期删除需要每间隔一段时间触发一次删除,所以需要用户对系统的业务量、请求峰谷点有熟悉的的了解,才能配置合适的频率,否则过于高频会平白增加 CPU 压力,过于低频会导致内存中过多无用内存占用,降低系统性能。

而惰性删除缺点非常直接,如果某些键过期了,且程序永远不会访问这些键,那么 redis 就永远不会释放这些键占用的内存,进而导致内存泄漏。

redis 中同时使用了这两种删除策略,一方面,每次读取键的时候会调用方法 db.c/expireIfNeeded 判断当前键是否过期,如果过期则删除并返回 nil。另一方面,redis 中有一个定期的时间事件函数,server.c/serverCron,每次执行都会收集与更新一些与服务器状态相关的信息,比如更新服务器时间、计算对象空转时长,管理客户端连接资源的释放等等。

其中也会执行一个 expire.c/activeExpireCycle 函数,默认配置了一千微妙内返回,activeExpireCycle 会在时间内选定数据库,随机的处理这些过期键,并给予删除。

所以,其实上 redis 通过这两种策略的结合,定期删除保证不存在某些过期键永远得不到删除以进而引发内存泄漏,惰性删除使得 redis 不用集中大量时间处理这些过期键以引起 CPU 负载过大。

下一节,我们讲 redis 如何做持久化存储,毕竟数据放在内存,一旦服务器宕机、断点,所有数据都会丢失,所以我们也需要将数据备份磁盘。下节见~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
PWN从入门到放弃(1)——PWN环境搭建
本文主要介绍利用ubuntu搭建pwn做题环境,包括pwntools,gdb,gdb-pwndbg,gdb-peda,libc库等
山深有杏
2024/01/30
9180
逆向工具pwntools和pwndbg的心酸安装史
这两天安装逆向工具 pwntools 和 pwndbg 可把爷给整懵了,由于 IDA Pro 在 Windows 上运行,所以用双系统的话不方便,一般都是虚拟机或者子系统安装这两个工具,但我尝试了各种方法,最后还是在自己双系统 ubuntu 上成功安装,这就来记录一下踩过的坑。
棒棒鸡不棒
2022/09/01
8.8K0
逆向工具pwntools和pwndbg的心酸安装史
【详解】安装免杀工具Veil-Evasion
Veil-Evasion 是一个用于生成绕过防病毒软件的恶意代码的开源框架。它支持多种语言和编码方式,能够帮助安全研究人员测试和评估防病毒软件的有效性。本文将详细介绍如何在Kali Linux系统上安装和配置 Veil-Evasion。
大盘鸡拌面
2025/01/15
1770
解决安装PyMySQL一直停在Building wheels for collected package:cryptography, cffi, pycparser的问题
  因为项目需要,我在树莓派上搭建了基于python编程的Django的web框架,需要从MySQL中读取树莓派以及传感器的数据,而Python3是不带PyMySQL的,所以就需要我们自行安装。
墨文
2020/02/28
5K0
解决安装PyMySQL一直停在Building wheels for collected package:cryptography, cffi, pycparser的问题
ubuntu上安装scrapy框架
Scrapy的安装有多种方式,它支持Python2.7版本及以上或Python3.3版本及以上, scrapy的依赖库比较多,而且各个平台的都不一样,这里我只介绍在debian/ubuntu下如何安装scrapy,以及我遇到的一些问题,windows用户自行百度了,哈哈(懒)
kevinfaith
2018/09/18
2.3K0
宝塔面板升级python3
Python 是一种广泛使用的高级编程语言,因其简洁的语法和丰富的库而受到开发者的喜爱。在许多Web应用程序和后端开发环境中,Python已成为一种重要的工具。因此,在使用如宝塔面板这样的服务器管理工具时,保持Python的更新是非常重要的。
秋月叶落
2025/03/05
1350
宝塔面板升级python3
ubuntu安装python3(源码安装方法)
(第0步)建议配置阿里镜像https://developer.aliyun.com/mirror/ubuntu
全栈程序员站长
2022/09/10
1.1K0
技巧总结-2018-06
MongoDB的聚合查询中,$substr只能匹配ASCII的数据,对于中文要使用$substrCP
青南
2018/08/31
5370
技巧总结-2018-06
fabric+supervisor+n
celery+virtualenv+supervisor的情形,其实只要指定celery程序为virtaulenv下面的那个即可,例如/home/xby/venv/mdwiki/bin/celery
py3study
2020/01/06
6270
如何在Ubuntu 18.04上安装Python 3并设置编程环境[快速入门]
Python是一种灵活多样的编程语言,在脚本编写,自动化,数据分析,机器学习和后端开发方面具有优势。
好烟
2018/10/10
9.2K0
Redash 二开 - 后端环境搭建
官方文档有一句话:Windows users: while it should be possible to run Redash on a Windows machine, we don’t know anyone who did this and lived to tell. We recommend using some sort of a virtual machine or Docker in such case. 当时没有注意,后面掉在坑里了,若对 Redash 进行二开,务必不要使用 Windows:第一点 Redash 依赖的 Python 包在Windows安装,本地编译的时候各种报错,不过还算都能解决。最要命的是第二点,某些包依赖的标准库模块,Windows 上没有,比如 group pwd 等。经过一下午和包安装的战斗,总算解决了,最后信心满满的想跑起来的时候,各种模块找不到。
晓晨
2020/10/10
2.8K0
Redash 二开 - 后端环境搭建
Ubuntu14.04安装Python3
Scrapy已经支持Python3了https://blog.scrapinghub.com/2016/02/04/python-3-support-with-scrapy-1-1rc1/
py3study
2020/01/13
1.1K0
Linux安装Python3.7
https://www.python.org/downloads/release/python-370/
py3study
2020/01/06
2.1K0
Linux安装Python3.7
CentOS/Ubuntu编译安装Python 3.9.10《详细》
指剑
2023/05/31
8090
scrapy安装步骤_scrapy安装教程
Scrapy的安装有多种方式,它支持Python2.7版本及以上或Python3.3版本及以上。下面说明Python3 环境下的安装过程。 Scrapy依赖的库比较多,至少需要依赖库有Twisted 14.0,lxml 3.4,pyOpenSSL 0.14。而在不同平 台环境又各不相同,所以在安装之前最好确保把一些基本库安装好,尤其是Windows。
全栈程序员站长
2022/10/02
3.9K0
scrapy安装步骤_scrapy安装教程
Python安装报错:”ModuleNotFoundError:No module named _ctypes“ 的解决方案[通俗易懂]
# 下载地址:https://www.python.org/ftp/python/
Java架构师必看
2022/06/06
5.9K0
如何在Ubuntu 18.04上安装Python 3并设置本地编程环境
Python是一种灵活的多功能编程语言,可用于许多实例中,在脚本撰写,自动化,数据分析,机器学习和后端开发方面具有优势。1991年首次出版,其名称灵感来自英国喜剧组织Monty Python,开发团队希望使Python成为一种有趣的语言。可以快速被设置,并以相对简单的方式编写并立即反馈错误,Python是初学者的绝佳选择但同样也是经验丰富的开发人员的绝佳选择。Python 3是该语言的最新版本,被认为是Python的未来。
物花无语
2018/10/09
2.8K0
docker部署jenkins安装使用教程_docker封装python程序
使用docker安装jenkins环境,jenkins构建的workspace目录默认是在容器里面构建的,如果我们想执行python3的代码,需进容器内部安装python3的环境。
全栈程序员站长
2022/09/16
7740
如何在Ubuntu 18.04服务器上安装Python 3和设置编程环境
Python是一种灵活且通用的编程语言,可在许多用例中利用,在脚本,自动化,数据分析,机器学习和后端开发方面具有优势。开发团队于1991年首次发布,其名称受到英国喜剧团体Monty Python的启发,开发团队希望使Python成为一种有趣的语言。Python设置迅速,并且以相对简单的风格编写,可以立即对错误进行反馈,对于初学者和经验丰富的开发人员而言,Python是一个不错的选择。Python 3是该语言的最新版本,被认为是Python的未来。
Python研究者
2020/09/28
1.6K0
如何在Debian 9上安装Python 3并设置编程环境
Python是一种灵活多样的编程语言,可用于许多用例,包括脚本,自动化,数据分析,机器学习和后端开发。1991年首次出版,其名称灵感来自英国喜剧组织Monty Python,开发团队希望使Python成为一种有趣的语言。快速设置,并以相对简单的方式编写并立即反馈错误,Python是初学者和经验丰富的开发人员的绝佳选择。Python 3是该语言的最新版本,被认为是Python的未来。
陈树丶
2018/11/05
4.7K0
推荐阅读
相关推荐
PWN从入门到放弃(1)——PWN环境搭建
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档