Redis:快速键值存储的入门指南

news2024/12/24 2:33:27

 一、什么是Redis?

Redis,全称为Remote Dictionary Server,是一种开源的、高性能的键值(Key-Value)存储系统。与传统的关系型数据库不同,Redis将数据主要存储在内存中,因此能够提供极低延迟的数据读写操作,这使其在需要高速数据访问的应用场景中表现卓越。Redis不仅仅是一个简单的键值存储,还具备丰富的数据结构和多样的功能,因而广泛应用于各种场景。

 1.1 Redis的设计理念

Redis的设计哲学集中在四个核心原则上:简单、高速、持久化和灵活性。它的简单性表现在易于使用的API和直观的命令,而高速则源于内存存储架构和优化的数据结构。持久化功能使得数据在系统崩溃或重启时依然可以被恢复。灵活性则通过支持多种数据结构和扩展机制得以体现。

 1.2 Redis的基本特性

- **内存存储**:数据主要存储在内存中,提供快速的读写速度。
- **持久化**:支持将数据定期保存到磁盘,防止数据丢失。
- **多种数据结构**:支持字符串、列表、集合、有序集合和哈希等多种数据类型。
- **高可用性**:通过主从复制和分片机制,支持高可用性和负载均衡。
- **高级特性**:支持事务、Lua脚本以及发布/订阅功能。

 1.3 Redis的发展历程

Redis由Salvatore Sanfilippo在2009年开始开发,最初是为了应对他在工作中遇到的性能瓶颈。随着时间的推移,Redis因其出色的性能和灵活性而迅速获得了社区的认可。以下是一些关键的时间点:

  • 2009年:第一个版本发布,主要作为一个简单的键值存储系统。
  • 2010年:开始支持更多的数据类型,如列表、集合和排序集合。
  • 2011年:引入了持久化功能,允许将内存中的数据定期或在断电时保存到磁盘上,以防止数据丢失。
  • 2013年:发布了2.6版本,引入了Lua脚本支持,增强了事务处理能力。
  • 2015年:发布了3.0版本,引入了集群支持,增强了系统的可扩展性和可用性。
  • 2019年:发布了6.0版本,增加了模块化支持,允许通过插件扩展Redis的功能。

Redis的不断发展使其成为了许多大型互联网公司(如Twitter、GitHub、Stack Overflow)和中小型企业中不可或缺的组成部分。它不仅在技术上持续创新,还在社区中积累了大量的用户和贡献者,形成了丰富的文档和工具生态。

 二、Redis的作用和用途

Redis不仅是键值存储,还可以作为多种应用程序构建的基础。以下是Redis的主要用途:

2.1 缓存

场景描述: 在高流量的Web应用中,频繁访问数据库以获取静态或变化不大的数据会导致性能瓶颈。Redis可以作为一个缓存层,存储这些数据,从而减少对数据库的直接请求,显著提升应用响应速度。

import redis.clients.jedis.Jedis;

public class CacheExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        // 将数据缓存到Redis中
        jedis.set("lastVisited", "2023-07-23");
        
        // 从Redis中获取缓存数据
        String lastVisited = jedis.get("lastVisited");
        System.out.println("Last visited on: " + lastVisited);
        
        jedis.close();
    }
}

具体案例: 假设你正在开发一个新闻网站,首页上显示的是最新的头条新闻。由于新闻列表不会频繁更新,但访问量却非常高,因此可以将这些头条新闻的信息存储在Redis中。当用户访问首页时,首先尝试从Redis中获取数据,如果数据存在,则直接返回,无需访问数据库。只有当Redis中没有数据或者数据过期时,才会查询数据库并更新Redis中的缓存。

2.2 消息队列

场景描述: 在异步处理或分布式任务调度中,使用Redis的列表或发布/订阅功能可以构建高效的消息队列。

import redis.clients.jedis.Jedis;

public class MessageQueueExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        // 生产者:向队列添加消息
        jedis.rpush("message_queue", "Hello from producer!");
        
        // 消费者:从队列读取消息
        String message = jedis.blpop(0, "message_queue");
        System.out.println("Message received: " + message);
        
        jedis.close();
    }
}

