Redis 快速入门

简单来说,Redis是基于内存的 key - value 存储系统。官方文档:https://redis.io/docs/

Redis 是 NoSQL 的一种。

关于SQL 与 NoSQL

SQL 是关系型数据库,数据是以表格形式存储的,是结构化的(有约束,有字段长度、类型等),比如 MySQL,Oracle等,它们使用SQL作为查询语言。强调数据的一致性和完整性,提供ACID(原子性、一致性、隔离性、持久性)事务保证

NoSQL 是非关系型数据库,通常不遵循关系数据库的结构规范,可以是 Redis 这种键值型存储的,还有 MongoDB 这种文档型存储的等等。每个NoSQL数据库都有自己独特的查询语言。通常提供最终一致性,可能牺牲一些数据一致性以换取更高的性能和可扩展性。

应用场景上:

  • SQL 数据库:数据结构固定,相关业务对数据安全性,一致性要求高的场景
  • NoSQL 数据库:数据结构不固定,对安全性,一致性要求不高,对性能要求高的场景

为什么需要 Redis

随着应用系统访问量越来越大,数据库性能会达到瓶颈。由于内存的读写速度远高于磁盘,所以如果把数据存到内存中,就可以大大提高性能,于是就有了Redis。

Redis 最核心的特性就是性能高,因为它基于内存,能够提供快速的数据存取能力。其他特性,如支持数据持久化(内存–>磁盘)、主从复制、哨兵模式和高可用性等,都是围绕着提高数据存取效率这一核心目的来构建的。

Redis 安装、配置和启动

参考B站 up 的视频

【Windows和Linux安装Redis】 https://www.bilibili.com/video/BV1ZR4y1c7PH/?share_source=copy_web&vd_source=f2d7b32c487a37a3e88341b014bc8114

Redis 的三种使用方式

CLI 命令行

API 写代码的方式操作Redis

GUI 图形用户界面

  • Another Redis Desktop Manager,安装:https://github.com/qishibo/AnotherRedisDesktopManager/releases

Redis 通用命令

可以查官方文档:https://redis.io/commands/,通过按组筛选找到需要的命令 Filter by group…

或者可以命令行输入 help @ 查看命令,比如 help @Generic,但不如官方文档详细

Generic,通用命令

  • KEYS:查看符合模板的所有key。效率低不建议在生产环境上使用

  • DEL:删除指定的一个或多个key,如果某个key不存在,则忽略该key。

  • EXISTS:如果key存在,则返回

  • EXPIRE:给一个key设置有效期,到期自动删除,最好每个key都设置有效期

  • TTL:查看一个key的剩余有效期,-1永久有效,-2失效

Redis 数据结构

key 是字符串,value 支持不同数据类型

具体命令,查官方文档:https://redis.io/commands/,通过按组筛选找到需要的命令 Filter by group…

五种基本数据类型

String 字符串(最常用)

List 列表

Set 集合

SortedSet 有序集合

Hash 哈希

五种高级数据类型

Stream 消息队列

Geospatial 地理空间

HyperLogLog

Bitmap 位图

Bitfield 位域

Redis 的 Java 客户端

Jedis

独立于 Spring 操作 Redis 的 客户端,提供了接近 Redis 原生命令的 API,使得开发者能直接、方便地执行 Redis 命令。

通过 JedisPool 类实现连接池功能,以复用连接,减少创建和销毁连接的开销,提高应用程序性能。

虽然单个 Jedis 实例不是线程安全的,但当配合连接池使用时,每个线程从池中获取自己的 Jedis 实例,从而保证了线程安全。

Lettuce

高阶 的操作 Redis 的 Java 客户端

支持同步、异步和响应式编程,并且是线程安全的

Spring Data Redis

关于 Spring Data,它是 Spring 的一部分,简单来说是一个帮助程序员更容易与各种数据库交互的工具。

image-20240515111858199

