Skip to main content

Redis Overview

基础数据结构

String

  1. 当做KV存储使用,Key和Value都可以是字符串或者序列化后的字符串
    1. key和value的长度呢?
    2. value可以容纳的数据长度是512MB
  2. 底层实现呢?
  3. 应用场景
    1. 缓存对象
    2. 常规计数,用incr自增KV
    3. 实现分布式锁,setnx key value ex 123语句可以被用于设置带expire time的KV
    4. 共享session信息

List

  1. 底层实现是双向链表或压缩列表,在Redis3.2之后,底层实现为quicklist
  2. 所以删除是pop,增加是append
  3. 使用场景:消息队列

Hash

  1. 常见hash map
  2. 注意hash冲突处理?
  3. 注意性能?

Set

  1. 可以用于过滤电话号码?

ZSet

  1. 有序的set,可以用来做排序
  2. 应用场景:实时排行榜

高级数据结构

BitMap

bitmap本质上本质上是bit数组,可以用于统计大量二值状态的数据(二值状态指集合元素的取值只有0或1),可以有效节省内存空间。

  • 使用string类型实现,而string本身就是byte数组,等同于bit数组

即使一天生成1亿(10^8)的数据,bitmap的内存占用也就10^8/8 ~= 12.5*10^6 bytes ~= 12MB,一周就是84MB,没有问题。

应用场景: 每天打卡的用户数

HyperLogLog

  1. 是Redis 2.8.9之后新增的数据结构,用于统计集合中基数(不重复的元素个数)。统计规则是基于概率实现的,误算率为0.81%。
    1. HyperLogLog提供不精确的去重计数。
  2. pros:只需要12KB内存就可以统计接近2^64个不同元素的基数,很省空间。
    1. 如果使用long类型,也就是8 bytes,2^64个不同元素需要2^64*8 ~= 2^67MB ~= 2^37GB内存空间

为什么Redis快?

  1. 纯内存操作
  2. 单线程模型
    1. 实现简单
    2. 无锁
    3. 可虚拟化,单机多实例部署
    4. 新版redis在网络io操作上使用多线程,但操作数据结构的仍旧是单线程
  3. 使用epoll(网络I/O多路复用)

备份

  • AOF(Append Only File)
    • 每执行一次命令添加一行log,可以压缩
    • pros:更新频率高;时效性强
    • cons:文件大;恢复速度慢
  • RDS(Redis Database)
    • 二进制文件,即某个时刻Redis的内存拷贝。定期备份
    • pros:更新频率低;时效性差
    • cons:文件小;恢复速度快

分布式(主从备份)

主节点(Master):

  • 负责处理写请求和读请求。

  • 将自身的数据异步复制给从节点。

从节点(Slave):

  • 只读(默认),也可以配置为可读。

  • 从主节点复制数据,可以用来分担读请求或作为备份。

NoSQL是否可以称作KV storage

一部分是(如 Redis、DynamoDB);

但也包含文档(MongoDB)、列式(Cassandra)等模型。

LUA事务

Lua 脚本可以用来实现 Redis 不支持的复杂逻辑,比如:

  • 计数器(带过期时间)

  • 队列限流

  • 带时间窗口的防刷(如滑动窗口限流)

  • 多 key 事务控制

  • 自定义排行榜逻辑

实践特殊样例,order fee的计算

Reference

  1. https://xiaolincoding.com/redis/data_struct/command.html#%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF