【学习记录】Redis 核心技术与实战

文章探讨了Redis的基础架构,包括基本模块和高可用、高可扩展特性。介绍了Redis的数据结构,如哈希表和避免冲突的方法,以及为何使用整数数组和压缩列表。此外,讨论了Redis的单线程高性能IO模型和I/O多路复用机制。在实践篇中,提到了String类型的存储开销和优化策略,如使用集合类型存储单值键值对,以及在不同场景下选择Set、SortedSet、Bitmap和HyperLogLog进行统计的考量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

个人学习记录。

一、基础篇

1. 基本架构:一个键值数据库包含什么?

  • 访问框架
  • 操作模块
  • 索引模块
  • 存储模块
    (Redis除上述四块外有高可用集群模块和高可扩展模块)

2. 数据结构:快速的Redis有哪些慢操作?

  • 键和值之间的存储是什么数据结构?
    • 使用了哈希表,称之为全局哈希表
    • 哈希表是一个数组,数组的每一个元素是一个哈希桶。
    • (可能变慢)出现哈希冲突则使用拉链法解决(链表)。
    • 为了避免rehash变慢,Redis采用了渐进式rehash
  • Redis基础数据类型和底层数据结构
    • 在这里插入图片描述
    • 整数数组和压缩列表在查找的时间复杂度上不占优势,为何Redis还使用它们作为底层数据结构呢?
      • 内存利用率高,整数数组和压缩列表的数据结构很紧凑,例如链表还需额外存储指针。
      • 数组是连续内存,对CPU高速缓存更友好。所以当数据量很少时不会降低访问速度。但当数据量超过阈值时,为了降低查询的时间复杂度会转变为哈希表或跳表。

3. 高性能IO模型:为什么单线程Redis能那么快?

  • Redis是单线程的吗?
    • 一般是指网络I/O和键值对读写是单线程完成的。
    • 其他功能是额外的线程执行的,比如持久化、异步删除、集群同步等。
    • Redis 6.0中引入了多线程模型,网络I/O部分改为多线程。(TODO)
  • 为什么用单线程?
    • 多线程开销:上下文切换、等待获取共享资源等。
  • 单线程为什么这么快?
    • 采用I/O多路复用机制

二、实践篇

11. 万金油的String为什么不好用了?

  • String类型存储开销大。
    • SDS结构体中除了buf(实际数据)外,还有len(已用长度 4字节)和alloc(实际分配长度 4字节)。
    • Redis统一使用RedisObject记录元数据,并指向实际数据。
      • 元数据(8字节)
      • 指针(8字节):指向了SDS。
  • 压缩列表(ZipList)可以节省内存。
  • 实践:如何使用集合类型来存储单值的键值对?
    • 基于Hash的二次编码
      • 以存储String举例,可以将字符串分组,比如10位数字,取前7位为Hash的Key,后三位为Field,对应value不变。
      • 需要注意设置hash-max-ziplist-entries和hash-max-ziplist-value,也就是用压缩列表存Hash时的最多元素个数和最大元素长度。如果超出了底层会变为哈希表。

12. 有一亿个keys要统计,应该用哪种集合?

  • 聚合统计
    • Set集合的交集、并集、差集。
    • 计算复杂度较高,数据量大的情况下会阻塞Redis。可以在主从集群中选择一个从节点负责聚合计算。
  • 排序统计
    • Sorted Set
    • 场景:最新列表、排行榜
  • 二值状态统计
    • 使用bitmap节省内存。(SETBIT、GETBIT、BITCOUNT)
    • 场景:签到打卡、1亿个用户中连续10天打卡的人数。
  • 基数统计
    • 统计一个集合中不重复的元素个数。
    • Set内存空间占用很大。
    • HyperLogLog当集合元素数量非常多时,计算基数所需的空间是固定的且比较小。但HyperLogLog是基于概率实现的,有一定误差。
    • 场景:统计UV,一个用户多次访问只计数1次。
### Redis实战应用核心技术 Redis 是一个高性能的键值存储系统,支持多种数据结构(如字符串、哈希、列表、集合等),并且具备持久化、分布式锁、消息队列等功能。以下是 Redis核心技术实战案例。 #### 1. 核心技术 - **高性能内存存储** Redis 将所有数据存储在内存中,这使得它能够以极高的速度处理读写请求[^1]。通过将数据保存在内存中,Redis 能够实现亚毫秒级的响应时间。 - **持久化机制** Redis 提供了两种主要的持久化方式:RDB(快照)和 AOF(Append-Only File)。RDB 是一种定期将内存中的数据保存到磁盘的方式,而 AOF 则记录每次写操作的日志[^1]。两者可以结合使用以平衡性能和数据安全性。 - **主从复制** Redis 支持主从复制模式,其中主节点负责写操作,从节点负责读操作。这种架构可以提高系统的可用性和扩展性[^2]。 - **分布式锁** 使用 `SETNX` 命令可以实现分布式锁,确保在分布式系统中只有一个进程能够获取锁并执行特定任务[^3]。此外,Redis 还支持更高级的锁实现,例如红锁(Redlock 算法)。 - **发布/订阅模式** Redis 提供了发布/订阅功能,允许客户端订阅某些频道,并在有新消息时接收通知。这一特性常用于实时通信系统,例如聊天应用或通知推送。 #### 2. 实战案例 - **电商秒杀系统** 在秒杀场景中,Redis 可以用来缓存商品库存信息,减少数据库的压力。同时,通过分布式锁控制并发访问,确保库存扣减的准确性[^2]。代码示例如下: ```python import redis r = redis.Redis(host='localhost', port=6379, db=0) def acquire_lock(lock_key, client_id, lock_timeout): return r.set(lock_key, client_id, nx=True, ex=lock_timeout) def release_lock(lock_key, client_id): if r.get(lock_key) == client_id: r.delete(lock_key) ``` - **缓存加速** Redis 常被用作缓存层,存储热点数据以减少对后端数据库的访问频率。例如,在博客网站中,可以将文章内容缓存在 Redis 中,从而显著提升页面加载速度。 - **实时数据分析** Redis 的数据结构非常适合用于实时统计和分析。例如,可以使用 HyperLogLog 来估算唯一访客数量,或者使用 Bitmap 计算用户活跃度。 - **任务队列** Redis 的列表数据结构可以用来实现简单的任务队列。生产者将任务推送到队列,消费者从队列中取出任务并执行。以下是一个简单的任务队列示例: ```python # 生产者 r.lpush('task_queue', 'task1') # 消费者 task = r.rpop('task_queue') print(f"Processing task: {task}") ``` #### 3. 高可用性设计 为了保证 Redis 在高并发场景下的稳定性,通常需要采用以下策略: - **多集群部署** 在不同的数据中心部署多个 Redis 集群,并通过负载均衡器分发流量[^2]。 - **故障检测自动切换** 使用 Redis Sentinel 或 Redis Cluster 自动监控主从节点状态,并在主节点失效时快速切换到从节点。 - **降级策略** 当 Redis 集群不可用时,可以降级到关系型数据库或其他 NoSQL 数据库,确保核心业务流程不受影响。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值