3、redis 十大数据类型

3. redis 十大数据类型

3.1 十大数据类型及命令介绍

3.1.1 redis字符串(String)

Redis Strings | Redis

  • string是redis最基本的类型,一个key对应一个value。
  • string类型是二进制安全的,意思是redis的string可以包含任何数据,比如jpg图片或者序列化的对象。
  • string类型是redis最基本的数据类型,一个redis中字符串value最多可以是512M。
  1. SET

    SET命令支持一组修改其行为的选项:

    x 1SET key value [NX | XX] [GET] [EX seconds | PX milliseconds |2  EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]
    
  • EX --以秒为单位设置指定的过期时间。(秒)

    127.0.0.1:6379> set k1 v1 ex 10
    OK
    127.0.0.1:6379> ttl k1
    (integer) 8
    127.0.0.1:6379> ttl k1
    (integer) 7
    
  • PX 毫秒 --设置指定的过期时间,以毫秒为单位。

    127.0.0.1:6379> set k1 v1 px 8000
    OK
    127.0.0.1:6379> ttl k1
    (integer) 6
    
  • EXAT timestamp-seconds --设置密钥将过期的指定Unix时间,以秒为单位。

    获得设置指定的Key过期的Unix时间,单位为秒:

    System.out.println(Long.toString(System.currentTimeMillis()/1000L))
    
    127.0.0.1:6379> set k1 v1 exat 1681559200
    OK
    127.0.0.1:6379> ttl k1
    (integer) 57
    127.0.0.1:6379> ttl k1
    (integer) 54
    
  • PXAT timestamp-milliseconds --设置密钥将过期的指定Unix时间,以毫秒为单位。

  • NX --仅在密钥不存在时设置该密钥。

  • XX --仅在密钥已经存在时设置该密钥。

    127.0.0.1:6379> set k1 v1 nx
    OK
    127.0.0.1:6379> get k1
    "v1"
    127.0.0.1:6379> set k1 v1 nx
    (nil)
    127.0.0.1:6379> set k1 v1xx xx
    OK
    
  • KEEPTTL --保留与密钥关联的生存时间。

    127.0.0.1:6379> set k1 v1 ex 60
    OK
    127.0.0.1:6379> ttl k1
    (integer) 58
    127.0.0.1:6379> set k1 v1keepttl keepttl
    OK
    127.0.0.1:6379> ttl k1
    (integer) 37
    
  • GET --返回key处存储的旧字符串,如果key不存在则返回nil。将返回一个错误 SET如果key处存储的值不是字符串,则中止。

    127.0.0.1:6379> set k1 v1 get
    "v1xx"
    127.0.0.1:6379> get k1
    "v1"
    
  1. MSET , MGET , MSETNX

    同时设置获取多个键值mset,mget,msetnx

    127.0.0.1:6379> set k1 v1
    OK
    127.0.0.1:6379> set k2 v2
    OK
    127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3
    OK
    127.0.0.1:6379> mget k1 k2 k3
    1) "v1"
    2) "v2"
    3) "v3"
    127.0.0.1:6379> MSETNX k1 v1 k4 v4
    (integer) 0
    127.0.0.1:6379> MSETNX k5 v5 k6 v6
    (integer) 1
    27.0.0.1:6379> mget k1 k2 k3 k5
    1) "v1"
    2) "v2"
    3) "v3"
    4) "v5"
    
  2. GETRANGE, SETRANGE

    获取指定区间范围内的值:

    127.0.0.1:6379> set k1 abcd1234
    OK
    127.0.0.1:6379> GETRANGE k1 0 -1
    "abcd1234"
    127.0.0.1:6379> GETRANGE k1 0 3
    "abcd"
    127.0.0.1:6379> SETRANGE k1 1 xxyy
    (integer) 8
    127.0.0.1:6379> get k1
    "axxyy234"
    
  3. INCR, INCRBY, DECR, DECRBY

    数值增减(一定是数字才能进行加减):

  • 增加数字

    127.0.0.1:6379> set k1 100
    OK
    127.0.0.1:6379> get k1
    "100"
    127.0.0.1:6379> INCR k1
    (integer) 101
    127.0.0.1:6379> INCR k1
    (integer) 102
    127.0.0.1:6379> INCR k1
    (integer) 103
    127.0.0.1:6379> INCR k1
    (integer) 104
    
  • 增加指定的整数

    127.0.0.1:6379> INCRBY k1 3
    (integer) 107
    127.0.0.1:6379> INCRBY k1 3
    (integer) 110
    127.0.0.1:6379> INCRBY k1 3
    (integer) 113
    
  • 递减数值

    127.0.0.1:6379> DECR k1
    (integer) 112
    127.0.0.1:6379> DECR k1
    (integer) 111
    127.0.0.1:6379> DECR k1
    (integer) 110
    
  • 减少指定的整数

    127.0.0.1:6379> DECRBY k1 3
    (integer) 107
    127.0.0.1:6379> DECRBY k1 3
    (integer) 104
    127.0.0.1:6379> DECRBY k1 3
    (integer) 101
    
  1. SERLEN,APPEND

    获取字符串长度和内容追加:

    127.0.0.1:6379> set k1 abcd
    OK
    127.0.0.1:6379> STRLEN k1
    (integer) 4
    127.0.0.1:6379> append k1 xxxx
    (integer) 8
    127.0.0.1:6379> get k1
    "abcdxxxx"
    
  2. 分布式锁

    127.0.0.1:6379> set k1 v1 
    OK
    127.0.0.1:6379> EXPIRE k1 10
    (integer) 1
    127.0.0.1:6379> ttl k1
    (integer) 7
    127.0.0.1:6379> SETEX k1 10 v1
    OK
    127.0.0.1:6379> ttl k1
    (integer) 6
    127.0.0.1:6379> SETNX k1 v11
    (integer) 1
    127.0.0.1:6379> get k1
    "v11"
    127.0.0.1:6379> SETNX k1 v11
    (integer) 0
    
  3. GETSET(先getset

    127.0.0.1:6379> GETSET k1 haha
    "v11"
    127.0.0.1:6379> get k1
    "haha"
    127.0.0.1:6379> set k1 v1 get
    "haha"
    127.0.0.1:6379> get k1
    "v1"
    

应用场景:

  • 抖音无限点赞某个视频或商品,点一下加一次

  • 是否喜欢的文章

3.1.2 redis列表(List)

Redis List | Redis

  • Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),它的底层实际是个双端列表
  • 最多可包含2^32-1个元素。
  • 主要功能有push/pop等,一般用在栈、队列、消息队列等场景。

