Redis(详解)

本文深入探讨Redis,包括Redis概述、常用数据类型(如String、Hash、List、Set)及其应用实践,Java操作Redis的Jedis和RedisTemplate介绍,以及重点讲解了Redis的数据持久化策略Rdb和Aof,分析了各自的优缺点,最后讨论了Redis的事务处理和主从复制、哨兵模式,以提升系统的高可用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

在我们的项目架构中,基本上是web服务器和数据库独立部署,独占服务器资源,随着用户数的增长,并发读写数据库,会增加数据库访问的压力,导致性能下降,严重则会导致系统宕机:

此时,我们可以在Tomcat同服务器上增加本地缓存,并在外部增加分布式缓存,缓存热门数据。也就是通过缓存把绝大部分请求在读写数据库前拦截掉,大大降低数据库压力。

基于这样的一种架构设计,于是redis分布式数据库就诞生了。

Redis 概述

Redis是一个Key-value存储系统,是一个分布式缓存数据库。

Redis常用数据类型

Redis作为一种Key/value结构的数据存储系统,为了便于对数据进行管理,提供了多种数据类型。

然后基于指定类型存储我们项目中产生的数据,例如用户的登录信息,购物车信息,商品详情信息等。

String类

字符串类型是redis中最简单的数据类型,它存储的值可以是字符串,其最大字符串长度支持到512M。基于此类型,可以实现博客的字数统计,将日志不断追加到指定key,实现一个分布式自增iid,实现一个博客的的点赞操作等

mset/mget

同时设置/获取多个键值
语法:MSET key value [key value …]
MGET key [key …]

Hash类型应用实践

Redis散列类型相当于Java中的HashMap,实现原理跟HashMap一致,一般用于存储对象信息,存储了字段(field)和字段值的映射,一个散列类型可以包含最多232-1个字段。

List类型应用实践

Redis的list类型相当于java中的LinkedList,其原理就就是一个双向链表。支持正向、反向查找和遍历等操作,插入删除速度比较快。经常用于实现热销榜,最新评论等的设计。

Set类型应用实践

Redis的Set类似Java中的HashSet,是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。Redis中Set集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

Java中操作redis

Jedis的基本应用

简介

Jedis是java操作redis的一个客户端,类似通过JDBC访问数据库。

RedisTemplate基本应用

简介

RedisTemplate为SpringBoot工程中操作redis数据库的一个java对象,此对象封装了redis的一些基本操作。

准备工作

第一步:添加在redis-template工程添加依赖

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.2.RELEASE</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

第二步:创建工程配置文件application.yml,其内容如下

spring:
  redis:
    host: 192.168.64.128  #写自己的ip
    port: 6379

第三步:创建工程启动类

Redis 数据持久化

背景
Redis是一种内存数据库,在断电时数据可能会丢失。比如你redis整个挂了,然后redis不可用了,如果没有持久化的话,redis就会丢失所有的数据,如果通过持久化将数据搞一份儿到磁盘上去,然后再定期同步到一些云存储服务上去,那么就可以保证一些数据不丢失,保证数据的可靠性。

持久化方式

Redis中为了保证在系统宕机(类似进程被杀死)情况下,能更快的进行故障恢复,设计了两种数据持久化方案,分别为rdb和aof方式。

配置准备工作
第一步:从redis.io官方下载对应版本的redis.conf文件,地址如下

https://redis.io/topics/config/


第二步:停止redis并删除挂载目录下(/usr/local/docker/redis01/conf)的redis.conf配置文件.
第三步:将下载的redis.conf文件拷贝到redis挂载目录(/usr/local/docker/redis01/conf)
第四步:基于vim打开redis.conf文件,然后注释 bind 127.0.0.1这一行,并修改protected-mode的值修改为no.(java连接redis需要改这两项目)
第五步:重启redis服务,并检查启动日志(docker logs 容器id)

Rdb方式持久化

