【Redis】---- 一些常用的技术

目录

1.基础事务
2.Redis事务回滚
3.使用watch命令监控事务
4.流水线(pipelined)
5.发布订阅
6.超时命令
7.使用Lua语言

1.基础事务

Redis事务是使用MULTI-EXEC的命令组合,提供两个重要的保证:

  • 事务是一个被隔离的操作,事务中的方法都会被Redis进行序列化并按顺序执行,事务在执行的过程中不会被其他客户端发生的命令所打断。
  • 事务是一个原子性的操作,它要么全部执行,要么就什么都不执行。

在Redis中使用事务经历三个过程:

  • 开启事务(multi)
  • 命令进入队列
  • 执行事务(exec)

其它Redis事务命令

  • watch key1[key2…] : 监听某些键,当被监听的键在事务执行前被修改,则事务会被回滚
  • discard:回滚事务(回滚进入队列的事务命令)

2.Redis事务回滚

在执行事务命令的时候,在命令入队的时候,Redis会检测事务的命令是否正确,如果不正确则会产生错误。无论之前还是之后的命令都会被事务所回滚。
命令格式正确,而因为操作数据结构引起的错误,则该命令执行执行错误,而之前还是之后的命令都会被正常执行。
在这里插入图片描述

3.使用watch命令监控事务

在multi命令之前使用watch命令监控某些键值对;
当Redis使用exec命令执行事务的时候,它首先会先去比对被watch命令所监控的键值对,
如果没有发生变化,那么它会执行事务队列中的命令,提交事务;
如果发生变化,那么它不会执行任何事务中的命令,而去事务回滚。

过程如图:

Redis参考了多线程中使用的CAS(比较与交换,Compare And Swap)去执行的

Redis机制是不会产生ABA问题的

4.流水线(pipelined)

在Redis事务中提供了队列,这是一个可以批量执行任务的队列,性能比较高,但是使用multi…exec事务命令是有系统开销的,因为会检测对应的锁和序列化命令。
Redis流水线技术: 没有任何附加条件的场景下使用队列批量执行一系列命令,提高系统性能,是一种通信协议

使用Spring操作Redis流水线

@Test
     public void test() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        RedisTemplate redisTemplate = applicationContext.getBean(RedisTemplate.class);
        // 使用Java8的Lambda表达式
        SessionCallback sessionCallback = (SessionCallback) (RedisOperations ops) -> {
            for (int i = 0; i < 10000; i++) {
                int j = i + 1;
                ops.boundValueOps("pipeline_key_" + j).set("pipeline_value_" + j);
                ops.boundValueOps("pipeline_key_" + j).get();
            }
            return null;
        };

        long start = System.currentTimeMillis();
        // 执行Redis的流水线命令
        List resultList = redisTemplate.executePipelined(sessionCallback);
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }

5.发布订阅

发布订阅首先要有消息源,也就是要有消息发出来,比如银行通知。订阅者可以接收消息进行处理

在这里插入图片描述
Redis中的命令:

	# 客户端1订阅 chat监听渠道
	SUBSCRIBE chat
	# 客户端2向渠道chat发送命令
    publish chat "let's go!!"
    # 客户端1
    "let's go!!"

6. 超时命令

Redis超时命令

命令说明
persist key持久化key,取消超时时间
ttl key查看key的超时时间(-1代表没有超时, 如果key不存在或已超时则为-2)
expire key seconds设置超时时间戳(秒)

问题: 如果key超时了,Redis会回收key的存储空间吗?
答: 不会。Redis的key超时不会被其自动回收,它只会表示哪些键值对超时了。 好处是如果一个很大的键值对超时,比如一个列表或者哈希结构,存在数以百万个元素,要对其回收需要很长的时间。如果采用超时回收,则可能产生停顿。

Redis提供两种方式回收超时键值对:

  • 定时回收:在确定的某个时间触发一段代码,回收超时的键值对
  • 惰性回收:当一个超时的键,被再次用get命令访问时,将触发Redis将其从内存中清空

7.使用Lua语言

Redis支持两种方式运行脚本

  • 直接输入一些Lua语言的程序代码(简单的脚本)
  • 将Lua语言编程写文件

对于采用简单脚本,Redis支持缓存脚本,使用SHA-1算法对脚本进行签名,然后把SHA-1标识返回回来,只要通过这个标识运行就可以了。

执行Lua程序代码命令格式: eval lua-script key-num [key1 key2 key3 … ] [value1 value2 value3 …]

key-num:整数代表参数中有多少个key,如果没有参数,则写0

7.1 Redis缓存脚本命令:

在这里插入图片描述

7.2 执行Lua文件:

test.lua

redis.call('set', KEYS[1], ARGV[1])
redis.call('set', KEYS[2], ARGV[2])
local n1 = tonumber(redis.call('get', KEYS[1]))
local n2 = tonumber(redis.call('get', KEYS[2]))
if n1 > n2 then
    return 1
end
if n1 == n2 then
    return 0
end
if n1 < n2 then
    return 2
end

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值