常用:

  1. lpush/rpush/lrange

    127.0.0.1:6379> lpush list 1 2 3 4 5
    (integer) 5
    127.0.0.1:6379> rpush list2 11 22 33 44 55
    (integer) 5
    127.0.0.1:6379> TYPE list
    list
    127.0.0.1:6379> LRANGE list 0 -1
    1) "5"
    2) "4"
    3) "3"
    4) "2"
    5) "1"
    127.0.0.1:6379> LRANGE list2 0 -1
    1) "11"
    2) "22"
    3) "33"
    4) "44"
    5) "55"
    
  2. lpop/rpop

    127.0.0.1:6379> LPOP list 
    "5"
    127.0.0.1:6379> RPOP list
    "1"
    
  3. lindex

    按照索引下标获得元素(从上到下)

    127.0.0.1:6379> LINDEX list 0
    "4"
    127.0.0.1:6379> LINDEX list 2
    "2"
    
  4. llen

    获取列表中元素个数

    127.0.0.1:6379> LLEN list
    (integer) 3
    127.0.0.1:6379> LLEN list2
    (integer) 5
    
  5. lrem

    删除N个值等于V1的元素

    127.0.0.1:6379> LRANGE list 0 -1
     1) "5"
     2) "4"
     3) "3"
     4) "3"
     5) "2"
     6) "2"
     7) "2"
     8) "1"
     9) "1"
    10) "1"
    11) "1"
    12) "4"
    13) "3"
    14) "2"
    127.0.0.1:6379> LREM list 3 1
    (integer) 3
    127.0.0.1:6379> LRANGE list 0 -1
     1) "5"
     2) "4"
     3) "3"
     4) "3"
     5) "2"
     6) "2"
     7) "2"
     8) "1"
     9) "4"
    10) "3"
    11) "2"
    
  6. ltrim

    截取指定范围的值后再赋值给key

    127.0.0.1:6379> LTRIM list 4 7
    OK
    127.0.0.1:6379> LRANGE list 0 -1
    1) "2"
    2) "2"
    3) "2"
    4) "1"
    
  7. rpoplpush

    127.0.0.1:6379> LRANGE list 0 -1
    1) "2"
    2) "2"
    3) "2"
    4) "1"
    127.0.0.1:6379> LRANGE list2 0 -1
    1) "11"
    2) "22"
    3) "33"
    4) "44"
    5) "55"
    127.0.0.1:6379> RPOPLPUSH list list2
    "1"
    127.0.0.1:6379> LRANGE list 0 -1
    1) "2"
    2) "2"
    3) "2"
    127.0.0.1:6379> LRANGE list2 0 -1
    1) "1"
    2) "11"
    3) "22"
    4) "33"
    5) "44"
    6) "55"
    
  8. lset

    127.0.0.1:6379> LSET list 1 mysql
    OK
    127.0.0.1:6379> LRANGE list 0 -1
    1) "2"
    2) "mysql"
    3) "2"
    
  9. linsert key before/after 已有值 插入的新值

    127.0.0.1:6379> LINSERT list before mysql java
    (integer) 4
    127.0.0.1:6379> LRANGE list 0 -1
    1) "2"
    2) "java"
    3) "mysql"
    4) "2"
    

应用场景:

  • 微信公众号订阅的消息
3.1.3 redis哈希表(Hash)
  • Redis hash 是一个 string 类型的 field(字段)和value(值)的映射表,hash特别适合用于存储对象。
  • 可以存储2^32-1键值对。

