redis介绍与快速入门

发布于:2025-09-09 ⋅ 阅读:(19) ⋅ 点赞:(0)

redis介绍与快速入门

一、NoSQL 概述及与 SQL 的区别

  1. 什么是 NoSQL

NoSQL(Not Only SQL)是一类非关系型数据库管理系统,设计用于处理大规模数据存储和高并发访问的场景。与传统的关系型数据库(SQL)不同,NoSQL数据库通常具有更灵活的数据模型,能够更好地适应现代应用程序的需求,特别是在大数据和实时Web应用方面。

  1. SQL NoSQL 的主要区别

特性

SQL (关系型数据库)

NoSQL (非关系型数据库)

数据模型

基于表格的固定结构

灵活的数据模型(文档、键值、列族、图等)

模式(Schema)

预定义的模式,结构严格

无模式或动态模式

可扩展性

垂直扩展(增加服务器性能)

水平扩展(增加服务器数量)

事务支持

ACID 事务支持完善

通常只支持基本事务或最终一致性

查询语言

使用标准化的 SQL 语言

无统一查询语言,各数据库不同

性能

适合复杂查询

适合高吞吐量和简单查询

数据关系

通过外键和JOIN操作维护关系

通常不强调关系,或通过嵌入文档处理

典型用例

需要复杂事务的应用(如银行系统)

大数据、实时分析、内容管理系统等

代表产品

MySQL, PostgreSQL, Oracle, SQL Server

MongoDB, Cassandra, Redis, Neo4j

垂直扩展与水平扩展详解:

垂直扩展 (Vertical Scaling)

垂直扩展又称为"向上扩展"(Scale Up),是指通过增加单个服务器的资源(CPU、内存、存储等)来提高系统性能。

水平扩展 (Horizontal Scaling)

水平扩展又称为"向外扩展"(Scale Out),是指通过增加更多服务器数量来分散负载,提高系统整体性能。

  1. NoSQL 的主要类型

    1. 文档数据库 (如 MongoDB):存储类似JSON的文档
    2. 键值存储 (如 Redis):简单的键值对存储
    3. 宽列存储 (如 Cassandra):按列而不是按行存储数据
    4. 图数据库 (如 Neo4j):专门存储和查询图结构数据
  1. 选择建议

  • 选择SQL:当需要复杂查询、严格的数据完整性和事务支持时
  • 选择NoSQL:当处理大量非结构化数据、需要高可扩展性或灵活的数据模型时

现代开发中,许多系统会结合使用SQL和NoSQL数据库,以利用各自的优势。

二、Redis介绍

Redis(Remote Dictionary Server)是一个开源的、内存中的键值存储系统,常用作数据库、缓存和消息代理。它支持多种数据结构,并提供持久化功能,是当前最流行的 NoSQL 数据库之一。

核心特性

  1. 内存存储:数据主要存储在内存中,提供极高的读写性能(10万+/秒 OPS)
  2. 数据结构丰富:不仅支持简单字符串,还支持:
    • 字符串(Strings)
    • 哈希(Hashes)
    • 列表(Lists)
    • 集合(Sets)
    • 有序集合(Sorted Sets)
    • 位图(Bitmaps)
    • HyperLogLogs
    • 地理空间索引(Geospatial indexes)
    • 流(Streams)
  3. 持久化选项
    • RDB(快照):定期将内存数据转储到磁盘
    • AOF(追加文件):记录所有写操作命令
  4. 高可用与分布式
    • Redis Sentinel(哨兵):提供自动故障转移
    • Redis Cluster:分布式解决方案,数据分片存储
  5. 多功能
    • 缓存(最常用场景)
    • 会话存储
    • 消息队列(Pub/Sub)
    • 实时分析
    • 排行榜/计数器

常见使用场景

  1. 缓存系统
    • 减轻数据库负载
    • 存储会话数据
    • 页面缓存
  2. 实时应用
    • 实时排行榜
    • 计数器
    • 实时分析
  3. 消息系统
    • 发布/订阅模式
    • 简单的消息队列
  4. 其他
    • 分布式锁
    • 限流系统
    • 地理位置应用

