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

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


1. Redis 事务(Transactions)

功能描述

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

代码示例
java 复制代码
@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 服务器,减少网络往返延迟,提升性能。适用于批量操作(如批量读写)。

代码示例
java 复制代码
@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 发布者
java 复制代码
@Service
public class RedisPublisherService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // 发布消息到频道
    public void publishMessage(String channel, String message) {
        redisTemplate.convertAndSend(channel, message);
    }
}
3.2 订阅者
java 复制代码
@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 复制代码
-- 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 脚本
java 复制代码
@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 命令缓存脚本,减少传输开销。

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

相关推荐
longlong int14 分钟前
【每日算法】Day 16-1:跳表(Skip List)——Redis有序集合的核心实现原理(C++手写实现)
数据库·c++·redis·算法·缓存
baobao176764083027 分钟前
Mysql 数据库编程技术01
数据库·mysql·oracle
一 乐33 分钟前
实验室预约|实验室预约小程序|基于Java+vue微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)
java·数据库·微信小程序·小程序·毕业设计·论文·实验室预约小程序
极限实验室34 分钟前
INFINI Labs 产品更新 | Coco AI 0.3 发布 – 新增支持 Widget 外部站点集成
数据库·搜索引擎
我科绝伦(Huanhuan Zhou)35 分钟前
MySQL数据库如何在线修改表结构及字段类型?
数据库·mysql
努力努力再努力wz42 分钟前
【c++深入系列】:类与对象详解(中)
java·c语言·开发语言·c++·redis
独行soc1 小时前
2025年渗透测试面试题总结- 某四字大厂面试复盘扩展 一面(题目+回答)
java·数据库·python·安全·面试·职场和发展·汽车
rockmelodies1 小时前
【MongoDB + 向量搜索引擎】MongoDB Atlas 向量搜索 提供全托管解决方案
数据库·mongodb·搜索引擎
西元.2 小时前
详解 Redis repl_backlog_buffer(如何判断增量同步)
数据库·redis·缓存
老华带你飞3 小时前
木里风景文化|基于Java+vue的木里风景文化管理平台的设计与实现(源码+数据库+文档)
java·数据库·vue.js·毕业设计·论文·风景·木里风景文化管理平台