N

Norlcayn的博客

A text-focused Halo theme

  • 首页
  • 文章
  • 默认分类
  • 关于
主页 性能优化-Redis数据库
文章

性能优化-Redis数据库

发表于 2026-01-15 更新于 昨天
作者 Administrator
41~53 分钟 阅读

概述

Redis是一个基于内存的key-value结构数据库,也是互联网技术领域使用最为广泛的存储中间件

官网:Redis - The Real-time Data Platform

中文网:Redis中文网

key-value结构存储:

key value
id 10001
name 小智
city 北京

主要特点:

  • 基于内存存储,读写性能高
  • 适合存储热点数据(热点商品、资讯、新闻)
  • 企业应用广泛

Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,官方提供的数据是可以达到**100000+**的QPS(每秒内查询次数)。它存储的value类型比较丰富,也被称为结构化的NoSql数据库

NoSql(Not Only SQL),不仅仅是SQL,泛指非关系型数据库。NoSql数据库并不是要取代关系型数据库,而是关系型数据库的补充

关系型数据库(RDBMS):

  • Mysql
  • PostgreSQL
  • Oracle
  • SQLServer

非关系型数据库(NoSql):

  • Redis
  • Mongodb
  • MemCached

Redis环境准备

下载与安装

安装

采用docker的方式来安装Redis

下载镜像:

docker pull redis

创建容器:

docker run -d --name redis --restart=always -p 6379:6379 redis --requirepass "123456"

查看效果:

d09f20b2-72d2-48a8-982f-86c57b438b20

客户端图形工具

图形化工具:Another Redis Desktop Manager

安装完毕后,直接双击启动

44c47aeb-3d02-457e-9d12-233fcca45e55

成功之后,可以直接查看Redis中存储的数据

4ea5af2c-aaf2-454a-85ec-6d445d86cac4

如果客户端连接Redis失败,可以进入到容器内部操作:

[root@localhost ~]# docker exec -it redis bash
root@081e74f9bedb:/data# redis-cli -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> get name
(nil)

Redis数据类型及命令

概述

Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:

  • 字符串 string
  • 哈希 hash
  • 列表 list
  • 无序集合 set
  • 有序集合 zset

字符串操作命令

Redis命令参考地址,Redis中文网:Redis 教程

Redis 中字符串类型常用命令:

以下是Redis常用命令的示例和说明:

语法 说明 示例 示例说明
SET key value 设置指定key的值为value SET username “john” 设置用户名为”john”
GET key 获取指定key的值 GET username 获取名为username的值,返回”john”
SETEX key seconds value 设置指定key的值为value,并将 key 的过期时间设为 seconds 秒(EX: EXpire) SETEX session_token 3600 “abc123” 设置会话令牌,3600秒(1小时)后自动过期
SETNX key value 在 key 不存在时设置 key 的值(分布式锁的原理)(NX: Not eXist) SETNX lock:user:123 “locked” 只有当lock:user:123不存在时才设置,用于实现分布式锁
  • set key(同一个key),后执行的会覆盖之前的数据
  • del key 删除key的数据,这个是通用的命令,不仅仅只是在字符串中适用
  • setnx与set在存储数据的时候,set可以覆盖之前的数据,sexnx则不行

案例:

> 192.168.100.168@6379 connected!
> set name lisi
OK
> get name
lisi
> setex age 10 20
OK
> get age
20
> get age
20
> get age
null     #获取不到数据则返回null
> setnx age 40
1        #设置成功返回1
> setnx age 50
0        #设置失败返回0
> setnx city beijing
1
> setnx city shanghai
0

哈希操作命令

Hash类型,也叫散列,其value是一个无序字典,类似于Java中的HashMap结构

Redis hash 是一个string类型的 field 和 value 的映射表,hash特别适合用于存储对象

数据特点:

Snipaste_2025-09-06_16-22-33

简易理解:

// Redis哈希表可以类比为JSON对象
{
  "user": {           // Redis中的key - user
    "name": "zhangsan",    // Redis哈希表中的field - name
    "age": "18"       // Redis哈希表中的field - age
  }
}

常用命令:

格式 说明
HSET key field value 将哈希表 key 中的字段 field 的值设为 value
HGET key field 获取存储在哈希表中指定字段的值
HKEYS key 获取哈希表中所有字段
HVALS key 获取哈希表中所有值
HDEL key field 删除存储在哈希表中的指定字段

