【中间件开发】Redis基础命令详解及概念介绍

news2025/1/16 5:02:15

文章目录

  • 前言
  • 一、Redis相关命令详解及原理
    • 1.1 string、set、zset、list、hash
      • 1.1.1 string
      • 1.1.2 list
      • 1.1.3 hash
      • 1.1.4 set
      • 1.1.5 zset
    • 1.2 分布式锁的实现
    • 1.3 lua脚本解决ACID原子性
    • 1.4 Redis事务的ACID性质分析
  • 二、Redis协议与异步方式
    • 2.1 Redis协议解析
      • 2.1.1 redis pipeline
      • 2.1.2 Redis协议图
    • 2.2 特殊协议操作-订阅发布
    • 2.3 异步redis协议
      • 2.3.1 hiredis + libevent
  • 总结


前言

本文介绍了Redis相关命令以及Redis当中的一些概念(协议)。


一、Redis相关命令详解及原理

内存是稀缺资源,所以:

  1. 当数据量少时,存储效率高为主
  2. 当数据量多时,运行速度快为主

1.1 string、set、zset、list、hash

  1. string 是一个安全的二进制字符串(兼容’\0’作为分隔符,安全指按长度);
  2. 双端队列 (链表) list :有序(插入有序);
  3. 散列表 hash:对顺序不关注,field 是唯一的;
  4. 无序集合 set:对顺序不关注,里面的值都是唯一的;
  5. 有序集合 zset :对顺序是关注的,里面的值是唯一的;根据 member 来确定唯一;根据 score 来 确定有序;

1.1.1 string

set key_test 1000

get key_test

# 原子减一
decr key_test
decrby key_test decrement(一个数字)

# 原子加一
incr key_test
incrby key_test increment

# set Not exist,当key_test存在时,什么也不做,否则等同于set
setnx key_test value
del key_test

----------
# 
setbit key_test offset value
# 第offset位设置为value
getbit key_test offset
# 统计字符串被设置为1的bit数
bitcount key_test
----------

image.png

image.png
image.png

应用

  1. 对象存储:set,get
  2. 累加器:incr
  3. 分布式锁:setnx
  4. 位运算:setbit,getbit,bitcount

1.1.2 list

双向链表,首尾操作时间复杂度O(1);中间元素操作O(n)

  1. list.size < 48 不压缩
  2. 元素压缩前后长度差不超过8,不压缩

为什么压缩?如何压缩的?

# 从队列左侧入队
lpush key value ...
lpop key

# 从队列右侧入队
rpush key value ...
rpop key 

# 尾索引
lrange key start end

# 从存于 key 的列表里移除前 count 次出现的值为 value 的元素
lrem key count value

# rpop的阻塞版本
brpop key timeout

image.png

应用

  1. 栈:lpush + lpop
  2. 队列:lpush + rpop
  3. 阻塞队列:lpush + brpop
  4. 异步消息队列
    1. 操作和队列一样,但是在不同系统间;生产者和消费者;
  5. 获取固定窗口记录
    1. ltrim key 0 4 保留最近5条记录

1.1.3 hash

散列表;C++ unordered_map

(节点数量 > 512 || 所有字符串长度 > 64) 采用dict
(节点数量 <= 512 || 所有字符串长度 < 64) 采用ziplist

hget key field
hgetall

hset key field value
# 设置多个键值对
hmset key field1 value1 field2 value2 field3 value3 ... fieldn valuen

hmget key field1 field2 ...

hincrby key field increment
# 获取有多少个键值对
hlen key

hdel key field

image.png

应用

  1. 存储对象
  2. 购物车:商品列表用list,其中属性用hash

1.1.4 set

无序集合

(元素都为整数 && 节点数量 <= 512) 采用整数数组存储
(元素不全为整数 || 节点数量 > 512) 采用字典存储

# 添加一个或多个
sadd key member ...
# 计算集合元素个数
scard key

smembers key
# 返回成员member是否为key的成员
sismember key member
# 随机返回key集合中的一个或多个元素
srandmember key [count]
# 移除一个随机元素
spop key [count]
# 返回差集
sdiff key [key...]
# 返回交集
sinter key [key...]
# 返回并集
sunion key [key...]

image.png

应用

  1. 抽奖:srandmember
  2. 共同关注:sdiff ; sinter; sunion

1.1.5 zset

有序集合;实现排行榜;有序唯一


zadd key 
# 从key中删除member的键值对
zrem key member [member...]
# 返回有序集key中member的score值
zscore key member
# 成员member的score值加上增量
zincrby key increment member
# 返回个数
zcard key
# 返回排名
zrank key member
# 返回指定范围的元素
zrange key start stop
# 返回指定范围的元素(逆序)
zrevrange key start stop

