redis命令/使用场景

支持五种数据类型:

*   string(字符串)
*   hash(哈希) =》 散列表 O(1)
*   list(列表) =》 双向链表 (两端O(1),查询O(n)
*   set(集合) =》 值为空的hash table  散列表 ,所有 O(1)
*   zset(sorted set:有序集合)  =》  散列表 O(1)+ 跳跃表  O ( logN) 

命令参考:
http://redisdoc.com/index.html
使用场景:
https://www.cnblogs.com/yy1234/p/7809551.html
redis过期策略:https://blog.csdn.net/xiangnan129/article/details/54928672

  • Redis进阶不得不了解的内存优化细节:https://cloud.tencent.com/developer/article/1162213

  • 把Redis当作队列来用,真的合适吗?:https://www.51cto.com/article/659208.html

String

String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。
常规key-value缓存应用;
常规计数:微博数,粉丝数等。

SET key value
SETNX key value   只有在 key 不存在时设置 key 的值。
SETEX key seconds value  将值 value 关联到 key ,并将 key 的过期时间设为 seconds 
PSETEX key milliseconds value  和 SETEX 命令相似,但它以毫秒为单位
MSET key value [key value ...]
GET key
MGET key1 [key2..]

INCR key
INCRBY key increment
DECR key
DECRBY key decrement

hash

Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
存储部分变更的数据,如用户信息等。

HSET  key  field  value
HMSET  key  field1  value1  [field2  value2 ]
HSETNX   key   field  value
HINCRBY key field increment

HEXISTS key field
HGET key field
HMGET key field1 [field2]
HGETALL key

HLEN key
HDEL key field1 [field2]

list

每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部添加或者删除元素,这样List即可以作为栈,也可以作为队列。

lpush/rpush key value [value…]
lpop/rpop key
llen key
lrange key start stop  左开右也开,和js不同 ,-1表示倒数第一个
lindex key index
lset key index value
ltrim key start end  保留指定片段, 左开右也开同lrange
  1. 取最新N个数据的操作
    //把当前登录人添加到链表里
    ret = r.lpush("login:last_login_times", uid)
    //保持链表只有N位
    ret = redis.ltrim("login:last_login_times", 0, N-1)
    //获得前N个最新登陆的用户Id列表
    last_login_list = r.lrange("login:last_login_times", 0, N-1)

  2. 消息队列系统
    使用list可以构建队列系统,使用sorted set甚至可以构建有优先级的队列系统。
    比如:将Redis用作日志收集器
    实际上还是一个队列,多个端点将日志信息写入Redis,然后一个worker统一将所有日志写到磁盘。

set

set就是一个集合,集合的概念就是一堆不重复值的组合。set中的元素是没有顺序的。

sadd key member [member …]
srem key member [member …]
smembers key  列举所有
ismember key member  是否成员
sdiff  key [key..] 差集  =》 sdiffstore destkey  key [key…]  差集并存储在destkey
sinter key [key ..] 交集  ...
sunion key [key..] 并集  ...
scard key  个数
spop key 随机弹出一个
srandmember key [count]随机取n个元素

案例:

  1. 在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。
    可以非常方便的实现如共同关注、共同喜好、二度好友等功能
    交集,并集,差集
    //即属于ruby又属于web的书?
    inter_list = redis.sinter("tag:web", "tag:ruby")
    //即属于ruby,但不属于web的书?
    diff_list = redis.sdiff("tag:ruby", "tag:web")
    //属于ruby和属于web的书的合集?
    union_list = redis.sunion("tag:ruby", "tag:web”)

  2. 获取某段时间所有数据去重值
    这个使用Redis的set数据结构最合适了,只需要不断地将数据往set中扔就行了,set意为集合,所以会自动排重。

sorted set

和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。zset使用了两种不同的存储结构,分别是 zipList(压缩列表)和 skipList(跳跃列表)

zipList(压缩列表)

当 zset 满足以下条件时,使用压缩列表:
1、成员的数量小于128 个;
2、每个 member (成员)的字符串长度都小于 64 个字节。


image.png

当 zset 使用压缩列表保存数据时,entry 的第一个节点保存 member,第二个节点保存 score。依次类推,集合中的所有成员最终会按照 score 从小到大排列。

skipList(跳跃列表)

底层是一个命名为zset的结构体,而一个zset结构同时包含一个字典和一个跳跃表。跳跃表按score从小到大保存所有集合元素。而字典则保存着从member到score的映射,这样就可以用O(1)的复杂度来查找member对应的score值。
插入、删除、查找的复杂度均为O(logN)

/*
 * 有序集合
 */
typedef struct zset {

    // 字典,键为成员,值为分值
    // 用于支持 O(1) 复杂度的按成员取分值操作
    dict *dict;

    // 跳跃表,按分值排序成员
    // 用于支持平均复杂度为 O(log N) 的按分值定位成员操作
    // 以及范围操作
    zskiplist *zsl;

} zset;
zadd key score member [score member … ]  增加member,重复这条命令(不同score) 可以修改member的score
zincrby key incr member  对指定成员的分数加上增量 increment
ZCARD key  返回集合的成员数
ZCOUNT key min max  返回区间分数的成员数 
zscore  key member  返回有序集中,成员的分数值
zrank/zrevrank key member   返回有序集合中指定成员的索引
ZREM key member [member ...]  移除有序集合中的一个或多个成员
ZREMRANGEBYRANK key start stop    按照排名范围删除元素
ZREMRANGEBYSCORE key min max  按照分数范围删除元素

zrange/zrevrange key start stop [withscores]  根据元素score从小到大顺序返回索引从start到stop之间所有元素(包含两端)
      等价: `select * from where id>=start  and id<=stop  order by id asc|desc`
zrangebyscore/zrevrangebyscore  key min max [withscores]  [limit offset count]  根据score分数范围 查member列表
      等价: `select * from where score>=min  and score<=max  order by score asc|desc`
  1. 排行榜应用,取TOP N操作
    将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即可。
    //将登录次数和用户统一存储在一个sorted set里
    zadd login:login_times 5 1
    zadd login:login_times 1 2
    zadd login:login_times 2 3
    //当用户登录时,对该用户的登录次数自增1
    ret = r.zincrby("login:login_times", 1, uid)
    //那么如何获得登录次数最多的用户呢,逆序排列取得排名前N的用户
    ret = r.zrevrange("login:login_times", 0, N-1)

  2. 比如在线游戏的排行榜,根据得分你通常想要:

    • 列出前100名高分选手
    • 列出某用户当前的全球排名
      模式是这样的,每次获得新得分时,我们用这样的代码:
      ZADD leaderboard
      得到前100名高分用户很简单:
      ZREVRANGE leaderboard 0 99
      用户的全球排名也相似,只需要:
      ZRANK leaderboard
      需要精准设定过期时间的应用
  3. 比如你可以把上面说到的sorted set的score值设置成过期时间的时间戳,那么就可以简单地通过过期时间排序,定时清除过期数据了,
    不仅是清除Redis中的过期数据,你完全可以把Redis里这个过期时间当成是对数据库中数据的索引,用Redis来找出哪些数据需要过期删除,然后再精准地从数据库中删除相应的记录。

  4. 范围查找
    他有一个IP范围对应地址的列表,现在需要给出一个IP的情况下,迅速的查找到这个IP在哪个范围,也就是要判断此IP的所有地。
    这个问题引来了Redis作者Salvatore Sanfilippo(@antirez)的回答。解答如下:
    例如有下面两个范围,10-20和30-40

  • A_start 10, A_end 20
  • B_start 30, B_end 40
    我们将这两个范围的起始位置存在Redis的sorted set数据结构中,基本范围起始值作为score,范围名加start和end为其value值:

redis 127.0.0.1:6379> zadd ranges 10 A_start
redis 127.0.0.1:6379> zadd ranges 20 A_end
redis 127.0.0.1:6379> zadd ranges 30 B_start
redis 127.0.0.1:6379> zadd ranges 40 B_end

这样数据在插入sorted set后,相当于是将这些起始位置按顺序排列好了。
现在我需要查找15这个值在哪一个范围中,只需要进行如下的zrangbyscore查找:
redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1

  1. "A_end"
    这个命令的意思是在Sorted Sets中查找大于15的第一个值。(+inf在Redis中表示正无穷大,15前面的括号表示>15而非>=15)

查找的结果是A_end,由于所有值是按顺序排列的,所以可以判定15是在A_start到A_end区间上,也就是说15是在A这个范围里。至此大功告成。
当然,如果你查找到的是一个start,比如咱们用25,执行下面的命令:
redis 127.0.0.1:6379> zrangebyscore ranges (25 +inf LIMIT 0 1

  1. "B_start"
    返回结果表明其下一个节点是一个start节点,也就是说25这个值不处在任何start和end之间,不属于任何范围。

当然,这个例子仅适用于类似上面的IP范围查找的案例,因为这些值范围之间没有重合。如果是有重合的情况,这个问题本身也就变成了一个一对多的问题。

Pub/Sub

Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。

使用场景
Pub/Sub构建实时消息系统

Redis实现访问频率限制 :
https://segmentfault.com/a/1190000004287708

Redis各种命令时间复杂度一览表
https://blog.csdn.net/qq_23564667/article/details/110917900

Redis集群详解

https://blog.csdn.net/miss1181248983/article/details/90056960/

Redis有三种集群模式,分别是:

  • 主从模式
  • Sentinel模式
  • Cluster模式

你可能感兴趣的:(redis命令/使用场景)