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

《程序猿之Redis缓存实战(1) · 基础知识》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗

🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • Redis 技术简介
    • Redis 数据结构
    • Redis 客户端工具
    • Key 的专栏
      • Key 定义规范
      • Key 层级结构
    • SpringBoot 整合 Redis
    • 专栏预告
    • 总结陈词

写在前面的话

近期博客正在更新设计模式和微信小程序专栏,工作流引擎LiteFlow也才更新了一集。但由于工作繁忙起来,又忘记推迟更新进度了。

这天,刚好工作中遇到有新人提问Redis相关内容,顺势温习了之前的Redis知识,发现内容还不少,就先插播介绍一下。

荒废不多说,直接先从枯燥的基础部分来介绍。


Redis 技术简介

Redis是一个基于内存的 key-value 键值存储的、可持久化的数据库,并且提供了非常丰富的数据结构,同时还支持非常丰富的功能特性。

Redis官网:https://redis.io/

特征:

  • 键值(Key-Value)型,Value支持多种不同的数据结构,功能丰富
  • 单线程,每个命令具有原子性
  • 低延迟,速度快(基于内存、IO多路复用、良好的编码)
  • 支持数据持久化
  • 支持主从集群、分片集群
  • 支持多语言客户端

Redis 数据结构

Redis是典型的key-value数据库,key一般是字符串,而value包含很多不同的数据类型。

先看一下五大基础数据结构:

● 字符串(Strings): 存储字符串类型的值。
● 哈希表(Hashes): 存储字段和对应值的映射。
● 列表(Lists): 存储有序的字符串列表。
● 集合(Sets): 存储不重复的字符串集合。
● 有序集合(Sorted Sets): 类似集合,但每个元素都关联一个分数,可以按分数排序。

再看看新增的高级数据结构:

  • 位图(Bitmap)
  • 超日志(HyperLogLog)
  • 地理空间(Geospatial)

注意事项:

学习不同的数据结构,除了掌握他们的基础命令外,应该明确各种类型分别运用在什么场景,才是最主要的。


Redis 客户端工具

【使用官方 Redis Insight】

RedisInsight 是一个强大的图形用户界面工具,旨在帮助用户更好地管理和监控 Redis 数据库。它提供了丰富的功能,包括数据浏览、性能监控、查询分析等。如果你在寻找 Redis 的可视化工具,RedisInsight 是一个非常不错的选择。你可以从 Redis 的官方网站下载并安装它。

Redis Insight 是 Redis 官方推荐的客户端工具,功能非常的齐全,不过不支持中文。

【使用第三方工具 Tiny】

强烈推荐大家使用 Tiny RDM,UI 很好看,支持中文和字体设置。

官网地址:https://redis.tinycraft.cc/zh/

下载地址:https://github.com/tiny-craft/tiny-rdm/tree/main


Key 的专栏

Key 定义规范

【背景说明】

在 Spring Boot 项目中,Redis Key 的定义需要遵循一定的规范,以确保代码的可读性、可维护性和可扩展性。

在团队开发中,制定并遵循 Redis key 的命名规范不仅能提高代码的可读性和可维护性,还能减少潜在的错误和冲突。因此,团队应该重视并共同遵循这些规范,以提高整体开发效率和代码质量。

【规范说明】

1、Key 命名规范

  • 使用前缀:为不同的业务模块或功能使用不同的前缀,以避免 key 冲突,例如:user:1001:session。
  • 使用冒号分隔:使用冒号(:)分隔 key 的各个部分,使其结构清晰,例如:app:module:submodule:key。
  • 避免使用特殊字符:尽量避免使用空格、斜杠等特殊字符,以防止在某些情况下出现解析错误。
  • 使用有意义的: Key 的名称应该清晰地描述存储的数据类型和用途,避免使用过于简短或模糊的名称。
  • 使用小写字母: 为了保持一致性,建议使用小写字母命名 Key。

2、Key 的长度