具体案例: 假设有一个后台任务需要处理大量用户上传的照片,并将它们转换为不同的尺寸以适应不同设备。可以使用Redis的列表数据结构作为消息队列,每当有新照片上传时,就将其ID推入队列。后台处理服务器可以从队列中取出任务(即照片ID),然后执行相应的图像处理工作。

2.3 实时数据处理

场景描述: 对于需要实时分析大量数据流的应用,如监控系统、广告平台等,Redis可以提供低延迟的数据处理和统计。

import redis.clients.jedis.Jedis;

public class RealtimeAnalyticsExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        // 增加页面访问计数
        long pageViews = jedis.incr("page_views");
        System.out.println("Total page views: " + pageViews);
        
        // 保存用户行为
        jedis.zadd("user_activity", System.currentTimeMillis(), "User1 viewed productX");
        
        jedis.close();
    }
}

具体案例: 设想一个广告平台需要实时跟踪用户行为并进行广告投放决策。可以使用Redis的有序集合来存储每个广告的展示次数和点击次数,利用其范围查询功能,实时计算出哪些广告最有效,以便调整广告投放策略。

2.4 会话存储

场景描述: 在分布式Web应用中,用户会话数据需要在多个服务器间共享。使用Redis存储会话信息可以确保会话数据的集中管理,同时提供高可用性和一致性。

import redis.clients.jedis.Jedis;

public class SessionStoreExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        // 存储用户会话
        jedis.hset("session:123", "username", "JohnDoe");
        jedis.hset("session:123", "loginTime", "2023-07-23T12:00Z");
        
        // 读取用户会话
        String username = jedis.hget("session:123", "username");
        String loginTime = jedis.hget("session:123", "loginTime");
        System.out.println("Username: " + username + ", Login time: " + loginTime);
        
        jedis.close();
    }
}

具体案例: 考虑一个在线购物平台,用户登录后,其会话信息(如登录状态、购物车内容等)需要在集群中的任何服务器上都可以访问。通过将这些会话数据存储在Redis中,可以实现跨服务器的会话共享,确保用户在切换服务器时仍然保持登录状态和购物车数据的连续性。

2.5 排行榜

场景描述: 在游戏、社交媒体或电商网站中,实时更新的排行榜可以激发用户的参与度。Redis的有序集合非常适合此类应用,可以轻松地实现基于分数的排序和排名。

import redis.clients.jedis.Jedis;

public class LeaderboardExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        // 更新用户分数
        jedis.zadd("leaderboard", 1000, "Player1");
        jedis.zadd("leaderboard", 800, "Player2");
        
        // 获取前10名玩家
        Set<String> topPlayers = jedis.zrevrange("leaderboard", 0, 9);
        System.out.println("Top players: " + topPlayers);
        
        jedis.close();
    }
}

具体案例: 以一个在线游戏为例,玩家的得分需要实时更新并显示在排行榜上。可以使用Redis的有序集合,将玩家ID作为成员,得分作为分数,这样就可以快速地添加新的得分、更新现有得分,并获取得分最高的玩家列表。

2.6 分布式锁

场景描述: 在分布式系统中,为了保证资源的一致性,需要在多个节点间协调对共享资源的访问。Redis可以用来实现分布式锁机制。

import redis.clients.jedis.Jedis;
import java.util.concurrent.TimeUnit;

public class DistributedLockExample {
    private static final String LOCK_NAME = "distributed_lock";
    
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        
        // 尝试获取锁,设置超时时间
        if (jedis.setnx(LOCK_NAME, "lock_acquired") == 1) {
            jedis.expire(LOCK_NAME, 30); // 锁的有效期为30秒
            try {
                // 在持有锁的情况下执行关键操作
                System.out.println("Critical section executed.");
            } finally {
                // 释放锁
                if (jedis.get(LOCK_NAME).equals("lock_acquired")) {
                    jedis.del(LOCK_NAME);
                }
            }
        } else {
            System.out.println("Lock is already held by another process.");
        }
        
