当前位置: 首页 > news >正文

Redis 除了数据类型外的核心功能 的详细说明,包含事务、流水线、发布/订阅、Lua 脚本的完整代码示例和表格总结

以下是 Redis 除了数据类型外的核心功能 的详细说明,包含事务、流水线、发布/订阅、Lua 脚本的完整代码示例和表格总结:


1. Redis 事务(Transactions)

功能描述

事务通过 MULTIEXEC 命令将一组命令打包执行,保证命令的原子性(非严格原子性)。事务中的命令会被顺序执行,但中间可能被其他客户端命令插入。

代码示例
@Service
public class RedisTransactionService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 使用事务操作
    public void transactionExample() {
        redisTemplate.multi(); // 开启事务
        try {
            // 添加多个命令到事务队列
            redisTemplate.opsForValue().set("key1", "value1");
            redisTemplate.opsForValue().increment("counter", 1);
            
            // 提交事务
            List<Object> results = redisTemplate.exec();
            System.out.println("事务执行结果:" + results);
        } catch (Exception e) {
            redisTemplate.discard(); // 回滚事务
            throw e;
        }
    }
}
注意事项
  • 事务中的命令若失败,后续命令仍会执行。
  • 使用 exec() 提交后,返回所有命令的执行结果列表。

2. Redis 流水线(Pipeline)

功能描述

流水线将多个命令批量发送到 Redis 服务器,减少网络往返延迟,提升性能。适用于批量操作(如批量读写)。

代码示例
@Service
public class RedisPipelineService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 使用流水线批量操作
    public void pipelineExample() {
        redisTemplate.executePipelined((RedisConnection connection) -> {
            connection.set("key1".getBytes(), "value1".getBytes());
            connection.set("key2".getBytes(), "value2".getBytes());
            connection.set("key3".getBytes(), "value3".getBytes());
            return null;
        });
    }
}
注意事项
  • 流水线通过 executePipelined 方法实现,需操作底层 RedisConnection
  • 批量操作需自行处理字节序列化。

3. Redis 发布/订阅(Pub/Sub)

功能描述

用于实时消息通信:

  • 发布者:向频道(channel)发送消息。
  • 订阅者:监听指定频道的消息。
代码示例
3.1 发布者
@Service
public class RedisPublisherService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 发布消息到频道
    public void publishMessage(String channel, String message) {
        redisTemplate.convertAndSend(channel, message);
    }
}
3.2 订阅者
@Configuration
public class RedisSubscriberConfig {
    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(new MessageListener() {
            @Override
            public void onMessage(Message message, byte[] pattern) {
                String channel = new String(message.getChannel());
                String payload = new String(message.getBody());
                System.out.println("收到消息:频道[" + channel + "],内容[" + payload + "]");
            }
        }, new PatternTopic("channel:*")); // 订阅所有以 "channel:" 开头的频道
        return container;
    }
}
注意事项
  • 需配置 RedisMessageListenerContainer 监听消息。
  • 消息不会持久化,客户端断开后未接收的消息会丢失。

4. Redis Lua 脚本(Lua Scripting)

功能描述

通过 Lua 脚本实现 原子性操作,适用于需要严格一致性的场景(如分布式锁、库存扣减)。Lua 脚本在 Redis 服务端单线程执行,确保原子性。

代码示例
4.1 示例脚本:库存扣减
-- Lua 脚本:扣减库存,仅当库存大于0时扣减
local stock = tonumber(redis.call("GET", KEYS[1]))
if stock and stock > 0 then
    redis.call("DECR", KEYS[1])
    return stock - 1
else
    return -1 -- 库存不足
end
4.2 Spring Boot 调用 Lua 脚本
@Service
public class RedisLuaService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 执行 Lua 脚本(库存扣减)
    public Long deductStock(String stockKey) {
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setScriptText(loadLuaScript("deduct_stock.lua")); // 加载脚本内容
        script.setResultType(Long.class);
        
        return redisTemplate.execute(
            script, 
            Collections.singletonList(stockKey), 
            new Object[]{});
    }

    // 加载 Lua 脚本内容(示例)
    private String loadLuaScript(String scriptName) {
        // 实际开发中可从文件或资源加载
        return "local stock = tonumber(redis.call('GET', KEYS[1])) ..."; // 省略脚本内容
    }
}
注意事项
  • 脚本在 Redis 服务端执行,需确保脚本逻辑正确。
  • 可通过 SHA1 哈希缓存脚本,减少传输开销。

5. 总结表格

功能描述代码方法适用场景
事务将一组命令打包执行,保证顺序性,但非严格原子性。redisTemplate.multi()redisTemplate.exec()需要命令顺序执行但允许部分失败的场景。
流水线批量发送命令,减少网络延迟。redisTemplate.executePipelined()大批量读写操作(如批量插入、查询)。
发布/订阅实时消息通信,支持频道或模式订阅。redisTemplate.convertAndSend()RedisMessageListenerContainer实时通知(如订单状态更新、聊天消息)。
Lua 脚本在 Redis 服务端原子性执行复杂逻辑,确保数据一致性。redisTemplate.execute(script, keys, args)需要严格原子性的操作(如分布式锁、扣减库存)。

6. 关键点总结

  1. 事务 vs Lua 脚本

    • 事务提供顺序执行,但非原子性(中间可能被其他命令中断)。
    • Lua 脚本确保原子性,适合需要严格一致性的场景。
  2. 流水线优化

    • 批量操作时,流水线可显著提升性能(减少网络 RTT)。
  3. 发布/订阅

    • 适用于实时消息通信,但需注意消息丢失风险(客户端断开时未接收的消息会丢失)。
  4. Lua 脚本注意事项

    • 脚本在服务端执行,需谨慎设计逻辑(避免死循环或高耗时操作)。
    • 可通过 EVALSHA 命令缓存脚本,减少传输开销。

通过合理使用这些功能,可以解决高并发场景下的性能、一致性和实时性挑战。

http://www.dtcms.com/a/109555.html

相关文章:

  • 【数据集】多视图文本数据集
  • Python第七章09:自定义python包.py
  • maven引入项目内本地包方法
  • WEB安全--文件上传漏洞--php伪协议的利用
  • MySQL索引(操作篇)
  • 分布式锁之redis6
  • GenerationMixin:_sample方法(GenerationMode.SAMPLE, GenerationMode.GREEDY_SEARCH)
  • 程序员学商务英语之Establing Biz Relations Inquiry
  • 自适应卡尔曼滤波
  • 探索 GitHub Copilot:当 AI 成为你的贴身编码助手
  • Win11本地从零开始部署dify全流程
  • TP6图片操作 Image::open 调用->save()方法时候报错Type is not supported
  • Redis基础知识-3
  • linux - 字符设备驱动简介
  • MySql 数据库题目
  • 三防笔记本有什么用 | 三防笔记本有什么特别
  • CentOS中挂载新盘LVM指南:轻松扩展存储空间,解决磁盘容量不足问题
  • ORM mybits mybits-plus
  • 探索现代网络技术:从负载均衡到 Kubernetes
  • ECMAScript介绍
  • 使用C#写的一个Kafka的使用工具
  • git的作用,以及和github的区别
  • 数据结构与算法学习笔记----贪心区间问题
  • C++中的IO流
  • 【动态规划】最长上升子序列模板
  • 网络编程—网络概念
  • 国产编辑器EverEdit - 扩展脚本:让EverEdit支持“批量查找”功能
  • 使用 requests 和 BeautifulSoup 解析淘宝商品
  • 安利免费开源的声音克隆、文本转语音整合包软件、一键本地安装!
  • Shopify独立站开发与运营全解析