概述

Rdb方式是通过手动(save-阻塞式,bgsave-异步)或周期性方式保存redis中key/value的一种机制,Rdb方式一般为0redis的默认数据持久化方式.系统启动时会自动开启这种方式的持久化机制。

面试常问

触发redis中rdb方式持久化的时机?

1)基于配置文件中的save规则周期性的执行持久化。
2)手动执行了shutdown操作会自动执行rdb方式的持久化。
3)手动调用了save或bgsave指令执行数据持久化。
4)在Master/Slave架构下,当有新的Slave连接Master时,Master会对数据进行rdb方式持久化.
 

Redis中的save和bgsave有什么不同?

Save命令执行一个同步保存操作,将当前Redis实例的所有数据快照以Rdb文件形式保存到磁盘。

Bgsave命令执行后立即返回OK,然后Redis分出一个子进程,子进程负责讲redis数据保存到磁盘,然后退出,原来的进程则继续处理客户端请求。

RDB持久化机制有哪些优缺点?

优点: RDB 方式持久化性能较好,执行持久化时可以fork 一个子进程,由子进程处理保存工作,父进程无须执行任何磁盘 I/O 操作。

缺点:RDB方式在服务器故障时容易造成数据的丢失。实际项目中,我们可通过配置来控制持久化的频率。但是,如果频率太频繁,可能会对 Redis 性能产生影响。所以通常可能设置至少5分钟才保存一次快照,这时如果 Redis 出现宕机等情况,则意味着最多可能丢失5分钟数据。

Aof方式数据持久化

概述

Aof方式是通过记录写操作日志的方式,实现redis数据持久化的一种机制,这个机制默认是关闭的。

AOF持久化机制有哪些优缺点?

优点:AOF 比 RDB更加可靠。你可以设置不同的 fsync 策略(no、everysec 和 always)。默认是 everysec,在这种配置下,redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据。

缺点:性能较慢

如何选择redis的持久化方式?

第一:不要仅仅使用RDB,因为那样会导致你丢失很多数据。
第二:也不要仅仅使用AOF,因为AOF做冷备没有RDB做冷备进行数据恢复的速度快,并且RDB简单粗暴的数据快照方式更加健壮。
第三:综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备。


Redis 事务处理实践

基本指令

redis进行事务控制时,通常是基于如下指令进行实现,例如:

  • multi 开启事务
  • exec 提交事务
  • discard 取消事务
  • watch 监控,如果监控的值发生变化,则提交事务时会失败
  • unwatch 去掉监控

Redis主从复制,哨兵模式!

Redis主从复制

简介

单个Redis支持的读写能力还是有限的,此时我们可以使用多个redis来提高redis的并发处理能力,这些redis如何协同,就需要有一定的架构设计,这里我们首先从主从(Master/Slave)架构进行分析和实现

基于redis,设计一主从架构,一个Master,两个Slave,其中Master负责Redis读写操作,并将数据同步到Slave,Slave只负责读.

Redis哨兵模式
简介
哨兵(Sentinel)是Redis主从架构模式下,实现高可用性(high availability)的一种机制。由一个或多个Sentinel实例组成的Sentinel系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器,并在被监视的主服务器进入下线状态时,自动将下线主服务器属下的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。
 

哨兵工作原理分析   


1)每个Sentinel以每秒一次的频率向它所知的Master,Slave以及其他 Sentinel 实例发送一个 PING 命令。
2)如果一个Redis服务距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值(这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒), 则这个Redis服务会被 Sentinel 标记为主观下线。
3)如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel 要以每秒一次的频率确认Master的确进入了主观下线状态。
4)当有足够数量的 Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 。
 

