搜索
首页数据库Redisredis的高级特性介绍

redis的高级特性介绍

Jan 13, 2021 am 10:11 AM
redis高级特性

redis的高级特性介绍

Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

(学习视频分享:redis视频教程

1.redis发布订阅模式

Redis除了提供像list的这种的消息队列模式,还提供了一组命令实现发布/订阅模式。例如微博,公众号等都是可以由此实现。

JV]1A(M)EO3S]FMA_YHZR}I.png

1.2 订阅频道

发布者需要将消息发送到一个地方,让订阅者可以订阅消息,这个地方就是频道(channel)。订阅者可以订阅一个或者多个频道,所有订阅了这个频道的订阅者都会受到这条消息。

开启两个客户端进行测试

客户端1 订阅channel1
127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1

客户端2 发布一则消息
127.0.0.1:6379> publish channel1 test
(integer) 1

客户端1 订阅消息
127.0.0.1:6379> subscribe channel1
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel1"
3) (integer) 1
1) "message"
2) "channel1"
3) "test"

1.2 按规则订阅

支持?和*占位符。?代表一个字符,*代表 0 个或者多个字符。

启动四个redis-cli,一个作为消息的发布者,另外三个作为订阅者。
订阅者1:订阅体育相关

psubscribe *sport

订阅者2:订阅新闻相关

psubscribe news*

订阅者3:订阅天气相关

psubscribe new weather*

发布者:

publish news-sport Kobe
publish news-music jaychou
publish news-weather rain

此时订阅者1将会收到Kobe,订阅者2将会收到全部信息,订阅者3将会收到rain。