常用:

  1. HSET 设置散列上一个或多个字段的值。

  2. HGET 返回给定字段的值。

  3. HMGET 返回一个或多个给定字段的值。

  4. HMGET/HGETALL/HDEL

    127.0.0.1:6379> HSET user:001 id 11 name zs age 25
    (integer) 3
    127.0.0.1:6379> HGET user:001 id
    "11"
    127.0.0.1:6379> HGET user:001 name
    "zs"
    127.0.0.1:6379> HMSET user:001 id 12 name 1s age 26
    OK
    127.0.0.1:6379> HMGET user:001 id name age
    1) "12"
    2) "1s"
    3) "26"
    127.0.0.1:6379> HGETALL user:001
    1) "id"
    2) "12"
    3) "name"
    4) "1s"
    5) "age"
    6) "26"
    127.0.0.1:6379> HDEL user:001 age
    (integer) 1
    127.0.0.1:6379> HGETALL user:001
    1) "id"
    2) "12"
    3) "name"
    4) "1s"
    
  5. hlen

    127.0.0.1:6379> HLEN user:001
    (integer) 2
    
  6. hexists key

    在key里面的某个值的key

    127.0.0.1:6379> HEXISTS user:001 name
    (integer) 1
    127.0.0.1:6379> HEXISTS user:001 age
    (integer) 0
    
  7. hkeys/hvals

    127.0.0.1:6379> HKEYS user:001
    1) "id"
    2) "name"
    127.0.0.1:6379> HVALS user:001
    1) "12"
    2) "1s"
    
  8. HINCRBY/hincrbyfloat 按提供的整数递增给定字段的值。

    127.0.0.1:6379> HSET user:001 age 25 score 99.5
    (integer) 2
    127.0.0.1:6379> HGETALL user:001
    1) "id"
    2) "12"
    3) "name"
    4) "1s"
    5) "age"
    6) "25"
    7) "score"
    8) "99.5"
    127.0.0.1:6379> HINCRBYFLOAT user:001 score 0.5
    "100"
    127.0.0.1:6379> HINCRBYFLOAT user:001 score 0.5
    "100.5"
    127.0.0.1:6379> HINCRBYFLOAT user:001 score 0.5
    "101"
    127.0.0.1:6379> HINCRBY user:001 age 1
    (integer) 26
    127.0.0.1:6379> HINCRBY user:001 age 1
    (integer) 27
    
  9. hsetnx

    不存在赋值,存在无效

    127.0.0.1:6379> HSETNX user:001 email zzyybs@126.com
    (integer) 1
    127.0.0.1:6379> HSETNX user:001 email zzyybs@126.com
    (integer) 0
    

应用场景:

  • JD购物车早期设计,目前不再采用,当前小中厂可用。
3.1.4 redis集合(Set)
  • Redis 的 Set 是 String 类型的 无序集合。集合成员是唯一的,这意味着集合中不能出现重复的数据。集合对象的编码可以是 intset 或者 hashtable。
  • Redis 的 Set 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
  • 集合的最大成员数为2^32-1。
  1. sadd key member[member...]:添加元素

    127.0.0.1:6379> SADD set1 1 1 1 2 2 2 3 3 4 4 5 
    (integer) 5
    
  2. smembers key:遍历集合中所有元素

    127.0.0.1:6379> SMEMBERS set1
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    
  3. sismember key member:判断元素是否在集合中

    127.0.0.1:6379> SISMEMBER set1 1
    (integer) 1
    127.0.0.1:6379> SISMEMBER set1 0
    (integer) 0
    
  4. scard:获取集合里元素个数

    127.0.0.1:6379> SREM set1 y
    (integer) 0
    127.0.0.1:6379> SREM set1 1
    (integer) 1
    127.0.0.1:6379> SMEMBERS set1
    1) "2"
    2) "3"
    3) "4"
    4) "5"
    127.0.0.1:6379> SCARD set1
    (integer) 4
    
  5. srandmember key[数字]:从集合里随机展现设置的数字个数,元素不删除

    127.0.0.1:6379> SRANDMEMBER set1 1
    1) "6"
    127.0.0.1:6379> SRANDMEMBER set1 3
    1) "4"
    2) "8"
    3) "5"
    127.0.0.1:6379> SMEMBERS set1
    1) "1"
    2) "2"
    3) "3"
    4) "4"
    5) "5"
    6) "6"
    7) "7"
    8) "8"
    
  6. spop 数字:从集合中随机弹出一个元素,出一个删一个

    127.0.0.1:6379> SPOP set1 1
    1) "3"
    127.0.0.1:6379> SPOP set1 2
    1) "7"
    2) "4"
    127.0.0.1:6379> SMEMBERS set1
    1) "1"
    2) "2"
    3) "5"
    4) "6"
    5) "8"
    
  7. smove key1 key2: 将key1里存在的某个值赋给key2

    127.0.0.1:6379> SMOVE set1 stet2 5
    (integer) 1
    127.0.0.1:6379> SMEMBERS set1 
    1) "1"
    2) "2"
    3) "6"
    4) "8"
    127.0.0.1:6379> SMEMBERS stet2
    1) "5"
    
  8. 集合运算:差集、并集、交集

    127.0.0.1:6379> SADD set1 a b c 1 2 
    (integer) 5
    127.0.0.1:6379> SADD set2 1 2 3 a x
    (integer) 5
    127.0.0.1:6379> SDIFF set1 set2
    1) "b"
    2) "c"
    127.0.0.1:6379> SDIFF set2 set1
    1) "x"
    2) "3"
    127.0.0.1:6379> SUNION set1 set2
    1) "c"
    2) "2"
    3) "3"
    4) "a"
    5) "1"
    6) "b"
    7) "x"
    127.0.0.1:6379> SINTER set1 set2
    1) "2"
    2) "a"
    3) "1"
    127.0.0.1:6379> SINTERCARD 2 set1 set2
    (integer) 3
    