Spring Data Redis 整合了 Lettuce 和 Jedis,提供了 RedisTemplate 工具类统一API来操作 Redis。

  1. 引入依赖

    spring-boot-starter-data-redis

  2. 在 application.yml 中配置Redis信息。注意:

    Spring Boot 2.x,配置的命名空间是 spring.redis

    springboot 3.x ,配置的命名空间是 spring.data.redis

    spring:
      application:
        name: springboot3-redis
      data:
        redis:
          host: 192.168.200.130
          port: 6379
          database: 1
          password: 123456
          timeout: 3000ms
          lettuce:	# springboot2.x后默认使用lettuce,如果选择Jedis,需要额外引入它的依赖
            pool:
              max-active: 20  # 最大连接数,负值表示没有限制,默认8
              max-wait: -1    # 最大阻塞等待时间,负值表示没限制,默认-1
              max-idle: 8     # 最大空闲连接,默认8
              min-idle: 0     # 最小空闲连接,默认0
    
    # Logger Config
    logging:
      level:
        com.hexadecimal: debug
    
  3. 注入 RedisTemplate。或者也可以用 StringRedisTemplate,这取决于你的具体需求。

    • StringRedisTemplate 默认使用 StringRedisSerializer 对键和值进行序列化,内部使用getBytes(),使字符串对象变字节,适合存储简单的字符串数据;
    • RedisTemplate 默认使用 JdkSerializationRedisSerializer,内部使用 ObjectOutPutStream,适用于任何Java对象的序列化,但这种方式可读性差,并且会增加存储开销,因为它会产生较大的序列化后的字节流(通常需要自定义序列化器)
  4. 可以根据需要自定义 RedisTemplate 的序列化器,例如使用更高效的序列化库如 Jackson2JsonRedisSerializerGenericJackson2JsonRedisSerializerOxmSerializer,这些都可以帮助减小序列化后数据的大小,并提高性能。

    @Configuration
    public class RedisConfig {
    
        @Bean
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory){
    
            // 创建 RedisTemplate 对象
            RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    
            // 设置连接工厂
            redisTemplate.setConnectionFactory(factory);
    
            //创建 Json 序列化工具
            GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
    
            // 设置key的序列化策略
            redisTemplate.setKeySerializer(RedisSerializer.string());
            redisTemplate.setHashKeySerializer(jsonRedisSerializer);
    
            // 设置value的序列化策略
            redisTemplate.setValueSerializer(jsonRedisSerializer);
            redisTemplate.setHashValueSerializer(jsonRedisSerializer);
    
            return redisTemplate;
        }
    }
    

关于序列化

因为Redis是一个键值存储系统,Java对象不能直接存储在其中,需要转换成字节序列来存储。

什么是序列化呢?

序列化就是把对象的状态信息转换为可以存储或传输的形式,简单来说就是,把对象转换成字节流,以便于网络传输或保存在文件、数据库。反序列化就是恢复这个对象。

查看 redisTemplate.opsForValue().set() 方法发现,它接受任何类型的对象(Object),说明Redis本身并不关心存储的数据的具体类型,它只关心数据的序列化形式

手动序列化

配置 Json序列化器的好处是自动序列化和反序列化,弊端是必须存储一条类型信息,因为在反序列化时必须要知道对象的类型,才能把它还原成 Java对象,所以这条类型信息会造成额外的内存消耗

{
    "@class": "priv.wzg.circlebackend.model.entity.User",
    "id": 1,
    "userAccount": "lisi1234",
    "userPassword": "123456",
    "nickname": "李四",
}

想节省内存空间,只能手动序列化,统一使用String序列化器。在存储和读取Java对象时,手动完成对象的序列化和反序列化

Java对象—>手动序列化成Json字符串—>写入Redis

从Redis中读取Json字符串—>手动反序列化成Java对象

@Test
    void testStringRedisTemplate() {
        User user = new User();
        user.setId(2L);
        user.setUserAccount("wang1234");
        user.setUserPassword("123456");
        user.setNickname("王五");

        String jsonStr = gson.toJson(user);
        stringRedisTemplate.opsForValue().set("user:2", jsonStr);
        String jsonStrValue = stringRedisTemplate.opsForValue().get("user:2");
        User userValue = gson.fromJson(jsonStrValue, User.class);
        System.out.println(userValue);
    }

Redisson

分布式操作 Redis 的 Java 客户端,让你像在使用本地的集合一样操作 Redis(分布式 Redis 数据网格)

应用场景,比如可以用分布式锁保证多机部署时定时任务不会重复执行,具体使用放在项目中,此处不过多介绍

引入依赖,写配置类

@Configuration
@ConfigurationProperties("spring.data.redis")
@Data
public class RedissonConfig {

    private String host;

    private String port;

    private String password;

    @Bean
    public RedissonClient redissonClient() {
        // 创建配置
        Config config = new Config();
        String redisAddress = String.format("redis://%s:%s", host, port);
        config.useSingleServer()
                .setAddress(redisAddress)
                .setPassword(password)
                .setDatabase(1);

        // 创建实例并返回(同步API)
        return Redisson.create(config);
    }
}
@SpringBootTest
public class RedissonTest {

    @Resource
    private RedissonClient redissonClient;

    @Test
    void testRList(){
        // 分布式List
        RList<Object> rList = redissonClient.getList("myList");
        rList.add("test");
        System.out.println(rList.get(0));
    }

    @Test
    void testRMap(){
        // 分布式Map
        RMap<String, String> RMap = redissonClient.getMap("myMap");
        RMap.put("key1", "value1");
        System.out.println(RMap.get("key1"));

    }

}

key 的设计

项目名:业务名:类型:id

对比

  1. 如果你用的是 Spring,并且没有过多的定制化要求,可以用 Spring Data Redis,最方便
  2. 如果你用的不是 Spring,并且追求简单,并且没有过高的性能要求,可以用 Jedis + Jedis Pool
  3. 如果你的项目不是 Spring,并且追求高性能、高定制化,可以用 Lettuce,支持异步、连接池

● 如果你的项目是分布式的,需要用到一些分布式的特性(比如分布式锁、分布式集合),推荐用 redisson

  • 24
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值