Redis7——基础篇(二)
前言:此篇文章系本人学习过程中记录下来的笔记,里面难免会有不少欠缺的地方,诚心期待大家多多给予指教。
基础篇:
- Redis(一)
接上期内容:上期完成了Redis环境的搭建。下面开始学习Redis常用命令,话不多说,直接发车。
一、Redis常用键(key)命令
1、前提说明
Redis是一种key-value类型的缓存数据库,我们常说的Redis十大数据类型说的是value的数据类型,key的类型都是字符串。
2、键(key)的常用命令
1、查看当前库的所有key
2、判断某个key是否存在,0不存在,1存在
3、查看key的value是什么类型
4、删除指定的key
5、设定key的过期时间
设置key的过期时间前要确保key存在。
6、查看某个key的过期时间,-1用不过期,-2已过期
7、将某个key移动到指定某个库中
redis默认有16个库,下标从0开始。但是可以在配置文件中修改数量。
8、切换数据库
9、查看当前数据库key的容量
10、清空当前库
禁止在生产上执行。
11、清空所有库
禁止在生产上执行。
二、Redis十大数据类型介绍
(一)、字符串(String)(常用)
最基础的数据类型,能存储任何形式的字符串,包括二进制数据。
(二)、列表(List)(常用)
列表是一个双向链表,可以实现左进右出或右进左出的操作,常用于消息队列。
(三)、哈希(Hash)(常用)
哈希类型用于存储字段和值的映射表,适合存储对象。
(四)、集合(Set)(常用)
集合是一个无序的、不重复元素的集合。可以用于实现交集、并集、差集等操作。
(五)、有序集合(Sorted Set)(常用)
有序集合在集合的基础上,每个元素都关联一个分数,根据分数来排序,适合实现排行榜功能。
(六)、地理空间(Geo)(常用)
用于存储地理空间信息,计算距离、范围查询等。
(七)、位图(Bitmap)(常用)
位图不是一种真正的数据类型,而是基于字符串类型的按位操作。可以用来统计用户的活跃天数、签到情况等。
(八)、流(Steam)(了解)
是 Redis 5.0 引入的新数据类型,用于实现消息队列,支持持久化、消息分组、消费者组等功能。
(九)、基数统计(HyperLogLog)(常用)
用于基数统计,能以极小的内存代价统计大量数据的基数,比如统计网站的 UV(独立访客)。统计数量越大,误差越小。
(十)、位域(BitFiled)(了解)
将一个Redis字符串看作是一个由二进制位组成的数组并能对变长位宽和任意没有字节对齐的指定整型位域进行寻址和修改。(了解即可)
三、实操
官网命令大全网址:Commands | Docs
1、String常用命令
1.1、设置key or 获取value值
1.2、设置多个key or 获取多个value
1.3、设置 or 获得key的下标的值,下标从0开始;
1.4、增加 or 增加指定数字,(只能是整数)
1.5、减少 or 减少指定数字,(只能是整数)
1.6、获取字符串长度 or 增加字符串内容
1.7、动态设置key的过期时间和值(key存在)
1.8、将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
1.9、String的应用场景
String的应用场景太多了,比如抖音无限点赞某个视频或者商品,点一下加一次(INCR KEY)。又比如统计谋篇文章的阅读数,只要点击了rest地址,直接可以使用INCR KEY命令增加一个数字1,完成记录数字等等.....
2、List常用命令
2.1、前提说明
list是一个双端链表的结构,容量是2的32次方减1个元素,主要功能有push/pop等,一般用在栈、队列、消息队列等场景。
如果key不存在,会创建新的链表;反之则新增内容;
如果将list中的value全部移除,对应的key也会删除;
left、right都可以插入添加;
key不能重复,value可以重复
2.2、从左 or 右加入列表
LPUSH / RPUSH key value value value....
2.3、遍历list
LRANGE key start stop
遵循先进后出,后进先出原则,类似java中的栈。
2.4、弹出list元素
lpop/rpop key [count],count省略默认取1
2.5、根据索引下标获取value
LINDEX key start
由于list是一个双向链表,对两端的操作性能很高,通过索引下标操作中间的节点性能会较差。
2.6、删除N个等于value的元素
LREM key count element
从left往right删除N个值等于value的元素,返回的值为实际删除的数量。N=0就是删除所有
2.7、截取指定区间的value在重新赋值给key
LTRIM key start stop
2.8、移除列表的最后一个元素,并将该元素添加到另一个列表并返回
RPOPLPUSH key key1
源列表的元素会消失
2.9、修改某个下标的元素
LSET key index element
2.10、在某个元素之前 or 后插入元素
LINSERT key before|after element(存在元素) element
2.10、List应用场景
比如微信公众号订阅的消息。用户的关注对象发布新内容(如动态、文章等)时,将这些内容的按照业务顺序添加到用户的动态列表(Redis List)中。
3、Hash常用命令
3.1、前提说明
redis的Hash类型类似于java中Map<String,Map<Object,Object>>,KV模式不变,但是V是一个键值对。
3.2、设置键(key) or 获取key对应的value
HSET key field1 value1 field2 value2
HGET key field
如果获取sex出现中文乱码时,退出redis客户端,重新登录,加上参数 --raw
3.4、获取所有元素 or 删除某个元素
HGETALL key
HDEL key field
3.5、统计key的个数 or 判断key是否存在
HLEN key
HEXISTS key
3.6、获取键(key)中的key or value
HKEYS key
HVALS key
3.7、对key中的value做加法(只能是数字)
加整数
HINCRBY key field increment
加小数
HINCRBYFLOAT key field increment
没有减法命令,但是可以传递负数实现减法效果
3.8、向键(key)中添加key
HSETNX key field value
有点类似于java中的map.put()方法,如果存在添加失败,反之成功。
3.9、Hash应用场景
比如购物车。可以使用 Redis 的哈希结构来存储用户的购物车信息,每个用户的购物车对应一个哈希表,字段为商品 ID,值为商品数量。
4、Set常用命令
4.1、前提说明
redis中set类型类似于Java中set<object>。value不允许重复
4.2、添加元素
SADD key value1 value2.....
4.3、遍历
MEMBERS key
4.4、判断元素是否存在
SISMEMBER key value
4.5、删除元素
SREM key value1 value2....
4.6、获取集合的元素个数
SCARD key
类似于java中size()方法
4.7、随机展示元素
SRANDMEMBER key [count],count省略默认取1
从set集合中随机取出N个数,如果超过集合最大数量,就全部取出。
如果随机数为负数,那么随机取的值可能重复。
4.8、随机弹出一个元素
SPOP key [count],count省略默认取1
弹出一个,删除一个。
4.9、移动某个元素到新key中
SMOVE key newKey value
4.10、集合运算
1、集合差集
SDIFF key1 key2
属于A但不属于B的元素 或 属于B但不属于A的元素
2、集合并集
SUNION key1 key2
属于A或属于B的合并后的元素
3、集合交集
SINTER key1 key2
A ∩ B
SINTERCARD numkeys key1 key2 [limit num],limit为可选参数,交集数达到num,立即停止计算返回
统计A ∩ B的基数,不返回元素,返回基数
4.11、Set应用场景
微信抽奖小程序、朋友圈共同好友点赞、QQ共同好友推荐等等....
5、Sorted Set常用命令
5.1、前提说明
sorted Set就是在set的基础上为每个value添加一个分数。
5.2、添加元素
ZADD key score1 value1 score2 value2....
5.3、遍历
1、正序遍历
ZRANGE key start stop [withscores]
按照元素分数从小到大的顺序,返回索引从start到stop之间的所有元素
2、倒序遍历
ZREVRANGE key start stop [withscores]
按照元素分数从大到小的顺序,返回索引从start到stop之间的所有元素
5.4、获取指定区间的元素
ZRANGEBYSCORE key (min max) [WITHSCORES] [LIMIT offset count]
- ( :表示不包含边界。
- [LIMIT offset count]:可选参数。offset表示跳过的元素数量,count表示要返回的元素量。例如offset为2,count为10,意味着跳过前2个符合分数范围的元素,然后返回接下来的10个符合条件元素。
5.5、获取元素的分数 or 获取元素下标
ZSCORE key value
正序获取下标
ZRANK key value [withscore]
逆序获取下标
ZREVRANK key value [withscore]
5.6、获取集合数量 or 统计指定分数区间的数量
ZCARD key
ZCOUNT key scoremin scoremMax
5.7、删除元素
ZREM key
5.8、增加分数
ZINCRBY key score value
5.9、弹出分数最大或最小的元素
ZMPOP numkeys key [key ...] <MIN|MAX> [COUNT count]
numkeys
:指定参与操作的有序集合键的数量。key [key ...]
:一个或多个有序集合的键名,代表要从中弹出元素的有序集合。<MIN|MAX>
:指定弹出元素的规则:MIN
:从有序集合中弹出分数最小的元素。MAX
:从有序集合中弹出分数最大的元素。
[COUNT count]
(可选):指定要弹出的元素数量,默认值为 1。
5.10、Sorted Set应用场景
比如天猫淘宝商品销售的排行榜,定义商品销售排行榜(sorted set集合),key为goods:sellsort,分数为商品销售数量,value为商品id。
6、Geo常用命令
6.1、前提说明
GEO主要为地理位置服务,将三维的地球变为二维的坐标,在将二维的坐标转换为一维的点块,最后将一维的点块转换为二进制,再通过base32编码。
6.2、添加经纬度坐标
首先通过百度地图获取经纬度,拾取坐标系统
GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]
- NX:只在元素不存在时,添加
- XX:只更新已存在的元素
- CH:返回被修改的成员数量,包括那些分数未发生变化但被更新的元素
- longitude:表示地理位置的经度
- latitude:表示地理位置的纬度
- member:代表要添加的地理位置的名称或标识
6.3、返回经纬度
GEOPOS key member1 member2....
6.4、返回坐标的 GEOHASH
GEOHASH key member1 member2....
6.5、返回两个位置之间的距离
GEODIST key member1 member2 [m|km|ft|mi]
m
:表示米,这是默认单位。km
:表示千米。mi
:表示英里。ft
:表示英尺。
6.6、以某个点为中心,查找xx半径内的地理坐标
1、根据经纬度查询
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC]
参数说明
-
必选参数:
-
key
:存储地理位置信息的有序集合的键名。 -
longitude
和latitude
:圆心的经度和纬度,以此为中心来确定圆形区域。 -
radius
:圆形区域的半径大小。 -
m|km|ft|mi
:半径的单位,m
表示米,km
表示千米,ft
表示英尺,mi
表示英里。
-
-
可选参数:
-
WITHCOORD
:返回匹配成员的经纬度。 -
WITHDIST
:返回匹配成员与给定圆心之间的距离,距离单位与半径单位一致。 -
WITHHASH
:返回匹配成员的geohash
值。geohash
是一种将经纬度编码为字符串的方法,可用于高效存储和检索地理位置信息。 -
ASC|DESC
:对结果进行排序,ASC
表示按距离从近到远排序,DESC
表示按距离从远到近排序。 -
COUNT count
:只返回前count
个匹配的成员,可结合ASC
或DESC
排序使用。
-
假设我目前所在位置为人民大会堂,116.400238,39.911394,我想查找10km以内的地理坐标
2、根据地标名字查询
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [ASC|DESC] [COUNT count]
假设我现在在天安门,想查询10km范围以内好玩的地方
6.7、GEO应用场景
高德地图、美团APP获取当前定位附近10KM以内的酒店、饭店。
7、Bitmap常用命令
7.1、前提说明
用String类型作为底层数据结构实现的一种统计二值状态的数据类型。位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们称之为一个索引)。
bitmap支持的最大位数是2^32位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息。
一句话:bitmap由0和1组成的二进制位的数组。
7.2、设置key
SETBIT key offset value
- 参数说明
- offset:二进制的偏移量,偏移量从0开始计数。如果偏移量大于当前字符串的长度,redis会自动将字符串进行扩展,扩展部分的二进制位会被初始化为0。
- value:要设置的二进制的值,只能是0或1。
然后A的二进制刚好是01000001,所以get k 会得到A。
7.3、获取key
GETBIT key offset
7.4、统计
1、统计占用多少字节
STRLEN key
不是统计字符串长度而是统计占据几个字节,超过8位后自己按照8位一组一byte再扩容
2、统计两个key中1的个数
BITCOUNT key
7.5、对不同的二进制进行位运算
BITOP operation destkey key [key ...]
参数说明:
operation
:指定要执行的按位操作类型,支持以下四种操作:AND
:对所有给定键对应的二进制位串进行按位与操作。OR
:对所有给定键对应的二进制位串进行按位或操作。XOR
:对所有给定键对应的二进制位串进行按位异或操作。NOT
:对单个给定键对应的二进制位串进行按位取反操作,该操作只接受一个输入键。
destkey
:用于存储操作结果的目标键。操作完成后,结果会被存储在这个键中。key [key ...]
:参与按位操作的一个或多个键。对于NOT
操作,只允许有一个键;对于其他操作,可以有多个键。
返回结果存储在 destkey
中二进制位串的长度(以字节为单位)
在统计用户某个时间段活跃度的场景下运用比较多。
7.6、Bitmap应用场景
该类型在统计用户签到,用户活跃度场景下运用比较多。
8、Steam常用命令
8.1、前提说明
stream类似于一个日志流,它是一个有序的消息链表,每个消息都有一个唯一的 ID,并且按照插入的顺序排列。消息是stream中的基本数据单元,由一个唯一的消息 ID 和一个键值对组成。消息 ID 的格式通常为 timestamp-sequence
,例如 1549854000123-0。
消费者组是 Redis Stream 提供的一种消费模式,多个消费者可以组成一个组,共同消费一个 Stream 中的消息。每个消费者组有一个游标,记录了该组消费到的位置,组内的消费者可以独立消费消息,互不影响。
stream数据结构
1 | Message Content | 消息内容 |
2 | Consumer group | 消费组,通过XGROUP CREATE 命令创建,同一个消费组可以有多个消费者 |
3 | Last_delivered_id | 游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动 |
4 | Consumer | 消费者,消费组中的消费者 |
5 | Pending_ids | 消费者会有一个状态变量,用于记录被当前消费已读取但未ack的消息Id,如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack它就开始减少。这个pending_ids变量在Redis官方被称之为 PEL(Pending Entries List),记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符),它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理。 |
list和steam结构对比
8.2、队列指令
1、添加消息
XADD key ID field value [field value ...]
key
:Stream 的键名。ID
:消息的 ID,通常使用*
表示让 Redis 自动生成。field value
:消息的键值对。
如果是自己手动生成,一定要确保消息ID比上一个ID大
2、获取消息列表
1、正序
XRANGE key start end [COUNT count]
key
:stream的键名。start
和end
:消息 ID 的范围,可以使用-
表示最小 ID,+
表示最大 ID。count
:可选参数,指定返回的消息数量。
2、反序
XREVRANGE key end start [COUNT count]
3、删除消息
XDEL key ID [ID ...]
4、获取消息队列长度
XLEN key
5、消息截取
1、保留x条消息
XTRIM key MAXLEN count
2、保留大于某个ID的消息
XTRIM key MINID id
6、读取消息
1、非阻塞读
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
- COUNT:最多读取多少条消息。
- BLOCK:是否以阻塞的方式读取消息,默认不阻塞,如果milliseconds设置为0,表示永远阻塞 。
$代表特殊ID,表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil。
0-0或0代表从最小的ID开始获取Stream中的消息,当不指定count,将会返回Stream中的所有消息
2、阻塞读
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...]
启动两个redis客户端。
生产者一有消息,消费者里面马上消费。
8.3、消费指令
1、创建消费者组
XGROUP CREATE key groupname id
key
:Stream
的键名,即要操作的Stream
对象。groupname
:要创建的消费者组的名称。id
:消费者组的起始 ID。常用$
表示从Stream
中最新的消息开始消费;用0
表示从Stream
中的第一条消息开始消费。
2、创建消费者
XGROUP CREATECONSUMER key groupname consumername
key
:Stream
的键名。groupname
:消费者所属的消费者组的名称。consumername
:要创建的消费者的名称。
3、消费消息
XREADGROUP GROUP groupname consumername [COUNT count] [BLOCK milliseconds] [NOACK] STREAMS key [key ...] ID [ID ...]
GROUP
:用于指定要操作的消费者组和消费者的名称。groupname
:消费者组的名称。consumername
:消费者组内的消费者名称。
COUNT
(可选):指定读取的消息数量。如果不设置,Redis 会尝试返回尽可能多的消息,直到达到内部限制。BLOCK
(可选):以阻塞模式读取消息。milliseconds
是阻塞的时长(以毫秒为单位),设置为0
时会无限期阻塞,直到有新消息到来。NOACK
(可选):如果指定该参数,读取消息时不会自动确认消息,需要后续使用XACK
命令手动确认。STREAMS
:标识后面跟随的是要读取消息的Stream
键名列表。key [key ...]
:要读取消息的Stream
键名,可以指定多个Stream
。ID [ID ...]
:每个Stream
对应的起始读取 ID,通常使用>
表示从消费者组中未分配给任何消费者的最新消息开始读取。
stream中的消息一旦被消费组里的一个消费者读取了,就不能再被该消费组内的其他消费者读取了,即同一个消费组里的消费者不能消费同一条消息。刚才的XREADGROUP命令再执行一次,此时读到的就是空值。
消费者的目的:让组内的多个消费者共同分担读取消息,所以,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的。
4、如何确保消息不丢失?
问题 | 基于 Stream 实现的消息队列,如何保证消费者在发生故障或宕机再次重启后,仍然可以读取未处理完的消息? |
1 | Streams 会自动使用内部队列(也称为 PENDING List)留存消费组里每个消费者读取的消息保底措施,直到消费者使用 XACK 命令通知 Streams“消息已经处理完成”。 |
2 | 消费确认增加了消息的可靠性,一般在业务处理完成之后,需要执行 XACK 命令确认消息已经被消费完成 |
8.4、查看消息状态
1、查看消费者组内待处理消息的总体信息
XPENDING key groupname
2、查看消费者组内待处理消息的详细信息
XPENDING key groupname start end count [consumer]
key
:Stream
的键名。groupname
:消费者组的名称。start
和end
:消息 ID 的范围,用于指定要查看的待处理消息的 ID 区间,可使用-
表示最小 ID,+
表示最大 ID。count
:指定返回的待处理消息数量。consumer
(可选):指定要查看的特定消费者的待处理消息。若不指定,会返回组内所有消费者的待处理消息。
8.5、确认消息
XACK key groupname ID [ID ...]
key
:Stream
的键名,代表要操作的Stream
对象。groupname
:消费者组的名称。ID [ID ...]
:要确认已处理的消息的 ID,可以指定一个或多个消息 ID。
签收后,consumer1消费者只有一条消息未确认了。
8.6、Stream应用场景
比如消息队列,支付宝或者微信支付消息通知等。Stream还是不能100%等价于Kafka、RabbitMQ来使用的,生产案例少,慎用。专业的事还是应该交给专业的人来做。
9、HyperLogLog常用命令
9.1、前提说明
HyperLogLog是Redis提供的一种用于进行基数统计的数据结构,能够对海量数据的基数进行较为准确的估算(去重)。
9.2、添加
PFADD key element1 element2....
element可以重复
9.3、统计基数
1、单独统计
PFCOUNT key1 key2...
2、合并统计
PFMERGE destkey sourcekey [sourcekey ...]
9.4、HypeLogLog应用场景
淘宝、天猫网站首页uv统计等等。
10、BitFiled常用命令
10.1、前提说明
将一个Redis字符串看作是一个由二进制位组成的数组并能对变长位宽和任意没有字节对齐的指定整型位域进行寻址和修改,有点类似java中修改class文件的操作。(了解即可)
10.2、返回指定位域
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
参数说明
- key:要操作的 Redis 键,该键对应的值必须是字符串类型。
- GET type offset:从指定的
offset
位置开始,按照指定的type
类型获取一个整数。- type:表示整数类型,格式为
[u|i]
后跟位数,u
表示无符号整数,i
表示有符号整数,例如u8
表示 8 位无符号整数,i16
表示 16 位有符号整数。 - offset:位偏移量,从 0 开始计数。
- type:表示整数类型,格式为
- SET type offset value:从指定的
offset
位置开始,按照指定的type
类型设置一个整数。 - INCRBY type offset increment:从指定的
offset
位置开始,按照指定的type
类型对整数进行增量操作。 - OVERFLOW WRAP|SAT|FAIL:可选参数,用于控制溢出行为。
- WRAP:溢出时进行回绕处理,例如对于 8 位无符号整数,当值从 255 增加到 256 时,会回绕到 0。
- SAT:溢出时进行饱和处理,即达到最大值时不再增加,达到最小值时不再减少。
- FAIL:溢出时不执行操作,并返回
nil
。
10.3、设置指定位域的值
10.4、对某个位域增加
四、总结
Redis丰富的数据类型为开发者提供了强大的工具,不同的数据类型适用于不同的业务场景。通过实操,我们更深入地理解了这些数据类型的使用方法和特点。在实际项目中,合理选择和使用 Redis的数据类型,能够极大地提高系统的性能和效率。
ps:努力到底,让持续学习成为贯穿一生的坚守。学习笔记持续更新中。。。。