Redis学习文档

Redis学习文档

1. Redis原理讲解

1.1 Redis基本概念

Redis(Remote Dictionary Server)是一个开源的、高性能的键值对存储数据库,具有以下特点:

  • 内存存储:数据主要存储在内存中,访问速度极快(读写速度可达10万+ QPS)
  • 持久化:支持RDB和AOF两种持久化机制,保证数据不丢失
  • 多种数据结构:支持String、List、Hash、Set、Sorted Set、HyperLogLog、Geo等多种数据结构
  • 单线程模型:采用单线程事件循环模型,避免了线程切换开销
  • 支持分布式:通过Redis Cluster支持分布式部署
  • 支持事务:支持简单的事务操作
  • 支持Lua脚本:可以执行Lua脚本,实现复杂业务逻辑

1.2 Redis数据结构

项目中主要使用了以下数据结构:

数据结构 特点 项目中的应用
String 简单的键值对,最大512MB 存储token、验证码、心跳时间、系统设置
List 有序的字符串列表,支持两端操作 存储联系人列表、会话列表

1.3 Redis持久化机制

Redis支持两种持久化机制:

  1. RDB(Redis Database)

    • 定时快照,将内存中的数据写入磁盘
    • 优点:文件小,恢复速度快
    • 缺点:可能丢失最后一次快照后的所有数据
  2. AOF(Append Only File)

    • 记录所有写操作,恢复时重新执行这些操作
    • 优点:数据安全性高,最多丢失1秒数据
    • 缺点:文件大,恢复速度慢

项目中使用了默认配置,通常生产环境建议同时开启RDB和AOF。

1.4 Redis连接池

项目中使用了Lettuce连接池,相比Jedis具有以下优点:

  • 线程安全:Lettuce是线程安全的,一个连接可以被多个线程共享
  • 异步操作:支持异步操作,提高并发性能
  • 支持Redis Cluster:内置支持Redis Cluster
  • 支持SSL:支持SSL连接

2. 重要参数讲解

2.1 Redis配置参数

application.yml中的Redis配置

yaml 复制代码
spring:
  data:
    redis:
      database: 0          # Redis数据库索引(默认为0)
      host: 127.0.0.1      # Redis服务器地址
      port: 6379           # Redis服务器端口
      timeout: 2000ms      # 连接超时时间(毫秒)
      lettuce:             # Lettuce连接池配置
        pool:
          max-active: 20   # 连接池最大连接数(使用负值表示没有限制)
          max-wait: PT10S   # 连接池最大阻塞等待时间(使用负值表示没有限制)
          max-idle: 10      # 连接池中的最大空闲连接
          min-idle: 0       # 连接池中的最小空闲连接

2.2 Redis过期时间常量

Constants.java中的Redis过期时间定义

常量名 描述
REDIS_KEY_EXPIRES_ONE_MIN 60 1分钟过期时间(秒)
REDIS_KEY_EXPIRES_HEART_BEAT 6 心跳过期时间(秒),用于维护用户在线状态
REDIS_KEY_EXPIRES_DAY 86400 1天过期时间(秒)
REDIS_KEY_TOKEN_EXPIRES 172800 2天过期时间(秒),用于token过期时间

2.3 Redis Key前缀常量

Constants.java中的Redis Key前缀定义

常量名 描述
REDIS_KEY_CHECK_CODE easychat:checkcode: 验证码Key前缀
REDIS_KEY_WS_TOKEN easychat:ws:token: WebSocket token前缀
REDIS_KEY_WS_TOKEN_USERID easychat:ws:token:userid 用户ID到token的映射前缀
REDIS_KEY_WS_USER_HEART_BEAT easychat:ws:user:heartbeat 用户心跳Key前缀
REDIS_KEY_WS_ON_LINE_USER easychat:ws:online: 在线用户Key前缀
REDIS_KEY_USER_CONTACT easychat:ws:user:contact: 用户联系人列表前缀
REDIS_KEY_USER_SESSION easychat:ws:user:session: 用户会话列表前缀
REDIS_KEY_SYS_SETTING easychat:syssetting: 系统设置Key前缀

3. 重要方法讲解

3.1 RedisUtils核心方法

RedisUtils.java是基础Redis操作封装类,提供了常用的Redis操作方法:

3.1.1 基本操作
java 复制代码
// 获取指定key的值
public V get(String key)

// 普通缓存放入
public boolean set(String key, V value)

// 普通缓存放入并设置时间
public boolean setex(String key, V value, long time)

// 删除缓存
public void delete(String... key)