### Redis 详细教程和功能解析 #### 一、Redis 简介 Redis 是一个开源的内存数据结构存储系统,可以用作数据库缓存和消息中间件。它支持多种数据结构,如字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)、有序集合(Sorted Sets)等[^3]。此外,Redis 提供了丰富的功能,包括事务支持、发布/订阅模式、Lua 脚本执行以及持久化选项。 #### 二、Redis 的用途 Redis 广泛应用于以下场景: - **缓存**:通过将频繁访问的数据存储在内存中,显著提高应用性能。 - **消息队列**:利用 Redis 的列表数据结构实现高效的队列管理。 - **会话存储**:存储用户会话信息,减少对传统数据库的压力。 - **计数器**:使用原子操作实现高并发环境下的计数功能。 - **地理位置查询**:借助 Geospatial 功能提供基于地理位置的服务[^2]。 #### 三、Redis 的特性 1. **高性能**:由于数据存储在内存中,Redis 的读写速度极快,每秒可处理数十万次请求。 2. **持久化支持**:提供 RDB(快照)和 AOF(追加日志)两种持久化方式,确保数据安全。 3. **丰富的数据结构**:支持多种数据类型,便于开发人员灵活处理复杂业务逻辑。 4. **分布式支持**:通过 Redis Cluster 实现水平扩展,满足大规模数据存储需求。 5. **多语言支持**:几乎所有的主流编程语言都提供了 Redis 客户端库[^3]。 #### 四、Redis 的 IO 模型 Redis 的 IO 模型主要包括单线程模型、混合线程模型和多线程模型: - **单线程模型**:Redis 主线程负责所有命令的处理,保证操作的原子性。 - **混合线程模型**:在网络 IO 和文件持久化过程中引入多线程,提升整体性能。 - **多线程模型**:从 Redis 6.0 开始,支持多线程处理网络请求,进一步增强并发能力[^1]。 #### 五、Redis 的安装与配置 以 Windows 系统为例,可以通过以下步骤安装 Redis: 1. 下载适用于 Windows 的 Redis 可执行文件或使用 Docker 镜像。 2. 解压后运行 `redis-server.exe` 启动服务。 3. 使用 `redis-cli.exe` 连接 Redis 服务器并测试基本命令[^3]。 #### 六、Redis 的核心功能解析 以下是 Redis 的一些核心功能及其使用方法: 1. **字符串(String)** ```python import redis r = redis.Redis(host='localhost', port=6379, db=0) r.set('key', 'value') # 设置键值对 print(r.get('key')) # 获取键对应的值 ``` 2. **哈希(Hash)** ```python r.hset('user:1000', mapping={'name': 'Alice', 'age': 25}) # 设置哈希字段 print(r.hgetall('user:1000')) # 获取整个哈希内容 ``` 3. **列表(List)** ```python r.lpush('queue', 'task1') # 左侧插入元素 r.rpush('queue', 'task2') # 右侧插入元素 print(r.lrange('queue', 0, -1)) # 获取列表中的所有元素 ``` 4. **集合(Set)** ```python r.sadd('fruits', 'apple', 'banana', 'orange') # 添加元素到集合 print(r.smembers('fruits')) # 获取集合中的所有成员 ``` 5. **有序集合(Sorted Set)** ```python r.zadd('scores', {'Alice': 100, 'Bob': 200, 'Charlie': 150}) # 插入带分数的元素 print(r.zrange('scores', 0, -1, withscores=True)) # 按分数排序获取元素 ``` 6. **Geospatial 功能** ```python r.geoadd('locations', longitude=116.3974, latitude=39.9075, member='Beijing') # 添加地理坐标 print(r.georadius('locations', 116.3974, 39.9075, 10, unit='km')) # 查询指定范围内的位置 ``` #### 七、Redis 的优缺点总结 - **优点**: - 极高的性能,适合需要快速响应的应用场景。 - 支持多种数据结构,能够灵活应对不同业务需求。 - 提供持久化功能,保障数据可靠性。 - **缺点**: - 数据存储在内存中,成本较高。 - 大规模数据存储时需要考虑分片和集群管理的复杂性[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值