三、redis的安装

在这里我们选择用虚拟机(Linux环境  centos 7)来实现部署redis

在官网中下载redis压缩包Redis下载

注意:浏览器可能识别文件不安全,选择保留文件

利用终端工具将压缩包上传到虚拟机并解压压缩包

tar -zvxf redis-5.0.4.tar.gz

结果如图:

注意的是redis是用C写的所以需要C的环境:

yum install -y gcc tcl



cd redis-5.0.4

编译redis

make && make install

如此编译成功:

四、redis的启动

1、默认启动

进入redis’的根目录

redis-server

如此启动成功

2、指定配置启动

打开redis.conf文件(在redis的根目录下)

监听的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,全产环境不要设置为0.0.0.0

守护进程,修改为yes后即可后台运行

设置密码,设置后访问redis 需要密码

设置完成后,保存并退出,

启动:

redis-server redis.conf

查看是否启动成功:

ps -ef | grep redis

五、redis客户端

1、命令行客户端

Redis 自带一个功能强大的命令行客户端工具 redis-cli,是与 Redis 服务器交互的主要方式之一。

连接本地 Redis 服务器(默认端口 6379):

   redis-cli

连接远程 Redis 服务器

   redis-cli -h hostname -p port -a password

例如:

  

 redis-cli -h redis.example.com -p 6380 -a mypassword

常用命令行选项

选项

说明

-h <host>

指定服务器主机名 (默认: 127.0.0.1)

-p <port>

指定服务器端口 (默认: 6379)

-a <password>

使用密码认证

-n <db>

选择数据库编号 (默认: 0)

--raw

显示原始格式的输出

--no-raw

强制格式化输出

--csv

输出 CSV 格式

--stat

实时显示服务器统计信息

--scan

使用 SCAN 命令代替 KEYS

--pattern <pat>

与 --scan 配合使用指定模式

--intrinsic-latency <sec>

测试 Redis 内在延迟

--eval <file>

执行 Lua 脚本文件

这里 我们使用本地连接:

redis-cli -a 123456

输入ping 命令,查看是否链接成功,

显示pong则为成功

做一些简单的命令:

2、图形化界面客户端

官方下载

Releases · lework/RedisDesktopManager-Windows

下载成功后解压,点击exe文件下载到本地,

填写数据,连接redis

注意:一定要关闭虚拟机的防火墙,否则将连接失败

sudo systemctl stop firewalld

最后,结果为

六、redis常见value 的数据结构/类型

Redis 支持多种数据结构类型,每种类型都有特定的使用场景和操作命令。以下是 Redis 中主要的 value 数据结构类型:

1、基本数据结构类型

类型

存储结构

特性

常用场景

String (字符串)

二进制安全字符串

最基本类型,最大512MB

缓存、计数器、分布式锁

Hash (哈希)

键值对集合

适合存储对象

用户信息、商品信息

List (列表)

双向链表

按插入顺序排序,元素可重复

消息队列、最新列表

Set (集合)

无序集合

元素唯一,支持集合运算

标签、好友关系

Sorted Set (有序集合)

带分数的集合

元素唯一,按分数排序

排行榜、优先级队列

2、高级数据结构类型

类型

存储结构

特性

常用场景

Bitmaps (位图)

字符串的位操作

极省空间

用户签到、布隆过滤器

HyperLogLog

概率数据结构

估算基数(去重计数)

UV统计

Geospatial (地理空间)

有序集合实现

存储地理位置

附近的人、地点搜索

Stream (流)

消息链表

持久化消息队列

消息系统、事件溯源

七、redis通用指令

KEYS:查看符合模板的所有key,不建议在生产环境设备上使用

DEL:删除一个指定的key

EXISTS:判断key是否存在

EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除

TTL:查看一个KEY的剩余有效期

