【Redis】核心特性、应用场景与安装配置

一、初识 Redis

1.1 Redis 概述

1. Redis 简介

Redis(Remote Dictionary Server) 是一款高性能的 键值存储(Key-Value Store) 数据库,属于 NoSQL 数据库的一种。相较于传统键值数据库,Redis 的核心优势在于其支持 多种数据结构,包括:

  • String(字符串)
  • Hash(哈希表)
  • List(列表)
  • Set(集合)
  • Sorted Set(有序集合)
  • Bitmaps(位图)
  • HyperLogLog(基数统计)
  • GEO(地理空间索引)

由于 Redis 数据主要存储在内存中,其读写性能极高(可达 10万+ QPS)。同时,Redis 提供 持久化机制(RDB 快照和 AOF 日志),确保数据在宕机或故障时不会丢失。

此外,Redis 还支持:

  • 键过期(Key Expiration)
  • 发布订阅(Pub/Sub)
  • 事务(Transactions)
  • 流水线(Pipeline)
  • Lua 脚本(Lua Scripting)

2. Redis 的发展历程

  • 2008 年:Redis 由 Salvatore Sanfilippo(@antirez) 开发,最初用于优化其项目 LLOOGG 的队列性能(替代 MySQL)。
  • 2009 年:Redis 1.0 开源发布,迅速获得广泛关注。
  • 至今:Redis 已成为全球最受欢迎的 内存数据库 之一,被众多 大型互联网公司 采用。

1.2 Redis 核心特性

  • MySQL 主要通过 存储数据,“关系型数据库”
  • Redis 通过 键值对 存储数据,“非关系型数据库”

根据官方的介绍,Redis 具有以下特性和优点:

1. 高性能

  • Redis 提供极高的读写性能,能在毫秒级的时间内完成数据操作。
  • 支持单线程架构,利用事件循环处理多个客户端请求,避免了上下文切换的开销。
  • 从网络角度上,Redis 使用了IO多路复用的机制(epoll)
  • Redis是C语言开发的,从某种程度上也减少了延迟以及提高了处理速度

2. 丰富的数据类型

  • 除了传统的键值对数据存储,Redis 支持多种复杂的数据类型,如:
    • 字符串(String)
    • 哈希(Hash)
    • 列表(List)
    • 集合(Set)
    • 有序集合(Sorted Set)
    • 位图(Bitmap)
    • HyperLogLog(用于基数统计)
    • 地理空间(Geospatial)

3. 持久化

  • Redis 提供了两种持久化机制:
    • RDB(Redis 数据库快照):通过定期将数据保存到磁盘中来持久化数据。
    • AOF(追加文件):每次对 Redis 进行写操作时,将操作命令追加到日志文件中。
  • 这两种方式可以结合使用,以确保数据的持久性和高可用性。

4. 原子操作

  • Redis 提供对数据的原子操作支持,确保在并发情况下,数据的修改不会发生冲突或不一致。

5. 主从复制

  • Redis 支持主从复制机制,可以通过复制将数据同步到多个从节点,从而提高数据的可用性与读取性能。

6. 高可用性与分布式

  • Redis 通过 Redis Sentinel 实现高可用性,能够自动故障转移(failover),保证系统的持续可用性。
  • Redis Cluster 支持分布式部署,可以自动分片(sharding),以支持大规模的数据存储。

7. 内存存储与低延迟

  • Redis 完全基于内存(RAM)操作,具有极低的延迟。
  • 适用于高频的读写操作,如实时应用程序、缓存等。

8. 灵活的过期策略

  • Redis 支持键值对的过期时间设置,可以自动删除过期的数据。
  • 支持 LRU(Least Recently Used)算法来清除最少使用的键,帮助控制内存使用。

9. 事务支持

  • Redis 提供了事务机制,支持 MULTIEXECWATCH 等命令来实现一组操作的原子执行。

10. 简单的 API

  • Redis 提供了非常简单直观的 API,易于集成和使用,支持多种编程语言,如 Python、Java、C、Go 等。

总结

下图是总结了Redis的核心功能:

在这里插入图片描述

  • 速度快:由于是内存数据库,读取速度极快。
  • 数据结构丰富:支持多种数据结构,能够满足不同场景的需求。
  • 高可用性:通过复制和故障转移机制确保系统的高可用性。
  • 易于扩展:支持分片和分布式架构,能轻松扩展为大规模分布式系统。
  • 灵活性强:支持多种持久化方案和过期策略。

1.3 Redis 应用场景

