LabHub
学习 学习路径 课程

Redis 与缓存

六种数据结构与各自的位置

在 LabHub 中继续学习

一句话总结

使用Redis的好处不是知道很多命令,而是选择适合问题的数据结构。

概念图: Sorted Set 意外地被广泛使用。 · 该信息将消失。 · XPENDING这就是核心。 · 确认一个关键因素是否占了整体很大一部分

为什么需要这个?

很多团队只用String写Redis,全部序列化为JSONSET做并且GET做。动作是做。但是即使只想更改用户资料的邮箱一个字段,也会读取整个内容,解析并修改后重新写入。同时,两个请求这样做的话,一方会覆盖另一个。

使用Hash的话HSET user:42 email a@b.com一条,不会与其他字段冲突。选择一个数据结构不满足竞争条件。

怎么行动

String是简单的值和计数器。INCR这个原子性这一点很重要——写在浏览量、延迟限制计数器、序列号上。SET key val NX EX 60是分散锁定的基本形式。

Hash是多个字段的对象。字段单位进行更新和查询,字段数量少时,Redis会使用内部压缩的编码,省去内存。

List是有序的列表,两端插入、删除是O(1)。写入工作队列和最近活动列表。中间访问是O(N),所以不能把大的列表作为索引。

Set是无重复的集合,交集、并集、差集是命令之一。用于标记、关注者、去重。SADD作为返回值,可以知道是“第一次看到吗”,也用于实现偏移性。

ZSet(排序集合)是具有分数的集合。始终保持按分数排序的状态,排名查询为O(log N)。写入排名、优先级队列、时间序列窗口(将分数作为时间戳)。在这个课程中,单独使用一个完整的练习非常重要。

Stream是额外的专用日志。有消费者群组和确认回复,真的离队列最近。在前道上都走了。

在现场相遇的样子

在运营中最要小心的是命令KEYS是。扫视整个kisspace,Redis这段时间不能做其他事情。因为Redis以单个线程处理命令,所以在键数百万的实例中KEYS *一次会造成数秒钟的全面停止。必须SCAN需要用光标旋转。

出于同样的理由FLUSHALL,关于大型收藏品的SMEMBERS/LRANGE 0 -1DEL消除巨大的身高(相反UNLINK)也需要小心。"Redis突然变慢"的大部分原因都是一个O(N)命令。

也值得了解一下记忆的角度。MEMORY USAGE <key>可以查看按键实际使用量,即使是相同的数据,根据数据结构也会有几倍的差异。

决定选择什么的表格

数据结构 使用位置 代表命令 注意
String 缓存值,计数器 SETINCR 512MB上限
Hash 对象的每个字段的更新 HSETHGETALL 如果字段多的话HGETALL这个很重
List 库,最近N个 LPUSHBRPOP 中间插入·查询为O(n)
Set 去重,标签 SADDSINTER 大集合的交集很贵
Sorted Set 排名,按时间顺序索引 ZADDZRANGEBYSCORE 最有用
Stream 活动日志,消费者群组 XADDXREADGROUP 比List更适合队列

**Sorted Set 意外地被广泛使用。**如果把分数作为时间戳,时间范围查询 成为(ZRANGEBYSCORE), 也容易删除旧的东西(ZREMRANGEBYSCORE). 如果想把“最近24小时内的活动”之类的东西做成List的话,很快就会被阻止。

Q比List更像Stream

用List创建队列的话BRPOP取出那一刻,信息就会消失。正在处理中 消费者死亡后,该信息将消失。

Stream有消费者群组和确认(ack)的概念。

XADD  orders * type payment amount 52000      # 발행
XREADGROUP GROUP workers w1 COUNT 10 STREAMS orders >   # 읽기(pending 으로 표시)
XACK  orders workers <id>                      # 처리 완료
XPENDING orders workers                        # 아직 확인 안 된 것
XCLAIM orders workers w2 60000 <id>            # 죽은 소비자의 것을 가져오기

**XPENDING这就是核心。**如果消费者死亡,该消息将留在pending中,其他 消费者XCLAIM带走。必须直接用List制作这个。

但是Stream也会无限增长XADD ... MAXLEN ~ 100000设置上限。 ~粘上的话可以很好地剪掉,所以更便宜。

大个子造成的问题

Redis以单个线程处理命令。如果一个花费很长时间,那么这段时间内全部 停止。

KEYS *                      → O(n). 절대 쓰지 않는다
HGETALL (필드 10만 개)      → 응답이 크고 오래 걸린다
SMEMBERS (원소 100만 개)    → 같은 문제
DEL (큰 컬렉션)             → 삭제도 O(n) 이다. UNLINK 를 쓴다

UNLINK将删除移至后台,避免阻止。删除大字体时,请使用这个。 写。

寻找大号钥匙是redis-cli --bigkeys--memkeys是。定期返还 确认一个关键因素是否占了整体很大一部分

下次实习要做的事情

逐一亲自处理六个数据结构,KEYS相反SCAN循环,最后将以相同的数据以不同的数据结构存储时的内存差异制成表格。