二、Redis基本类型与命令

15 阅读12分钟

基本类型及命令

string类型

string类型分为字符型字符串和数值型字符串,因此命令也大致分为两种。一种是针对数值型字符串的特殊命令,另一种是两种字符串都可以使用的通用命令。

通用命令

1.  set命令
    格式:set  key  value
    含义:新增字符串类型的值
2.  get命令
    格式:get  key
    含义:根据key获取值
3.  del命令
    格式:del  key
    含义:根据key删除值,支持批量删除
4.  mset命令
    格式:mset  k1  v1  k2  v2
    含义:批量添加值
5.  mget命令
    格式:mget  k1  k2
    含义:批量获取值
6.  setrange命令
    格式:setrange  key  起始索引  value
    含义:将key对应的value值,按照起始索引开始用新value一个一个的字符进行替换
7.  getrange命令
    格式:getrange  key  起始索引  结束索引
    含义:获取索引部分的值
8.  append命令
    格式:append  key  value
    含义:在key对应的value后面追加字符串
9.  strlen命令
    格式:strlen  key
    含义:返回字符串长度

数值型字符串的特殊命令

1.  incr命令
    格式:incr  key
    含义:数值型字符串值加1
2.  decr命令
    格式:decr  key
    含义:数值型字符串值减1
3.  incrby命令
    格式:incrby  key  数值
    含义:数值型字符串值加某个值
4.  decrby命令
    格式:decrby  key  数值
    含义:数值型字符串值减某个值
5.  incrbyfloat命令
    格式:incrbyfloat  key  小数
    含义:数值型字符串值加上某个小数

bitmap类型

1.  setbit命令
    格式:setbit  key  **位索引**  0/1
    含义:对某个字节中的位设置值。位索引从0开始
2.  bitcount命令
    格式:bitcount  key  0/1  **字节索引**起始位置  **字节索引**结束位置
    含义:统计字节索引区间内0/1这个值出现的个数
3.  bitpos命令
    格式:bitpos  key  0/1  **字节索引**起始位置  **字节索引**结束位置
    含义:返回从左到右,在字节索引区间内0/1第一次出现的位置
4.  bitop命令
    格式:bitop  逻辑运算符(andor等)  目标key  k1 k2 k3...
    含义:对多个key的值按位进行逻辑运算,结果存入目标key

bitmap的经典案例

案例一

背景:假设一年365天,统计某个人在一年内登录游戏的情况。

方案:使用bitmap进行统计,位索引0对应第一天,一次类推。

第一天登录了:setbit 人名 0 1 第二天登录了:setbit 人名 1 1

最后还可以统计这个人一年内登录的天数: bitcount 人名 1 0 -1

案例二

背景:假设统计一周内活跃用户数量。只要一周内出现一次就属于活跃用户数了。

方案:使用bitmap进行统计,key为日期,位索引为人名的映射

张三在2023年7月3号登录了:setbit 20230703 0 1

李四在2023年7月3号登录了:setbit 20230703 1 1

张三在2023年7月4号登录了:setbit 20230704 0 1

李四在2023年7月5号登录了:setbit 20230705 1 1

统计从3号到5号的活跃用户情况:bitop or key 20230703 20230704 20230705

统计从3号到5号的活跃用户数量:bitcount key 1 0 -1

list类型

队列类型的命令

1.  lpush命令
    格式:lpush  key  1 2 3
    含义:从key对应的队列左边依次存入1 2 3;结果存的是3 2 1
2.  rpush命令
    格式:rpush  key  1 2 3
    含义:从key对应的队列右边依次存入1 2 3;结果存的是1 2 3
3.  lpop命令
    格式:lpop  key
    含义:从key对应的队列左边取出数据
4.  rpop命令
    格式:rpop  key
    含义:从key对应的队列右边取出数据

数组类型的命令

1.  lindex命令
    格式:lindex  key  index
    含义:从key对应的队列中取出索引位置的值
2.  lrange命令
    格式:lrange  key  起始索引  结束索引
    含义:从key对应的队列中取出索引范围内的值
3.  lset命令
    格式:lset  key  index  value
    含义:修改队列中索引位置的值
4.  llen命令
    格式:llen  key
    含义:返回队列的长度

链表类型的命令