Redis 适用场景

  1. 缓存

    • Web缓存:Redis 常被用作缓存系统,以提高Web应用的响应速度和减轻数据库的负载。它通过存储热数据,避免重复查询数据库。
    • 页面缓存:可以将渲染过的页面存储在 Redis 中,从而快速返回给用户,减少服务器端渲染负担。
    • 数据库查询结果缓存:将数据库查询结果缓存在 Redis 中,避免对数据库的重复查询,减少数据库负载。
  2. 会话存储(Session Store)

    • Redis 常被用作会话存储,尤其是在处理大量用户会话时。由于 Redis 支持键值对存储和高效的过期策略,非常适合存储用户会话数据。
    • 它能支持高并发的读写,并且提供自动过期功能,确保会话数据能在合理时间后自动清理。
  3. 实时数据分析

    • Redis 的快速读写能力使它非常适合做实时数据分析。例如,使用 Redis 存储网站的实时访问数据、用户活动数据等。
    • 计数器:利用 Redis 的自增操作,可以很方便地实现点击计数、PV(页面浏览量)和 UV(独立访客数)等功能。
    • 实时流数据处理:借助 Redis 的 列表集合 等数据结构,可以实时处理和分析大量流数据。
  4. 排行榜/计分系统

    • 有序集合(Sorted Set) 是 Redis 的一项强大功能,非常适合实现排行榜和计分系统。通过有序集合,可以高效地存储并排序用户分数。
    • 常见应用如在线游戏的排行榜、社交平台的用户积分等。
  5. 消息队列(Message Queue)

    • Redis 可以作为高效的消息队列系统,支持 发布/订阅(Pub/Sub) 模式以及 列表 结构作为队列实现。
    • 它可以用来在分布式系统中进行异步任务处理、事件通知等场景。其快速的生产者/消费者模型能够实现低延迟的消息传递。
  6. 实时聊天系统

    • Redis 的发布/订阅模型(Pub/Sub)常常用于实现实时消息推送系统。通过 Redis,用户可以在不同的聊天室中实时交换消息。
    • 该功能非常适合社交应用、即时通讯工具、在线客服等场景。
  7. 队列任务系统

    • Redis 的列表(List)数据结构非常适合用来实现任务队列,支持 LPUSHRPOP 等原子操作,可以高效地进行任务的推送和消费。
    • 例如,后台任务处理、异步任务分发等场景。
  8. 分布式锁

    • 在分布式系统中,Redis 可以作为分布式锁的实现方式。通过 Redis 提供的 SETNX 命令,多个进程可以竞争获取锁,确保资源在同一时刻只被一个进程访问。
    • 这种锁的机制可广泛应用于分布式系统中的资源控制、事务管理等场景。

Redis 不适用场景

站在数据规模的角度看,数据可以分为大规模数据和小规模数据;我们知道 Redis 的数据是存在内存中的,如果数据量过于大的情况下,使用Redis经济成分很高(内存的价格远高于磁盘)

站在数据冷热的角度看,数据分为热数据与冷数据;热数据通常指需要频繁操作的数据,反之为冷数据,对于一个视频网站来说,视频的基本信息就属于热数据,用户观看记录一般情况下不会经常访问,属于冷数据。
如果将这些冷数据放在Redis中,就浪费了其内存空间。这些冷数据就不适合放在Redis中。
即将那些要经常被访问的数据放到内存中,而不经常被访问的放在磁盘中存储。


Redis 适用场景举例

缓存场景

下图是较典型的缓存使用场景,其中 Redis 作为缓冲层、MySQL作为 存储层,绝大部分请求的数据都是从 Redis 中获取。由于 Redis 有支撑高并发的特性,所以缓存通常能起到加速读写和降低后端压力的作用。

Redis + MySQL 组成的缓存存储架构:
在这里插入图片描述

  1. 假设根据用户UID获取用户信息:

    UserInfo getUserInfo(long long uid) {
        ...
    }
    
  2. 首先从 Redis 中获取用户信息,假设用户信息存储在键 “user:info:<uid>” 中:

    // 生成 Redis 键
    String key = "user:info:" + uid;
    // 尝试从 Redis 获取值
    String value = REDIS_EXEC: get key;
    // 缓存命中
    if (value != null) {
        // 假设用户信息为 JSON 格式
        UserInfo userInfo = JSON.deserialize(value);
        return userInfo;
    }
    
  3. 如果缓存未命中(miss),则从 MySQL 中获取用户信息,并将其写入缓存:

    // 缓存未命中
    if (value == NULL) {
        // 从数据库获取用户信息
        UserInfo userInfo = SQL_EXEC: select * from user_info where uid = <uid>;
        // 如果未找到用户信息
        if (userInfo == null) {
            response: 404;
            return null;
        }
        // 将用户信息序列化为 JSON 格式
        String value = json::serialize(userInfo);
        
        // 将数据写入缓存,设置过期时间为 1 小时
        REDIS_EXEC: set key value ex 3600;
    
        // 返回用户信息
        return userInfo;
    }
    