以下是Redis哈希表命令的示例和说明:

格式 说明 示例 示例说明
HSET key field value 将哈希表 key 中的字段 field 的值设为 value HSET user:1001 name “Alice” 在user:1001哈希表中设置name字段为”Alice”
HGET key field 获取存储在哈希表中指定字段的值 HGET user:1001 name 获取user:1001哈希表中name字段的值
HKEYS key 获取哈希表中所有字段 HKEYS user:1001 获取user:1001哈希表中所有字段名
HVALS key 获取哈希表中所有值 HVALS user:1001 获取user:1001哈希表中所有字段的值
HDEL key field 删除存储在哈希表中的指定字段 HDEL user:1001 name 删除user:1001哈希表中的name字段

案例:

> hset user name zhangsan
1
> hget user name
zhangsan
> hdel user name
1
> hget user name
null
> hset user name zhangsan
1
> hkeys user 
name
> hset user age 30
1
> hvals user 
zhangsan
30

列表操作命令

Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索

特征也与LinkedList类似:

  • 有序
  • 元素可以重复
  • 插入和删除快
  • 查询速度一般

bef5df86-1a90-4250-9339-3a66028b01f0

常用命令:

格式 说明 示例 示例说明
LPUSH key value1 [value2] 将一个或多个值插入到列表头部,并返回列表中元素的个数 LPUSH mylist “apple” “banana” 将”apple”和”banana”插入到mylist列表头部
LRANGE key start stop 获取列表指定范围内的元素 LRANGE mylist 0 -1 获取mylist列表中所有元素
RPOP key 移除并获取列表最后一个元素 RPOP mylist 移除并返回mylist列表的最后一个元素
LLEN key 获取列表长度 LLEN mylist 返回mylist列表中元素的个数

示例:

> lpush list a b c
3
> llen list
3
> lrange list 0 1
c
b
> lrange list 0 -1
c
b
a
> rpop list
a
> lrange list 0 -1
c
b
> lpop list
c
> lrange list 0 -1
b

集合操作命令

Redis的Set结构与Java中的HashSet类似,可以看做是一个value为null的HashMap。因为也是一个hash表,因此具备与HashSet类似的特征:

  • 无序
  • 元素不可重复
  • 查找快
  • 支持交集、并集、差集等功能

常见命令:

以下是Redis集合命令的示例和说明:

格式 说明 示例 示例说明
SADD key member1 [member2] 向集合添加一个或多个成员 SADD tags “redis” “database” “nosql” 向tags集合添加三个成员
SMEMBERS key 返回集合中的所有成员 SMEMBERS tags 返回tags集合中的所有成员
SCARD key 获取集合的成员数 SCARD tags 返回tags集合中成员的数量
SINTER key1 [key2] 返回给定所有集合的交集 SINTER group1 group2 返回group1和group2集合的交集
SUNION key1 [key2] 返回所有给定集合的并集 SUNION group1 group2 返回group1和group2集合的并集

案例:

> sadd set1 a b c d a
4
> smembers set1
a
b
c
d
> scard set1
4
> sadd set2 a e f
3
> sinter set1 set2
a
> sunion set1 set2
a
b
c
d
e
f

有序集合操作命令

Redis的 SortedSet / ZSet 是一个可排序的set集合,与Java中的TreeSet有些类似,但底层数据结构却差别很大。SortedSet中的每一个元素都带有一个score属性,可以基于score属性对元素排序,底层的实现是一个**跳表(SkipList)加 hash表**

SortedSet具备下列特性:

  • 可排序
  • 元素不重复
  • 查询速度快

因为SortedSet的可排序特性,经常被用来实现排行榜这样的功能

常用命令:

格式 说明 示例 示例说明
ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员 ZADD leaderboard 100 “Alice” 85 “Bob” 92 “Charlie” 向leaderboard有序集合添加三个成员及其分数
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间内的成员 ZRANGE leaderboard 0 -1 WITHSCORES 返回leaderboard中所有成员按分数升序排列
ZINCRBY key increment member 有序集合中对指定成员的分数加上增量 increment ZINCRBY leaderboard 10 “Alice” 给Alice的分数增加10分
ZREM key member [member …] 移除有序集合中的一个或多个成员 remove ZREM leaderboard “Bob” “Charlie” 从leaderboard中移除Bob和Charlie