控制 key 的长度:尽量保持 key 的简短,避免过长的 key 影响性能。一般建议不超过 64 个字符。

3、使用常量类

在 Spring Boot 项目中,可以定义一个常量类来集中管理 Redis 的 key。

这样可以避免硬编码,提高代码的可读性和可维护性。

另外,如果项目中有多个模块,建议集中管理 Redis 的 key 定义,避免各个模块之间的 key 冲突。

public class RedisKeys {
    public static final String USER_SESSION_PREFIX = "user:";
    public static String getUserSessionKey(Long userId) {
        return USER_SESSION_PREFIX + userId + ":session";
    }
}

4、版本控制(可选)

在 key 中加入版本号,以便在需要时进行 key 的迁移或更新。例如:user:v1:1001:session。

5、使用 Hash 数据结构(按需)

使用 Hash:对于相关联的数据,可以使用 Redis 的 Hash 数据结构来存储,减少 key 的数量。

例如,存储用户信息时,可以使用 user:1001 作为 key,用户的各个属性作为 Hash 的字段。

6、设置过期时间(按需)

对于临时数据,设置合理的过期时间,避免 Redis 中存储过多无用数据。

7、监控和清理(可选)

监控使用情况,定期监控 Redis 的 key 使用情况,清理不再使用的 key。

8、文档化(可选)

文档化 key 的用途:为每个 key 的命名和用途编写文档,方便团队成员理解和使用。

9、避免使用用户输入(可选)

避免直接使用用户输入:在生成 key 时,避免直接使用用户输入的内容,以防止注入攻击或意外的 key 冲突。


Key 层级结构

【问题背景】

Redis 没有类似数据库表空间和表的概念,那么我们该如何区分不同业务类型的Key呢?

如果都根据id直接作为Key,那如果用户ID和订单ID重复的话,岂不是乱套了?

答案是,我们可以通过给key添加前缀加以区分,不过这个前缀不是随便加的,有一定的规范。

【层级结构】

  • key允许有多个单词形成层级结构,多个单词之间用:隔开,格式:项目名:业务名:id
  • 以项目名称是portal,业务是user,以此缓存为例,可以是portal:user:001
  • 注意如果业务是通用的,也可以省去项目层级,直接使用user:001
  • 在Redis的客户端工具中,也会以相同前缀作为层次结构,让数据看起来层次分明,关系清晰。

SpringBoot 整合 Redis

【知识介绍】

SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis

官网地址:https://spring.io/projects/spring-data-redis

  • 提供了对不同Redis客户端的整合(Lettuce和Jedis)
  • 提供了RedisTemplate统一API来操作Redis
  • 支持Redis的发布订阅模型
  • 支持Redis哨兵和Redis集群
  • 支持基于Lettuce的响应式编程
  • 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
  • 支持基于Redis的JDKCollection实现

SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。并且将不同数据类型的操作API封装到了不同的类型中:

【具体步骤】

Step1、引入依赖

<!-- 整合Redis -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- JSON处理 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>${fastjson.version}</version>
</dependency>

Step2、添加配置

spring:
  data:
    redis:
      host: 192.168.75.129    # Redis服务器地址
      port: 6379              # Redis服务器连接端口
      password: lyd           # Redis服务器连接密码(默认为空)
      database: 0              # Redis数据库索引(默认为0)
      # 建议不要采用url的方式
      # url: redis://192.168.75.129:6379     # Redis服务器的连接URL,在Spring中相当于是password+ip+port,格式为:redis://[password@]host:port[/database]
      timeout: 60s             # 连接空闲超过N(s秒、ms毫秒,不加单位时使用毫秒)后关闭,0为禁用,这里配置值和tcp-keepalive值一致
      # Lettuce连接池配置
      lettuce:
        pool:
          max-active: 10       # 允许最大连接数,默认8(负值表示没有限制),推荐值:大于cpu * 2,通常为(cpu * 2) + 2
          max-idle: 8          # 最大空闲连接数,默认8,推荐值:cpu * 2
          min-idle: 0          # 最小空闲连接数,默认0
          max-wait: 5s         # 连接用完时,新的请求等待时间(s秒、ms毫秒),超过该时间抛出异常,默认-1(负值表示没有限制)