通过引入缓存机制,在理想情况下,每个用户信息在 1 小时内只会触发一次 MySQL 查询,显著提高了查询效率,并减少了 MySQL 的负载。

与 MySQL 等关系型数据库不同,Redis 没有表、字段等命名空间,也没有强制要求键名的格式(部分特殊字符除外)。
然而,合理的键名设计有助于避免键冲突,并提高项目的可维护性。一般建议使用“业务名:对象名:唯一标识:属性”的格式来设计键名。
例如,MySQL 数据库 ol 中的 t_user_info 表,可以使用 “ol:t_user_info:6379” 或 “ol:t_user_info:6379:name” 来表示。如果 Redis 只为一个业务使用,可以省略业务名 ol
如果键名过长,可以使用权威的缩写来代替。例如,“user:6379:friends:messages:5217” 可以简化为 “u:6379:fr:m:5217”。这样可以避免键名过长导致 Redis 性能下降。


2. 计数功能

很多业务都会采用 Redis 作为计数的基础工具。Redis 可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源。

如下图所示,视频网站的视频播放次数可以使用 Redis 完成:用户每播放一次视频,相应的视频播放数会自增1。

记录一个视频的播放次数
在这里插入图片描述

long incrVideoCounter(long vid)
{
	key = "video" + vid;
	long count = REDIS_EXEC("incr key");
	return counter;
}

3. 共享会话

如下图所示:一个分布式Web服务将用户的Session信息(例如用户登录信息)保存在各自的服务器中。

以负载均衡的视角:分布式服务会将用户的访问请求均衡到不同服务器上,且一般不会保证每次用户请求会被均衡到同一台服务器,此时用户刷新后再次访问就得重新登录。

在这里插入图片描述

为了解决此问题,可以使用 Redis 将用户的 Session 信息进行集中管理,如下图所示,在这种模式下,只要保证 Redis 是最高可用和可扩展性的,无论用户被均衡到哪台服务器,都集中从 Redis 中查询、更新 Session 信息。

在这里插入图片描述


手机验证码

大多应用出于安全考虑,会在用户登录时,输入手机号确认验证码。
为了使短信功能接口不被频繁访问,会限制用户每分钟获取验证码的频率,一般是每60秒获取一次。

在这里插入图片描述

同样可用通过 Redis 实现:

String sendVerificationCode(phoneNumber)
{
	key = "shortMsg:limit:" + phoneNumber
	// 设置过期时间 1 分钟
	// 使用 NX,只在不存在 key 时才能设置成功
	bool r = REDIS_EXEC("set key 1 ex 60 nx")
	if (r == false)
	{
		// 已经设置过该号码的验证码
		long c = REDIS_EXEC("incr key")
		if (c > 0) {
			// 1分钟内已经发送过了
			// 限制发送
			return null
		}
	}
	
	// 此前没有设置过该号码的验证码
	String verificationCode = uuid::uuid(6); // 生成随机6位数验证码
	
	verificationKey = "verification:" + phoneNumber;
	REDIS_EXEC("set verificationKey verificationCode ex 60")
	// 返回验证码
	return verificationCode;
}

// 验证⽤⼾输⼊的验证码是否正确
bool 验证验证码(phoneNumber, validationCode) {
	validationKey = "verification:" + phoneNumber;
	String value = Redis 执⾏命令:get validationKey;
	if (value == null) {
		// 说明没有这个⼿机的验证码记录,验证失败
		return false;
	}
	if (value == validationCode) {
		return true;
	} else {
		return false;
	}
}

1.4 Redis 版本

Redis 借鉴了 Linux 操作系统的版本号命名规则:如果版本号的第二位是奇数,则表示该版本为非稳定版本(例如 2.7、2.9、3.1);如果是偶数,则为稳定版本(例如 2.6、2.8、3.0、3.2)。当前的奇数版本是下一个稳定版本的开发版本,例如 2.9 是 3.0 版本的开发版本。因此,生产环境通常选择偶数版本的 Redis。如果希望提前体验新的特性,可以选择最新的奇数版本。


二、Redis 安装与基础操作

下面相关的安装与操作部分主要以Ubuntu系统为主进行介绍:

2.1 安装 Redis

  1. 在 Ubuntu 系统中,直接使用 apt 安装即可:
apt install redis -y # -y 自动确认安装过程中的提示
  1. Windows 系统安装reids:

2.2 支持远程连接

  1. Ubuntu 系统 修改 /etc/redis/redis.conf
  • 修改 bind 127.0.0.1bind 0.0.0.0
  • 修改 protected-mode yes 改为 protected-mode no
    在这里插入图片描述
  1. Windows 系统修改下载目录下的 redis.windows-service.conf
    在这里插入图片描述