HQ$K[2XJT@K4T4(0F1{NJ`2.png

2.redis事务

2.1 为什么要用事务

我们都是知道redis的单个命令是原子性的,但是如果需要用多个命令作为一个不可分割的操作序列,就需要用到事务。
例如使用setnx实现分布式锁,我们一般先set,然后对key设置expire,防止del发生异常时候锁不会释放,业务处理完之后在del,这三个操作我们就希望作为一组命令执行。
redis事务有两个特点:

  • 按照进入队列的顺序执行

  • 不会受到其他客户端请求影响

redis的事务设计四个命令:multi(开启事务),exec(执行事务),dicard(取消事务),watch(监视)

2.2 事务的用法

转账场景A和B各有100元,A向B转账10元,A减10元,B加10元

127.0.0.1:6379> set A 100
OK
127.0.0.1:6379> set B 100
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby A 10
QUEUED
127.0.0.1:6379> incrby B 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 90
2) (integer) 110
127.0.0.1:6379> get A
"90"
127.0.0.1:6379> get B
"110"

通过multi命令开启事务。事务不能嵌套,多个multi命令效果一样的
使用multi开启事务之后,客户端向服务器发送多条命令,这些命令并不会立即被执行,而是会被放到一个队列中,当exec命令调用之后,队列中的命令才会被执行。
我们可以使用discard来清空事务队列。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> set k2 2
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get k1
(nil)
127.0.0.1:6379> get k2
(nil)

当我们执行事务的时候出现了问题会回滚吗?

exec之前发生错误 (如指令语法错误)

127.0.0.1:6379> clear
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set name test
QUEUED
127.0.0.1:6379> hset user lisi
(error) ERR wrong number of arguments for 'hset' command
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get name
(nil)

exec之后发生错误(对同一个key使用不同数据类型的命令)

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k1 1
QUEUED
127.0.0.1:6379> hset k1 a b
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get k1
"1"

通过上面操作,我们可以知道当事务在exec前发生错误,将会回滚所有操作;如果在exec后发生错误,只有错误的命令不会被执行。
为什么redis在一个事务中存在错误不进行回滚呢?
我们从上面操作可以看出,redis只有在指令语法错误的时候进行回滚,而指令操作错误是有开发人员导致的bug,例如:你对一个int类型进行+1,然后不小心+2,或者对一个string类型进行+1,回滚是不适用的

2.3 watch指令

它可以为Redis事务提供CAS乐观锁操作,也就是多个线程更新某个变量的时候,会让旧值跟内存地址相比较,如果相等,则更新为新值。
我们可以用watch监视一个或者多个key,如果开启事务之后,至少有一个被监视的key在exec执行之前被修改,则会取消整个事务。

首先client 1执行watch监视money这个key,并开启事务对money进行增加100

127.0.0.1:6379> set money 1000
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby money 100
QUEUED

在事务结束之前,在client 2对money进行减少100

127.0.0.1:6379> decrby money 100
(integer) 900

此时client 1结束事务,money的值并没有被增加,反而减少,说明事务的修改失效

127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get money
"900"

3. Lua脚本

Lua脚本是一种轻量级脚本语言,C语言编写的,跟存储过程有点类似。为啥要用lua脚本呢?

一次发送多个命令,减少网络开销Redis会将脚本作为一个整体执行,保证原子性(可用此方式替换事务)脚本复用,便于多个客户端完成相同的逻辑。

3.1 使用

我们可以使用以下命令进行调用lua脚本

eval script numkeys [key1 key2 key3 ....] [arg1 arg2 arg3 ....]

eval 执行lua脚本

script 代表lua脚本的内容

numkeys key的数量

[key1 key2 key3 ....] 键名参数,表示在脚本中所用到的那些 Redis 键(key),这些键名参数可以在 Lua 中通过全局变量 KEYS 数组,用 1 为基址的形式访问( KEYS[1] , KEYS[2] ,以此类推)。

[arg1 arg2 arg3 ....] 全局变量,可以在 Lua 中通过全局变量 ARGV 数组访问,访问的形式和 KEYS 变量类似( ARGV[1] 、 ARGV[2] ,诸如此类)

来个简单的例子

127.0.0.1:6379> eval "return {KEYS[1],ARGV[1],KEYS[2],ARGV[2]}" 2 key1 key2 val1 val1
1) "key1"
2) "val1"
3) "key2"
4) "val1"
127.0.0.1:6379> eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 val1 val1
1) "key1"
2) "key2"
3) "val1"
4) "val1"

在lua脚本如何调用redis命令呢?
我们可以使用 redis.call(command, key [param1, param2…])进行操作

commond redis的命令,如set,get等key 被操作的键[param1, param2…]表示给key的参数

127.0.0.1:6379> eval "redis.call('mset',KEYS[1],ARGV[1],KEYS[2],ARGV[2])" 2 name age lisi 18
(nil)
127.0.0.1:6379> mget name age
1) "lisi"
2) "18

以上命令等价于 mset name lisi age 18, key的数量为2,2 后面两个值为key,在之后就是args

直接在redis-cli中写lua脚本不够方便,通常我们会把脚本放在文件中,然后执行这个文件
我们在一个目录下新建一个test.lua的脚本,填写以下内容后执行。

root@VM-0-5-centos src]# mkdir testlua
[root@VM-0-5-centos src]# cd testlua/
[root@VM-0-5-centos testlua]# ll
total 0
[root@VM-0-5-centos testlua]# touch test.lua
[root@VM-0-5-centos testlua]# vim test.lua
redis.call('set',KEYS[1],ARGV[1])
return redis.call('get',KEYS[1])
[root@VM-0-5-centos testlua]# redis-cli --eval test.lua 1 myname , Armin
"Armin"

值得注意的是key和arg之间需要加上空格逗号空格(myname , Armin)

3.2 缓存lua脚本

之所以需要缓存lua脚本,这是因为每次调用的时候都将整个脚本传给redis服务端,会产生较大的网络开销。为了解决这个问题,Redis提供了evalsha命令,让开发人员通过脚本内容的SHA1摘要执行脚本。

那么怎么将生成这个SHA1并将脚本内容加载到缓存呢,这就用到script load命令去计算脚本的SHA1摘要并记录脚本到缓存中,执行evalsha时,redis会根据提供的摘要去脚本缓存找到对应脚本内容,如果找到则执行,否则返回错误提示: “NOSCRIPT No matching script. Please use EVAL”

127.0.0.1:6379> script load "return 'Hey boy'"
"3760855b303510c83f0be2e8acfb0be64113ae6e"
127.0.0.1:6379> evalsha 3760855b303510c83f0be2e8acfb0be64113ae6e 0
"Hey boy"
127.0.0.1:6379> script exists 3760855b303510c83f0be2e8acfb0be64113ae6e //判断是否存在
1) (integer)

Redis还给lua脚本的执行提供了超时时间,默认的超时时间为5s,超过5s之后redis会接受其他命令但是会返回一个"BUSY"的错误
可在redis.conf中修改指定参数

lua-time-limit 5000

Redis提供了个script kill的命令来终止正在运行的脚本

127.0.0.1:6379> set name lisi
(error) BUSY Redis is busy running a script. You can only call SCRIPT KILL or SHUTDOWN NOSAVE.
127.0.0.1:6379> script kill
OK
127.0.0.1:6379> set name lisi
OK

如果数据进行了修改操作,将无法使用script kill终止脚本,因为违反了原子性。此时只能通过shutdown nosave来强行终止redis。
shutdown nosave 和 shutdown 的区别在于 shutdown nosave 不会进行持久化 操作,意味着发生在上一次快照后的数据库修改都会丢失。

相关推荐:redis数据库教程

以上是redis的高级特性介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金。如有侵权,请联系admin@php.cn删除
REDIS:对其数据库方法进行分类REDIS:对其数据库方法进行分类Apr 15, 2025 am 12:06 AM

Redis的数据库方法包括内存数据库和键值存储。1)Redis将数据存储在内存中,读写速度快。2)它使用键值对存储数据,支持复杂数据结构,如列表、集合、哈希表和有序集合,适用于缓存和NoSQL数据库。

为什么要使用redis?利益和优势为什么要使用redis?利益和优势Apr 14, 2025 am 12:07 AM

Redis是一个强大的数据库解决方案,因为它提供了极速性能、丰富的数据结构、高可用性和扩展性、持久化能力以及广泛的生态系统支持。1)极速性能:Redis的数据存储在内存中,读写速度极快,适合高并发和低延迟应用。2)丰富的数据结构:支持多种数据类型,如列表、集合等,适用于多种场景。3)高可用性和扩展性:支持主从复制和集群模式,实现高可用性和水平扩展。4)持久化和数据安全:通过RDB和AOF两种方式实现数据持久化,确保数据的完整性和可靠性。5)广泛的生态系统和社区支持:拥有庞大的生态系统和活跃社区,

了解NOSQL:Redis的关键特征了解NOSQL:Redis的关键特征Apr 13, 2025 am 12:17 AM

Redis的关键特性包括速度、灵活性和丰富的数据结构支持。1)速度:Redis作为内存数据库,读写操作几乎瞬时,适用于缓存和会话管理。2)灵活性:支持多种数据结构,如字符串、列表、集合等,适用于复杂数据处理。3)数据结构支持:提供字符串、列表、集合、哈希表等,适合不同业务需求。

REDIS:确定其主要功能REDIS:确定其主要功能Apr 12, 2025 am 12:01 AM

Redis的核心功能是高性能的内存数据存储和处理系统。1)高速数据访问:Redis将数据存储在内存中,提供微秒级别的读写速度。2)丰富的数据结构:支持字符串、列表、集合等,适应多种应用场景。3)持久化:通过RDB和AOF方式将数据持久化到磁盘。4)发布订阅:可用于消息队列或实时通信系统。

REDIS:流行数据结构指南REDIS:流行数据结构指南Apr 11, 2025 am 12:04 AM

Redis支持多种数据结构,具体包括:1.字符串(String),适合存储单一值数据;2.列表(List),适用于队列和栈;3.集合(Set),用于存储不重复数据;4.有序集合(SortedSet),适用于排行榜和优先级队列;5.哈希表(Hash),适合存储对象或结构化数据。

redis计数器怎么实现redis计数器怎么实现Apr 10, 2025 pm 10:21 PM

Redis计数器是一种使用Redis键值对存储来实现计数操作的机制,包含以下步骤:创建计数器键、增加计数、减少计数、重置计数和获取计数。Redis计数器的优势包括速度快、高并发、持久性和简单易用。它可用于用户访问计数、实时指标跟踪、游戏分数和排名以及订单处理计数等场景。

redis命令行怎么用redis命令行怎么用Apr 10, 2025 pm 10:18 PM

使用 Redis 命令行工具 (redis-cli) 可通过以下步骤管理和操作 Redis:连接到服务器,指定地址和端口。使用命令名称和参数向服务器发送命令。使用 HELP 命令查看特定命令的帮助信息。使用 QUIT 命令退出命令行工具。

redis集群模式怎么搭建redis集群模式怎么搭建Apr 10, 2025 pm 10:15 PM

Redis集群模式通过分片将Redis实例部署到多个服务器,提高可扩展性和可用性。搭建步骤如下:创建奇数个Redis实例,端口不同;创建3个sentinel实例,监控Redis实例并进行故障转移;配置sentinel配置文件,添加监控Redis实例信息和故障转移设置;配置Redis实例配置文件,启用集群模式并指定集群信息文件路径;创建nodes.conf文件,包含各Redis实例的信息;启动集群,执行create命令创建集群并指定副本数量;登录集群执行CLUSTER INFO命令验证集群状态;使

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能