Redis
约 4262 字大约 14 分钟
2026-05-26
Redis
Redis 是一个 开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。
Redis - 官网
Redis - 中文网
Redis - W3Cschool - 教程
Redis是一个基于内存的key-value结构数据库。
- 基于内存存储,读写性能高
- 适合存储热点数据(热点商品、资讯、新闻)
- 企业应用广泛
Redis 简介
Redis是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列代理。
它支持字符串、哈希表、列表、集合、有序集合,位图,hyperloglogs等数据类型。内置复制、Lua脚本、LRU收回、事务以及不同级别磁盘持久化功能,同时通过Redis Sentinel提供高可用,通过Redis Cluster提供自动分区。
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到100000+的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库。
NoSql(Not Only SQL),不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充。
数据库分类
- 关系型数据库(RDBMS)
- Mysql
- Oracle
- DB2
- SQLServer
- 非关系型数据库(NoSQL)
- Redis
- Mongo db
- MemCached
Redis 应用场景
- 缓存
- 任务队列
- 消息队列
- 分布式锁
Redis下载与安装
Redis安装包分为windows版和Linux版:
Windows版下载地址 5.0.14
windows安装教程
Windows版下载地址 7.2.6
windows安装教程
Linux版 所有下载地址
配置环境变量, 若安装的时候已经勾选, 则不需要配置环境变量, 反之则反.
// 安装完毕后,进入redis安装目录找到配置文件redis.windows-service.conf
// 在配置文件中,找到requirepass foobared字样,在其后面追加一行,输入requirepass 123456设置访问Redis时所需的密码
// 一般测试情况下可以不用设定密码。我这里设置123456做演示。// 步骤一: 按住键盘上面的Win+R 输入cmd
// 步骤二: 输入 redis-cli
// 步骤三: auth 123456 (这是你设置的访问密码,,默认是没有的,需要你自行设置)# 在Linux系统安装Redis步骤:
# 1.将Redis安装包上传到Linux
# 2.解压安装包,命令:tar -zxvf redis-4.0.0.tar.gz -C /usr/local
# 3.安装Redis的依赖环境gcc,命令:yum install gcc-c++
# 4.进入/usr/local/redis-4.0.0,进行编译,命令:make
# 5.进入redis的src目录,进行安装,命令:make installRedis 服务启动与停止
Linux中redis服务启动,可以使用 redis-server,默认端口号为6379
# 启动 Redis
# 进入对应的目录
cd /usr/local/redeis.4.0.0/src
# 启动服务
./redis-server
# 停止 Redis
Ctrl + C
# 客服端 连接Redis服务
# 前提需要开启 启动服务 ./redis-server
./redis-cli
keys * # 可以查看 key-value后台运行配置文件
# 停止服务
Ctrl + C
# ./redis-server 启动服务 这时是霸屏的模式
# 首先退出服务 让redis后台运行
# 解决方案:
# 步骤一: 进入配置文件
cd /usr/local/redis-7.4.2
vim redis.conf
# 步骤二: 进入配置文件 输入 /dae 回车 快速查找
daemonize no ==> 修改成 daemonize yes
# 后台 启动服务
cd /usr/local/redis-7.4.2 # 进入目录里面
src/redis-server ./redis.conf # 执行命令Windows系统中启动Redis,直接双击redis-server.exe即可启动Redis服务,redis服务默认端口号为6379
- Ctrl + C 停止Redis服务
Redis 设置密码
redis默认是不要密码就可以登录的,这样不安全,设置密码的步骤如下:
# 步骤一: 进入配置文件
cd /usr/local/redis-7.4.2
vim redis.conf
# 快速搜索
/requirepass # 回车 快速搜索
# 步骤二: 将 下面 注释去掉
# requirepass foobared(默认密码)
requirepass 123456 # 将密码修改成123456Redis 密码访问
# 步骤一: 查看进程
ps -ef | grep redis
# 步骤二: 有进程 需要杀死进程
kill -9 1674
# 步骤三: 重启服务
src/redis-server ./redis.conf
# 步骤四: 客服端连接
./redis-cli
# 步骤五: 查看key-value
keys *
# 会报错
(error) NOAUTH Authentication required. # 需要身份验证
# 身份验证
auth 123456 # 123456 这是密码 (redis.conf 配置文件里面有)
# 或者客服端连接的时候就认证
./redis-cli -h localhost -p 6379 -a 123456
./redis-cli -a 123456Redis 开启远程连接
# 开启远程连接
cd /usr/local/redis-7.4.2
vim redis.conf
# 快速搜索
/bind
# 将下面的语句注释
bind 127.0.0.1 -::1
# 在 window 需要安装 PowerShell 来检测是否可以远程连接Redis 数据类型
Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:
- 字符串 string ( 常用 )
- 哈希 hash ( 适合存储对象 )
- 列表 list ( 按照插入顺序排序,可以有重复元素 )
- 集合 set ( 无序集合,没有重复元素 )
- 有序集合 sorted set ( 有序集合,没有重复元素 )
Redis 常用命令
# 需要启动Redis服务 -a 123456(这是密码)
/usr/local/redis-7.4.2/src/redis-cli -a 123456字符串string操作命令
Redis 中字符串类型常用命令:
SET key value
设置指定key的值
GET key
获取指定key的值
SETEX key seconds value
设置指定key的值,并将key的过期时间设为seconds秒
eg: 验证码
SETNX key value
只有在key不存在时设置key的值
# 设置指定key的值
set name 张三 #设置中文 获取的值是 "\xe5\xbc\xa0\xe4\xb8\x89"
set name zhangsan
# 获取指定的值
get age # 若没有设置这个值 获取的结果是 (nil)
get name
# 设置指定key的值,并将key的过期时间设为seconds秒
setex code 10 2365
# 只有在key不存在时设置key的值
setnx birthday 2000-10-20
setnx birthday 2002-05-03 # 这时设置的值不会生效哈希 hash 操作命令
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象,常用命令:
HSET key field value
将哈希表key中的字段field的值设为value
HGET key field
获取存储在哈希表中指定字段的值
HDEL key field
删除存储在哈希表中的指定字段
HKEYS key
获取哈希表中所有字段
HVALS key
获取哈希表中所有值
HGETALL key
获取在哈希表中指定key的所有字段和值
# 将哈希表key中的字段field的值设为value
hset user name xiaofeng
hset user age 26
# 获取存储在哈希表中指定字段的值
hget user name
hget user age
hget user phone # 返回值是 (nil)
# 删除存储在哈希表中的指定字段
hdel user age
# 获取哈希表中所有字段
hkeys user
# 获取哈希表中所有值
hvals user
# 获取在哈希表中指定key的所有字段和值
hgetall user列表list操作命令
Redis列表是简单的字符串列表,按照插入顺序排序,常用命令:
LPUSH key value1 [value2]
将一个或多个值插入到列表头部
LRANGE key start stop
获取列表指定范围内的元素
RPOP key
移除并获取列表最后一个元素
LLEN key
获取列表长度
BRPOP key1 [key2] timeout
移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
# 将一个或多个值插入到列表头部
lpush userlist a b c d
# 获取列表指定范围内的元素
lrange userlist 0 -1
# 移除并获取列表最后一个元素
rpop userlist
# 获取列表长度
llen userlist
# 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止
brpop userlist 10集合set操作命令
Redis set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据,常用命令:
SADD key member1 [member2]
向集合添加一个或多个成员
SMEMBERS key
返回集合中的所有成员
SCARD key
获取集合的成员数
SINTER key1 [key2]
返回给定所有集合的交集
SUNION key1 [key2]
返回所有给定集合的并集
SDIFF key1 [key2]
返回给定所有集合的差集
SREM key member1 [member2]
移除集合中一个或多个成员
# 向集合添加一个或多个成员
sadd userset1 q w e r t y u i o
sadd userset2 q w a s d f
# 返回集合中的所有成员
smembers userset1
# 获取集合的成员数
scard userset1
# 返回给定所有集合的交集
sinter userset1 userset2
# 返回所有给定集合的并集
sunion userset1 userset2
# 返回给定所有集合的差集
sdiff userset1 userset2
sdiff userset2 userset1
# 移除集合中一个或多个成员
srem userset1 y u i o有序集合sorted set操作命令
Redis sorted set 有序集合是string类型元素的集合,且不允许重复的成员。每个元素都会关联一个double类型的分数(score)。redis正是通过分数来为集合中的成员进行从小到大排序。有序集合的成员是唯一的,但分数却可以重复。常用命令:
ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,或者更新已存在成员的 分
ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合中指定区间内的成员
ZINCRBY key increment member
有序集合中对指定成员的分数加上增量increment
ZREM key member [member...]
移除有序集合中的一个或多个成员
# 向有序集合添加一个或多个成员,或者更新已存在成员的分
zadd userset66 0.2 aaa 1.6 bbb 2.3 ccc 0.8 ddd
# 通过索引区间返回有序集合中指定区间内的成员
zrange userset66 0 -1
zrange userset66 0 -1 withscores # 可以查看分数值
# 有序集合中对指定成员的分数加上增量increment
zincrby userset66 3.0 aaa # 这是aaa 为3.2 即原有基础上加3.0
# 移除有序集合中的一个或多个成员
zrem userset66 aaa通用命令
KEYS pattern
查找所有符合给定模式(pattern)的key
EXISTS key
检查给定key是否存在
TYPE key
返回key所储存的值的类型
TTL key
返回给定key的剩余生存时间(TTL,timetolive),以秒为单位
DEL key
该命令用于在key存在是删除key
# 查找所有符合给定模式(pattern)的key
keys * # 查询所有的key
keys name # 查询key
# 检查给定key是否存在
exists name
# 返回key所储存的值的类型
type name
# 返回给定key的剩余生存时间(TTL,timetolive),以秒为单位
ttl name
# 该命令用于在key存在是删除key
del name
del name age addr # 一次可以删除多个key在Java中操作Redis
Redis的Java客户端很多,官方推荐的有三种:
- Jedis
- Lettuce
- Redisson
Spring对Redis客户端进行了整合,提供了Spring Data Redis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis
jedis
jedis的maven坐标
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
</dependency>使用Jedis操作Redis的步骤:
- 获取连接
- 执行操作
- 关闭连接
// 使用Jedis操作Redis的详细步骤
// 前提: 需要引进maven坐标
// 步骤一: 获取连接
Jedis jedis = new Jedis("192.168.48.128",6379);
// 步骤二: 若设置了密码 需要使用密码连接
jedis.auth("123456");
// 步骤三: 执行操作
jedis.set("userName", "xiaofeng");
jedis.set("addr" , "贵州-贵阳");
// 步骤四: 关闭连接
jedis.close();spring Data Redis
在Spring Boot项目中,可以使用Spring Data Redis来简化Redis操作,maven坐标:
<!-- 前提此项目需要是 springboot项目 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>Spring Data Redis 中提供了一个高度封装的类: Redis Template,针对jedis客户端中大量api进行了归类封装,将同一类 型操作封装为operation接口,具体分类如下:
- ValueOperations:简单K-V操作
- SetOperations:set类型数据操作
- ZSetOperations:zset类型数据操作
- HashOperations:针对map类型的数据操作
- ListOperations:针对list类型的数据操作
Redis-.yml配置
spring:
data: # 报错就在加这一层
# redis相关配置
redis:
host: 192.168.48.128
port: 6379
password: 123456
database: 0 # 默认操作0号数据库 切换数据库 select index index的取值范围[0,15) 即共有16个数据库RedisConfig
// 前提条件 该项目是由 springboot 创建的
// 序列化相关的操作
// 若不配置 存储的key值 \xac\xed\x00\x05t\x00\x04userName
// 配置后 存储的key值 userName
// 配置文件 config/RedisConfig
package com.zkwy.helloword.config;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory){
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
// 默认key的序列化器为: JdkSerializationRedisSerializer 现在将他修改成 StringRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(connectionFactory);
return redisTemplate;
}
}字符串String
@Slf4j
@SpringBootTest
class HellowordApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
/*
* 字符串 Spring 的相关操作
* */
@Test
void springBataRedisStringTest() {
// 1. 设定指定key的值 存储的key值为 "\xac\xed\x00\x05t\x00\x04userName"
// 配置相关的序列化 .../config/RedisConfig 里面配置的
// 配置完成后存储的key就是 opsName
redisTemplate.opsForValue().set("userName", "小艾同学");
// 2. 设定key的过期时间
redisTemplate.opsForValue().set("code", "8465", 300L, TimeUnit.SECONDS); // 过期时间为5分钟
// 3. 只有key不存在时 才设置key值 返回值boolean类型 true添加成功 false 添加失败
redisTemplate.opsForValue().setIfAbsent("userName", "小刘同学");
redisTemplate.opsForValue().setIfAbsent("addr", "湖南-岳阳");
// 4. 获取指定的key值
String userName = (String) redisTemplate.opsForValue().get("userName");
String code = (String) redisTemplate.opsForValue().get("code");
String addr = (String) redisTemplate.opsForValue().get("addr");
// 5. 将分别打印出 userName code addr 的值
log.info("用户的姓名: {}; 地址: {} 验证码: {}", userName, addr, code);
}
}哈希hash
@Slf4j
@SpringBootTest
class HellowordApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
/*
* 哈希 Hash 的相关操作
* */
@Test
void springBataRedisHashTest() {
// 存储 hash 值
redisTemplate.opsForHash().put("userInfoHash", "name", "小张同学");
redisTemplate.opsForHash().put("userInfoHash", "age", "18");
redisTemplate.opsForHash().put("userInfoHash", "addr", "湖南-长沙");
// 获取 hash 值
String name = (String) redisTemplate.opsForHash().get("userInfoHash", "name");
String age = (String) redisTemplate.opsForHash().get("userInfoHash", "age");
String addr = (String) redisTemplate.opsForHash().get("userInfoHash", "addr");
// 将获取的 hash 值 打印出来
log.info("用户的姓名: {} 年龄: {} 地址: {}", name, age, addr);
// 获取 hash 表中的所有key hashKey
Set userInfoHashKeys = redisTemplate.opsForHash().keys("userInfoHash");
for (Object userInfoHashKey : userInfoHashKeys) {
log.info("userInfoHashKey: {}", userInfoHashKey);
}
// 获取 hash 表中的所有value hashValue
List userInfoHashValues = redisTemplate.opsForHash().values("userInfoHash");
for (Object userInfoHashValue : userInfoHashValues) {
log.info("userInfoHashValue: {}", userInfoHashValue);
}
// 删除 hash 里面的 addr字段
// index 代表删除的个数
Long index = redisTemplate.opsForHash().delete("userInfoHash", "addr");
log.info("index: {}", index);
}
}列表list
@Slf4j
@SpringBootTest
class HellowordApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
/*
* 列表 list 的相关操作
* */
@Test
void springBataRedisListTest() {
// 存储 list 数据
// 一次只能存储一个值
redisTemplate.opsForList().leftPush("myList", "xiaofeng");
// 一次存储多个值
redisTemplate.opsForList().leftPushAll("myList", "a", "b", "c");
// 取出 list 数据
List<String> myList = redisTemplate.opsForList().range("myList", 0, -1);
for (String value : myList) {
log.info("myList: {}", value);
}
// 获取列表的长度 List
int size = redisTemplate.opsForList().size("myList").intValue();
for (int i = 0; i < size ; i++) {
// 出队列
// 注意点: 所有的队列都出完了 keys * 则不能获取到 myList
Object element1 = redisTemplate.opsForList().rightPop("myList");
// Object element2 = redisTemplate.opsForList().leftPop("myList");
log.info("我是后边出: {}", element1);
}
}
}集合set
@Slf4j
@SpringBootTest
class HellowordApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
/*
* 集合 set 的相关操作
* */
@Test
void springBataRedisSetTest() {
// 向集合 set 中存储数据
redisTemplate.opsForSet().add("mySet", "q", "w", "e", "r", "q");
// 先集合 set 中取出数据
Set<String> mySet = redisTemplate.opsForSet().members("mySet");
for (String val : mySet) {
log.info("集合里面存储的数据: {}", val);
}
// 删除集合中的 数据
redisTemplate.opsForSet().remove("mySet", "w", "e");
// 删除过后在此获取集合里面的数据
mySet = redisTemplate.opsForSet().members("mySet");
for (String val : mySet) {
log.info("删除后里面的数据: {}",val);
}
}
}有序集合sorted set
@Slf4j
@SpringBootTest
class HellowordApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
/*
* 有序集合 sorted set 的相关操作
* */
@Test
void springBataRedisSortedSetTest() {
// 向有序集合里面存储数据
redisTemplate.opsForZSet().add("myZSet", "小艾", 0.1);
redisTemplate.opsForZSet().add("myZSet", "小张", 2.2);
redisTemplate.opsForZSet().add("myZSet", "小刘", 2.1);
redisTemplate.opsForZSet().add("myZSet", "小李", 5.0);
redisTemplate.opsForZSet().add("myZSet", "小李", 11.0);
// 向有序集合里面取出数据
Set<String> myZSet = redisTemplate.opsForZSet().range("myZSet", 0, -1);
for (String val : myZSet) {
log.info("有序集合里面的数据: {}", val);
}
// 修改有序集合里面的分数
redisTemplate.opsForZSet().incrementScore("myZSet", "小艾", 12.0);
myZSet = redisTemplate.opsForZSet().range("myZSet", 0, -1);
for (String val : myZSet) {
log.info("修改分数后 - 有序集合里面的数据: {}", val);
}
// 删除有序集合里面的数据
redisTemplate.opsForZSet().remove("myZSet", "小刘");
}
}通用操作
@Slf4j
@SpringBootTest
class HellowordApplicationTests {
@Autowired
private RedisTemplate redisTemplate;
/*
* 通用的相关操作 针对不同的数据类型都可以操作
* */
@Test
void springBataRedisCommonTest(){
// 获取 Redis 中所有的key
Set<String> keys = redisTemplate.keys("*");
for (String key : keys) {
log.info("获取的key值有: {}",key);
}
// 判断某个 key 是否存在
Boolean isUserName = redisTemplate.hasKey("userName");
Boolean isName = redisTemplate.hasKey("name");
log.info("userName是否存在: {}, name是否存在: {}",isUserName,isName);
// 删除指定的 key
Boolean addr = redisTemplate.delete("addr");
log.info("addr删除是否成功: {}", addr);
// 获取指定 key 对应的 value 的数据类型
DataType mySet = redisTemplate.type("mySet");
log.info("获取mySet的数据类型: {}",mySet);
}
}