Redis 入门:从数据结构到 Java 客户端,轻松上手!
作为一名开发者,在日常工作中,缓存是提升系统性能的关键手段之一,而 Redis 作为一款高性能的键值对数据库,在缓存领域占据着重要地位。今天,我就来和大家分享 Redis 的一些基础知识,从数据结构、通用命令,再到 Java 客户端的使用,带大家轻松入门 Redis。
一、Redis 数据结构:多样类型,满足不同需求
Redis 是典型的 key - value 数据库,key 一般为 String 类型,而 value 类型丰富多样,可分为基本类型和特殊类型。
(一)基本类型
- String:最基础的字符串类型,能存储普通的文本内容,比如 “hello world” 这样的简单字符串,是 Redis 中最常用的数据类型之一,可用于存储简单的键值对信息,像用户的昵称等。
- Hash:类似 Java 中的 Map 结构,可存储一组键值对集合,例如
{name: "Jack", age: 21},非常适合存储对象类的数据,比如用户的个人信息,包含姓名、年龄等多个字段,方便对对象的各个属性进行操作。 - List:有序列表,元素可以重复,且按照插入顺序排列,比如
[A -> B -> C -> C]。这种特性使得它很适合实现队列、栈等数据结构,比如消息队列场景,消息按顺序入队和出队。 - Set:无序集合,元素具有唯一性,例如
{A, B, C}。基于这个特性,它可用于实现交集、并集等集合操作,比如统计两个用户群体的共同爱好。 - SortedSet:有序集合,每个元素会关联一个分数(score),并按照分数进行排序,如
{A: 1, B: 2, C: 3}。在实际应用中,常用于排行榜等需要排序的场景,比如游戏玩家的积分排行榜。
(二)特殊类型
- GEO:专门用于存储地理位置信息,像
{A: (120.3, 30.5)},可以实现附近地点查找等地理相关操作,例如外卖平台查找用户附近的商家。 - BitMap:以位为单位进行操作,存储二进制数据,如
0110110101110101011。适合处理大量布尔型数据,比如用户的签到记录,用每一位表示用户某一天是否签到。 - HyperLog:用于基数统计,能够高效地统计集合中不同元素的数量,基于二进制数据操作,在数据量很大时也能节省空间,比如统计网站的独立访客数量。
二、Redis 通用命令:便捷操作 Redis 数据
通用命令是部分数据类型都可以使用的指令,掌握这些命令能让我们更便捷地操作 Redis 数据。
- KEYS:用于查看符合模板的所有 key。不过要注意,由于它会遍历所有 key,在生产环境有大量数据的情况下,会阻塞 Redis 服务器,所以不建议在生产环境使用。
- DEL:删除指定的 key,能快速清理不需要的数据。
- EXISTS:判断 key 是否存在,可用于检查数据是否存在于 Redis 中。
- EXPIRE:为 key 设置有效期,当有效期到期时,该 key 会被自动删除,这对于实现缓存的自动失效非常有用。
- TTL:查看一个 key 的剩余有效期,方便我们了解缓存还有多久失效。
如果想查看某个命令的具体用法,可以通过 help [command],比如 help keys,就能看到 KEYS pattern 等相关说明。
三、Redis 的 Java 客户端:让 Java 与 Redis 交互更简单
Java 连接 Redis 有多种客户端,下面介绍几种常用的:
- Jedis:方法名和 Redis 命令基本一致,学习成本低,简单实用。但 Jedis 实例是线程不安全的,在多线程环境下需要基于连接池来使用。
- Lettuce:基于 Netty 实现,支持同步、异步和响应式编程方式,并且是线程安全的。还支持 Redis 的哨兵模式、集群模式和管道模式,适用于对性能和并发要求较高的场景。
- Redisson:是一个基于 Redis 实现的分布式、可伸缩的 Java 数据结构集合。包含了诸如 Map、Queue、Lock、Semaphore、AtomicLong 等强大功能,能很方便地实现分布式相关操作,比如分布式锁。
Jedis 连接池
由于 Jedis 本身线程不安全,且频繁创建和销毁连接会带来性能损耗,所以推荐大家使用 Jedis 连接池代替 Jedis 的直连方式。下面是一个简单的 Jedis 连接池示例代码:
public class JedisConnectionFactory {
private static final JedisPool jedisPool;
static {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大连接数
jedisPoolConfig.setMaxTotal(8);
// 最大空闲连接
jedisPoolConfig.setMaxIdle(8);
// 最小空闲连接
jedisPoolConfig.setMinIdle(0);
// 设置最长等待时间,单位 ms
jedisPoolConfig.setMaxWaitMillis(200);
jedisPool = new JedisPool(jedisPoolConfig, "192.168.150.101", 6379, 1000, "123321");
}
// 获取Jedis对象
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
通过连接池,我们可以在多线程环境下安全、高效地获取 Jedis 连接,避免了频繁创建和销毁连接的性能问题。
四、SpringDataRedis:Spring 家族的 Redis 工具
SpringDataRedis 中提供了 RedisTemplate 工具类,其中封装了各种对 Redis 的操作。并且将不同数据类型的操作 API 封装到了不同的类型中,比如:
redisTemplate.opsForValue():返回 ValueOperations,用于操作 String 类型数据。redisTemplate.opsForHash():返回 HashOperations,用于操作 Hash 类型数据。redisTemplate.opsForList():返回 ListOperations,用于操作 List 类型数据。redisTemplate.opsForSet():返回 SetOperations,用于操作 Set 类型数据。redisTemplate.opsForZSet():返回 ZSetOperations,用于操作 SortedSet 类型数据。
同时,redisTemplate本身也支持通用的命令。
使用时,我们可以通过 @Autowired 注入 RedisTemplate,然后编写测试代码来操作 Redis 数据,比如:
@SpringBootTest
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
void testString() {
// 插入一条string类型数据
redisTemplate.opsForValue().set("name", "李四");
// 读取一条string类型数据
Object name = redisTemplate.opsForValue().get("name");
System.out.println("name = " + name);
}
}
SpringDataRedis 的序列化方式
在使用 SpringDataRedis 时,序列化方式很重要,它决定了数据在 Redis 中的存储形式以及读取时的解析方式。主要有以下两种方式:
(一)自定义 RedisTemplate 序列化(相对简单,不那么省空间)
我们可以自定义 RedisTemplate 的序列化方式,代码如下:
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
// 创建Template
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
// 设置连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置序列化工
GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// key和 hashKey采用 string序列化
redisTemplate.setKeySerializer(RedisSerializer.string());
redisTemplate.setHashKeySerializer(RedisSerializer.string());
// value和 hashValue采用 JSON序列化
redisTemplate.setValueSerializer(jsonRedisSerializer);
redisTemplate.setHashValueSerializer(jsonRedisSerializer);
return redisTemplate;
}
这种方式使用 JSON 序列化来处理 value 和 hashValue,使用起来相对简单,不需要手动进行序列化和反序列化操作,但由于存储的是 JSON 格式的数据,相对来说没有那么节省空间。
(二)使用 StringRedisTemplate(省空间,需手动序列化)
为了节省内存空间,我们可以使用 StringRedisTemplate。它的 key 和 value 的序列化方式默认就是 String 方式。当需要存储 Java 对象时,需要手动完成对象的序列化和反序列化。
例如,有一个 User 类:
public class User {
private String name;
private Integer age;
// 构造方法、getter、setter等方法
}
存储和读取 User 对象的代码如下:
@Autowired
private StringRedisTemplate stringRedisTemplate;
// JSON工具
private static final ObjectMapper mapper = new ObjectMapper();
@Test
void testStringTemplate() throws JsonProcessingException {
// 准备对象
User user = new User("虎哥", 18);
// 手动序列化
String json = mapper.writeValueAsString(user);
// 写入一条数据到redis
stringRedisTemplate.opsForValue().set("user:200", json);
// 读取数据
String val = stringRedisTemplate.opsForValue().get("user:200");
// 反序列化
User user1 = mapper.readValue(val, User.class);
System.out.println("user1 = " + user1);
}
这种方式因为统一使用 String 序列化器,只存储 String 类型的 key 和 value,所以比较节省空间,但需要手动进行对象的序列化和反序列化,相对麻烦一些。
以上就是 Redis 从数据结构、通用命令到 Java 客户端,以及 SpringDataRedis 序列化方式的相关知识。希望能帮助大家轻松入门 Redis,在实际开发中更好地运用它来提升系统性能。
更多推荐

所有评论(0)