Redis是什么?一篇讲透它的定位、特点与应用场景

1. Redis的定义与核心概念

1.1 什么是Redis?

Redis(Remote Dictionary Server) 是一个开源的、基于内存的数据结构存储系统,可以用作数据库缓存消息代理。Redis由意大利开发者Salvatore Sanfilippo于2009年开发,目前已成为最受欢迎的NoSQL数据库之一。

1.2 Redis的核心定位

定位角色描述典型场景
内存数据库将数据主要存储在内存中,提供超高性能的读写操作实时计算、会话存储
缓存系统作为传统数据库的缓存层,加速数据访问Web应用缓存、API响应缓存
消息中间件支持发布/订阅模式,实现消息传递实时通知、事件驱动架构

1.3 Redis的数据模型

Redis采用**键值对(Key-Value)**的数据模型,但与传统KV存储不同的是,Redis的Value支持多种数据结构:

Key -> Value
其中Value可以是:
├── String(字符串)
├── Hash(哈希表)
├── List(列表)
├── Set(集合)
├── Sorted Set(有序集合)
├── Bitmap(位图)
├── HyperLogLog(基数统计)
└── Stream(流,Redis 5.0+)

2. Redis的关键特性深度解析

2.1 内存存储 + 持久化

内存优先策略

  • Redis将数据主要存储在内存中,读写速度可达10万-20万QPS
  • 支持两种持久化方式:RDB快照AOF日志
  • 可以在性能和数据安全性之间找到平衡

持久化对比表

持久化方式RDB快照AOF日志
存储内容内存数据快照写命令日志
文件大小较小较大
恢复速度
数据完整性可能丢失部分数据更完整
CPU开销定期执行,开销小持续写入,开销大

2.2 丰富的数据结构

Redis不仅仅是简单的KV存储,而是一个数据结构服务器

Redis数据结构
String 字符串
Hash 哈希表
List 列表
Set 集合
ZSet 有序集合
特殊结构
计数器
缓存JSON
分布式锁
对象存储
用户信息
消息队列
最近访问
标签去重
好友关系
排行榜
延时队列
Bitmap位图
HyperLogLog
Stream流

2.3 单线程模型的高性能

Redis采用单线程事件循环模型,避免了多线程的上下文切换和锁竞争:

Redis性能优势来源

  1. 内存操作:避免磁盘I/O瓶颈
  2. 单线程:无锁设计,避免线程切换开销
  3. I/O多路复用:使用epoll/kqueue处理并发连接
  4. 高效数据结构:针对不同场景优化的数据结构实现

2.4 原子性操作

Redis的所有操作都是原子性的,这意味着:

  • 单个命令的执行不会被其他命令打断
  • 可以使用Redis事务(MULTI/EXEC)实现多命令原子性
  • 支持Lua脚本,实现复杂原子性操作

3. Redis与其他数据库的对比

3.1 Redis vs MySQL

对比维度RedisMySQL
存储方式内存 + 持久化磁盘存储
数据模型NoSQL键值对关系型表结构
查询能力简单查询复杂SQL查询
事务支持简单事务ACID完整事务
扩展性水平扩展容易垂直扩展为主
性能读写:10万+QPS读写:几千QPS
数据一致性最终一致性强一致性
适用场景缓存、会话、计数器业务数据存储

3.2 Redis vs Memcached

对比维度RedisMemcached
数据结构8种丰富数据结构仅支持字符串
持久化支持RDB和AOF不支持
分布式原生Cluster支持客户端分片
内存回收多种淘汰策略LRU淘汰
单线程/多线程单线程多线程
网络模型事件驱动多线程
功能丰富度极其丰富相对简单

4. Redis的典型应用场景

4.1 缓存系统

场景描述:作为数据库前端缓存,减少数据库压力,提升响应速度。

Java实现示例

@Service
public class UserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate UserMapper userMapper;/*** 查询用户信息(带缓存)*/public User getUserById(Long userId) {String cacheKey = "user:" + userId;// 1. 先从缓存查询User user = (User) redisTemplate.opsForValue().get(cacheKey);if (user != null) {return user; // 缓存命中}// 2. 缓存未命中,查询数据库user = userMapper.selectById(userId);if (user != null) {// 3. 写入缓存,设置过期时间redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES);}return user;}/*** 更新用户信息(缓存失效)*/@Transactionalpublic void updateUser(User user) {// 1. 更新数据库userMapper.updateById(user);// 2. 删除缓存String cacheKey = "user:" + user.getId();redisTemplate.delete(cacheKey);}
}

4.2 分布式锁

场景描述:在分布式系统中实现互斥访问,防止并发问题。