1.  lrem命令
    格式:lrem  key  正数/负数/0  value
    含义:删除队列中value值。如果key后面是0,则删除所有value值;如果是正数,则从左到右删除对应个数的value值;如果是负数,则从右到左删除对应个数的value值
2.  linsert命令
    格式:linsert  key  after/before  v1  v2
    含义:在队列中的v1值前面或者后面添加v2。如果队列中有多个v1,则只会在左边第一个v1前后添加
3.  ltrim命令
    格式:ltrim  key  起始索引  结束索引
    含义:取出索引区间内的值

阻塞队列类型的命令

1.  blpop命令
    格式:blpop  key  timeout
    含义:从key对应的队列左边取数,如果队列中没有数,则等待timeout时间
2.  brpop命令
    格式:brpop  key  timeout
    含义:从key对应的队列右边取数,如果队列中没有数,则等待timeout时间

hash类型

增删改查操作

1.  hset命令
    格式:hset  key  k1 v1
    含义:在hash中添加k1  v1 键值对
2.  hget命令
    格式:hget  key  k1
    含义:在hash中取出k1对应的值
3.  hmset命令
    格式:hmset  key  k1 v1  k2  v2
    含义:在hash中批量添加键值对
4.  hmget命令
    格式:hmget  key  k1  k2
    含义:从hash中取出k1 k2对应的值
5.  hdel命令
    格式:hdel  key  k1  k2
    含义:从hash中删除k1  k2键值对
6.  hgetall命令
    格式:hgetall  key
    含义:取出key对应的hash所有的键值对
7.  hkeys命令
    格式:hkeys  key
    含义:取出hash中所有的键
8.  hvals命令
    格式:hvals  key
    含义:取出hash中所有的值

针对value是数值型字符串的命令

1.  hincrby命令
    格式:hincrby  key  k1  1
    含义:hash中k1对应的值加1
2.  hincrbyfloat命令
    格式:hincrbyfloat  key  k1  0.5
    含义:hash中k1对应的值加0.5

set类型

基本命令

1.  sadd命令
    格式:sadd  key  v1  v2
    含义:将v1和v2存入set2.  smembers命令
    格式:smembers  key
    含义:查看set中的所有数据
3.  srem命令
    格式:srem  key  v1  v2
    含义:删除set中的v1和v2

交并差集操作

1.  sinter命令
    格式:sinter  k1 k2
    含义:求出k1和k2的交集
2.  sinterstore命令
    格式:sinterstore  key  k1 k2
    含义:求出k1和k2的交集,并且存入key3.  sunion命令
    格式:sunion  key  k1 k2
    含义:求出k1和k2的并集
4.  sunionstore命令
    格式:sunionstore  key  k1 k2
    含义:请求k1和k2的并集,并且存入key5.  sdiff命令
    格式:sdiff  k1  k2
    含义:从k1中去除k2中的元素后,返回剩余结果
6.  sdiffstore命令
    格式:sdiffstore  key  k1 k2
    含义:从k1中去除k2中的元素后,将剩余结果存入key

随机取数

1.  srandmember命令
    格式:srandmember  key  count
    含义:从set中随机取出count个数。count可以是正数也可以是负数。
    如果是正数,取出的数不是重复的。如果count数比set中元素个数要多,那也只会把所有元素取出来。
    如果是负数,取出的数可能是重复的,并且一定会取出count个数
    备注:count为正数时,好比每次取出数后不会放回;count为负数时,好比每次取出数后都会放回。
2.  spop命令
    格式:spop  key  count
    含义:从key中取出count个数,但是每次取出的数都会从set中删除。
    备注:如果count比set中的元素个数要多,只会把set中所有的元素取出并删除。

sorted-set类型

介绍

  1. sorted-set是有序集合,与set比是有序的,与list比是元素不会重复。
  2. 有序集合的数据都是带分值的。

命令

1.  zadd命令
    格式:zadd  key  score  v1  score  v2
    含义:集合中存入v1和v2,并且按照分值从小到大,从左到右排序
2.  zrange命令
    格式:zrange  key  起始索引  结束索引
    含义:从集合中取出索引范围内的元素
3.  zrevrange命令
    格式:zrevrange  key  起始索引  结束索引
    含义:从集合中取出索引范围内的元素,然后倒序展示
4.  zrangebyscore命令
    格式:zrangebyscore  key  minscore  maxscore
    含义:从集合中取出分值范围内的元素