应用场景:

  • 微信抽奖小程序
  • 微信朋友圈点赞查看同赞朋友
  • QQ内推可能认识的人
3.1.5 redis有序集合(ZSet)
  • Redis zsetset一样也是 string类型元素的集合,且不容许重复的成员。
  • 不同的是每个成员都会关联一个double类型的分数,redis正是通过分数来为集合中的成员进行从小到大排序。
  • zset成员是为一个的,但分数(score)却可以重复。
  • zset集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
  • 集合的最大成员数为2^32-1。
  • 在 set 基础上,每个 val 值前加一个 score 分数值。之前的 set 是k1 v1 v2 v3,现在 zsetk1 score1 v1 score2 v2
  1. zadd key score member[score member...]:向有序集合中加入一个元素和该元素的分数

    127.0.0.1:6379> ZADD zset1 60 v1 70 v2 80 v3 90 v4 100 v5
    (integer) 5
    
  2. zrange key start stop [withscores]:按照分数从小到大的顺序返回索引从startstop之间所有元素

    127.0.0.1:6379> ZRANGE zset1 0 -1
    1) "v1"
    2) "v2"
    3) "v3"
    4) "v4"
    5) "v5"
    127.0.0.1:6379> ZRANGE zset1 0 -1 withscores
     1) "v1"
     2) "60"
     3) "v2"
     4) "70"
     5) "v3"
     6) "80"
     7) "v4"
     8) "90"
     9) "v5"
    10) "100"
    
  3. zrevrange

    127.0.0.1:6379> ZREVRANGE zset1 0 -1 withscores
     1) "v5"
     2) "100"
     3) "v4"
     4) "90"
     5) "v3"
     6) "80"
     7) "v2"
     8) "70"
     9) "v1"
    10) "60"
    
  4. zrangebyscore key min max [withscores] [limit offset count]:获取指定分数范围的元素

    127.0.0.1:6379> ZRANGEBYSCORE zset1 60 90
    1) "v1"
    2) "v2"
    3) "v3"
    4) "v4"
    127.0.0.1:6379> ZRANGEBYSCORE zset1 60 90 withscores
    1) "v1"
    2) "60"
    3) "v2"
    4) "70"
    5) "v3"
    6) "80"
    7) "v4"
    8) "90"
    127.0.0.1:6379> ZRANGEBYSCORE zset1 (60 90 withscores
    1) "v2"
    2) "70"
    3) "v3"
    4) "80"
    5) "v4"
    6) "90"
    127.0.0.1:6379> ZRANGEBYSCORE zset1 (60 90 withscores limit 0 1
    1) "v2"
    2) "70"
    127.0.0.1:6379> ZRANGEBYSCORE zset1 (60 90 withscores limit 0 2
    1) "v2"
    2) "70"
    3) "v3"
    4) "80"
    
  5. zscore key member:获取元素的分数

    127.0.0.1:6379> ZSCORE zset1 v5
    "100"
    
  6. zcard key:获取集合中元素的数量

    127.0.0.1:6379> ZCOUNT zset1 60 100
    (integer) 4
    127.0.0.1:6379> ZCOUNT zset1 65 79
    (integer) 1
    
  7. zrem key:某score下对应的value值,作用是删除元素

    127.0.0.1:6379> ZREM zset1 v5 
    (integer) 1
    127.0.0.1:6379> ZREM zset1 v5 
    (integer) 0
    127.0.0.1:6379> ZRANGE zset1 0 -1 withscores
    1) "v1"
    2) "60"
    3) "v2"
    4) "70"
    5) "v3"
    6) "80"
    7) "v4"
    8) "90"
    
  8. zincrby key increment member:增加某个元素分数

    127.0.0.1:6379> ZINCRBY zset1 3 v1
    "63"
    127.0.0.1:6379> ZRANGE zset1 0 -1 withscores
    1) "v1"
    2) "63"
    3) "v2"
    4) "70"
    5) "v3"
    6) "80"
    7) "v4"
    8) "90"
    
  9. zmpop:从键名列表中第一个非空排列集中弹出一个或多个元素,它们是成员分数对

    127.0.0.1:6379> ZMPOP 1 zset1 min count 1
    1) "zset1"
    2) 1) 1) "v1"
          2) "63"
    
  10. zrank:获取下标值

    127.0.0.1:6379> ZRANK zset1 v2
    (integer) 0
    
  11. zrevrank : 逆序获取下标值

    127.0.0.1:6379> ZREVRANK zset1 v2
    (integer) 2
    

对应场景:

  • 根据商品销售对商品进行排序显示