image.png

应用

  1. 百度热榜
  2. 延时队列
  3. 分布式定时器
  4. 时间窗口限流

1.2 分布式锁的实现

释放锁操作:事务操作

锁:谁持有,谁释放

get dislock

-- 释放锁
local uuid = redis.call("get", KEYS[1])
if uuid == KEYS[2] then
	redis.call("del", KEYS[1])
end

1.3 lua脚本解决ACID原子性

# 开启事务
multi

# 提交事务
exec

# 取消事务
discard

# 检测key的变动
watch

实际中是使用lua脚本
  • redis 中加载了一个 lua 虚拟机;用来执行 redis lua 脚本;
  • redis lua 脚本的执行是原子性的;
  • 当某个脚本正在执行的时候,不会有其他命令或者脚本被执行;
  • lua 脚本当中的命令会直接修改数据状态;
  • lua 脚本 mysql 存储区别:MySQL存储过程不具备事务性,所以也不具备原子性;

注意:如果项目中使用了 lua 脚本,不需要使用上面的事务命令
image.png

1.4 Redis事务的ACID性质分析

  • A 原子性;事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败;redis 不支持回滚;即使事务队列中的某个命令在执行期间出现了错误,整个事务也会继续执行下去,直 到将事务队列中的所有命令都执行完毕为止。

  • C 一致性;事务的前后,所有的数据都保持一个一致的状态,不能违反数据的一致性检测;这里 的一致性是指预期的一致性而不是异常后的一致性;所以 redis 也不满足;这个争议很大:redis 能 确保事务执行前后的数据的完整约束;但是并不满足业务功能上的一致性;比如转账功能,一个扣 钱一个加钱;可能出现扣钱执行错误,加钱执行正确,那么最终还是会加钱成功;系统凭空多了 钱;

set zhang 1000
lpush zhang 1 3 4 #error
get mark
  • I 隔离性;各个事务之间互相影响的程度;redis 是单线程执行,天然具备隔离性;

  • D 持久性;redis 只有在 aof 持久化策略的时候,并且需要在 appendfsync=always 才具备持久性;实际项目中几乎不会使用 redis.conf 中 aof 持久化策略;

  • 面试时候回答:lua 脚本满足原子性和隔离性;一致性和持久性不满足;

get zhang ==>100

set zhang 200

如果这两个命令没有作为一个整体,那么可以会有另一条连接set。这将导致数据不一致。

什么时候探讨事务?多条并发连接
什么时候探讨原子操作?多核

二、Redis协议与异步方式

2.1 Redis协议解析

2.1.1 redis pipeline

redis pipeline 是一个客户端提供的机制,而不是服务端提供的;

注意:pipeline 不具备事务性;

目的:节约网络传输时间;

通过一次发送多次请求命令,从而减少网络传输的时间。

image.png

2.1.2 Redis协议图

image.png

上图描述了如何界定数据包:

  1. 长度 + 二进制流
  2. 二进制流 + 特殊分割符

2.2 特殊协议操作-订阅发布

为了支持消息的多播机制,redis引入了发布订阅:发送者发送消息,订阅者接收消息。

# 订阅频道
subscribe `channel`
# 订阅模式频道
psubscribe `channel`
# 取消订阅频道
unsubscribe `channel`
# 发布具体频道或模式频道的内容
publish `channel` `message`
# 客户端接收具体频道内容
message `specificChannel` `message`
# 客户端接收模式频道内容
pmessage

应用

  1. 发布订阅可以收到redis主动推送的内容
  2. 项目中支持发布订阅,需要另开一条连接

缺点

  1. 生产者传递来一条消息,redis找到相应的消费者并传递过去,如果没有消费者,消息丢弃;
  2. 如果有两个消费者,此时其中一个消费者挂掉了,重连上来将不会接收到该消息;
  3. redis停机重启,发布订阅的消息不会持久化。

2.3 异步redis协议

同步连接方案采用阻塞IO来实现
优点:代码书写是同步的,业务逻辑不割裂
缺点:阻塞当前线程,直到返回结果,通常需要多个线程来实现线程池来解决效率问题。

异步连接方案采用非阻塞IO来实现
优点:不阻塞当前线程,redis没有返回,可以继续向redis发送命令
缺点:代码书写是异步的,业务逻辑割裂,可以通过协程解决(skynet,openresty)

2.3.1 hiredis + libevent

我们需要做的事情:
适配

  1. 事件对象
  2. 事件操作函数

hiredis需要做:

  1. 协议解析
  2. 读写事件
  3. 缓冲区操作
  4. 协议加密等