示例:

> zadd zset 10 heima
1
> zadd zset 10 heima 20 itcast
1
> zrange zset 0 20
heima
itcast
> zincrby zset 30 heima
40
> zincrby zset 50 heima
90
> zrange zset 0 -1 withscores
itcast
20
heima
90

通用键操作命令

Redis的通用键操作命令是不分数据类型,都可以使用的命令:

格式 说明 示例 示例说明
KEYS pattern 查找所有符合给定模式(pattern)的 key KEYS “user:*” 查找所有以”user:”开头的key
EXISTS key 检查给定 key 是否存在 EXISTS username 检查username这个key是否存在
TYPE key 返回 key 所储存的值的类型 TYPE user:1001 返回user:1001的值类型
DEL key 该命令用于在 key 存在时删除 key DEL temp_data 删除temp_data这个key
> keys *
zset
set2
name
age
heima
set
city
> exists heima
1
> exists heima2
0
> type heima
hash
> del heima
1
> exists heima
0

Spring Data Redis

Redis常见的客户端

Redis 的 Java 客户端很多,常用的几种:

  • Jedis
  • Lettuce
  • Spring Data Redis

Spring 对 Redis 客户端进行了整合,提供了 Spring Data Redis,封装了 Jedis,在Spring Boot项目中还提供了对应的Starter,即 spring-boot-starter-data-redis

概述

Spring Data Redis 是 Spring 的一部分,在 Spring 应用中通过简单的配置就可以访问 Redis 服务,对 Redis 底层开发包进行了高度封装。在 Spring 项目中,可以使用Spring Data Redis来简化 Redis 操作

网址:Spring Data Redis

Spring Boot提供了对应的Starter,maven依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Spring Data Redis中提供了一个高度封装的类:RedisTemplate,对相关api进行了归类封装,将同一类型操作封装为Operation接口,具体分类如下:

  • ValueOperations:string数据操作
  • HashOperations:hash类型的数据操作
  • SetOperations:set类型数据操作
  • ZSetOperations:zset类型数据操作
  • ListOperations:list类型的数据操作

操作字符串数据类型

基于刚才的命令,字符串类型常见命令有:set get setex setnx

/**
 * 操作字符串类型的数据
 */
@Test
public void testString() {
    // 普通的set方法
    redisTemplate.opsForValue().set("name", "张三");
    System.out.println(redisTemplate.opsForValue().get("name"));
    // 设置带有过期时间的key
    redisTemplate.opsForValue().set("token", "123qweasd",20, TimeUnit.SECONDS);
    System.out.println(redisTemplate.opsForValue().get("token"));

    // setnx 当指定的键key不存在时,会将key的值设置为value,返回true,否则返回false(不能覆盖原有值)
    System.out.println(redisTemplate.opsForValue().setIfAbsent("lock", "09876", 5, TimeUnit.MINUTES));
    System.out.println(redisTemplate.opsForValue().setIfAbsent("lock", "34567", 5, TimeUnit.MINUTES));
}

操作哈希类型数据

基于刚才的命令,哈希类型常见命令有:hset hget hkeys hvals hdel

@Test
public void testHash() {
    // hash请求   大key 小key  value
    redisTemplate.opsForHash().put("user", "name", "张三");
    redisTemplate.opsForHash().put("user", "age", "30");
    // 根据大key和小key获取值
    System.out.println(redisTemplate.opsForHash().get("user", "name"));

    // 根据大key获取所有的小key
    Set<Object> keys = redisTemplate.opsForHash().keys("user");
    System.out.println(keys);

    // 根据大key获取所有的值
    List<Object> values = redisTemplate.opsForHash().values("user");
    System.out.println(values);

    // 删除小key和值
    redisTemplate.opsForHash().delete("user", "age");
}

操作列表类型数据

基于刚才的命令,列表类型常见命令有:lpush lrange rpop lpop llen

/**
 * 操作列表类型的数据
 */