3.1.6 redis地理空间(GEO)
  • 经纬度
  1. geoadd

    127.0.0.1:6379> GEOADD city 116.403963 39.915119 "天安门" 116.403414 39.924091 "故宫" 116.024067 40.362639 "长城"
    (integer) 3
    127.0.0.1:6379> type city
    zset
    127.0.0.1:6379> ZRANGE city 0 -1
    1) "\xe5\xa4\xa9\xe5\xae\x89\xe9\x97\xa8"
    2) "\xe6\x95\x85\xe5\xae\xab"
    3) "\xe9\x95\xbf\xe5\x9f\x8e"
    127.0.0.1:6379> quit
    [root@hadoop100 myredis]# redis-cli -a www.123.com --raw
    Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    127.0.0.1:6379> ZRANGE city 0 -1
    天安门
    故宫
    长城
    
  2. geopos

    127.0.0.1:6379> GEOPOS city 天安门 故宫 长城
    116.40396326780319214
    39.91511970338637383
    116.40341609716415405
    39.92409008156928252
    116.02406591176986694
    40.36263993239462167
    
  3. geohash:算法生成的base32编码值,3维变维变1维(经纬度坐标)

    127.0.0.1:6379> GEOHASH city 天安门 故宫 长城
    wx4g0f6f2v0
    wx4g0gfqsj0
    wx4t85y1kt0
    
  4. geodist:(两个位置间距离)

    127.0.0.1:6379> GEODIST city 天安门 故宫 km
    0.9988
    127.0.0.1:6379> GEODIST city 天安门 故宫 m
    998.8332
    
  5. georadius:以半径为中心查找附近的xxx

    127.0.0.1:6379> GEORADIUS city 116.418017 39.914402 10 km withdist withcoord withhash count 10 desc
    故宫
    1.6470
    4069885568908290
    116.40341609716415405
    39.92409008156928252
    天安门
    1.2016
    4069885555089531
    116.40396326780319214
    39.91511970338637383
    
3.1.7 redis基数统计(HyperLogLog)
  • 统计某个网站的UV,统计某个文章的UV(Unique Visitor,独立访客,一般理解为客户端IP)。

  • HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定且是很小的。

  • 在redis里,每个hyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

  • 但是,因为HyperLogLog只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog不能像集合那样,返回输入的各个元素。

  1. pfadd key element[element...]:添加指定元素到HyperLogLog

    127.0.0.1:6379> PFADD hll01 1 3 5 7 9
    (integer) 1
    127.0.0.1:6379> PFADD hll02 1 2 4 4 4 5 9 10
    (integer) 1
    
  2. pfcount key:返回给定HyperLogLog的基数估算值

    127.0.0.1:6379> PFCOUNT hll01
    (integer) 5
    127.0.0.1:6379> PFCOUNT hll02
    (integer) 6
    
  3. pfmerge destkey sourcekey [sourcekey]:将多个HyperLogLog合并为一个HyperLogLog

    127.0.0.1:6379> PFMERGE hllresult hll01 hll02
    OK
    127.0.0.1:6379> PFCOUNT hllresult
    (integer) 8
    
3.1.8 redis位图(bitmap)
  • 由0和1状态表现的二进制位的bit数组。
  • (能干什么)用于状态记录
  • 偏移量从0开始
  1. setbit key offset val:给指定key的值的第offset赋值val,时间复杂度O(1).

    127.0.0.1:6379> SETBIT k1 1 1 
    (integer) 1
    127.0.0.1:6379> SETBIT k1 2 1 
    (integer) 1
    127.0.0.1:6379> SETBIT k1 3 0
    (integer) 1
    127.0.0.1:6379> type k1
    string
    
  2. getbit key offset:获取指定key的第offset位,时间复杂度O().

    127.0.0.1:6379> GETBIT k1 0
    (integer) 0
    127.0.0.1:6379> GETBIT k1 1
    (integer) 1
    127.0.0.1:6379> GETBIT k1 2
    (integer) 1
    127.0.0.1:6379> GETBIT k1 3
    (integer) 0
    
  3. strlen:统计字节数占多少

    不是字符串长度,而是所占字节,超过8位后,按照8位一组一byte再扩充。

    127.0.0.1:6379> SETBIT k2 0 1
    (integer) 0
    127.0.0.1:6379> SETBIT k2 7 1
    (integer) 0
    127.0.0.1:6379> STRLEN k2
    (integer) 1
    127.0.0.1:6379> SETBIT k2 8 1
    (integer) 0
    127.0.0.1:6379> STRLEN k2
    (integer) 2
    
  4. bitcount key start end:返回指定key中的[start, end]中为1 的数量,时间复杂度O(n).

    127.0.0.1:6379> SETBIT uid:login123 1 1
    (integer) 0
    127.0.0.1:6379> SETBIT uid:login123 2 1
    (integer) 0
    127.0.0.1:6379> SETBIT uid:login123 3 1
    (integer) 0
    127.0.0.1:6379> BITCOUNT uid:login123
    (integer) 3
    
  5. bitop operation destkey key:对不同的二进制存储数据进行位运算(AND\OR\NOT\XOR),时间复杂度O(n).

    127.0.0.1:6379> HSET uid:map 0 uid-092iok-lkj
    (integer) 1
    127.0.0.1:6379> HSET uid:map 1 uid-7388c-xxx
    (integer) 1
    127.0.0.1:6379> HGETALL uid:map
    1) "0"
    2) "uid-092iok-lkj"
    3) "1"
    4) "uid-7388c-xxx"
    127.0.0.1:6379> SETBIT 20230420 0 1
    (integer) 0
    127.0.0.1:6379> SETBIT 20230420 1 1 
    (integer) 0
    127.0.0.1:6379> GETBIT 20230420 0
    (integer) 1
    127.0.0.1:6379> SETBIT 20230420 2 1 
    (integer) 0
    127.0.0.1:6379> SETBIT 20230420 3 1 
    (integer) 0
    127.0.0.1:6379> SETBIT 20230421 0 1 
    (integer) 0
    127.0.0.1:6379> SETBIT 20230421 2 1
    (integer) 0
    127.0.0.1:6379> BITCOUNT 20230420
    (integer) 4
    127.0.0.1:6379> BITCOUNT 20230421
    (integer) 2
    127.0.0.1:6379> BITOP and k3 20230420 20230421
    (integer) 1
    127.0.0.1:6379> BITCOUNT k3
    (integer) 2
    