适配事件对象和函数。

static int redisAttach(reactor_t *r, redisAsyncContext *ac) {
    redisContext *c = &(ac->c);
    redis_event_t *re;
    
    /* Nothing should be attached when something is already attached */
    if (ac->ev.data != NULL)
        return REDIS_ERR;

    /* Create container for ctx and r/w events */
    re = (redis_event_t*)hi_malloc(sizeof(*re));
    if (re == NULL)
        return REDIS_ERR;

    re->ctx = ac;
    re->e.fd = c->fd;
    re->e.r = r;
    // dont use event buffer, using hiredis's buffer
    re->e.in = NULL;
    re->e.out = NULL;
    re->mask = 0;

    ac->ev.addRead = redisAddRead;
    ac->ev.delRead = redisDelRead;
    ac->ev.addWrite = redisAddWrite;
    ac->ev.delWrite = redisDelWrite;
    ac->ev.cleanup = redisCleanup;
    ac->ev.data = re;
    return REDIS_OK;
}

总结

本文介绍了Redis的基本命令以及Redis协议中的部分内容。Redis是内存型数据库,围绕着内存的特性,Redis结合了lua脚本,分布式锁(最快的),异步连接等一系列特性。

参考链接:
https://github.com/0voice

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

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

相关文章

设计模式的艺术读书笔记

设计模式的艺术 面向对象设计原则概述单一职责原则开闭原则里氏代换原则依赖倒转原则接口隔离原则合成复用原则迪米特法则 创建的艺术创建型模式单例模式饿汉式单例与懒汉式单例的讨论通过静态内部类实现的更好办法 简单工厂模式工厂方法模式重载的工厂方法工厂方法的隐藏工厂方…

计算机毕设-基于springboot的甜品店管理系统的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

Mac 录制电脑系统内的声音的具体方法?

1.第一步&#xff1a;下载BlackHole 软件 方式1&#xff1a;BlackHole官方下载地址 方式2&#xff1a; 百度云下载 提取码: n5dp 2.第二步&#xff1a;安装BlackHole 双击下载好的BlackHole安装包&#xff0c;安装默认提示安装。 3.第三步&#xff1a;在应用程序中找到音频…

【开源免费】基于Vue和SpringBoot的课程答疑系统(附论文)

博主说明&#xff1a;本文项目编号 T 070 &#xff0c;文末自助获取源码 \color{red}{T070&#xff0c;文末自助获取源码} T070&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

ACM latex模板中的CCSXML (即:CCS Concept)怎么填?

CCS Concept 感谢CCS Concept 怎么填 的珠玉在前. 问题描述 如下&#xff0c;ACM模板&#xff08;比如ACM computing surveys&#xff09;有一段是需要填写 ccsxml&#xff1a; %% %% The code below is generated by the tool at [http://dl.acm.org/ccs.cfm.](http://dl.…

【Transformer序列预测】Pytorch中构建Transformer对序列进行预测源代码

Python&#xff0c;Pytorch中构建Transformer进行序列预测源程序。包含所有的源代码和数据&#xff0c;程序能够一键运行。此程序是完整的Transformer&#xff0c;即使用了Encoder、Decoder和Embedding所有模块。源程序是用jupyterLab所写&#xff0c;建议分块运行。也整理了.p…

Mybatis-plus 简单使用,mybatis-plus 分页模糊查询报500 的错

一、mybtis-plus配置下载 MyBatis-Plus 是一个 Mybatis 增强版工具&#xff0c;在 MyBatis 上扩充了其他功能没有改变其基本功能&#xff0c;为了简化开发提交效率而存在。 具体的介绍请参见官方文档。 官网文档地址&#xff1a;mybatis-plus 添加mybatis-plus依赖 <depe…

前端项目使用gitlab-cicd+docker实现自动化部署

GitLab CI/CD 是一个强大的工具&#xff0c;可以实现项目的自动化部署流程&#xff0c;从代码提交到部署只需几个步骤。本文将带你配置 GitLab CI/CD 完成一个前端项目的自动化部署。 前言 为什么使用cicddocker&#xff1f; 目前我们公司开发环境使用的shell脚本部署&#…

设计模式:20、状态模式(状态对象)

目录 0、定义 1、状态模式的三种角色 2、状态模式的UML类图 3、示例代码 0、定义 允许一个对象在其内部状态改变时改变它的行为&#xff0c;对象看起来似乎修改了它的类。 1、状态模式的三种角色 环境&#xff08;Context&#xff09;&#xff1a;环境是一个类&#xff0…

Unity3D学习FPS游戏(13)玩家血量控制