例子:

# 1. 设置一个带过期时间的键值

127.0.0.1:6379> SET session:user123 "auth_token_xyz" EX 300

OK # 设置值并设置300秒过期时间

# 2. 检查key是否存在

127.0.0.1:6379> EXISTS session:user123

(integer) 1

 # 3. 查看剩余时间

127.0.0.1:6379> TTL session:user123

(integer) 287

# 剩余287秒 # 4. 修改过期时间

127.0.0.1:6379> EXPIRE session:user123 600

(integer) 1

# 5. 再次查看剩余时间

127.0.0.1:6379> TTL session:user123

(integer) 598

# 已更新为约600秒 # 6. 删除key

127.0.0.1:6379> DEL session:user123

(integer) 1

# 7. 确认删除

127.0.0.1:6379> EXISTS session:user123

(integer) 0

八、redis  key的类型以及常用指令

String类型,也就是字符串类型,是Redis中最简单的存储类型。

其value是字符串,不过根据字符串的格式不同,又可以分为3类:

string:普通字符串

int:整数类型,可以做自增、自减操作

float:浮点类型,可以做自增、自减操作

不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512m.

String类型的常见命令

SET:添加或者修改已经存在的一个String类型的键值对

GET:根据key获取String类型的value

MSET:批量添加多个String类型的键值对

MGET:根据多个key获取多个String类型的value

INCR:让一个整型的key自增1

INCRBY:让一个整型的key自增并指定步长,例如:incrbynum2让num值自增2

INCRBYFLOAT:让一个浮点类型的数字自增并指定步长

SETNX:添加一个String类型的键值对,前提是这个key不存在,否则不执行

SETEX:添加一个String类型的键值对,并且指定有效期

九、redis的层级结构

Redis 虽然没有内置的层级结构支持,但通过合理的 key 命名规范可以模拟出层级结构,

其中分隔符分层法是最常用的,一般以:作为风格符

例子:

user:1001:profile        # 用户1001的基本资料

user:1001:settings       # 用户1001的个人设置

user:1001:orders         # 用户1001的订单集合

user:1001:cart           # 用户1001的购物车

十、哈希类型

Redis 的哈希类型是一种键值对集合,非常适合存储对象类型的数据。

+---------------------+

|   Redis Hash Key    |

+----------+----------+

|  Field1  |  Value1  |

+----------+----------+

|  Field2  |  Value2  |

+----------+----------+

|   ...    |   ...    |

+----------+----------+

|  FieldN  |  ValueN  |

+----------+----------+

Hash类型的常见命令

HSETkeyfieldvalue:添加或者修改hash类型key的field的值

HGETkeyfield:获取一个hash类型key的field的值

HMSET:批量添加多个hash类型key的field的值

HMGET:批量获取多个hash类型key的field的值

HGETALL:获取一个hash类型的key中的所有的field和value

HKEYS:获取一个hash类型的key中的所有的field

HVALS:获取一个hash类型的key中的所有的value

HINCRBY:让一个hash类型key的字段值自增并指定步长

HSETNX:添加一个hash类型的key的field值,前提是这个field不存在,否则不执行

十一、List类型

Redis 的列表(List)类型是一个双向链表结构,支持从两端插入和弹出元素,是实现队列、栈等数据结构的理想选择。

List类型的常见命令

LPUSHkeyelement...:向列表左侧插入一个或多个元素

LPOPkey:移除并返回列表左侧的第一个元素,没有则返回nil

RPUSHkeyelement...:向列表右侧插入一个或多个元素

RPOPkey:移除并返回列表右侧的第一个元素

LRANGEkeystarend:返回一段角标范围内的所有元素

BLPOP和BRPOP:与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil

示例:

十二、set类型

Redis 的集合(Set)是一个无序的、元素唯一的集合数据类型,它提供了高效的成员检查、交集、并集等操作。

特点

无序

元素不可重复

查找快

支持交集、并集、差集等功能

常用命令