        jedis.close();
    }
}

具体案例: 在一个分布式支付系统中,当处理退款或转账时,同一笔交易不能同时被多个节点处理,否则会导致账户余额错误。使用Redis的SETNX命令(现已被SET命令的NX选项替代)可以实现一个简单的分布式锁,确保同一时刻只有一个节点能够处理这笔交易。

三、Redis的数据结构

Redis支持多种数据结构,每种结构都适合不同应用场景。以下是Redis主要的数据结构及其应用:

3.1 字符串(Strings)

作为Redis最基本的数据类型,字符串可以存储任何类型的数据,包括照片、视频等二进制数据。每个字符串的最大大小限制为512MB。字符串支持常见的操作,如设置、获取、追加和修改。它们适用于缓存简单的数据,如用户信息、配置信息等。

3.2 列表(Lists)

列表是由有序字符串组成的集合,支持从两端推入和弹出元素。列表可用于实现消息队列、任务队列以及其他需要维护顺序的数据结构。通过`LRANGE`命令,开发者可以高效获取列表中的子集,适用于显示最近活动、评论等场景。

3.3 集合(Sets)

集合是由唯一字符串组成的无序集合,支持高效的添加、删除和查找操作。它可以被用于实现标签的集合、社交媒体的好友列表等。集合支持多种集合操作,如并集、交集和差集,使得开发者可以轻松处理复杂的集合运算。

3.4 有序集合(Sorted Sets)

有序集合在集合的基础上增加了每个元素一个分数,用于排序。Sorted Sets可用于实现排名系统,支持高效的范围查询和获取排名最高的元素,非常适合实时排行榜、竞赛排名等应用。

3.5 哈希表(Hashes)

哈希表是键值对的集合,适合存储对象类型的数据。它特别适用于存储用户信息、商品信息等结构化数据。哈希表支持对某个字段的增删改查操作,非常灵活,方便开发者管理复杂的数据结构。

四、Redis的持久化机制

Redis的持久化机制是确保数据安全的重要保障。通过持久化,Redis能够在系统崩溃或重启后恢复数据。Redis支持两种主要的持久化方式:RDB(Redis Database)和AOF(Append Only File)。

4.1 RDB持久化

RDB持久化通过定期将内存中的数据快照保存到磁盘中来实现。开发者可以通过配置持久化的频率和条件来控制RDB的行为。此方式适合对性能要求高的场景,但如果在快照之间发生崩溃,将可能会丢失那些未保存的写入数据。

4.2 AOF持久化

AOF持久化通过将每个写操作附加到日志文件中来保存数据。这种方式更加精细,能够保障更高的持久化准确性。开发者可以设置AOF文件的同步策略,如每次写操作后同步、每秒同步或从不同步。在该文件中,Redis可使用`rewrite`来进行日志压缩,避免文件过于庞大。

4.3 持久化的选择

开发者可以根据具体的应用需求选择合适的持久化方式。既可以选择仅使用RDB,也可以组合使用AOF。在大多数场景下,AOF文件的持久化方式更为可靠,而RDB文件在需要快速恢复和减少数据丢失时更加有效。

五、Redis的高级特性

5.1 事务

Redis支持事务处理,允许将多个命令聚合在一起,以确保其原子性。通过`MULTI`、`EXEC`、`WATCH`等命令,开发者可以控制命令的执行流程,实现复杂的业务逻辑。

5.2 Lua脚本

Redis内置的Lua脚本支持允许开发者在Redis端执行多行命令,减少了客户端和服务端之间的网络往返,提高了性能。通过使用Lua脚本,开发者可以实现复杂的批处理操作和业务逻辑,增强了Redis的灵活性。

5.3 发布/订阅

Redis的发布/订阅功能支持消息的广播机制。通过`PUBLISH`、`SUBSCRIBE`和`UNSUBSCRIBE`命令,应用程序可以轻松实现消息的实时发布与接收,适用于聊天系统、实时通知等场景。