// 设置键的过期时间
public boolean expire(String key, long time)
3.1.2 List操作
java 复制代码
// 获取列表中所有元素
public List<V> getQueueList(String key)

// 将元素插入到列表左侧(头部)
public boolean lpush(String key, V value, long time)

// 从列表中移除元素
public long remove(String key, Object value)

// 将多个元素插入到列表左侧(头部)
public boolean lpushAll(String key, List<V> values, long time)

3.2 RedisComponet业务方法

RedisComponet.java是业务层Redis操作封装类,提供了与业务相关的Redis操作:

3.2.1 用户认证相关
java 复制代码
// 根据token获取用户信息
public TokenUserInfoDto getTokenUserInfoDto(String token)

// 根据用户ID获取用户信息
public TokenUserInfoDto getTokenUserInfoDtoByUserId(String userId)

// 保存用户token信息到Redis
public void saveTokenUserInfoDto(TokenUserInfoDto tokenUserInfoDto)

// 根据用户ID清除用户的token信息
public void cleanUserTokenByUserId(String userId)
3.2.2 心跳检测相关
java 复制代码
// 保存用户最后心跳时间
public void saveUserHeartBeat(String userId)

// 删除用户心跳记录
public void removeUserHeartBeat(String userId)

// 获取用户心跳时间
public Long getUserHeartBeat(String userId)
3.2.3 联系人管理相关
java 复制代码
// 获取用户联系人列表
public List<String> getUserContactList(String userId)

// 添加用户联系人
public void addUserContact(String userId, String contactId)

// 清空用户联系人列表
public void cleanUserContact(String userId)

// 删除用户联系人
public void removeUserContact(String userId, String contactId)

// 批量添加用户联系人
public void addUserContactBatch(String userId, List<String> contactIdList)
3.2.4 会话管理相关
java 复制代码
// 获取用户会话列表
public List<String> getUserSessionList(String userId)

// 添加用户会话
public void addUserSession(String userId, String sessionId)

// 清空用户会话列表
public void cleanUserSession(String userId)
3.2.5 系统设置相关
java 复制代码
// 保存系统设置
public void saveSysSetting(SysSettingDto sysSettingDto)

// 获取系统设置
public SysSettingDto getSysSetting()

4. 具体例子

4.1 用户认证示例

场景:用户登录成功后,生成token并保存到Redis中。

实现代码

java 复制代码
// 生成token
String token = StringTools.getRandomString(32);

// 创建用户信息DTO
TokenUserInfoDto tokenUserInfoDto = new TokenUserInfoDto();
tokenUserInfoDto.setToken(token);
tokenUserInfoDto.setUserId(userInfo.getUserId());
tokenUserInfoDto.setNickName(userInfo.getNickName());

// 保存到Redis
redisComponet.saveTokenUserInfoDto(tokenUserInfoDto);

Redis中存储的数据

  • Key: easychat:ws:token:{token}
  • Value: TokenUserInfoDto对象(JSON格式)
  • 过期时间: 2天

4.2 验证码示例

场景:用户注册或登录时,生成验证码并发送到邮箱,同时保存到Redis中。

实现代码

java 复制代码
// 生成验证码
String code = StringTools.getRandomNumber(6);

// 生成验证码key
String checkCodeKey = StringTools.getRandomString(32);

// 保存到Redis,10分钟过期
redisUtils.setex(Constants.REDIS_KEY_CHECK_CODE + checkCodeKey, code, 60 * 10);

Redis中存储的数据

  • Key: easychat:checkcode:{checkCodeKey}
  • Value: 6位数字验证码(字符串)
  • 过期时间: 10分钟

4.3 心跳检测示例

场景:WebSocket连接中,客户端定期发送心跳消息,服务器保存心跳时间到Redis。

实现代码

java 复制代码
// 接收到心跳消息
public void handleHeartBeat(String userId) {
    // 保存心跳时间到Redis,6秒过期
    redisComponet.saveUserHeartBeat(userId);
}

// 定期检查用户在线状态
public void checkOnlineStatus() {
    // 获取所有在线用户
    List<String> onlineUsers = getAllOnlineUsers();
    for (String userId : onlineUsers) {
        // 获取用户心跳时间
        Long heartBeatTime = redisComponet.getUserHeartBeat(userId);
        // 如果心跳时间超过10秒,则认为用户离线
        if (heartBeatTime == null || System.currentTimeMillis() - heartBeatTime > 10000) {
            // 处理用户离线逻辑
            handleUserOffline(userId);
        }
    }
}

Redis中存储的数据

  • Key: easychat:ws:user:heartbeat{userId}
  • Value: 心跳时间戳(Long)
  • 过期时间: 6秒