应用场景:

  • 用户登录多少天(签到、打卡)
3.1.9 redis位域(bitfield
  • 通过bitfield命令可以一次性操作多个比特位域(指的是连续的多个比特位),它会执行一系列操作并返回一个响应数组,这个数组中的元素对应参数列表中的相应操作的执行结果。
  • 通过bitfield命令我们可以一次性对多个比特位域进行操作。

ASCII码对照表

  1. bitfield key [get type offset]

    127.0.0.1:6379> set fieldkey hello
    OK
    127.0.0.1:6379> BITFIELD fieldkey get i8 0
    104
    127.0.0.1:6379> BITFIELD fieldkey get i8 8
    101
    127.0.0.1:6379> BITFIELD fieldkey get i8 16
    108
    
  2. bitfield key [set type offset value]

    127.0.0.1:6379> BITFIELD fieldkey set i8 8 120
    101
    127.0.0.1:6379> get fieldkey
    hxllo
    
  3. bitfield key [incrby type offset increment]

    127.0.0.1:6379> set fieldkey hello
    OK
    127.0.0.1:6379> BITFIELD fieldkey incrby u4 2 1 #从第2位开始,对接下来4位无符号数+1
    11
    127.0.0.1:6379> BITFIELD fieldkey incrby u4 2 1
    12
    127.0.0.1:6379> BITFIELD fieldkey incrby u4 2 1
    13
    127.0.0.1:6379> BITFIELD fieldkey incrby u4 2 1
    14
    127.0.0.1:6379> BITFIELD fieldkey incrby u4 2 1
    15
    127.0.0.1:6379> BITFIELD fieldkey incrby u4 2 1  #默认overflow为wrap,即循环溢出
    0
    
  4. 溢出控制overflow [wrap|sat|fail]

    • wrap:使用回绕(wrap around)方法处理有符号整数和无符号整数的溢出情况。
    • sat:使用饱和计算(saturation arithmetic)方法处理溢出,下溢计算结果为最小的整数值,而上溢的计算结果为最大的整数值。
    • fail:命令将拒绝执行那些会导致上溢或者下溢情况出现的计算,并向用户返回空值表示计算未执行。
    127.0.0.1:6379> set test a  #ascii码97
    OK
    127.0.0.1:6379> BITFIELD test get i8 0 #i8表示有符号的8位二进制数,范围(-128-127)
    97
    127.0.0.1:6379> BITFIELD test set i8 0 127
    97
    127.0.0.1:6379> BITFIELD test get i8 0
    127
    127.0.0.1:6379> get test
    
    127.0.0.1:6379> BITFIELD test set i8 0 138 #默认overflow为wrap,即循环溢出
    127
    127.0.0.1:6379> BITFIELD test get i8 0
    -118
    127.0.0.1:6379> BITFIELD test overflow sat set i8 0 128  #上溢
    -118
    127.0.0.1:6379> BITFIELD test get i8 0
    127
    127.0.0.1:6379> BITFIELD test overflow fail set i8 0 888
    (nil)
    
3.1.10 redis流(Stream)

Redis Streams | Redis

  • Redis Stream 是 Redis 5.0 版本增加的数据结构。
  • Redis Stream 主要用于消息队列(MQ,Message Queue),Redis本身是有一个Redis发布订阅(pub/sub)来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis宕机等,消息就会被丢弃。
  • 简单来说发布订阅(pub/sub)可以分发消息,但无法记录历史消息。
  • 而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻数据,并且记住每一个客户端的访问位置,还能保证消息不丢失。

队列相关指令:

  1. XADD 向流中添加新条目,如果指定Stream队列不存在,则该命令执行时会创建一个Stream队列。

    • 消息ID必须比上个ID大
    • 默认用*号表示自动生成规矩
    • *用于XADD命令中,让系统自动生成ID
    127.0.0.1:6379> XADD mystream * id 11 cname zs
    1681991364460-0
    127.0.0.1:6379> XADD mystream * id 22 cname ls
    1681991376583-0
    127.0.0.1:6379> XADD mystream * k1 v1 k2 v2 k3 v3 
    1681991401445-0  #生成的消息ID有两部分组成,毫秒时间戳-该毫秒内产生的第一条消息
    127.0.0.1:6379> XADD mystream 1681991401445-0 k1 v1 k2 v2 k3 v3 
    ERR The ID specified in XADD is equal or smaller than the target stream top item
    127.0.0.1:6379> type mystream
    stream
    
  2. XREAD 读取一个或多个条目,从给定的位置开始并在时间上向前移动。

    • 用于获取消息(阻塞/非阻塞),只会返回大于指定ID的消息

    • 非阻塞(BLOCK是否以阻塞的方式读取消息,默认不阻塞,如果,milliseconds设置为0,表示永远阻塞)

    • 阻塞

      127.0.0.1:6379> XREAD count 1 block 0 streams mystream $
      mystream
      1681994552433-0
      k9
      v9
      

      新开一个终端

      127.0.0.1:6379> XADD mystream * k9 v9
      "1681994552433-0"
      
    • $代表特殊ID,表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil

      127.0.0.1:6379> XREAD count 2 streams mystream $
      
      
    • 0-0代表从最小的ID开始获取Stream的消息,当不指定count,将会返回Stream中的所有消息,注意也可以使用0(00/000)也都是可以的。

      127.0.0.1:6379> XREAD count 2 streams mystream 0-0
      mystream
      1681992655414-0
      k2
      v2
      1681993110007-0
      k3
      v3
      k4
      v4
      k5
      v5
      127.0.0.1:6379> XREAD count 2 streams mystream 000
      mystream
      1681992655414-0
      k2
      v2
      1681993110007-0
      k3
      v3
      k4
      v4
      k5
      v5
      
  3. XRANGE 返回两个提供的条目ID之间的条目范围。

    127.0.0.1:6379> XRANGE mystream - +
    1681991364460-0
    id
    11
    cname
    zs
    1681991376583-0
    id
    22
    cname
    ls
    1681991401445-0
    k1
    v1
    k2
    v2
    k3
    v3
    
    127.0.0.1:6379> XRANGE mystream - + count 1
    1681991364460-0
    id
    11
    cname
    zs
    
  4. xrevrange

    127.0.0.1:6379> XREVRANGE mystream + 1
    1681991401445-0
    k1
    v1
    k2
    v2
    k3
    v3
    1681991376583-0
    id
    22
    cname
    ls
    1681991364460-0
    id
    11
    cname
    zs
    
  5. XLEN 返回流的长度。

    127.0.0.1:6379> XLEN mystream
    2
    
  6. xdel

    127.0.0.1:6379> XDEL mystream 1681991401445-0
    1
    
  7. xtrim

    127.0.0.1:6379> XADD mystream * k1 v1
    1681992648764-0
    127.0.0.1:6379> XADD mystream * k2 v2
    1681992655414-0
    127.0.0.1:6379> XRANGE mystream - +
    1681991364460-0
    id
    11
    cname
    zs
    1681991376583-0
    id
    22
    cname
    ls
    1681992648764-0
    k1
    v1
    1681992655414-0
    k2
    v2
    
    • 用于对Stream的长度进行截取,如超长会进行截取

    • MAXLEN允许的最大长度,对流进行修剪限制长度

      127.0.0.1:6379> XTRIM mystream maxlen 2
      2
      127.0.0.1:6379> XRANGE mystream - +
      1681992648764-0
      k1
      v1
      1681992655414-0
      k2
      v2
      
    • 允许的最小id,从某个id值开始比该id值小的将会抛弃

      127.0.0.1:6379> XTRIM mystream minid 1681992648764-0
      0
      127.0.0.1:6379> XTRIM mystream minid 1681992655414-0
      1
      127.0.0.1:6379> XRANGE mystream - +
      1681992655414-0
      k2
      v2
      

消费组相关指令:

  1. xgroup create:用于创建消费者组

    • $表示从Stream尾部开始消费
    • 0表示从Stream头部开始消费
    127.0.0.1:6379> XGROUP create mystream groupX $
    OK
    127.0.0.1:6379> XGROUP create mystream groupA 0
    OK
    
  2. xreadgroup group

    • >表示从第一条尚未被消费的消息开始读取

      127.0.0.1:6379> XGROUP create mystream groupb 0
      OK
      127.0.0.1:6379> XREADGROUP group groupA consumer1 streams mystream >
      1) 1) "mystream"
         2) 1) 1) "1681992655414-0"
               2) 1) "k2"
                  2) "v2"
            2) 1) "1681993110007-0"
               2) 1) "k3"
                  2) "v3"
                  3) "k4"
                  4) "v4"
                  5) "k5"
                  6) "v5"
            3) 1) "1681993142483-0"
               2) 1) "k6"
                  2) "v6"
            4) 1) "1681993282122-0"
               2) 1) "k7"
                  2) "v7"
            5) 1) "1681993288147-0"
               2) 1) "k8"
                  2) "v8"
            6) 1) "1681994552433-0"
               2) 1) "k9"
                  2) "v9"
      
    • 消费组groupA内的消费者consumer1mystream消息队列中读取所有消息

      127.0.0.1:6379> XREADGROUP group groupA consumer2 streams mystream >
      (nil)
      
    • 但是,不同消费组的消费者可以消费同一条消息

      127.0.0.1:6379> XREADGROUP group groupb consumer1 streams mystream >
      1) 1) "mystream"
         2) 1) 1) "1681992655414-0"
               2) 1) "k2"
                  2) "v2"
            2) 1) "1681993110007-0"
               2) 1) "k3"
                  2) "v3"
                  3) "k4"
                  4) "v4"
                  5) "k5"
                  6) "v5"
            3) 1) "1681993142483-0"
               2) 1) "k6"
                  2) "v6"
            4) 1) "1681993282122-0"
               2) 1) "k7"
                  2) "v7"
            5) 1) "1681993288147-0"
               2) 1) "k8"
                  2) "v8"
            6) 1) "1681994552433-0"
               2) 1) "k9"
                  2) "v9"
      127.0.0.1:6379> XREADGROUP group groupb consumer2 streams mystream >
      (nil)
      
    • 消费组的目的:让组内的多个消费者共同分担读取信息,所以,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的。

      127.0.0.1:6379> XGROUP create mystream groupc 0
      OK
      127.0.0.1:6379> XREADGROUP group groupc consumer1 count 2 streams mystream >
      1) 1) "mystream"
         2) 1) 1) "1681992655414-0"
               2) 1) "k2"
                  2) "v2"
            2) 1) "1681993110007-0"
               2) 1) "k3"
                  2) "v3"
                  3) "k4"
                  4) "v4"
                  5) "k5"
                  6) "v5"
      127.0.0.1:6379> XREADGROUP group groupc consumer2 count 2 streams mystream >
      1) 1) "mystream"
         2) 1) 1) "1681993142483-0"
               2) 1) "k6"
                  2) "v6"
            2) 1) "1681993282122-0"
               2) 1) "k7"
                  2) "v7"
      127.0.0.1:6379> XREADGROUP group groupc consumer3 count 2 streams mystream >
      1) 1) "mystream"
         2) 1) 1) "1681993288147-0"
               2) 1) "k8"
                  2) "v8"
            2) 1) "1681994552433-0"
               2) 1) "k9"
                  2) "v9"
      127.0.0.1:6379> XREADGROUP group groupc consumer4 count 2 streams mystream >
      (nil)
      
  3. 重点问题:

    基于Stream实现消息队列,如何保证消费者在发生故障或者宕机再次重启后,仍然可以读取未处理完的消息?

    • Streams会自动使用内部队列(也称为PENDING List)留存消费组里每个消费者读取的消息保底措施,直到消费者使用XACK命令通知Streams消息已经处理完成。
    • 消息确认增加了消息的可靠性,一般在业务处理完成之后,需要执行XACK命令确认消息已经被完成。
  4. xpending

    127.0.0.1:6379> XPENDING mystream groupc
    1) (integer) 6
    2) "1681992655414-0"
    3) "1681994552433-0"
    4) 1) 1) "consumer1"
          2) "2"
       2) 1) "consumer2"
          2) "2"
       3) 1) "consumer3"
          2) "2"
          
    127.0.0.1:6379> XPENDING mystream groupA
    1) (integer) 6
    2) "1681992655414-0"
    3) "1681994552433-0"
    4) 1) 1) "consumer1"
          2) "6"
    
  5. xack

    127.0.0.1:6379> XPENDING mystream groupc - + 10 consumer2  #ack签收之前2条
    1) 1) "1681993142483-0"
       2) "consumer2"
       3) (integer) 936115
       4) (integer) 1
    2) 1) "1681993282122-0"
       2) "consumer2"
       3) (integer) 936115
       4) (integer) 1
    127.0.0.1:6379> XACK mystream groupc 1681993142483-0  #ack成功确认返回1
    (integer) 1
    127.0.0.1:6379> XPENDING mystream groupc - + 10 consumer2 #ack签收过后一条
    1) 1) "1681993282122-0"
       2) "consumer2"
       3) (integer) 989652
       4) (integer) 1
    
  6. xinfo用于打印stream \consumer\group的详细信息

    127.0.0.1:6379> XINFO stream mystream
     1) "length"
     2) (integer) 6
     3) "radix-tree-keys"
     4) (integer) 1
     5) "radix-tree-nodes"
     6) (integer) 2
     7) "last-generated-id"
     8) "1681994552433-0"
     9) "max-deleted-entry-id"
    10) "1681991401445-0"
    11) "entries-added"
    12) (integer) 10
    13) "recorded-first-entry-id"
    14) "1681992655414-0"
    15) "groups"
    16) (integer) 4
    17) "first-entry"
    18) 1) "1681992655414-0"
        2) 1) "k2"
           2) "v2"
    19) "last-entry"
    20) 1) "1681994552433-0"
        2) 1) "k9"
           2) "v9"
    

使用建议:

  • Stream还是不能100%等价于Kafka、RabbitMQ来使用的,生产案例少,慎用。

3.2 命令查阅

3.3 Redis键(key)

Redis 中 Key(键)相关的命令

命令不区分大小写,key区分大小写.

帮助命令@类型:help @string

  • key* 查看当前库所有的key
  • exists key 判断某个key是否存在
  • type key 查看你的key是什么类型
  • del key 删除指定的key数据
  • unlike key 非阻塞删除,仅仅将key从keyspqce元数据中删除
  • ttl key 查看还有多少秒过期,-1表示永不过期,-2表示已过期
  • expire key 秒钟 为给定的key设置过期时间
  • move key dbindex[0-15] 将当前数据的key移动到给定的数据库db
127.0.0.1:6379> set key1 hello
OK
127.0.0.1:6379> get key1
"hello"
127.0.0.1:6379> get Key1
(nil)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值