Java实现示例

@Component
public class RedisDistributedLock {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('del', KEYS[1]) " +"else return 0 end";/*** 获取分布式锁*/public boolean tryLock(String lockKey, String requestId, int expireTime) {Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, Duration.ofSeconds(expireTime));return Boolean.TRUE.equals(result);}/*** 释放分布式锁*/public boolean releaseLock(String lockKey, String requestId) {DefaultRedisScript<Long> script = new DefaultRedisScript<>();script.setScriptText(LOCK_SCRIPT);script.setResultType(Long.class);Long result = redisTemplate.execute(script, Collections.singletonList(lockKey), requestId);return result != null && result == 1L;}
}

4.3 计数器和限流器

Java实现示例

@Component
public class RedisCounterService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 增加计数*/public Long increment(String key) {return redisTemplate.opsForValue().increment(key);}/*** 获取计数*/public Long getCount(String key) {String value = redisTemplate.opsForValue().get(key);return value != null ? Long.parseLong(value) : 0L;}
}@Component
public class RedisRateLimiter {@Autowiredprivate RedisTemplate<String, String> redisTemplate;// 滑动窗口限流Lua脚本private static final String RATE_LIMIT_SCRIPT = "local key = KEYS[1] " +"local window = tonumber(ARGV[1]) " +"local limit = tonumber(ARGV[2]) " +"local current = tonumber(ARGV[3]) " +"redis.call('zremrangebyscore', key, '-inf', current - window) " +"local cnt = redis.call('zcard', key) " +"if cnt < limit then " +"redis.call('zadd', key, current, current) " +"redis.call('expire', key, window + 1) " +"return 1 " +"else " +"return 0 " +"end";/*** 滑动窗口限流*/public boolean isAllowed(String key, int windowSize, int limit) {DefaultRedisScript<Long> script = new DefaultRedisScript<>();script.setScriptText(RATE_LIMIT_SCRIPT);script.setResultType(Long.class);long currentTime = System.currentTimeMillis();Long result = redisTemplate.execute(script, Collections.singletonList(key), String.valueOf(windowSize * 1000), String.valueOf(limit), String.valueOf(currentTime));return result != null && result == 1L;}
}

4.4 排行榜系统

Java实现示例

@Service
public class RankingService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String RANKING_KEY = "game:ranking";/*** 更新用户分数*/public void updateScore(String userId, double score) {redisTemplate.opsForZSet().add(RANKING_KEY, userId, score);}/*** 获取排行榜TOP N*/public List<RankingItem> getTopRanking(int topN) {Set<ZSetOperations.TypedTuple<String>> tuples = redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, topN - 1);List<RankingItem> rankings = new ArrayList<>();int rank = 1;for (ZSetOperations.TypedTuple<String> tuple : tuples) {RankingItem item = new RankingItem();item.setRank(rank++);item.setUserId(tuple.getValue());item.setScore(tuple.getScore());rankings.add(item);}return rankings;}/*** 获取用户排名*/public Long getUserRank(String userId) {Long rank = redisTemplate.opsForZSet().reverseRank(RANKING_KEY, userId);return rank != null ? rank + 1 : null;}
}@Data
public class RankingItem {private Integer rank;private String userId;private Double score;
}

5. Redis的架构模式

5.1 单机模式

适用场景:开发环境、小型应用、非关键业务

优点

  • 部署简单
  • 运维成本低
  • 性能高

缺点

  • 单点故障风险
  • 容量限制
  • 无法水平扩展

5.2 主从复制模式

适用场景:读写分离、数据备份、提高可用性

Java配置示例

@Configuration
public class RedisReplicationConfig {@Bean@Primarypublic LettuceConnectionFactory masterConnectionFactory() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName("redis-master");config.setPort(6379);return new LettuceConnectionFactory(config);}@Beanpublic LettuceConnectionFactory slaveConnectionFactory() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName("redis-slave");config.setPort(6379);return new LettuceConnectionFactory(config);}
}

6. Java中的Redis实战示例

6.1 Spring Boot集成Redis

依赖配置

<dependencies><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>
</dependencies>

配置文件

spring:redis:host: localhostport: 6379password: database: 0timeout: 3000mslettuce:pool:max-active: 200max-wait: -1msmax-idle: 50min-idle: 10

6.2 Redis工具类封装

@Component
public class RedisUtil {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 普通缓存获取*/public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通缓存放入并设置时间*/public boolean set(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {redisTemplate.opsForValue().set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 递增*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}
}

7. 生产环境最佳实践

7.1 键命名规范

推荐规范