4.4 联系人管理示例

场景:用户添加新联系人后,更新Redis中的联系人列表。

实现代码

java 复制代码
// 添加联系人
public void addContact(String userId, String contactId) {
    // 数据库操作:添加联系人记录
    userContactService.addContact(userId, contactId);
    
    // Redis操作:添加到联系人列表
    redisComponet.addUserContact(userId, contactId);
}

// 获取联系人列表
public List<String> getContactList(String userId) {
    // 先从Redis获取
    List<String> contactList = redisComponet.getUserContactList(userId);
    if (CollectionUtils.isEmpty(contactList)) {
        // Redis中没有,从数据库获取
        contactList = userContactService.getContactList(userId);
        // 保存到Redis
        redisComponet.addUserContactBatch(userId, contactList);
    }
    return contactList;
}

Redis中存储的数据

  • Key: easychat:ws:user:contact:{userId}
  • Value: 联系人ID列表(List)
  • 过期时间: 2天

5. Redis使用最佳实践

5.1 Key设计规范

  1. 使用前缀 :为不同业务场景的Key添加不同前缀,如easychat:checkcode:
  2. 使用冒号分隔 :使用冒号分隔不同层级,如easychat:ws:token:{token}
  3. 避免过长Key:Key长度不宜过长,建议不超过100字节
  4. 使用统一命名规范:使用小写字母、数字和冒号,避免特殊字符

5.2 过期时间设置

  1. 根据业务场景设置合理的过期时间

    • 验证码:5-10分钟
    • Token:1-7天
    • 心跳:根据心跳间隔设置,建议为心跳间隔的1.5倍
    • 缓存数据:根据数据更新频率设置
  2. 避免设置永久过期时间:除非必要,否则不要设置永久过期时间,避免Redis内存溢出

5.3 数据序列化

  1. 使用JSON序列化:项目中使用了JSON序列化,便于调试和跨语言使用
  2. 避免使用Java序列化:Java序列化效率低,且不便于跨语言使用
  3. 根据数据类型选择合适的序列化方式
    • String类型:直接使用String序列化
    • 对象类型:使用JSON序列化
    • 二进制数据:使用二进制序列化

5.4 连接池配置

  1. 合理设置连接池大小:根据业务并发量设置,建议最大连接数为CPU核心数的2-4倍
  2. 设置合理的最大等待时间:避免线程长时间阻塞
  3. 设置合理的空闲连接数:根据业务低谷期的连接数设置

5.5 监控和维护

  1. 监控Redis使用情况:使用Redis自带的INFO命令或第三方监控工具(如RedisInsight、Prometheus+Grafana)
  2. 定期备份数据:开启RDB或AOF持久化,定期备份数据文件
  3. 避免大Key:避免存储过大的Key,如超过1MB的字符串或包含大量元素的List
  4. 使用Pipeline批量操作:对于批量操作,使用Pipeline提高效率

6. 总结

Redis是一个高性能的键值对存储数据库,在项目中广泛应用于用户认证、验证码、心跳检测、联系人管理、会话管理和系统设置等场景。通过合理的配置和使用,可以显著提高系统的性能和可靠性。

本文档结合项目中的实际使用情况,讲解了Redis的基本原理、重要参数、核心方法和最佳实践,希望对学习和使用Redis有所帮助。

在实际开发中,需要根据业务场景选择合适的Redis数据结构和过期时间,同时注意监控Redis的使用情况,及时发现和解决问题。

相关推荐
我科绝伦(Huanhuan Zhou)2 小时前
Oracle数据库内存管理实操指南:PGA与SGA优化实战
数据库·oracle
哈哈老师啊2 小时前
Springboot基于双减政策的家校互动管理系统8e613(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
进击的丸子2 小时前
人脸识别项目如何在Spring Boot项目中如何建立数据库和管理
数据库·后端·mysql
●VON2 小时前
2025年人工智能新方向:从算力竞赛到智能体生态
人工智能·学习
IvorySQL2 小时前
PostgreSQL 19:超高速聚合的全新突破
数据库·人工智能·postgresql·开源
陈逸轩*^_^*2 小时前
操作系统复习题库(期末速通版)
学习·操作系统·期末复习
电商API_180079052473 小时前
Python爬虫从入门到实战:核心技术与合规指南
大数据·数据库·爬虫
pixle03 小时前
从零学习Node.js框架Koa 【七】Koa实战:构建企业级邮箱验证注册系统
javascript·学习·node.js·koa·注册·全栈·邮箱注册
古城小栈3 小时前
从MySQL迁移到PostgreSQL
数据库·mysql·postgresql