SADDkeymember...:向set中添加一个或多个元素

SREMkeymember..:移除set中的指定元素

SCARDkey:返回set中元素的个数

SISMEMBERkeymember:判断一个元素是否存在于set中

SMEMBERS:获取set中的所有元素

SINTERkey1key2..:求key1与key2的交集

SDIFFkey1key2...:求key1与key2的差集

SUNiONkey1key2..:求key1和key2的并集

示例:

十三、SortedSet类型

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

特点

可排序

元素不重复

查询速度快

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

常见命令

ZADDkeyscoremember:添加一个或多个元素到sortedset,如果已经存在则更新其score值

ZREMkeymember:删除sortedset中的一个指定元素

ZScOREkeymember:获取sortedset中的指定元素的score值

ZRANKkeymember:获取sortedset中的指定元素的排名

ZCARDkey:获取sortedset中的元素个数

ZCOUNTkeyminmax:统计score值在给定范围内的所有元素的个数

ZINcRBYkeyincrementmember:让sortedset中的指定元素自增,步长为指定的increment值

ZRANGEkeyminmax:按照score排序后,获取指定排名范围内的元素

ZRANGEBYSCOREkeyminmax:按照score排序后,获取指定score范围内的元素

ZDIFF、ZINTER、ZUNION:求差集、交集、并集

示例:

十四、redis 的java客户端

Redis 提供了多种 Java 客户端选择,以下是主流的java客户端:

客户端

维护者

特点

适用场景

Jedis

Redis 官方

同步阻塞IO、API 直接映射 Redis 命令

简单应用、快速开发

Lettuce

Redis 官方

基于 Netty 的异步非阻塞、支持响应式编程

高并发、异步应用

Redisson

社区

分布式和可扩展的 Java 数据结构

分布式系统、复杂场景

Spring Data Redis

Spring

对 Jedis/Lettuce 的封装、与 Spring 生态集成

Spring 应用

1Jedis

Jedis 是 Redis 官方推荐的 Java 客户端,是一个轻量级、高效且功能完整的 Redis Java 驱动库。但是Jedis本身是线程不安全的,并且频繁的创建和销毁连接会有性能损耗,因此我们一般使用Jedis连接池代替Jedis的直连方式

实战:

导入依赖:

<!--         jedis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>3.7.0</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>5.7.0</version>
        </dependency>

创建配置类(连接池)

private static final JedisPool jedisPool;
static {
    //配置Redis连接池
    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

    jedisPoolConfig.setMaxTotal(8);//最大连接数
    jedisPoolConfig.setMaxIdle(8);//最大空闲连接数
    jedisPoolConfig.setMinIdle(0);//最小空闲连接数
    jedisPoolConfig.setMaxWaitMillis(1000);//最大等待时间
    //创建连接池对象
    jedisPool = new JedisPool(jedisPoolConfig, "192.168.81.131", 6379, 1000);

}

public static Jedis getJedisPool() {
    return jedisPool.getResource() ;
}

在测试类中测试:

private Jedis jedis;

@BeforeEach
public void setUp() {
    // 建立连接
    jedis = JedisConnectionFactory.getJedisPool();
    // 设置密码
    jedis.auth("123456");
    // 选择数据库
    jedis.select(1);
}

@Test
public void testString() {
    //存入数据
    String result = jedis.set("name", "张三");
    System.out.println("result存入" + result);

    //获取数据
    String value = jedis.get("name");
    System.out.println("name = " + value);
}

@Test
public void testHash() {
    //存入数据
    Long name = jedis.hset("user:1", "name", "李四");
    Long name1 = jedis.hset("user:1", "age", "21");

    System.out.println("result存入" + name + "年龄"+ name1);

    //获取数据
    Map<String, String> stringStringMap = jedis.hgetAll("user:1");
    System.out.println("name = " + stringStringMap);
}


@AfterEach
public void tearDown() {
    if (jedis != null) {
        jedis.close();
    }
}

运行的结果:

2springdataredis

Spring Data Redis 是 Spring 生态系统中用于访问 Redis 的模块,它提供了对 Redis 的高级抽象和便捷的集成方式。

特点:

提供了对不同Redis客户端的整合(Lettuce和Jedis)

提供了RedisTemplate统一APl来操作Redis

支持Redis的发布订阅模型

支持Redis哨兵和Redis集群

支持基于Lettuce的响应式编程

支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化

支持基于Redis的JDKCollection实现

实战:

创建spring boot项目,引入依赖:

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


<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>



在application.properties中写入配置:

spring.data.redis.host=192.168.81.131
spring.data.redis.port=6379
spring.data.redis.password=123456
spring.data.redis.database=3
spring.data.redis.timeout=10000
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=100ms
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0

编写测试:

@Autowired
private RedisTemplate redisTemplate;
@Test
void contextLoads() {
    redisTemplate.opsForValue().set("name","一只游鱼");
    //获取
    Object object = redisTemplate.opsForValue().get("name");
    System.out.println(object);

}

需要注意 的是这样插入中文,会出现这样的问题:

出现这样问题的原因是默认序列化器RedisTemplate 默认使用 JdkSerializationRedisSerializer

该序列化器会将对象转为字节数组存储,导致可读性差

所以我们可以通过配置类来修改其序列化配置:

public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {

    // 创建RedisTemplate对象
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    // 设置连接工厂
    template.setConnectionFactory(connectionFactory);
    // 创建JSON序列化工具
    GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
    // 设置Key的序列化
    template.setKeySerializer(RedisSerializer.string());
    template.setHashKeySerializer(RedisSerializer.string());
    //设置value的序列化
    template.setValueSerializer(jsonRedisSerializer);
    template.setHashValueSerializer(jsonRedisSerializer);

    // 返回
    return template;

}

当然需要添加依赖:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.2</version>
</dependency>

修改测试类:

@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Test
void contextLoads() {
    redisTemplate.opsForValue().set("name","一只游鱼");
    //获取
    Object object = redisTemplate.opsForValue().get("name");
    System.out.println(object);

}

如此,解决问题:

当然了,springdataredis提供了专门的stringRedisTemplate来针对String类型(默认为String),这样可以不用通过配置类来实现功能

如下:

@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
void contextLoads() {
    stringRedisTemplate.opsForValue().set("name","一只游鱼");
    //获取
    Object object = stringRedisTemplate.opsForValue().get("name");
    System.out.println(object);

}

当然也可以存入JOSN

创建User实体类:

private static final long serialVersionUID = 1L;

private String name;
private int age;

// 无参构造函数
public User() {
}

// 带参构造函数
public User(String name, int age) {
    this.name = name;
    this.age = age;
}

// 必须提供公共的getter和setter方法
public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

@Override
public String toString() {
    return "User{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
}

编写测试:

@Autowired
private StringRedisTemplate stringRedisTemplate;



private static final ObjectMapper objectMapper = new ObjectMapper();

 @Test
 void testObject() throws JsonProcessingException {
     //创建
     User user = new User("一只游鱼", 21);
     //手动序列化
     String json = objectMapper.writeValueAsString(user);
     //写入数据
     stringRedisTemplate.opsForValue().set("user:1",json);
     //获取数据
     String userJson = stringRedisTemplate.opsForValue().get("user:1");

     //反序列化
     User user1 = objectMapper.readValue(userJson, User.class);
     System.out.println(user1);

 }

如下得到结果:

哈希类型

@Test
void testHash() {
    stringRedisTemplate.opsForHash().put("user:2","name","一只游鱼");
    stringRedisTemplate.opsForHash().put("user:2","age","21");
    //获取
    Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:2");
    System.out.println(entries);
}

结果如下:

最后双手奉上作者的学习源码:    YoyuDev/redisStudent: redis学习笔记

如果有帮助,记得点个赞~~

   


网站公告

今日签到

点亮在社区的每一天
去签到