  • 使用冒号分隔命名空间:user:profile:1001
  • 避免过长的键名,建议不超过250字符
  • 使用有意义的名称,避免缩写

7.2 内存优化策略

  1. 设置合理的过期时间
  2. 选择合适的数据结构
  3. 避免大key
  4. 配置内存淘汰策略

7.3 安全配置

  1. 设置访问密码
  2. 绑定内网IP
  3. 禁用危险命令
  4. 开启安全模式

8. 总结

Redis作为一个高性能的内存数据库,具有以下核心优势:

  1. 极高的性能:基于内存存储,支持10万+QPS
  2. 丰富的数据结构:支持8种数据类型,适应多种场景
  3. 高可用性:支持主从复制、哨兵、集群等部署模式
  4. 持久化保障:RDB+AOF双重保障数据安全
  5. 生态丰富:与各种编程语言和框架完美集成

Redis适用于缓存、会话存储、计数器、排行榜、分布式锁等多种场景,是现代互联网架构中不可或缺的组件。

通过本文的学习,你应该对Redis有了全面的认识。在后续文章中,我们将深入探讨Redis的各个特性和实现原理。


下一篇预告:《Redis环境搭建指南:Windows/Linux/Docker多场景安装与配置》


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922116.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922116.shtml
英文地址,请注明出处:http://en.pswp.cn/news/922116.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一款免费开源轻量的漏洞情报系统 | 漏洞情报包含:组件漏洞 + 软件漏洞 + 系统漏洞

工具介绍 bug_search一款免费开源轻量的漏洞情报系统 基于python3 Amis2.9 开发&#xff0c;仅依赖Flask,requests&#xff0c;无需数据库&#xff0c;Amis是百度开源的低代码前端框架漏洞情报包含&#xff1a;组件漏洞 软件漏洞 系统漏洞 增加邮件发送消息报警功能增加钉钉…

详解在Windows系统中生成ssl证书,实现nginx配置https的方法

目录一、下载安装OpenSSL二、证书生成三、修改nginx配置总结Nginx 是一个高性能的HTTP和反向代理web服务器&#xff0c;在进行web项目开发时&#xff0c;大多都是使用nginx对外提供web服务。HTTPS &#xff08;全称&#xff1a;Hypertext Transfer Protocol Secure [5]&#xf…

AI视觉算法中的OpenCV API (二)

视频写入 (FourCC, VideoWriter)​ 1. VideoWriter_fourcc - 视频编码器四字符代码 # OpenCV 3.x, 4.x fourcc cv2.VideoWriter_fourcc(M,J,P,G)fourcc cv2.VideoWriter_fourcc(*H264)fourcc cv2.VideoWriter_fourcc(*MJPG) ​FourCC​&#xff1a; 代表 ​Four ​Charac…

分享| 2025年版AIGC数字人实验室解决方案教学资源解析

AIGC数字人实验室解决方案构建了涵盖基础层、平台环境层与资源层的多层次教学架构&#xff0c;依托150平方米的实体空间与60人并行授课的规模化支持&#xff0c;为学生提供了技术实践与创新的高效平台。其教学资源体系覆盖AIGC文本生成、图像生成、数字人应用与智能体开发四大核…

内存大(巨)页

一、大&#xff08;巨&#xff09;页 大&#xff08;巨&#xff09;页&#xff0c;很好理解&#xff0c;就是的大的页。说这个大页前&#xff0c;得先把计算机中内存的管理简单说明一下&#xff0c;否则可能对于一些新手或者把操作系统中内存管理的方法的开发者不太友好。最早的…

langgraph astream使用详解

langgraph中graph的astream&#xff08;stream&#xff09;方法分别实现异步&#xff08;同步&#xff09;流式应答&#xff0c;在langgraph-api服务也是核心方法&#xff0c;实现与前端的对接&#xff0c;必须要把这个方法弄明白。该方法中最重要的参数是stream_mode&#xff…

【C++】模板进阶:非类型参数、模板特化与分离编译

目录 1. 非类型模板参数 2. 模板的特化 3. 分离编译 1. 非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即&#xff1a;出现在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff0c;就是用一个常量作为类(函数)模板…

栈-1047.删除字符串中的所有相邻重复项-力扣(LeetCode)

一、题目解析 1、反复执行重复项删除操作 2、s仅由小写英文字母组成 二、算法原理 该题并不难&#xff0c;难的是能不能想到用栈这个数据结构解题 解法&#xff1a;栈模拟 横着看起来不好理解&#xff0c;我们把它竖起来&#xff0c;是不是和消消乐很类似&#xff0c;两两消…

【每日算法】移除元素 LeetCode

双指针方法是解决数组或链表问题中非常高效的技巧之一&#xff0c;尤其适用于原地修改数组或减少时间复杂度的场景。以下是对双指针方法的详细讲解。1. 双指针方法的核心思想双指针方法通常使用两个指针&#xff08;或索引&#xff09;在数组或链表中协同工作&#xff0c;通过一…

Android 项目:画图白板APP开发(六)——分页展示

本篇将介绍如何为我们的画板应用添加分页展示功能&#xff0c;让用户可以创建多个画布并在它们之间轻松切换。这章没有啥知识点的讲解&#xff0c;主要介绍一下每页保存的数据结构是什么样的。 一、ListView 多页数据的管理我们使用ListView。之前有文章讲过ListView这里就不多…

智能眼镜产品成熟度分析框架与评估

引言 当前(2025年9月12日),智能眼镜(Smart Glasses)市场正处于快速演进阶段,从早期的新奇设备向主流消费电子转型。AI整合、AR显示和多模态交互的进步推动了这一转变。根据最新数据,2025年AI眼镜发货量预计达686万台,同比增长265%,全球市场规模从2024年的约19.3亿美元…

(网络编程)网络编程套接字 UDP的socket API 代码解析

网络编程基础 为什么需要网络编程?--丰富的网络资源 用户在浏览器中,打开在线视频网站,如优酷看视频,实质是通过网络,获取到网络上的一个视频资源。与本地打开视频文件类似,只是视频文件这个资源的来源是网络。 相比本地资源来说,网络提供了更为丰富的网络资源:所谓的网络资源…

【STM32】状态机(State Machine)

这篇博客介绍 状态机&#xff08;State Machine&#xff09;&#xff0c;适合用于嵌入式开发、驱动开发、协议解析、按键识别等多种场景。 一、什么是状态机&#xff08;State Machine&#xff09;&#xff1f; 状态机&#xff08;State Machine&#xff09;是一种用于描述系统…

深度学习在离岗检测中的应用

离岗检测技术正逐步成为现代企业精细化管理和安全生产的重要工具。这项基于计算机视觉和人工智能的应用&#xff0c;通过自动化、实时化的监测方式&#xff0c;有效提升了工作纪律性和运营效率&#xff0c;为项目管理者和企业提供了创新的监管解决方案。在许多工作场景中&#…

Spring缓存(二):解决缓存雪崩、击穿、穿透问题

1. 缓存穿透问题与解决方案 1.1 什么是缓存穿透 缓存穿透是指查询一个不存在的数据&#xff0c;由于缓存中没有这个数据&#xff0c;每次请求都会直接打到数据库。 如果有恶意用户不断请求不存在的数据&#xff0c;就会给数据库带来巨大压力。 这种情况下&#xff0c;缓存失去了…

PHP 与 WebAssembly 的 “天然隔阂”

WebAssembly&#xff08;简称 WASM&#xff09;是一种低级二进制指令格式&#xff0c;旨在为高级语言提供高性能的编译目标&#xff0c;尤其在浏览器环境中实现接近原生的执行效率。它主要用于前端性能密集型场景&#xff08;如游戏引擎、视频编解码、3D 渲染等&#xff09;&am…

unity中通过拖拽,自定义scroll view中子物体顺序

1.在每个content的子物体上挂载DragHandler脚本&#xff0c;并且添加Canvs Group组件&#xff0c;设置见图2.DragHandler脚本内容&#xff1a;using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections.Generic; using System.Coll…

用 Matplotlib 绘制饼图:从基础语法到实战美化,全面掌握分类数据可视化技巧

用 Matplotlib 绘制饼图:从基础语法到实战美化,全面掌握分类数据可视化技巧 在数据分析与可视化的世界里,**“图胜千言”**早已成为共识。而在众多图表类型中,饼图(Pie Chart)以其直观的比例展示方式,成为展示分类数据分布的常见选择。无论是业务报表、用户画像,还是市…

基础算法之二分算法 --- 2

大家好&#xff0c;不同的时间&#xff0c;相同的地点&#xff0c;时隔多日我们又见面了。继上次的二分算法后&#xff0c;我们这次要来学习的是二分答案了。这个部分相较于前面的二分算法难度有相当的提升&#xff0c;希望大家有所准备。虽然难度增加了&#xff0c;但是博主还…

发挥nano banana的最大能力

1. 概述Nano Banana 简介&#xff1a;Nano Banana 是 Google DeepMind 开发的 AI 图像生成与编辑模型&#xff0c;集成在 Google Gemini 平台中&#xff08;具体为 Gemini 2.5 Flash 版本&#xff09;。它以高效的图像编辑能力闻名&#xff0c;尤其在角色一致性、光影理解和快速…