Redis
常用场景
场景 | 应用场景 |
---|---|
缓存 | 数据缓存、会话管理、页面缓存等 |
计数器 | 访问次数、在线人数、PV、UV等 |
消息队列 | 异步任务、实时消息推送、事件通知等 |
分布式锁 | 分布式事务、资源协调、防止重复提交等 |
地理位置 | LBS、社交应用、出行服务等 |
全文检索 | 搜索引擎、文本分析、关键字提取等 |
基本数据结构
数据结构 | 特点 | 适用场景 |
---|---|---|
String(字符串) | 最基本的数据类型,是二进制安全的,可以存储任何类型的数据 | 缓存、计数器、限流、分布式锁等 |
List(列表) | 可以存储有序的字符串列表,支持从两端进行元素的插入和弹出操作 | 消息队列、任务队列、排行榜、时间轴等 |
Set(集合) | 可以存储多个唯一的字符串,支持集合运算,如并集、交集、差集等 | 标签系统、好友关系、投票系统、推荐系统等 |
Hash(哈希表) | 可以存储多个键值对,支持单个键值的添加、删除和获取操作 | 对象存储、商品属性、用户信息、配置信息等 |
Zset(有序集合) | 可以存储多个成员,每个成员都有一个分数,支持按分数排序和范围查找 | 排行榜、计分板、游戏排名等 |
部署方式
部署方式 | 描述 | 适用场景 |
---|---|---|
单机模式 | Redis 运行在单台服务器上,不进行数据分片,只使用一份配置文件。 | 适用于开发、测试等小规模环境。 |
主从复制模式 | 将 Redis 实例分为主节点和从节点,主节点负责写入数据,从节点负责读取数据。当主节点发生故障时,从节点可以自动切换为主节点。 | 适用于对数据一致性要求较高的应用场景,如电商、金融等。 |
Sentinel 模式 | Sentinel 是 Redis 的高可用性解决方案,通过多个 Sentinel 进程对 Redis 主从节点进行监控,当主节点失效时自动将从节点切换为主节点。 | 适用于对高可用性和数据一致性要求较高的应用场景,如金融、医疗等。 |
集群模式 | Redis Cluster 可以将数据分散到多个节点上进行存储和管理,支持自动数据分片和负载均衡。 | 适用于对扩展性要求较高的应用场景,如互联网应用、物联网等。 |
配置要求
部署方式 | 机器内存 | 机器CPU | 磁盘 | 并发 | 响应指标 |
---|---|---|---|---|---|
单机模式 | 1GB-4GB | 单核或双核 | 10GB-100GB | 10K-100K QPS | 响应时间一般在毫秒级别 |
主从复制模式 | 4GB-32GB | 四核或八核 | 100GB-1TB | 10K-100K QPS | 主节点写入时响应时间一般在毫秒级别,从节点读取时响应时间较快 |
Sentinel 模式 | 8GB-64GB | 四核或八核 | 100GB-1TB | 10K-100K QPS | 响应时间一般在毫秒级别,当主节点失效时,切换时间一般在秒级别 |
集群模式 | 32GB-512GB | 多核 | 多个硬盘 | 100K-1M QPS | 响应时间一般在毫秒级别 |
实现一个分布式锁
Redis 可以通过 SETNX(set if not exists)命令实现分布式锁。具体实现步骤如下:
- 定义一个键(key)表示锁的名字,例如 lock:my_lock。
- 在获取锁之前,需要设置一个过期时间(expire_time),避免因为某个客户端崩溃或者网络异常导致锁一直被占用。可以通过 SETNX 命令设置键值,如果返回值为 1,表示设置成功,获得锁;如果返回值为 0,表示该锁已经被占用,获取锁失败。
- 如果成功获取到锁,需要在执行完任务后及时释放锁,可以通过 DEL 命令删除键值释放锁。
下面是一个简单的示例代码:
def get_lock(conn, lock_name, expire_time=10):
# 尝试获取锁
is_locked = conn.setnx(lock_name, 'locked')
if is_locked:
# 设置锁的过期时间
conn.expire(lock_name, expire_time)
return True
else:
return False
def release_lock(conn, lock_name):
# 释放锁
conn.delete(lock_name)
在使用分布式锁的时候,需要考虑到网络延迟、锁的粒度等问题。同时,为了避免死锁的发生,需要设置合理的过期时间,并在释放锁的时候检查是否是自己持有的锁。
Redis Key 的过期机制
过期机制 | 描述 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
定时过期 | 当设置了键的过期时间时,Redis会自动在键的过期时间到达时将其删除 | 需要自动清理过期数据的场景,例如缓存 | 实现简单,易于理解和维护;能够确保过期键及时被删除 | 在键过期时会阻塞主线程,可能会影响性能;无法处理键在过期之前就被更新或删除的情况 |
惰性过期 | 当键过期后,只有在被访问时才会被删除 | 需要缓存的数据量非常大的场景,避免一次性删除大量数据影响性能 | 减少了过期键对性能的影响,能够优化内存的使用;可以处理键在过期之前被更新或删除的情况 | 无法保证过期键及时被删除;可能会出现一些过期键没有被及时删除的情况 |
定期过期 | Redis会定期扫描过期键并删除它们,确保不会出现太多过期键没有被删除的情况 | 需要删除过期键,但又不能承受一次性删除过多数据的场景 | 能够保证过期键的及时删除,对性能的影响相对较小;可以处理键在过期之前被更新或删除的情况 | 无法保证过期键及时被删除,可能会出现一些过期键没有被及时删除的情况;定期过期的时间间隔需要根据实际情况进行调整 |
Redis key 的淘汰策略
淘汰策略 | 描述 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
LRU(Least Recently Used) | 淘汰最近最少使用的键 | 适用于读多写少的场景,例如缓存 | 能够确保经常使用的键不会被淘汰;实现简单,性能高 | 在写入时会影响性能;不适用于访问模式不规律的场景 |
LFU(Least Frequently Used) | 淘汰访问频率最少的键 | 适用于访问频率较为稳定的场景,例如热点数据 | 能够确保访问频率高的键不会被淘汰;能够适应访问模式的变化 | 需要额外记录键的访问次数,增加了内存开销;不适用于访问模式频繁变化的场景 |
Random | 随机选择一个键进行淘汰 | 适用于所有场景 | 实现简单,无需记录键的访问次数 | 无法确保经常使用的键不会被淘汰;淘汰效率低下 |
TTL | 淘汰剩余时间最短的键 | 适用于具有时效性的数据,例如会话数据 | 能够确保过期时间较短的键不会占用过多内存空间 | 只适用于具有时效性的数据;无法处理访问频率高的键 |
stop the world 问题
Redis是一个单线程的内存数据库,这意味着它使用一个主线程来处理所有客户端请求。Redis设计为使用非阻塞I/O,因此在执行一些操作时不会阻塞主线程。这样可以避免大多数"stop the world"问题。
然而,Redis在执行一些操作时也可能出现阻塞主线程的情况。例如,当执行某些命令,如BGSAVE、BGREWRITEAOF、FLUSHALL和FLUSHDB时,Redis会执行一个持久化操作,这时需要将内存中的数据写入磁盘。在这些操作期间,Redis主线程将被阻塞,直到操作完成。如果Redis数据库非常大,这个过程可能需要一段时间,从而导致长时间的停顿。
此外,当Redis主线程执行大量计算时,也可能会出现阻塞主线程的情况。例如,当执行复杂的Lua脚本或执行大型集合运算时,Redis主线程可能会被占用,导致客户端请求无法及时得到响应。
因此,虽然Redis在大多数情况下不会出现"stop the world"问题,但在某些情况下仍然可能出现。为了避免这种情况,需要对Redis的使用进行仔细规划和优化,以确保操作能够在可接受的时间内完成。
竞品分析
竞品名称 | 差异 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
Memcached | - 不支持持久化 - 不支持数据结构 - 支持分布式锁 |
- 简单易用 - 高性能 - 高并发 - 内存使用效率高 |
- 仅支持缓存场景 - 不支持持久化 - 不支持复杂的数据结构 |
适用于高并发、读写比例高、数据量大的缓存场景 |
RocksDB | - 存储介质不限于内存 - 可以保存磁盘上的数据 - 支持事务 |
- 支持多种数据结构 - 高性能 - 可扩展性强 |
- 不支持分布式 | 适用于需要对大量数据进行持久化存储的场景 |
LevelDB | - 存储介质不限于内存 - 可以保存磁盘上的数据 |
- 高性能 - 支持事务 - 轻量级 |
- 不支持复杂的数据结构 - 不支持分布式 |
适用于需要对大量数据进行持久化存储的场景 |
Cassandra | - 支持分布式 - 可以水平扩展 - 支持多数据中心部署 |
- 高可用性 - 高可靠性 - 高扩展性 |
- 复杂性高 - 部署和维护成本高 |
适用于需要存储海量数据且需要高可用性、高可靠性的场景 |
MongoDB | - 支持复杂数据结构 - 支持事务 |
- 高可用性 - 高灵活性 - 支持分布式部署 |
- 性能较差 - 不支持 ACID 特性 |
适用于需要存储复杂数据结构、需要高可用性、高灵活性的场景 |
powered by ChatGPT