5.4 地理空间(Geospatial)

Redis提供了地理空间功能,可以存储和查询地理位置信息,支持一系列的地理计算。开发者能够使用`GEOADD`、`GEORADIUS`和`GEODIST`等命令,轻松处理与位置相关的任务,在社交应用、外卖服务等
 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络传输层——UDP与TCP

前言&#xff1a; 1.国际网络体系结构&#xff1a; OSI模型: open system interconnect 理论模型 1977 国际标准化组织 各种不同体系结构的计算机能在世界范围内互联成网。 应用层:要传输的数据信息&#xff0c;如文件传输&#xff0c;电子邮件等…

【C语言】宏定义常量加 ; 的错误

我在使用宏定义常量定义二维数组的时候&#xff0c;编译器报错&#xff1a;应输入“]”&#xff0c;如下&#xff1a; 原因是宏定义不是C语言规定的语句&#xff0c;它的结尾不加 ; 。在上图的 int mine[EASY_ROWS][EASY_COLS]; 中&#xff0c;把 EASY_ROWS 替换为了 9;2; &…

Typora 以 Github 作为图床使用 PicGo 上传图片

本文简练快速介绍如标题所述的操作流程 文章目录 1.前言1.1 图床简述1.2 Github图床的优缺点1.2.1 优点1.2.2 缺点 2.下载PicGo3.Github访问加速4.用github创建图床服务器4.1 注册4.2 创建仓库 4.3 生成TOKEN令牌5.设置PicGo6.设置Typora7.完成 1.前言 1.1 图床简述 图床&…

车载音频记录

一、车载音频总线 2.8车载音频总线A2B Automotive Audio Bus_a2b总线-CSDN博客 传统的车载音频接口采用的是点对点模式&#xff0c;车身数字音频总线采用环型或者菊花链型总线。 A2B&#xff1a;Automotive Audio Bus 支持串联拓扑&#xff0c;即单个主机最多连接10个…

RedHat8安装Oracle19C

RedHat8安装Oracle19C 1、 更新yum源 更新yum源为阿里云镜像源&#xff1a; # 进入源目录 cd /etc/yum.repos.d/ # 删除 redhat 默认源 rm redhat.repo # 下载阿里云的centos7源 curl -O http://mirrors.aliyun.com/repo/Centos-8.repo # 替换 Centos-8.repo 中的 $releasev…

机器学习(二十二):精度和召回率

一、倾斜数据集 倾斜数据集&#xff1a;一个数据集中的正面和负面例子的比例非常不平衡&#xff0c;比如数据集中&#xff0c;结果为1的占比20%&#xff0c;结果为0的占比80% 例子&#xff1a;如果数据集的结果中只有0.5%是1&#xff0c;其余结果是0。有一个模型的预测准确度…

24.7.17数据结构|顺序表

目录 大O的工程意义&#xff1f; 线性表 引入&#xff1a; 主要掌握【代码实现】&#xff1a; 一、线性结构 1、逻辑描述 2、顺序表 1、如何定义结构 1&#xff09;静态顺序表 1&#xff09;动态顺序表 2、写代码 &#xff08;1&#xff09;【clion创建工程】 ​编…

Unity横板动作游戏 - 素材导入和整理

导入素材 编辑器布局 点击每个窗口右上角的三个点可以有更多的窗口选项。 在屏幕的右上角有一个菜单可以保存布局或读取已经报错的布局。 工具按钮 编辑器上的工具按钮在启动的时候是蓝色的&#xff0c;在不启动的时候是灰色的。 这个按钮将会决定场景中的物体是以锚点显示还…

大模型算法面试题(十三)

本系列收纳各种大模型面试题及答案。 1、微调后的模型出现能力劣化&#xff0c;灾难性遗忘是怎么回事 微调后的模型出现能力劣化&#xff0c;灾难性遗忘&#xff08;Catastrophic Forgetting&#xff09;是一个在机器学习领域&#xff0c;尤其是在深度学习和大模型应用中频繁出…

麒麟系统信创改造