2.3 Redis 基础控制

  1. 启动 Redis 服务

    service redis-server start
    
  2. 停止 Redis 服务

    service redis-server stop
    
  3. 重启 Redis 服务

    service redis-server restart
    

三、Redis 重要文件 & 作用

3.1 工具 & 脚本

下面是一些Redis中重要的工具与脚本,用于服务器的管理、性能测试、监控、数据文件的检查与修复等功能:

文件路径解释作用
/usr/bin/redis-benchmarkRedis 基准测试工具用于测试 Redis 服务器性能。可以模拟大量并发操作来评估 Redis 的性能表现。
/usr/bin/redis-check-aofAOF 文件检查工具用于检查和修复 Redis 的 AOF(追加文件)日志。如果 Redis 崩溃或数据不一致,可以使用它来检查和修复 AOF 文件。
/usr/bin/redis-check-rdbRDB 文件检查工具用于检查和修复 Redis 的 RDB(数据库快照)文件。如果 RDB 文件损坏或不完整,可以使用该工具进行修复。
/usr/bin/redis-cliRedis 命令行客户端通过命令行连接到 Redis 服务器,允许用户发送 Redis 命令进行交互、管理 Redis 实例。
/usr/bin/redis-sentinelRedis Sentinel 监控工具用于管理 Redis 集群的高可用性。它监控主服务器的健康状态,并在主服务器发生故障时,自动切换到备用服务器。
/usr/bin/redis-serverRedis 服务器启动程序启动 Redis 服务器实例,处理所有客户端的请求并执行数据存储和查询操作。
/usr/libexec/redis-shutdownRedis 关闭服务脚本用于优关闭 Redis 服务器,确保数据被正确保存并释放资源。

3.2 配置文件

/etc/redis-sentinel.conf
/etc/redis.conf
  • /etc/redis.conf 是 Redis 服务器的配置文件。
  • /etc/redis-sentinel.conf 是 Redis Sentinel 的配置文件。

3.3 持久化文件存储目录

/var/lib/redis/

Redis 持久化生产的 RDB 和 AOF ⽂件都默认生成于该目录下。

3.4 日志文件目录

/var/log/redis/

该目录下会保存 Redis 运行期间 产生的日志文件,默认按照天数进行分割,并会将一定日期的日期文件使用gzip格式压缩保存。

四、Redis 命令行客户端

Redis客户端与服务端的交互过程如下图:
在这里插入图片描述

4.1 连接Redis服务器的两种模式

1. 交互式连接(推荐用于日常操作)

连接命令格式

redis-cli -h {host} -p {port}

典型使用场景

  • 需要连续执行多个命令
  • 调试和开发环境
  • 需要查看命令返回值的场景

操作示例

$ redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> ping  # 测试连接
PONG
127.0.0.1:6379> set user:1001 "张三"  # 设置键值
OK
127.0.0.1:6379> get user:1001  # 获取值
"张三"
127.0.0.1:6379> info memory  # 查看内存信息

2. 命令行模式(适合脚本调用)

命令格式

redis-cli -h {host} -p {port} {command}

适用场景

  • Shell脚本中调用Redis命令
  • 需要直接获取命令结果的场景
  • 自动化任务执行

使用示例

$ redis-cli ping  # 测试连接
PONG
$ redis-cli set counter 100  # 设置值
OK
$ redis-cli incr counter  # 原子递增
(integer) 101
$ redis-cli --raw get counter  # 原始格式输出
101

4.2 连接参数简化技巧

默认连接配置

  • 当连接本地服务器(127.0.0.1)和默认端口(6379)时,可省略参数:
redis-cli  # 等同于 redis-cli -h 127.0.0.1 -p 6379

常用连接选项

参数说明示例
-a认证密码redis-cli -a password
-n选择数据库redis-cli -n 1
–raw原始格式输出redis-cli --raw get key
–stat实时监控redis-cli --stat

4.3 高级连接技巧

1. 批量命令执行

$ redis-cli <<EOF
SET user:1002 "李四"
EXPIRE user:1002 3600
GET user:1002
EOF

2. 管道操作(提升批量操作性能)

$ echo -e "SET key1 value1\nGET key1" | redis-cli --pipe

3. TLS安全连接(Redis 6.0+)

redis-cli --tls --cert ./redis.crt --key ./redis.key

4.4 连接问题排查

常见错误处理

  1. 连接拒绝:

    $ redis-cli
    Could not connect to Redis at 127.0.0.1:6379: Connection refused
    

    解决方案

    • 确认Redis服务已启动:ps aux | grep redis
    • 检查防火墙设置
  2. 认证失败:

    (error) NOAUTH Authentication required
    

    解决方案

    redis-cli -a yourpassword
    
  3. 连接超时:
    解决方案

    redis-cli -h remote_host --timeout 5
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值