Redis的Java客户端
1. 常见客户端
-
Jedis:
以Redis命令作为方法名称,学习成本低。但Jedis线程不安全,多线程需要基于线程池来使用(控制并发线程数量)。
-
Lettuce
基于Netty实现,支持同步、异步和响应式编程方式,线程安全。支持Redis哨兵模式、集群模式和管道模式
-
Redisson:
基于Redis实现的分布式、可伸缩的数据结构集合。包含了Map,Queue,Lock,Semaphore,AtomicLong等强大功能。
SpringDataRedis:整合了Jedis和Lettuce!
2. Jedis
2.1 使用方式
- 引入Jedis的Maven依赖
- 创建Jedis对象。
- 设置IP,端口,密码,库来建立连接。
- 调用方法。
- 释放资源。(close)
2.2 Jedis线程池
Jedis本身线程不安全,且频繁创建和销毁连接影响性能,推荐使用Jedis连接池代替直连。
- 创建JedisPoolConfig对象。
- 通过JedisPoolConfig设置参数(最大连接数,最大空闲连接,最小空闲连接,最长等待时间等)
- 传入JedisPoolConfig创建JedisPool。
- 通过JedisPool获取Jedis连接对象。
3. SpringDataRedis
3.1 特点
- 对不同Redis客户端的整合(Lettuce和Jedis)。
- 提供了RedisTemplate统一API来操作Redis。
- 支持Redis的发布订阅模型。
- 支持Redis的哨兵和集群模式。
- 支持基于Lettuce的响应式、同步、异步编程方式。
- 支持基于JDK、JSON、字符串、Spring对象的序列化/反序列化。
- 支持基于Redis的JDKCollection实现。
3.2 快速入门
API | 返回值类型 | 说明 |
---|---|---|
redisTemplate.opsForValue() | ValueOperations | 操作String数据类型 |
redisTemplate.opsForHash() | ValueOperations | 操作Hash数据类型 |
redisTemplate.opsForList() | ValueOperations | 操作List数据类型 |
redisTemplate.opsForSet() | ValueOperations | 操作Set数据类型 |
redisTemplate.opsForZSet() | ValueOperations | 操作SortedSet数据类型 |
redisTemplate | 通用命令 |
3.3 使用方式
- 创建一个Spring项目。
- 导入NoSQL下的SpringDataRedis依赖。
- 导入连接池依赖:commons-pool2。
- 配置文件中,配置Redis连接信息。
- AutoWire注入RedisTemplate对象。
- 调用方法,操作Redis。
3.4 RedisTemplate的RedisSerializer(序列化)
- 存入Redis的是序列化后的key和value。
- 包含序列化器:keySerializer,valueSerializer,hashKeySerializer,hashValueSerializer。
- 默认是JDKSerializer器,底层是ObjectOutputStream(对象转字节,而非JSon)
- key和value都转字节。
- 可读性差。
- 内存占用大。
3.5 改变RedisTemplate的RedisSerializer
3.5.1 可用的序列化器:
- Key用StringSerializer。(key一般是字符串)
- Value用GenericJackson2JsonRedisSerializer。(value可能是对象,序列化为Json)
3.5.1 改变步骤:
- 创建RedisTemplate对象
- 设置RedisTemplate的连接工厂RedisConnectFactory。
- 引入序列化器的Maven依赖并创建序列化器。
- 设置RedisTemplate的序列化器。
- 返回RedisTemplate对象。
RedisConnection | RedisConnectionFactory | RedisTemplate | |
---|---|---|---|
描述 | Redis通信的核心构建块(Lettuce和Jedis) | RedisConnection的工厂 | 对RedisConnection进一步封装 |
作用 | 接受和返回二进制值(字节数组)的低级方法 | 创建RedisConnection的工厂类 | 序列化和连接管理,使用户无需处理二进制数据 |
3.6 GenericJackson2JsonRedisSerializer的缺陷和解决方案
缺陷:
- 将对象写入Redis中,Json序列化器会自动将class序列化为Json,但同时会将类的class字节码写入json结果中。
- 每个对象都写入字节码的化,浪费太多空间了。
解决方案:统一使用String类型的序列化器,将Value序列化为String类型。手动序列化到Redis,读取时手动反序列化。
Spring默认提供了StringRedisTemplate,直接用StringRedisTemplate写入。
3.7 RedisTemplate的两种序列化实践方案
方案1:自定义RedisTemplate,修改RedisTemplate的序列化器为GenericJackson2JsonRedisSerializer。
方案2:使用StringRedisTemplate,写入Redis时手动将对象序列化为Json,读取时手动将Json反序列化为对象。