redis简介及相关原理
redis数据类型及应用
key常用命令 String常用命令
命令 | 描述 |
---|---|
SET key value | 设置指定 key 的值 |
GET key | 获取指定 key 的值。 |
GETSET key value | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
SETEX key seconds value | 获取指定 key 的值。 |
SETNX key value | 只有在 key 不存在时设置 key 的值。 |
INCR key | 将 key 中储存的数字值增一。 |
DECR key | 将 key 中储存的数字值减一。 |
String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。 常规key-value缓存应用;常规计数:微博数,粉丝数等。 |
String常见应用
- 单值缓存
set key value; get key
- 对象缓存
set user:1 value[json数据]
mset user:100:name xiaoming user:100:age 18
- 分布式锁
- 计数器
incr article:count:id
-
session
-
分布式序列号
incrby orderid 1000(批量生成序列号)
List常用命令
命令 | 描述 |
---|---|
LLEN key | 获取列表长度 |
LPOP key | 移出并获取列表的第一个元素。 |
LPUSH key value1 [value2] | 将一个或多个值插入到列表头部。 |
LRANGE key start stop | 获取列表指定范围内的元素。 |
RPOP key | 移除列表的最后一个元素,返回值为移除的元素。 |
RPUSH key value1 [value2] | 在列表中添加一个或多个值。 |
List常见应用
list 就是链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,消息列表等功能都可以用Redis的 list 结构来实现。Redis list 的实现为一个双向链表,即可以支持反向查找和遍历,更方便操作,不过带来了部分额外的内存开销。另外可以通过 lrange 命令,就是从某个元素开始读取多少个元素,可以基于 list 实现分页查询,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西(一页一页的往下走),性能高。
- 数据结构
栈=lpush+lpop ->FILO
队列=lpush+rpop
阻塞队列=lpush+brpop(有元素就拿出一个,没有就等待直到有一个)
Set常用命令
命令 | 描述 |
---|---|
SADD key member1 [member2] | 向集合添加一个或多个成员 |
SPOP key | 移除并返回集合中的一个随机元素 |
SCARD key | 获取集合的成员数。 |
SISMEMBER key member | 判断 member 元素是否是集合 key 的成员。 |
SMEMBERS key | 返回集合中的所有成员。 |
SUNION key1 [key2] | 返回所有给定集合的并集。 |
SREM key member1 [member2] | 移除集合中一个或多个成员。 |
Set常见应用
set 对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。可以基于 set 轻易实现交集、并集、差集的操作。比如:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程,具体命令:sinterstore key1 key2 key3 (将交集存在key1内)
- 微信抽奖小程序
①点击参与抽奖加入集合 sadd key [userID]
②查看参与抽奖所有用户 smembers key
③抽取count名中奖者 srandmember key [count] (不会从集合删除) / spop key [count] (会从集合删除)
- 点赞,收藏,标签
①点赞 sadd like:消息id 用户id
②取消点赞 srem like:消息id 用户id
③检查用户是否点过赞 sismember like:消息id 用户id
④获取点赞列表 smembers like:消息id
⑤获取点赞用户数 scard like:消息id
- 关注模型
①小明关注的人:xiaoming ->{a,b,c}
②小王关注的人:xiaowang ->{a,b,c,d}
③小李关注的人:xiaoli ->{a,b,c,d,e}
小明和小王共同关注:sinter xiaoming xiaowang
小明关注的人也关注他(小王):sismember a xiaowang;sismember b xiaowang;sismember c xiaowang
我可能认识的人: sdiff xiaowang xiaoming
Sorted Set常用命令
命令 | 描述 |
---|---|
ZADD key score1 member1 [score2 member2] | 向有序集合添加一个或多个成员,或者更新已存在成员的分数 |
ZCARD key | 获取有序集合的成员数 |
ZRANGE key start stop [WITHSCORES] | 通过索引区间返回有序集合指定区间内的成员。 |
ZSCORE key member | 返回有序集中,成员的分数值。 |
ZREM key member [member ...] | 移除有序集合中的一个或多个成员。 |
Sorted Set常见应用
和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。 举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维度的消息排行榜)等信息,适合使用 Redis 中的 SortedSet 结构进行存储。
- 排行榜
①点击新闻 zincrby hotNews:20200808 1 你幸福吗
②展示当日排行 zrevrange hotNews:20200808 0 9 withscores
③三日搜索榜单 zunionstore hotNews:20200808-20200810 3 hotNews:20200808 hotNews:20200809hotNews:20200810(对三个集合求并集,分数相加)
④展示七日排行榜 zrevrange hotNews:20200808-20200810 0 9 withscores
Hash常用命令
命令 | 描述 |
---|---|
HDEL key field1 [field2] | 删除一个或多个哈希表字段 |
HEXISTS key field | 查看哈希表 key 中,指定的字段是否存在。 |
HGET key field | 获取存储在哈希表中指定字段的值。 |
HGETALL key | 获取在哈希表中指定 key 的所有字段和值。 |
HKEYS key | 获取所有哈希表中的字段。 |
HLEN key | 获取哈希表中字段的数量。 |
HSET key field value | 将哈希表 key 中的字段 field 的值设为 value 。 |
Hash常见应用
- 对象缓存
Hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,后续操作的时候,你可以直接仅仅修改这个对象中的某个字段的值。 比如我们可以Hash数据结构来存储用户信息,商品信息等等。
优点: 相比string消耗内存和cpu更小;相比string存储更节省空间
缺点:过期功能只能用在key上;redis集群架构不适合大量使用(集群目的为了数据分散存储,假如hash存储的是用户数据,那相当于用户数据全部存储在某一个节点下。)
bitmaps常用命令
命令 | 示例 |
---|---|
SETBIT key offset value | setbit bitmaps_test 10 1 |
GETBIT key offset | getbit bitmaps_test 10 |
BITCOUNT key | bitcount bitmaps_test(统计位的值为1的数量) |
BITOP op destkey key[key....] | bitop是一个复合操作,它可以做多个Bitmaps的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在destkey中 |
严格来说Bitmaps并不是一个新的数据结构,而是一个符合特殊约定的字符串。是set、get等一系列字符串操作的一种扩展,与其不同的是,它提供的是位级别的操作,从这个角度看,我们也可以把它当成是一种位数组、位向量结构。Redis从2.2.0版本开始新增了setbit ,getbit , bitcount等几个bitmap相关命令,我们详细看一下bitmaps是怎么操作的: | |
set bitmaps_test 1 |
1对应二进制(1对应ASCII码为49,49转换成二进制就是110001)
00110001
getbit bitmaps_test 2 (获取到结果为1)
get bitmaps_test 3 (获取到结果为1)
get bitmaps_test 5 (获取到结果为0)
get bitmaps_test 7 (获取到结果为1)
setbit bitmaps_test 6 1
get bitmaps_test (获取到结果为3,因为我们将第7位改成了1,即00110011,转换成10进制就是51,查询ascii码表可得到它的值位3)
首先bitmap本质是String,String的最大长度为512m,所以它可以表示2^32=4294967296个不同的位。基本不用担心位数不够的问题。
-
利用bitmaps实现点赞功能
当我们不需要记录点赞顺序的情况下我们就可以使用bitmap优雅的实现,我们使用不同位对应用户ID,当ID为10000的用户点赞了,我门就可以将offset为10000的位设置为1来标记当前点赞用户。当我们需要统计点赞总数时只需要使用bitcount 统计出所有为1的数即可实现。
-
利用bitmaps实现统计任意时间窗口登录用户数(统计日活、月活) (说明:8月8日id为1和2的都登录了,8月9日id为1的登录了,统计这两天登录的用户数我们利用一个并集就可以了。)