Redis 基础
远程字典服务
Remote Dictionary Service
安装
后台启动服务端
./redis-server --daemonize yes
启动客户端:
redis-cli
用途
- 记录帖子的点赞数、评论数和点击数 (hash)。
- 记录用户的帖子 ID 列表 (排序),便于快速显示用户的帖子列表 (zset)。
- 记录帖子的标题、摘要、作者和封面信息,用于列表页展示 (hash)。
- 记录帖子的点赞用户 ID 列表,评论 ID 列表,用于显示和去重计数 (zset)。
- 缓存近期热帖内容 (帖子内容空间占用比较大),减少数据库压力 (hash)。
- 记录帖子的相关文章 ID,根据内容推荐相关帖子 (list)。
- 如果帖子 ID 是整数自增的,可以使用 Redis 来分配帖子 ID(计数器)。
- 收藏集和帖子之间的关系 (zset)。
- 记录热榜帖子 ID 列表,总热榜和分类热榜 (zset)。
- 缓存用户行为历史,进行恶意行为过滤 (zset,hash)。
数据结构
5 种基础数据结构:
string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。
list/set/hash/zset 这四种数据结构是容器型数据结构。
字符串 String
Theory
Redis 所有的数据结构都是以唯一的 key 字符串作为名称,
通过这个唯一 key 值来获取相应的 value 数据。
不同类型的数据结构的差异就在于 value 的结构不一样。
用于:缓存(用户信息)
采用预分配冗余空间的,最大长度为 512M.
字符串长度小于 1M 时,扩容都是加倍现有的空间.
超过 1M,扩容时一次只会多扩 1M 的空间。
Use
设过期(setex name 5 codehole)
可计数(incrby age 5)
列表 List
Theory
对标Java LinkedList
用于:队列
是链表
插入和删除 O(1),定位 O(n)
Use
# 右边进左边出:队列
> rpush books python java golang
(integer) 3
> llen books
(integer) 3
> lpop books
"python"
> lpop books
"java"
> lpop books
"golang"
> lpop books
(nil)
右边进右边出:栈
> rpush books python java golang
(integer) 3
> rpop books
"golang"
> rpop books
"java"
> rpop books
"python"
> rpop books
(nil)
字典 Hash
Theory
无序字典
对标 Java HashMap
渐进式 rehash
Use
与String一样,但可以分段取出用户信息。
优:按量,提高传输效率。
缺:相较String耗费存储空间。
> hset books java "think in java" # 命令行的字符串如果包含空格,要用引号括起来
(integer) 1
> hset books golang "concurrency in go"
(integer) 1
> hset books python "python cookbook"
(integer) 1
> hgetall books # entries(),key 和 value 间隔出现
1) "java"
2) "think in java"
3) "golang"
4) "concurrency in go"
5) "python"
6) "python cookbook"
> hlen books
(integer) 3
> hget books java
"think in java"
> hset books golang "learning go programming" # 因为是更新操作,所以返回 0
(integer) 0
> hget books golang
"learning go programming"
> hmset books java "effective java" python "learning python" golang "modern golang programming" # 批量 set
OK
集合 Set
Theory
对标Java HashSet 键值对无序唯一。
用于:
存储活动中奖的用户 ID,可以保证同一个用户不会中奖两次。
Use
> sadd books python
(integer) 1
> sadd books python # 重复
(integer) 0
> sadd books java golang
(integer) 2
> smembers books # 注意顺序,和插入的并不一致,因为 set 是无序的
1) "java"
2) "python"
3) "golang"
> sismember books java # 查询某个 value 是否存在,相当于 contains(o)
(integer) 1
> sismember books rust
(integer) 0
> scard books # 获取长度相当于 count()
(integer) 3
> spop books # 弹出一个
"java"
有序集合 SortedSet
Theory
类 Java 的 SortedSet 和 HashMap 的结合体
set,保证了内部 value 的唯一性
给 value 赋 score,表权重。
内部是「跳跃列表」的数据结构。
用于:
粉丝列表,value 值是粉丝的用户 ID,score 是关注时间。按关注时间进行排序。
学生的成绩,value 值是学生的 ID,score 是他的考试成绩。得名次。
Use
> zadd books 9.0 "think in java"
(integer) 1
> zadd books 8.9 "java concurrency"
(integer) 1
> zadd books 8.6 "java cookbook"
(integer) 1
> zrange books 0 -1 # 按 score 排序列出,参数区间为排名范围
1) "java cookbook"
2) "java concurrency"
3) "think in java"
> zrevrange books 0 -1 # 按 score 逆序列出,参数区间为排名范围
1) "think in java"
2) "java concurrency"
3) "java cookbook"
> zcard books # 相当于 count()
(integer) 3
> zscore books "java concurrency" # 获取指定 value 的 score
"8.9000000000000004" # 内部 score 使用 double 类型进行存储,所以存在小数点精度问题
> zrank books "java concurrency" # 排名
(integer) 1
> zrangebyscore books 0 8.91 # 根据分值区间遍历 zset
1) "java cookbook"
2) "java concurrency"
> zrangebyscore books -inf 8.91 withscores # 根据分值区间 (-∞, 8.91] 遍历 zset,同时返回分值。inf 代表 infinite,无穷大的意思。
1) "java cookbook"
2) "8.5999999999999996"
3) "java concurrency"
4) "8.9000000000000004"
> zrem books "java concurrency" # 删除 value
(integer) 1
> zrange books 0 -1
1) "java cookbook"
2) "think in java"
跳跃列表
跳跃列表采取一个随机策略来决定新元素可以兼职到第几层。
首先 L0 层肯定是 100% 了,L1 层只有 50% 的概率,L2 层只有 25% 的概率,L3 层只有 12.5% 的概率,一直随机到最顶层 L31 层。绝大多数元素都过不了几层,只有极少数元素可以深入到顶层。列表中的元素越多,能够深入的层次就越深,能进入到顶层的概率就会越大。
参考信息
掘金的《Redis 深度历险:核心原理与应用实践》
https://juejin.im/book/5afc2e5f6fb9a07a9b362527/section/5afc2e5f51882542714ff291
一个秒杀商品测试网站
http://redis.ipuxin.com/
一个PHP测试的Redis测试工具
http://redis.root.ipuxin.com/redis.php
一个Redisl图形化工具
http://see.redis.ipuxin.com/?overview
一个不仅仅是Redis面试的超全资料
http://www.mianshigee.com/tutorial/redis-cli-2019/f98c70acd4eaf1f3.md