技术总结(二十一)
一、Redis是什么
Redis(Remote Dictionary Server)是一个开源的、基于内存的数据结构存储系统,它可以用作数据库、缓存和消息中间件。以下是关于 Redis 的详细介绍:
一、数据结构支持
- 字符串(String)
- 这是 Redis 最基本的数据类型。可以存储任何形式的字符串,包括整数、浮点数(以字符串形式存储)和二进制数据等。例如,可以用一个字符串类型的键值对来存储用户的登录令牌(token)。
- 操作命令示例:
SET key value
用于设置键值对,GET key
用于获取指定键的值。
- 列表(List)
- 它是一个按照插入顺序排序的字符串元素集合。可以在列表的两端进行插入(
LPUSH
和RPUSH
命令)和删除(LPOP
和RPOP
命令)操作。 - 比如,一个简单的消息队列可以使用 Redis 列表来实现。生产者将消息使用
RPUSH
命令插入到列表的尾部,消费者使用LPOP
命令从列表头部获取消息进行处理。
- 它是一个按照插入顺序排序的字符串元素集合。可以在列表的两端进行插入(
- 集合(Set)
- 集合是一个无序的、不包含重复元素的字符串集合。可以进行添加元素(
SADD
命令)、删除元素(SREM
命令)和检查元素是否存在(SISMEMBER
命令)等操作。 - 例如,在一个社交网络应用中,可以使用集合来存储用户的关注列表。当用户关注另一个用户时,使用
SADD
命令将被关注用户的 ID 添加到关注列表集合中。
- 集合是一个无序的、不包含重复元素的字符串集合。可以进行添加元素(
- 有序集合(Sorted Set)
- 它和集合类似,但是每个元素都会关联一个分数(score),Redis 会根据这个分数对元素进行排序。可以通过分数范围获取元素(
ZRANGEBYSCORE
命令)。 - 例如,在一个游戏排行榜应用中,玩家的得分和玩家 ID 可以组成有序集合,根据玩家得分来实时更新排行榜。
- 它和集合类似,但是每个元素都会关联一个分数(score),Redis 会根据这个分数对元素进行排序。可以通过分数范围获取元素(
- 哈希(Hash)
- 哈希是一个键值对集合。它适合存储对象,其中字段(field)相当于对象的属性,值(value)相当于属性的值。可以通过
HSET
命令设置哈希中的字段和值,通过HGET
命令获取指定字段的值。 - 例如,存储用户信息(姓名、年龄、性别等),可以将用户 ID 作为键,用户的各项信息作为哈希中的字段和值。
- 哈希是一个键值对集合。它适合存储对象,其中字段(field)相当于对象的属性,值(value)相当于属性的值。可以通过
二、主要特点
- 高性能
- 由于 Redis 的数据存储在内存中,读写操作速度非常快。相比传统的基于磁盘的数据库,它能够在极短的时间内处理大量的读写请求。这使得 Redis 在对性能要求极高的场景下,如高频交易系统的实时数据存储和查询、大型网站的热点数据缓存等,发挥着重要的作用。
- 持久化
- Redis 提供了两种持久化方式来确保数据在重启后不会丢失。一种是 RDB(Redis Database)持久化,它是在指定的时间间隔内将数据集快照写入磁盘。另一种是 AOF(Append Only File)持久化,它以日志的形式记录服务器所接收的每一个写操作,在服务器重启时,这些日志可以被重新执行来恢复数据集。
- 分布式支持
- Redis 支持集群模式,能够实现数据的分布式存储和高可用性。在集群模式下,数据被自动分片存储在多个节点上,并且可以通过主从复制等机制来保证数据的冗余和故障恢复。例如,当一个主节点出现故障时,从节点可以快速接管服务,确保系统的连续性。
- 简单易用的 API
- Redis 提供了简单直观的命令行接口和丰富的客户端库,支持多种编程语言,如 Python、Java、Node.js 等。这使得开发者可以很方便地在自己熟悉的语言环境中使用 Redis,快速集成到现有的应用系统中。
三、应用场景
- 缓存应用
- 这是 Redis 最常见的应用场景之一。通过将经常访问的数据存储在 Redis 中,当客户端再次请求这些数据时,可以直接从 Redis 中获取,而不必从后端的数据库(如 MySQL、MongoDB 等)中读取,大大提高了系统的响应速度。例如,在一个电商网站中,商品的详情信息、热门商品列表等都可以缓存到 Redis 中。
- 计数器应用
- 可以利用 Redis 的原子操作来实现计数器功能。比如,统计网站的访问量、文章的点赞数、用户的登录次数等。由于 Redis 的操作是原子性的,在高并发环境下能够保证计数的准确性。
- 消息队列应用
- 如前面提到的,Redis 的列表数据结构可以作为一个简单的消息队列。在分布式系统中,不同的服务可以通过 Redis 消息队列进行通信和协作,实现异步处理,提高系统的整体性能和可扩展性。
- 排行榜应用
- 利用 Redis 的有序集合可以轻松地实现排行榜功能,如游戏排行榜、电商网站的商品销量排行榜等。可以实时更新排名,并且能够快速地获取排名前列的元素。
二、Redis雪崩
edis雪崩是指在某个时间段内,大量的缓存数据同时失效或过期,导致大量的请求直接落到数据库上,从而引起数据库负载激增,影响系统性能的现象。12
原因
- 缓存数据过期时间设置不合理:如果大量的缓存数据在同一时间过期,会导致请求直接打到数据库上。
- 缓存服务宕机:如果Redis缓存服务宕机,请求无法获取缓存数据,会直接打到数据库上。
- 缓存层错误:缓存层出现错误,不能正常工作,导致请求直接打到数据库上。
解决方案
- 设置合理的缓存过期时间:给不同的缓存数据设置不同的过期时间,避免大量数据同时过期。
- 缓存预热:将数据提前加入到缓存中,当数据发生变更时,再将最新的数据更新到缓存。
三、Redis缓存预热
Redis缓存预热是指系统上线后,提前将相关的缓存数据直接加载到缓存系统中。这样做的主要目的是减少数据库的压力,避免在用户请求时直接查询数据库,从而提高系统的响应速度和性能12。
缓存预热的原因和好处
- 减少数据库压力:通过缓存预热,用户发送请求时不需要再从数据库查询数据,而是直接从Redis缓存中获取,从而减轻数据库的负担,特别是在高并发场景下效果显著2。
- 提高系统响应速度:预加载缓存数据可以避免在用户首次请求时从磁盘读取数据到内存的过程,减少响应时间,提升用户体验12。
- 避免数据不一致:如果Redis启动后没有进行缓存预热,客户端请求会导致Redis从磁盘中读取数据到内存中,如果此时的数据已经过期或者已被删除,就会导致客户端得到的数据不一致1。
四、Redis缓存穿透
edis缓存穿透是指当一个请求查询一个不存在于缓存中的数据时,由于缓存中不存在该数据,每次查询都会直接访问后端数据源,导致后端数据源压力大增,甚至可能导致服务不可用。
Redis缓存穿透的原因
缓存穿透的主要原因有两个:
- 查询的数据在数据库中确实不存在:当用户查询一个在数据库中也不存在的数据时,缓存和数据库都无法提供数据,导致每次请求都会直接访问数据库。
- 恶意请求:恶意用户或攻击者通过发送大量的无效查询来绕过缓存,直接访问数据库,导致数据库压力激增。