@Test
public void testList() {
    // 插入多个值[a,b,c]
    redisTemplate.opsForList().leftPushAll("mylist", "a", "b", "c");
    // 在列表左边插入一个值[d,a,b,c]
    redisTemplate.opsForList().leftPush("mylist", "d");
    // 获取列表中的数据
    System.out.println(redisTemplate.opsForList().range("mylist", 0, -1));
    // 从左边弹出一个,并获取值,弹出后列表中删除
    System.out.println(redisTemplate.opsForList().leftPop("mylist"));
    // 获取列表的长度
    System.out.println(redisTemplate.opsForList().size("mylist"));
}

操作集合类型数据

基于刚才的命令,集合类型常见命令有:sadd smembers scard sinter sunion

/**
 * 操作集合类型的数据
 */
@Test
public void testSet() {
    // 添加数据
    redisTemplate.opsForSet().add("myset1", "a", "b", "c", "d");
    redisTemplate.opsForSet().add("myset2", "a", "b", "x", "y");
    // 获取集合中的所有成员
    Set<String> members = redisTemplate.opsForSet().members("myset1");
    System.out.println(members);

    // 获取集合大小
    long size = redisTemplate.opsForSet().size("myset1");
    System.out.println(size);

    // 交集
    Set<String> intersection = redisTemplate.opsForSet().intersect("myset1", "myset2");
    System.out.println("交集:" + intersection);
    // 并集
    Set<String> union = redisTemplate.opsForSet().union("myset1", "myset2");
    System.out.println("并集:" + union);
}

操作有序集合类型数据

基于刚才的命令,有序集合类型常见命令有:zadd zrange zincrby zrem

/**
 * 操作有序集合类型的数据
 */
@Test
public void testZset() {
    // 添加数据
    redisTemplate.opsForZSet().add("myzset", "a", 1);
    redisTemplate.opsForZSet().add("myzset", "b", 10);
    redisTemplate.opsForZSet().add("myzset", "c", 20);

    // 获取集合中的所有成员
    Set<String> members = redisTemplate.opsForZSet().range("myzset", 0, -1);
    System.out.println(members);

    // 给a成员的分数增加10
    redisTemplate.opsForZSet().incrementScore("myzset", "a", 10);

    // 删除a、b两个成员
    redisTemplate.opsForZSet().remove("myzset", "a", "b");
}

通用命令操作

基于刚才的命令,字符串类型常见命令有:keys exists type del

/**
 * 通用命令操作
 */
@Test
public void testCommon() {
    // 获取所有key
    Set<String> keys = redisTemplate.keys("*");
    System.out.println(keys);

    // 判断key是否存在
    Boolean isName = redisTemplate.hasKey("name");
    System.out.println(isName);

    // 获取key的类型
    DataType type = redisTemplate.type("myzset");
    System.out.println(type.name());

    // 删除key
    redisTemplate.delete("myzset");

}
数据库
后端 非关系型数据库 优化
许可协议:  CC BY 4.0
分享

相关文章

1月 15, 2026

性能优化-Redis数据库

概述 Redis是一个基于内存的key-value结构数据库,也是互联网技术领域使用最为广泛的存储中间件 官网:Redis - The Real-time Data Platform 中文网:Redis中文网 key-value结构存储: key value id 10001 name 小智

1月 15, 2026

性能优化-MySQL索引

为什么要使用索引? 使用索引是为了提高数据检索的效率。当数据量很大时,如果没有索引,数据库系统需要**逐条扫描数据**来找到符合条件的记录,这样会消耗大量的时间和资源。而使用索引可以通过创建特定的数据结构,将数据按照某种规则有序地组织起来,从而加快数据的查找速度 索引可以在数据库表的一列或多列上创建

1月 15, 2026

MySQL数据库

数据库 数据库:DataBase(DB),是存储和管理数据的仓库 数据库管理系统:DataBase Management System(DBMS),操纵和管理数据库的大型软件 SQL:Structured Query Language,操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准

下一篇

Swagger在线接口文档

上一篇

性能优化-MySQL索引

最近更新

  • Hello Halo
  • 状态机
  • 数据表设计规范
  • 缓存优化
  • 事务失效

热门标签

Halo 异常处理 Redisson 并行 Vue 并发 递归 请求限流 SpringAMQP 类加载器

目录

©2026 Norlcayn的博客. 保留部分权利。

使用 Halo 主题 Chirpy