5.  zincrby命令
    格式:zincrby  key  num  value
    含义:将value对应的分值加上num
6.  zunionstore命令
    格式:zunionstore  dest  num  k1  k2  weights  w1  w2  aggregate  sum|min|max
    含义:多个集合求并集,结果存入目标集合中。num是集合的个数,weights后面是分值比例,
    k1集合中的每个元素的分值乘以w1,k2是乘以w2。aggregate后面的操作是针对多个集合中相同的value的。
    相同的value的分值可以是求和/求最小值/求最大值之后,再存入目标集合中。
    备注:weights(含weights)后面的都可以省略。这样就是把多个集合中的分值按照原数相加。

有序集合的底层结构

有序集合zset的底层结构是跳跃表结构

image.png

跳跃表查询步骤:

  1. 从最上层左边第一个数开始遍历,判断是否比-1大,比119小,如果是,从-1往下走,到第二层
  2. 判断是否比-1大,比21小,如果比21大;再判断是否比21大,比37小,如果是,从21往下走
  3. 判断是否比21大,比32小,结果不是,值就等于32,查询成功。

管道技术

为什么需要管道技术

如果需要redis执行一批命令,这些命令依次发送给Redis执行的话,系统消耗主要发生在网络IO上。

管道技术是将这批命令打包后发送给Redis,然后再依次执行,提高效率。

一次IO可以执行多个命令,提高执行效率。

管道技术注意事项

命令与命令之间完全解耦。不能出现下条命令的执行过程需要上条命令的执行结果的情况。

订阅发布

Redis订阅发布功能存在两个角色,一个是订阅者,一个是发布者。发布者发布消息后,所有的订阅者都会收到消息,是广播订阅的模式。

订阅发布命令

1.  订阅命令:subscribe
    格式:subscribe  key
    含义:订阅key中的数据,如果没有数据会堵塞,有数据会拿到数据
2.  发布命令:publish
    格式:publish  key  value
    含义:向key中发布消息value

需要注意的是:如果先向key发布消息,再订阅key的话,那么订阅者无法拿到创建之前的消息。也就是说,如果没有订阅者,发布者的消息也不会保留,直接丢弃。

事务

与关系型数据库不同,Redis事务没有回滚操作

命令

1.  命令:multi
    格式:multi
    含义:开启事务
2.  命令:exec
    格式:exec
    含义:提交事务
    注意:如果多个客户端开启了多个事务,那么谁先提交事务,谁的命令先执行
3.  命令:watch
    格式:watch  k1  k2
    含义:监视k1和k2,如果在事务执行过程中k1或者k2的值发生变化,那么事务不会执行
    注意:事务执行过程包括:multi命令执行后,一直到exec命令执行完成,这一整个过程

布隆过滤器

下载和安装

1.进入redis.io英文官网,点击resources,选择module 2.module界面点击redisbloom,进入github网站 3.选择下载zip压缩包,放入linux中 4.使用unzip命令解压,进入解压的文件夹中,使用make命令编译 5.使用 redis-server --loadmodule redisbloom.so的绝对路径 命令即可使用布隆过滤器

原理

布隆过滤器使用的数据结构是bitmap。首先,布隆过滤器中有多个hash函数,某个数据经过这些函数的运算,求出多个结果,这些结果对应着bitmap的位置,每个位置设置成1。这样一来,下次某个数再经过布隆过滤器,经过函数运算后,如果求出的bitmap的位置上的数都是1的话,说明Redis中是存在这个key的,允许其访问。

解决的问题和弊端

布隆过滤器解决了缓存穿透的问题。即某一时刻,大量的请求访问Redis,这些请求的key都是Redis中不存在的key,如果放行,那么这些请求会直接落到数据库中,导致数据库奔溃。布隆过滤器就是为了过滤掉这些请求。

不过布隆过滤器也存在弊端,存在1%的概率,会放行Redis中不存在的key的请求。因为有这样一种情况:假设Redis中k1在布隆过滤器的bitmap的p1这个位置设置了1,某个请求想访问k2,经过布隆过滤器的函数运算,k2在p1这个位置正好也是1,这样一来,Redis中的k1无意中给k2做了掩护,欺骗了布隆过滤器,使得k2被放行。还好这种概率小于1%。