麒麟系统信创改造 一、查看操作系统架构下载相应的依赖,压缩包1、查看Linux系统架构、CPU(1)uname -m(2)lscpu(3)cat /proc/cpuinfo(4)arch(5)getconf LONG_BIT(6)dmidecode2、根据Linux系统架构、CPU的差异进行下载相关依赖,看第二项二、以下是根据本系统的aarc…

Golang | Leetcode Golang题解之第297题二叉树的序列化与反序列化

题目&#xff1a; 题解&#xff1a; type Codec struct{}func Constructor() (_ Codec) {return }func (c Codec) serialize(root *TreeNode) string {if root nil {return "X"}left : "(" c.serialize(root.Left) ")"right : "("…

WordPress插件介绍页源码单页Html

源码介绍 WordPress插件介绍页源码单页Html源码&#xff0c;这是一款产品介绍使用页面&#xff0c;也可以用来做其他软件或者应用介绍下载页&#xff0c;界面简约美观&#xff0c;源码由HTMLCSSJS组成&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器…

理解文件系统(上)

模拟实现文件库 创建文件以便理解 自己想实现的文件接口&#xff0c;进行模拟实现 模拟的头文件要准备的头文件 open接口的实现 write接口的实现fflush接口的实现 flose接口的实现 文件实现 stdio.h stdio.c test.c makefile 创建makefile 编译运行 执行后输出log.txt,看…

宏集物联网工控屏网关实现Modbus TCP数据采集并通过TCP转发

前言 在日常的生产活动中&#xff0c;许多企业需要使用底层PLC或传感器数据&#xff0c;但部分企业的终端平台仅支持TCP协议&#xff0c;而不支持常见的PLC或Modbus协议。为了实现兼容性&#xff0c;需要使用协议转换网关&#xff0c;将底层协议转换为TCP协议。 宏集物联网工…

Python客户端操作Elasticsearch

一.Python与Elasticsearch交互示例 这段代码是使用Python的elasticsearch模块与Elasticsearch进行交互的示例&#xff1a; from elasticsearch import Elasticsearch# 一.创建连接 # 建立到Elasticsearch的连接&#xff0c;指定主机和端口&#xff0c;设置请求超时时间为3600…

【数据结构】单链表面试题(Java + 力扣 + 详解)

&#x1f387;&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳&#xff0c;欢迎大佬指点&#xff01; 人生格言: 当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友…

【日常记录】【插件】Typed.js:用于创建打字效果的 JavaScript 库

文章目录 1. 引言2. 安装3. 基本使用参考链接 1. 引言 Typed.js是一个用于创建打字效果的 JavaScript 库。这个效果就是 chatgpt、百度的文心一言等其他的大模型&#xff0c;回复用户的问题的时候的效果 typed-js 官网typed 案例 2. 安装 CDN方式 这俩都可以&#xff0c;还有其…

17 推荐系统方案中那些不得不知的坑

你好&#xff0c;我是大壮。《易经》中说&#xff1a;“上九&#xff1a;亢龙有悔”。上九是指阳爻在卦中处于最高位&#xff0c;亢龙是指飞向尽头的龙&#xff0c;穷尽至极力终有尽时&#xff0c;力尽则悔&#xff0c;悔不可及。 在前面的 18 讲我们已经讨论了整个推荐算法的…

C语言中的IO控制流

文章目录 一、什么是C语言中的IO控制流二、open函数 1.使用open函数创建文件2.使用使用open函数打开文件三、文件的权限四、文件的描述符五、read函数六、write函数七、lseek函数八、close函数 一、什么是C语言中的IO控制流 在linux系统中一切皆文件&#xff0c;C语言中的IO控…

【SQL 新手教程 4/20】关系模型 --索引

&#x1f497; 关系数据库建立在关系模型上⭐ 关系模型本质上就是若干个存储数据的二维表 记录 (Record)&#xff1a; 表的每一行称为记录&#xff08;Record&#xff09;&#xff0c;记录是一个逻辑意义上的数据 字段 (Column)&#xff1a;表的每一列称为字段&#xff08;Colu…