六种数据结构与各自的位置
一句话总结
使用Redis的好处不是知道很多命令,而是选择适合问题的数据结构。
为什么需要这个?
很多团队只用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 -1,DEL消除巨大的身高(相反UNLINK)也需要小心。"Redis突然变慢"的大部分原因都是一个O(N)命令。
也值得了解一下记忆的角度。MEMORY USAGE <key>可以查看按键实际使用量,即使是相同的数据,根据数据结构也会有几倍的差异。
决定选择什么的表格
| 数据结构 | 使用位置 | 代表命令 | 注意 |
|---|---|---|---|
| String | 缓存值,计数器 | SET,INCR |
512MB上限 |
| Hash | 对象的每个字段的更新 | HSET,HGETALL |
如果字段多的话HGETALL这个很重 |
| List | 库,最近N个 | LPUSH,BRPOP |
中间插入·查询为O(n) |
| Set | 去重,标签 | SADD,SINTER |
大集合的交集很贵 |
| Sorted Set | 排名,按时间顺序索引 | ZADD,ZRANGEBYSCORE |
最有用 |
| Stream | 活动日志,消费者群组 | XADD,XREADGROUP |
比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循环,最后将以相同的数据以不同的数据结构存储时的内存差异制成表格。