玩家血量控制 血条UI玩家Canvas下的Slider血量逻辑控制 子弹攻击掉血子弹发射者的区分玩家受伤逻辑子弹碰撞检测 效果 血条UI 和之前我们前面介绍的玩家武器弹夹UI的思路是一样的&#xff0c;跟详细的细节可以参考博客Unity3D装弹和弹夹UI显示。 玩家Canvas下的Slider 之前玩…

【开源免费】基于SpringBoot+Vue.JS高校学科竞赛平台(JAVA毕业设计)

博主说明&#xff1a;本文项目编号 T 075 &#xff0c;文末自助获取源码 \color{red}{T075&#xff0c;文末自助获取源码} T075&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

学在西电录播课使用python下载,通过解析m3u8协议、多线程下载ts视频块以及ffmpeg合并

本文涵盖的内容仅供个人学习使用&#xff0c;如果侵犯学校权利&#xff0c;麻烦联系我删除。 初衷 研究生必修选逃&#xff0c; 期末复习怕漏过重点题目&#xff0c;但是看学在西电的录播回放课一卡一卡的&#xff0c;于是想在空余时间一个个下载下来&#xff0c;然后到时候就…

基于php+mysql的旅游网站——记忆旅行 旅游分享 攻略分享 设计与实现 源码 配置 文档

旅游网站 1.项目描述2. 概述3.项目功能4.界面展示5.源码获取 1.项目描述 摘 要 随着互联网的不断发展&#xff0c;计算机网络逐渐普及到人们的生活&#xff0c;为人们带来了便捷。互联网的趋势扩大&#xff0c;运用到家家户户中。各行各业都在考虑利用互联网将自己的信息推广…

2024.12.6——攻防世界php_rce

知识点&#xff1a;PHP框架 RCE远程命令执行 PHP常用框架&#xff1a;php常用的7大框架_php框架-CSDN博客 1.小型项目&#xff1a;CodeIngiter 2.中型项目&#xff1a;CakePHP、Zend Framework、Laravel、Thinkphp 3.大型重量级项目&#xff1a;Yii、Symfony、Laravel 使用…

autogen 人工输入模式

一、Allowing Human Feedback in Agents 允许代理中的人类反馈 发起聊天 (initiate_chat) 功能&#xff1a;用于启动对话过程。 参数&#xff1a;max_turns&#xff1a;限制对话的最大回合数。如果设置为3&#xff0c;意味着对话将在第三个回合后自动终止&#xff0c;除非提前…

网络渗透实验四(渗透课)

实验目的和要求实验目的&#xff1a;通过对目标靶机的渗透过程&#xff0c;了解CTF竞赛模式&#xff0c;理解CTF涵盖的知识范围&#xff0c;如MISC、PPC、WEB等&#xff0c;通过实践&#xff0c;加强团队协作能力&#xff0c;掌握初步CTF实战能力及信息收集能力。熟悉网络扫描、…

C++_关于异常处理throw-try-catch

文章目录 作用1. 无异常捕获2. 有异常捕获 作用 简单说&#xff0c;异常处理机制主要作用是让程序能够继续执行&#xff0c;或者以一种可控的方式终止&#xff0c;而非让程序因为错误直接崩溃 一个简单的动态数组类&#xff0c;来看看有异常捕获和无异常捕获的区别 1. 无异常…

LabVIEW氢同位素单质气体定量分装系统

氢同位素单质气体在多个行业中有重要应用&#xff0c;如能源和化工。传统的分装方法面临精度和自动化程度不足的问题。为此&#xff0c;开发了一套基于LabVIEW和质量流量控制器的定量分装系统&#xff0c;提高分装精度和效率&#xff0c;同时减少资源浪费和环境污染。 项目背景…

第427场周赛: 转换数组、用点构造面积最大的矩形 Ⅰ、长度可被 K 整除的子数组的最大元素和、用点构造面积最大的矩形 Ⅱ

Q1、转换数组 1、题目描述 给你一个整数数组 nums&#xff0c;它表示一个循环数组。请你遵循以下规则创建一个大小 相同 的新数组 result &#xff1a; 对于每个下标 i&#xff08;其中 0 < i < nums.length&#xff09;&#xff0c;独立执行以下操作&#xff1a; 如…

华为服务器使用U盘重装系统

一、准备工作 下载官方系统&#xff08;注意服务器CPU的架构是x86-64还是aarch64&#xff0c;不然可能报意想不到的错&#xff09;制作启动U盘&#xff08;下载rufus制作工具&#xff0c;注意文件系统选FAT32还是NTFS&#xff09; 二、安装步骤 将U盘插入USB接口重启服务器…