Redis 基础入门
一、为什么用 Redis?
Redis 是用C语言开发的一个把数据放在内存里的键值存储(内存型 Key–Value 存储),读写极快QPS达10万+,常见用途包括:缓存、会话(session)存储、短信验证码、排行榜、限流、简单队列等。它既可以做缓存加速,也能在某些场景下当轻量型数据库来用。
二、下载与安装
2.1 Windows
- Redis-x64-3.0 绿色版,解压即用

3.2 Linux
示例流程:使用xshell把 redis-6.x.tar.gz 上传并编译:
cd /usr/local/redis-6.x
make
make install
关键文件解释:
redis-server:启动服务的可执行文件redis-cli:命令行客户端redis.conf:配置文件(修改密码、持久化、端口等都在这里)
三、Redis基本使用
3.1 启动
redis-server /path/to/redis.conf
Windows 命令:
redis-server.exe redis.windows.conf
3.2 连接
redis-cli # 默认连接 localhost:6379
redis-cli -h host -p port -a password
3.3 设置访问密码
在 redis.conf 中设置:
requirepass 你的密码
修改配置要重启 Redis 才生效。注意:Redis 只有密码,认证方式与MySQL不同。
3.4 Redis客户端图形工具
redis-cli命令行操作及其繁琐,也没有图形化界面,我们使用第三方的redis图形化客户端工具:
Another Redis Desktop Manager-win-1.7
安装完毕后,直接双击启动
新建连接
连接成功
四、Redis 常用数据类型
4.1 String(字符串)
- 场景:验证码、单值缓存、简单计数器
4.2 Hash(哈希)
- 场景:对象(用户信息)存储,字段级别读写更方便
4.3 List(列表)
- 场景:消息队列、时间线(按顺序)、最近记录
4.4 Set(集合)
- 场景:去重、好友关系、标签集合(支持交集并集差集)
4.5 Sorted Set(有序集合 / ZSet)
- 场景:排行榜、带权重排序的数据(score 可以是分数、时间戳)
五、常用命令
5.1 字符串
SET key value
示例:> SET name jack OKGET key> GET name "jack" # 在 redis-cli 普通输出会显示为:jack(或带双引号,取决客户端) > GET noexist (nil)SETEX key seconds value(设置并指定过期时间)> SETEX code 300 1234 OK > TTL code (integer) 299SETNX key value(仅当 key 不存在时设置)
第一次设置:> SETNX lock 1 (integer) 1再次设置:
> SETNX lock 2 (integer) 0 > GET lock "1"
5.2 哈希命令
HSET key field value> HSET user:100 name xiaoming (integer) 1 # 返回 1 表示新字段被创建;如果是更新字段则返回 0 > HSET user:100 age 22 (integer) 1HGET key field> HGET user:100 name "xiaoming" > HGET user:100 notexists (nil)HDEL key field> HDEL user:100 name (integer) 1 # 返回删除的字段数HKEYS key/HVALS key> HKEYS user:100 1) "age" 2) "name" > HVALS user:100 1) "22" 2) "xiaoming"
5.3 列表命令
LPUSH key val1 [val2 ...]> LPUSH mylist a b c (integer) 3 # 返回列表当前长度(这里是 3)LRANGE key start stop> LRANGE mylist 0 -1 1) "c" 2) "b" 3) "a"RPOP key> RPOP mylist "a" > LLEN mylist (integer) 2LLEN key> LLEN mylist (integer) 2BRPOP key timeout(阻塞弹出)> BRPOP q 5 1) "q" 2) "message" # 如果超时并且仍无元素则返回 (nil)
5.4 集合命令
SADD key member1 [member2]> SADD set1 a b c d (integer) 4 > SADD set1 a (integer) 0 # 重复成员不再被添加SMEMBERS key> SMEMBERS set1 1) "d" 2) "c" 3) "b" 4) "a" # 注:集合无序,返回顺序不固定SCARD key(成员数)> SCARD set1 (integer) 4SINTER key1 key2(交集)> SADD set2 a b x y (integer) 4 > SINTER set1 set2 1) "b" 2) "a"SREM key member(移除)> SREM set1 a (integer) 1
5.5 有序集合(ZSet)命令
ZADD key score member [score member ...]> ZADD zset1 10.0 a 10.5 b (integer) 2 > ZADD zset1 10.2 c (integer) 1ZRANGE key start stop [WITHSCORES]> ZRANGE zset1 0 -1 1) "a" 2) "c" 3) "b" > ZRANGE zset1 0 -1 WITHSCORES 1) "a" 2) "10" 3) "c" 4) "10.199999999999999" 5) "b" 6) "10.5"ZINCRBY key increment member> ZINCRBY zset1 5.0 a "15" # 返回 member 最新的 score(字符串形式)ZREM key member> ZREM zset1 b (integer) 1
5.6 通用命令(跨类型)
KEYS pattern(慎用,生产环境尽量不用)> KEYS * 1) "set2" 2) "mylist" 3) "zset1" 4) "name" 5) "key1" 6) "set1" 7) "100"EXISTS key> EXISTS name (integer) 1 > EXISTS noexist (integer) 0TYPE key> TYPE name string > TYPE set1 set > TYPE mylist listDEL key [key ...](删除 key)> DEL name (integer) 1 > DEL 100 key1 (integer) 2
六、Spring Data Redis
在 Java 中操作 Redis 常用客户端:
- Jedis:命令映射直观,学习成本低
- Lettuce:基于 Netty,支持多线程异步/响应式,性能好
- Spring Data Redis:在 Spring Boot 中最方便,推荐用于企业项目
6.1 Spring Data Redis 使用
Spring Data Redis 是 Spring 的一部分,提供了在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作。
网址:https://spring.io/projects/spring-data-redis
- 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.yml:
spring:
redis:
host: localhost
port: 6379
password: 123456
database: 10
- 自定义
RedisTemplate序列化,默认的key序列化器为JdkSerializationRedisSerializer,导致我们存到Redis中后的数据和原始数据有差别,设置为StringRedisSerializer序列化器:
/*
* redisConnectionFactory:这个连接工厂对象并不需要自己去创建,因为在
* server子模块下的pom.xml文件已经引入了starter依赖,这个starter依赖
* 会自动的把这个连接工厂对象给我们创建好,并且放到Spring容器中,所以这个地方只需要声明一下
* 就可以把它注入进来了。
* */
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 记录创建RedisTemplate对象的日志
log.info("开始创建redis对象");
// 实例化RedisTemplate
RedisTemplate redisTemplate = new RedisTemplate();
// 设置Redis连接工厂
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 设置键的序列化方式为StringRedisSerializer,确保键以字符串形式存储
redisTemplate.setKeySerializer(new StringRedisSerializer());
// 返回配置好的RedisTemplate实例
return redisTemplate;
}
- 两种序列化的最直接区别
- 五种类型api
@SpringBootTest
public class SpringDataRedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testRedisTemplate(){
System.out.println(redisTemplate);
//string数据操作
ValueOperations valueOperations = redisTemplate.opsForValue();
//hash类型的数据操作
HashOperations hashOperations = redisTemplate.opsForHash();
//list类型的数据操作
ListOperations listOperations = redisTemplate.opsForList();
//set类型数据操作
SetOperations setOperations = redisTemplate.opsForSet();
//zset类型数据操作
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
}
6.2 5种数据类型基本操作
1). 操作字符串类型数据
@Test
public void testString(){
// set、 get 、setex、 setnx
//1.设置指定key的值
redisTemplate.opsForValue().set("name","小明");
//2.获取指定key的值,返回的是object对象,可以进行强转
String city = (String) redisTemplate.opsForValue().get("name");
System.out.println(city);//小明
//3.设置指定key的值,并指定 key 的过期时间
// 参数:k、V、过期时间、单位(TimeUnit.MINUTES分钟,这是枚举类型)
redisTemplate.opsForValue().set("code","1234",3, TimeUnit.MINUTES);
//4.只有在 key 不存在时设置 key 的值
//问题:前面讲过这个set命令操作的value是字符串类型,但是这个地方使用java来操作的时候value变为object类型了?
// 答: java中调用方法的时候这个value可以是任意类型,最终他都会把这个对象进行一个序列化,最终都会转化成redis中的String来进行存储。
redisTemplate.opsForValue().setIfAbsent("lock","1"); //第一次没有k成功
redisTemplate.opsForValue().setIfAbsent("lock","2"); //第二次有k失败
}
2). 操作哈希类型数据
@Test
public void testHash(){
//hset、 hget、 hdel、 hkeys、 hvals
HashOperations hashOperations = redisTemplate.opsForHash();
//1.将哈希表 key 中的字段 field 的值设为 value
hashOperations.put("100","name","tom");
hashOperations.put("100","age","20");
//2.获取存储在哈希表中指定字段的值,返回的是object对象,可以进行强转
String name = (String) hashOperations.get("100", "name");
System.out.println(name); //tom
//3.获取哈希表中所有字段
Set keys = hashOperations.keys("100");
System.out.println(keys);//[name, age]
//4.获取哈希表中所有值
List values = hashOperations.values("100");
System.out.println(values);//[tom, 20]
//5. 删除存储在哈希表中的指定字段
hashOperations.delete("100","age");
}
3). 操作列表类型数据
@Test
public void testList(){
//lpush 、lrange 、rpop 、llen
ListOperations listOperations = redisTemplate.opsForList();
//1. 将一个或多个值插入到列表头部
listOperations.leftPushAll("mylist","a","b","c");//一次性插入多个
listOperations.leftPush("mylist","d");//一次性插入一个
//2.获取列表指定范围内的元素 0代表从队列头部开始 -1代表队列的尾部
List mylist = listOperations.range("mylist", 0, -1);
System.out.println(mylist);//[d, c, b, a]
//3.移除并获取列表最后一个元素,并且这个命令会返回这个值
listOperations.rightPop("mylist");
//4.获取列表长度
Long size = listOperations.size("mylist");
System.out.println(size);//3
}
4). 操作集合类型数据
@Test
public void testSet(){
//sadd、 smembers 、scard 、sinter、 sunion 、srem
SetOperations setOperations = redisTemplate.opsForSet();
//1.向集合添加一个或多个成员
setOperations.add("set1","a","b","c","d");
setOperations.add("set2","a","b","x","y");
//2. 返回集合中的所有成员
Set members = setOperations.members("set1");
System.out.println(members);//[d, c, b, a]
//3.获取集合的成员数
Long size = setOperations.size("set1");
System.out.println(size);//4
//4.返回给定所有集合的交集
Set intersect = setOperations.intersect("set1", "set2");
System.out.println(intersect);//[b, a]
//5.返回所有给定集合的并集
Set union = setOperations.union("set1", "set2");
System.out.println(union);//[b, a, d, c, y, x]
//6.移除集合中一个或多个成员
setOperations.remove("set1","a","b");
}
5). 操作有序集合类型数据
@Test
public void testZset(){
//zadd 、zrange、 zincrby 、zrem
ZSetOperations zSetOperations = redisTemplate.opsForZSet();
//1.向有序集合添加一个或多个成员
zSetOperations.add("zset1","a",10);
zSetOperations.add("zset1","b",12);
zSetOperations.add("zset1","c",9);
//2.通过索引区间返回有序集合中指定区间内的成员
Set zset1 = zSetOperations.range("zset1", 0, -1);
System.out.println(zset1);//[c, a, b]
//3.有序集合中对指定成员的分数加上增量 increment
zSetOperations.incrementScore("zset1","c",10);
//4. 移除有序集合中的一个或多个成员
zSetOperations.remove("zset1","a","b");
}
6). 通用命令操作
@Test
public void testCommon(){
//keys 、exists、 type 、del
//1.查找所有符合给定模式( pattern)的 key
Set keys = redisTemplate.keys("*");
System.out.println(keys);//[set2, zset1, set1]
//2.检查给定 key 是否存在
Boolean name = redisTemplate.hasKey("name");
Boolean set1 = redisTemplate.hasKey("set1");
//3.返回 key 所储存的值的类型
for (Object key : keys) {
DataType type = redisTemplate.type(key);
System.out.println(type.name());//SET ZSET SET
}
//4.该命令用于在 key 存在是删除 key
redisTemplate.delete("mylist");
}
欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1701220998@qq.com