Step3、添加自定义RedisTemplate

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        // 设置键序列化器为 StringRedisSerializer,所有的键都会被序列化为字符串
        redisTemplate.setKeySerializer(StringRedisSerializer.UTF_8);
        redisTemplate.setHashKeySerializer(StringRedisSerializer.UTF_8);

        // 设置值序列化器为 GenericJackson2JsonRedisSerializer,所有的值都会被序列化为 JSON 格式
        GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashValueSerializer(serializer);

        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }
}

Step4、测试效果

@SpringBootTest
@RunWith(SpringRunner.class)
public class SpringBaseTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Test
    public void test() {
        redisTemplate.opsForValue().set("K1", "战神");
        System.out.println(redisTemplate.opsForValue()
                .get("K1"));
        System.out.println(stringRedisTemplate.opsForValue()
                .get("K1"));
    }
}

专栏预告

本篇仅仅是为了知识连贯性,先介绍一篇基础部分的,后续会针对Redis各项专栏进行实战讲解。

包含但不限于:

1、五大基础结构以及三大高级结构;

2、发布订阅模式;

3、流处理模式;

4、延迟队列;

5、分布式锁;

6、各类部署方案;

7、缓存数据库一致性;

8、持久化策略;

9、缓存三大问题;

10、其他专栏,比如序列化、事务等等。。。


总结陈词

本篇算是Redis系列文章的开篇,仅简单介绍了Redis的基础知识。后续会逐个将前面提到的知识领域在实战中的用法,全部展示出来。

💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。


http://www.kler.cn/news/324366.html

相关文章:

  • 哈希知识点总结:哈希、哈希表、位图、布隆过滤器
  • 视频融合共享平台LntonAIServer视频智能分析抖动检测算法和过亮过暗检测算法
  • vue3 实现文本内容超过N行折叠并显示“...展开”组件
  • 基于Hive和Hadoop的图书分析系统
  • jdk1.6版本发送HTTPS请求,报错Could not generate DH keypair问题解决
  • Synchronized和 ReentrantLock有什么区别?
  • OFDM通信系统发射端需要做ifftshift的原因分析
  • C语言课程设计题目六:学生信息管理系统设计
  • Excel提取数据
  • FPGA IP 和 开源 HDL 一般去哪找?
  • Linux基础命令zip,unzip详解
  • 【ESP32】Arduino开发 | I2C控制器+I2C主从收发例程
  • 2024华为OD机试E卷-构成正方形的数量-(C++/Java/Python)
  • Redis 实现分布式锁时需要考虑的问题
  • 使用 Frida Hook Android App
  • Linux文件IO(十一)-复制文件描述符与截断文件
  • 大数据复习知识点2
  • Deep Learning for Video Anomaly Detection: A Review 深度学习视频异常检测综述阅读
  • flink设置保存点和恢复保存点
  • 详细分析Mybatis中的动态Sql(附Demo)
  • JWT的基础与使用
  • C/CPP中的编程技巧及其概念
  • 【零散技术】Odoo PDF 打印问题问题合集
  • 《AI办公类工具表格处理系列之二——Excell-AI》
  • C++那些事之变量模版
  • 大厂面试真题-说一下Mybatis的缓存
  • 【分布式微服务云原生】详细介绍下dubbo和springcloud所能支持的微服务特性,为啥能支持的技术原理,以及适用的业务场景,并对两者各方面做个详细的比较
  • Qt/C++ 解决调用国密SM3,SM4加密解密字符串HEX,BASE64格式转换和PKCS5Padding字符串填充相关问题
  • Java线程基础
  • SQL CREATE TABLE 语句