当前位置: 首页 > news >正文

一篇讲清Redis中常见数据类型的用法

目录

string

SET命令

GET命令

MSET命令

MGET命令

INCR命令

INCRBY命令

DECR命令

DECRBY命令

INCRBYFLOAT命令

APPEND命令

GETRANGE命令

SETRANGE命令

STRLEN命令

命令小结

内部编码

int

embstr

raw

典型应用场景

缓存功能

计数功能

共享会话

手机验证码

hash

HSET命令

HGET命令

HEXISTS命令

HDEL命令

HKEYS命令

HVALS命令

HGETALL命令

HMGET命令

HSCAN命令

HLEN命令

HSETNX命令

HINCRBY命令

HINCRBYFLOAT命令

命令小结

内部编码

应用场景

list

LPUSH命令

LRANGE命令

LPUSHX命令

RPUSH命令

RPUSHX命令

LPOP命令

RPOP命令

LINDEX命令

LINSERT命令

LLEN命令

LREM命令

LTRIM命令

LSET命令

阻塞命令

命令小结

内部编码

应用场景

消息队列

分频道的消息队列

set

SADD命令

SCARD命令

SMEMBERS命令

SISMEMBER命令

SPOP命令

SRANDMEMBER命令

SMOVE命令

SREM命令

集合操作命令

SINTER命令

SINTERSTORE命令

SUNION命令

SUNIONSTORE命令

SDIFF命令

SDIFFSTORE命令

命令小结

内部编码

应用场景

zset

ZADD命令

ZRANGE命令

ZREVRANGE命令

ZRANGEBYSCORE命令

ZCARD命令

ZCOUNT命令

ZPOPMAX命令

ZPOPMIN命令

ZRANK命令

ZREVRANK命令

ZSCORE命令

ZREM命令

ZREMRANGEBYRANK命令

ZREMRANGEBYSCORE命令

ZINCRBY命令

阻塞命令

BZPOPMAX命令

BZPOPMIN命令

集合操作命令

zinterstore命令

zunionstore命令

命令小结

内部编码

应用场景

其他数据类型

stream

geospatial

hyperloglog

bitmaps

bitfields

渐进式遍历


string

redis中的字符串,直接就是按照二进制数据方式存储的,不会做任何编码转换,存的是什么,取出来还是什么。

SET命令

SET key value [expiration EX seconds | PX milliseconds]  [NX|XX]

SET key value ex 10 相当于 SET key value + expire key 10

设置了存活时间可以用ttl命令来查看剩余的存活时间,返回的值的单位为秒,如果key没设置ex则返回的是-1,如果这个key存活时间结束,返货的是-2

NX:如果key不存在才设置,如果key存在则不设置返回nil

XX:如果key存在才设置,如果key不存在则不设置返回nil



SETNX 为 SET key value NX 简写,不存在才设置成功,存在则设置失败

SETEX 为 SET key value EX 简写,设置key存活的秒数。

PSETEX 为 SET key value PX 简写,设置key存活的毫秒数。

注意:使用set的时候,如果key存在,会让新的value覆盖旧的value,可能会改变原本的数据类型,原来这个key的ttl也会时效。

GET命令

get key

对于GET来说,它只支持字符串类型的value,对于其他类型,使用GET获取就会出错。

MSET命令

mset key1 value1 key2 value2 key3 value3 .... 

一次可以set多个键值对

时间复杂度:O(N) N为key的数量,但也通常认为是O(1)。

MGET命令

mget key1 key2 key3 ...

一次可以取出多个value

时间复杂度:O(N) N为key的数量。

INCR命令

incr key

针对key对应的value+1,返回值为value+1的值

注意:自增的数必须是整数,并且不能超过64位/8字节的整数范围。

其他类型不能自增

超过范围也不能自增

incr操作的key如果不存,就会把key的value当作0进行增加

INCRBY命令

incrby key n

针对key对应的value进行+n操作,返回值为+n的值

注意事项和incr相同。

但incrby能够加负数,达到减法的效果

DECR命令

decr key

针对key对应的value进行-1操作,返回值为-1后的值

注意事项和上面类似。

DECRBY命令

decrby key n

针对key对应的value值进行-n的操作,返回值为-n的值

注意事项同上,并且decrby命令也能实现加法

INCRBYFLOAT命令

incrbyfloat key n

针对key对应的value进行+或者-运算,返回值为运算后的值

同时也能实现减法

increbyfloat不仅能处理小数,同时也可以处理整数加减,但是目前没有所对应的decrbyfloat命令。

小结:上述所有进行加减的命令都只能针对整数,除了increbyfloat可以针对小数有效,并且都不能超过64位所能表示的范围,所有的时间复杂度也为O(1)。

在redis处理命令的时候也不用担心修改数据引起的线程安全问题,因为redis为单线程模型。

APPEND命令

append key s

针对字符串进行追加,返回值为追加后的字符串长度(单位为字节)

如果key不存在,那么相当于使用set创建了一个字符串

注意:对于redis字符串,因为redis不会对字符编码做任何处理,存进去什么样,取出来就什么样,因此在存储中文字符的时候,也是同样如此

我这里使用的是Xshell终端,默认字符集是utf8,因此在终端输入汉字后,redis也就安装utf8编码存储数据,这里显示的就是对应的utf8编码的十六进制数据。

为了避免自己转化的麻烦,可以在启动redis终端的时候添加--raw这样的选项,就可以使redis客户端能够自动的把二进制数据尝试解码翻译。

GETRANGE命令

getrange key start end

针对字符串进行截取,由start 和 end 两个参数指定范围,返回值为截取后的字串

其中start和end表示的区间为闭区间,和Java或者C++大部分编程语言稍微不太一样,这里为左闭区右闭

并且区间也可以写成负数,例如-1表示倒数第1个字符

但如果start或者end两个超出了字符串长度的范围返回的则是空串

注意:redis中存储的是二进制数据,操作是以一个字节为单位,不是一个字符,因此在getrange中文字符的时候就会出现问题。

SETRANGE命令

setrange key offset value

针对字符串进行指定范围替换,offset为偏移量表示开始替换的起始位置,替换的长度取决于value,返回值为替换后的新的字符串长度

setrange也能对不存在的key进行操作,对不存在的key操作相当于创建了一个key和value,并且offset之前的会被填充为0

STRLEN命令

strlen key

针对字符串获取字符串长度,返回值为字符串长度

注意:这里字符串长度单位是字节(C++中,字符串长度本身就是以字节为单位,而Java字符串是以字符为单位,Java一个char==2个字节)

此处使用的Xshell终端默认编码方式是uft8一个中文字符占3个字节

strlen只能对字符串起作用,其他类型则会报错

命令小结

内部编码

查看内部编码命令

object encoding key

int

当存储的字符串是8个字节的长整型的时候,redis使用的内部编码为int

embstr

当存储的字符串长度小于等于某个字节长度时,redis内部编码为embstr,表示压缩字符串的方式,能够节省空间

raw

当存储的字符串长度大于某个字节长度时,redis内部编码为raw,表示普通类型的字符串

注意:embstr和raw编码转化的临界值没有具体的值,在实际工作中一般是可以进行动态调整的,并且在redis6及以前的版本中这个临界值默认是39,而我目前使用的是redis7,经过测试是在字符串长度到达45的时候发生变化的,因此去记住具体的值是没有意义的。

拓展:redis存储小数的时候本质上还是字符串

如果用字符串存小数,那么在每次计算的时候,都需要把字符串转成小数,计算完毕后,结果又转成字符串进行保存,两次转化也会增加开销。

典型应用场景

缓存功能

例如Redis+MySQL构成缓存架构

Redis作为缓存,空间相对较小,当每把数据写入Redis中时,同时也会设置一个过期时间,Redis会根据内存淘汰策略,释放空间确保内存够用。

计数功能

例如统计视频播放次数

它可以实现快速计数、查询缓存的功能,同时数据可以异步处理或者落地到其他数据源。

共享会话

session的集中管理

通过Redis可以使用会话集中管理,这样每次用户请求的不到不同的服务器都能做出合理的响应,保证了Redis的高可用和扩展性。

手机验证码

最主要的是key可以设置过期时间

hash

哈希类型中的映射关系通常称为 field-value,用于区分 Redis 整体的键值对(key-value),注意这里的 value 是指 field 对应的值,不是键(key)对应的值。

HSET命令

hset key field1 value1 [field2 value2 ...]

添加hash类型的数据,可以一次设置多个,返回值为设置成功的个数

HGET命令

hget key field

获取key中的哈希表中field的值,返回值为value值,如不存在则返回nil

HEXISTS命令

hexists key field

判断key中的field是否存在,返回1表示存在,0表示不存在

HDEL命令

hdel key field [field ...]

删除key中指定的field,返回值为删除成功的个数

注意:hdel是删除key的field,而del是删除key。

HKEYS命令

hkeys key

获取hash中所有的字段,返回值为字段列表

这个操作是根据key找到对应的hash,O(1),然后在遍历hash,O(N)。如果hash中的字段多这个操作也存在一定风险,和keys *类似数据过多可能会造成redis服务器阻塞。

HVALS命令

hvals key

返回值为可hash中所有字段的value值

这个操作的时间复杂度和hkeys相同。

HGETALL命令

hgetall key

获取到key中所有的field和对应的value,返回值为fileld和value相邻输出的列表

HMGET命令

hmget key field [field ...]

查询key中指定的field字段,返回对应字段value的列表

HSCAN命令

hscan key cursor 

hscan命令可以避免发生一次性处理大量数据而造成redis服务器阻塞,上述的hkeys,hvals,hgetall会获取所有数据,在数据比较庞大时极有可能会造成服务器阻塞,而hscan则是能够做到分批查询。

其中cursor表示游标,说明遍历的位置,返回值第一个数为下次开始遍历的位置

HLEN命令

hlen key

获取key中的hash键值对的个数

HSETNX命令

hsetnx key field vlaue

field字段不存在时才设置成功,成功返回1,失败返回0

HINCRBY命令

hincrby key field n

对hash中field对的value进行加减整数n,返回值为加减结果后的值

HINCRBYFLOAT命令

hincrbyfloat key field n

对hash中field对的value进行加减小数n,返回值为加减结果后的值

命令小结

内部编码

listpack是对hash表中的元素进行压缩(redis6之前是ziplist),能够节省一定内存空间,但是listpack付出的代价是在进行读写的时候速度相对来说会比较慢

如果哈希表中元素个数比较少,会使用listpack表示,元素个数比较多会转成hashtable

如果每个vlaue的值的长度都比较短,使用listpack表示,value的长度太长了也会转成hashtable。

转换的配置可以根据实际需求在redis.conf配置文件中,修改hash-max-ziplist-entries(默认值为512个)配置根据元素个数转换条件,修改hash-max-ziplist-value(默认值为64字节长度)配置根据value值的长度转化条件。(配置文件默认地址:/etc/redis/redis.conf)

应用场景

作为缓存

hash结构更适合存储一些结构化的数据

数据库如果存在一张这样的表结构,我们可以使用redis像下面方式进行存储

这样的存储string类型也能做到,需要使用json的格式存储,但在转换的过程中没有hash方便直接。

使用string和hash作为缓存的对比

string缺点:如果需要读取/修改其中的某一个字段,需要将整个字符串读取出来然后进行转化成对象,读取/修改后再转会字符串子存回去,这样序列化和反序列化开销大,过程也繁琐,不灵活。

hash缺点:需要控制listpack和hashtable两种编码转换,空间开销可能比较大。

string优点:内存呢使用效率比较高。

hash优点:简单、直观、灵活。尤其是针对信息的局部变更或者获取操作。

list

list数据类型类似于数组或顺序表,内部的编码方式类似于双端队列

LPUSH命令

lpush key element [element ...]

将一个或者多个元素从左侧插入(头插)到list中,如果key不存在自动创建一个key,返回值为插入后list的长度

LRANGE命令

lrange key start syop

查看list的中指定的范围的元素,区间范围为闭区间,下标同样支持负数

LPUSHX命令

lpush key element [element ...]

若key存在时,将一个或者多个元素从左侧放入,不存在则直接返回,返回值是插入后list的长度

key不存在的情况

RPUSH命令

rpush key element [element...]

将一个或者多个元素从右侧插入(尾插)到list中,如果key不存在自动创建一个key,返回值为插入后list的长度

RPUSHX命令

rpushx key element [element...]

若key存在时,将一个或者多个元素从右侧放入,不存在则直接返回,返回值是插入后list的长度

key不存在的情况

LPOP命令

lpop key [count]

从list左侧取出一个元素(头删),参数count可以指定要删除的个数,返回值为取出的元素或nil

RPOP命令

rpop key [count]

从list右侧取出一个元素(尾删),参数count可以指定要删除的个数,返回值为取出的元素或nil

LINDEX命令

lindex key index

给定下标,获取到对应的元素,时间复杂度O(N),如果下标非法返回的是nil

LINSERT命令

linsert key <before|after> privot elment

在基准值(privot)的前面(before)或者后面(after),插入元素(elment),返回值表示插入之后新的list的长度

如果基准值不存在则返回-1

注意:这个基准值是从左往右找到的第一个元素。

LLEN命令

llen key

计算list的长度并返回,如果key不存在则返回0

LREM命令

lrem key count element

删除list中count数量个的element元素,返回删除后list的长度

注意:

count>0时从左往右找count个元素进行删除

count<0时从右往左找-count个元素进行删除

count=0时删除所有的element元素。

LTRIM命令

ltrim key start stop

只保留list从start和stop区间的元素,区间外的两边元素就直接被删除了

LSET命令

lset key index element

根据下标修改元素,时间复杂度O(N),成功返回OK,index越界失败会报错

阻塞命令

<blpop|brpop> key [key...] timeout

blpop和brpop为lpop和rpop阻塞版本的命令,当元素为空时,lpop和rpop会返回nil,而blpop和brpop会根据timeout(单位秒)阻塞一段时间,再返回一个二元组(pair)包含key和key中返回的值。

命令中如果设置了多个key,redis会从左向右遍历,哪个key先有元素就返回哪个key的元素。

如果有多个客户端对同一个key进行阻塞pop,等key中有元素了后,哪个客户端最先发起的请求就给哪个客户端响应。

1.针对有元素的list

效果基本和lpop一样

2.针对list为空的情况

当指定的timeout时间到了客户端还没有添加元素就会返回nil

命令小结

内部编码

目前redis的list类型内部编码方式是quicklist

quicklist是由双向链表+多个 ziplist 的组合构成,当list中元素过多会转化成多个quicklist组合而成,具体多少元素才转化的可以根据配置文件进行修改,配置文件路径:/etc/redis/redis.conf

应用场景

消息队列

消费者采用轮询的策略获取元素,消费者通过“先到先得”这样的方式依次获取元素,当消费者拿到元素后会离开队列,如果再次想重新请求,就得重新排队。

分频道的消息队列

就例如刷视频的时候,会同时获取几个频道的信息,一个播放视频,一个这是显示弹幕,一个展示评论,这样同时也做到了解耦合。

set

set是一个无序集合,而list是属于有序集合,set集合中的元素是不重复的唯一的。

SADD命令

sadd key member [member...]

将key中加入元素,返回值为本次操作添加成功的个数

SCARD命令

scard key

求key集合中的元素个数

SMEMBERS命令

smembers key

查询出当前集合的所有元素

SISMEMBER命令

sismember key member

判断集合key中是否存在member这个元素,存在返回1,不存在返回0

SPOP命令

spop key [count]

随机删除key中一个或count个元素,返回值为被删除的那个数

SRANDMEMBER命令

srandmember key [count]

随机获取一个或count个key中的元素但不删除,返回值为随机获取的元素

SMOVE命令

smove source destination member

将source集合当中的member移动到destination集合中去,移动成功返回1,失败返回0

SREM命令

srem key member [memebr...]

删除集合中的一个或多个member,返回值为成功删除的个数

集合操作命令

集合的操作主要是求交集,并集,差集

SINTER命令

sinter key [key...]

求所有集合的交集,此处一个key对应一个集合,时间复杂夫为O(N*M),N为最小的集合元素个数,M为最大的集合元素个数,返回结果为交集后的元素

SINTERSTORE命令

sinterstore destination key [key...]

将算好的交集方在destination集合中,返回交集的个数

SUNION命令

sunion key [key...]

返回所有key并集的结果,时间复杂度O(N),N指的是总的元素个数,返回值为并集的结果

SUNIONSTORE命令

sunionstore destination key [key...]

直接把并集的结果保存到destination集合中,返回值为并集元素的个数

SDIFF命令

sdiff key [key...]

计算第一个key对后面的差集,结构跟key的顺序有关,时间复杂度O(N),返回值为差集的结果

SDIFFSTORE命令

sdiffstore destination key [key...]

将计算差集的结果保存到destination集合中,返回差集结果的个数

命令小结

内部编码

intset(整数集合)

当元素个数均为整数,并且元素的个数不是很多的时候,就会以intset作为内部编码,这种结构有特定的优化,能够节省空间

hashtable(哈希表)

当集合中包含其他除整数外的元素,或者集合个数较多时就会转化为哈希表的结构

应用场景

标签系统

短视频软件会将不同种类的视频抽象成一个个标签,根据每个用户在不同视频上的停留时间,来给当前用户打上不同标签,结合每个用户所属标签不同推送不同的视频。

信息去重

一个互联网产品在衡量用户量和用户规模时,会根据PV(page view) 指的是用户每次访问服务器都会产生一个PV, 还有一个UV(user view)同一个用户访问服务器只会产生一个UV,而这个UV去重的过程就是利用set来实现的。

社交网络

根据set有交集并集差集的特点,在社交软件中能够根据你当前的好友信息,向你推送你可能认识的人、显示共同好友,查找单方面好友。

zset

zset为有序集合,这里的有序指的是升序或者降序,set为无序,list为顺序,注意区分。

ZADD命令

zadd key [NX|XX] [GT|LT] [CH] [INCR] score member [score member...]

往有序集合中添加元素和分数

参数选项:

XX:只更新当前已经存在的member,不存在则操作失败

NX:只添加新的member,对已经存在的不做处理

不加XX|NX:member不存在就添加,存在就更新分数

LT:现在需要更新的分数必须比之前的分数小,否则更新失败(元素不存在时不阻止添加元素)

GT:现在需要更新的分数必须比之前的分数大,否则更新失败(元素不存在时不阻止添加元素)

CH:影响zadd的返回值,本来zadd返回的是新增成功的元素的个数,加上CH会包含修改值的个数

INCR:表示对某个成员的分数进行累加(增加),只能指定一个元素的成员,如果成员不存在,则相当于添加新成员。返回值会变成增加后的分数。

排序方式:zset内部是按照升序方式进行排列的。

修改分数,如果位置发生变化会重新排序

ZRANGE命令

zrange key start stop  [withscores]

返回指定区间的元素,分数按照升序返回,withscores参数表示把元素对应的分数也带上返回

ZREVRANGE命令

zrevrange key start stop  [withscores]

根据指定区间,按照分数降序返回

ZRANGEBYSCORE命令

zrevrangebyscore key min max  [withscores]

根据分数区间来找元素,返回值为区间的元素和分数

ZCARD命令

zcard key

获取key中元素的个数,时间复杂度O(logN)

ZCOUNT命令

zcount key min max

返回分数在 min 和 max 之间的元素个数,默认情况下,min 和 max 都是包含的,时间复杂度O(logN),zcount在计算的时候,是现根据分数找到元素,在根据元素获取排名,再把排名相减,得到元素个数。返回值为符合要求元素的个数

但也可以通过 左括号( 来进行排除。

max和min都还可以写成浮点数,zset中支持使用-inf表示负无穷大,inf表示无穷大

ZPOPMAX命令

zpopmax key [count]

删除并返回分数最大的元素,也可设置删除的个数count,时间复杂度O(logN),虽然redis的有序集合记录了结尾的元素,但是删除的时候使用的通用的删除函数,导致出现了重新查找的过程。

ZPOPMIN命令

zpopmin key [count]

删除并返回分数最小的元素,也可以设置删除的个数count,时间复杂度O(logN)原理同zpopmax

ZRANK命令

zrank key member 

获取集合中指定元素的排名下标(升序),时间复杂度O(logN),返回值为该membe对应的分数在有序集合中的排名下标的下标(下标从0开始)

ZREVRANK命令

zrevrank key member 

获取集合中指定元素的排名下标(降序),时间复杂度O(logN),返回值为该membe对应的分数在有序集合中的排名的下标(下标从0开始)

ZSCORE命令

zscore key member

查询指定元素的分数,时间复杂度O(1),此处Redis进行了专门的优化,花费了额外的空间代价,提示了查询速度,返回值为对应元素的分数

ZREM命令

zrem key member [member...]

删除有序集合中指定的元素,时间复杂度为O(logN*M),返回值为删除成功的元素个数

ZREMRANGEBYRANK命令

zremrangebyrank key start stop 

删除指定区间(排名下标)的元素,时间复杂度为O(logN+M),查询只需查询一次花费logN,N为整个有序集合的元素个数,M为start-stop区间中的元素个数,返回值为删除成功的元素个数

ZREMRANGEBYSCORE命令

zremrangebyscore key min max

删除指定分数范围的元素,时间复杂度O(logN+M),返回值为成功删除元素的个数

ZINCRBY命令

zincrby key increment member

对有序集合中指定的member进行增加increment分数(可以是负数也可以是小数),返回值为增加后的分数结果

阻塞命令

主要是zpopmax和zpopmin的阻塞版本

BZPOPMAX命令

bzpopmax key [key...] timeout

删除有序集合中,最大的一个元素,该命令为zpopmax的阻塞版本,timeout时间单位为秒,时间复杂度为O(logN),返回值包括key,member,score

如果有序表中存在元素,就会和zpopmax一样直接返回结果,如果key中没有元素了,则会进入阻塞等待

如果在timout时间内有元素被添加则会输出,如果没有则会返回nil

BZPOPMIN命令

bzpopmin key [key] timeout

删除有序集合中,最小的一个元素,该命令为zpopmin的阻塞版本,timeout时间单位为秒,时间复杂度为O(logN),返回值包括key,member,score

当有序表中存在元素那么效果和zpopmin一样,如果没有元素则会进入阻塞等待,当集合中有元素被添加则会唤醒返回元素,超过等待时间还没元素则会返回nil

集合操作命令

zset的集合操作包括zinter,zunion,zdiff,zinterstore,zunionstore,zdiffstore,这些操作命令和set中的集合操作命令类似,但是zset是针对元素member进行集合操作和分数score多少无关

zinterstore命令

zinterstore destination numkeys key [key...] [WEIGHTS weight [weight...] ] [AGGREGATE sum|min|max]

destination:表示交集过后的结果存放的位置key

numkeys:表示接下来要进行交集的key的数量

WEIGHTS:表示对每个key所占的权重

AGGREGATE:表示交集后member对应的score是多少,默认情况下是用到sum

时间复杂度O(N*K + M*log(M)),N 是输入的有序集合中元素数量最少的那个集合的大小,K是输入有序集合的数量,M是结果集中元素的数量

返回值为交集成功后包含的元素个数

下面是添加参数的用法

首先,根据每个key中元素的找到相同的member。

其次,因为设置了权重占比,那么key1的所有score就会乘1,key2的所有score就会乘2。

最后,AGGREGATE的参数为MAX,会根据通过权重计算后的score,最大的score方在key4中。

zunionstore命令

zunionstore destination numkeys key [key...] [WEIGHTS weight [weight...] ] [AGGREGATE sum|min|max]

求多个有序集合的并集并保存起来,参数和求交集相同,返回值为并集成功后包含的元素个数

命令小结

内部编码

如果有序集合中的元素个数较少,或者的单个元素体积较小,使用listpack来存储。如果当前元素个数比较多,或者单个元素体积非常大,使用skiplist来存储。

在redis的配置文件中可以设置skiplist跳表的条件,zset-max-listpack-entries表示元素的个数,zset-max-listpack-value表示元素的大小单位字节

应用场景

游戏排行榜

可以将每个游戏玩家的id和分数存储到有序集合中,通过分数进行排序,从而展示每个用户的排名。

微博热搜榜

热搜榜的维度可能是多方面的:阅读量、点赞量、转发量、评论量等多个维度获取,然后每个维度有不同的权重划分,在通过求并集方式得到最终热搜排行榜。

其他数据类型

stream

Redis 的 Stream 就是个能存流式数据的类型,类似于消息队列一样。

消息按顺序保存,有唯一 ID,掉电不丢失。

支持多组人同时消费,各看各的,消息处理完得确认。

能回头看历史消息,适合日志收集、实时传数据这些场景。

geospatial

Redis 的 GEO 类型专门用来存地理位置信息(比如经纬度)。

能方便地查两点距离、找某个范围内的地点,还能按距离排序。

适合做附近的人、周边店铺这类功能,用起来简单直接。

hyperloglog

Redis 的 HyperLogLog 是一种专门用来做基数统计的类型。

基数就是 “不重复的元素个数”,比如统计网站独立访客数。

它的特点是占内存极小,不管统计多少数据,大概就几 KB。

适合那些需要统计 “有多少不同个体,但不需要知道每个内容是啥”,又不想耗太多内存的场景。

精度存在一定误差,误差大概是0.81%

bitmaps

Redis 的 Bitmaps 是一种通过位(bit) 来存储数据的类型,本质是对字符串(String)的位操作封装。

它把数据按位记录(1 或 0),比如用 1 表示 “已签到”,0 表示 “未签到”。

优点是极度省内存(1 字节能存 8 个状态),适合做连续天数签到、用户在线状态等场景的统计。

核心是用位运算(如与、或、非)高效处理批量数据,比如统计 “连续 7 天都签到的用户”。

bitfields

Redis 的 BITFIELD 是个灵活的位操作命令。

bitfields可以理解成一串二进制序列(字节数组),同时可以把这个字节数组中的某几个位,赋予特定的含义,并且可以进行读取/修改/算术运算等相关操作。

能把二进制数据分成不同长度的 “小段”,直接读写、增减这些小段里的数值。

可以一次干多个操作,适合用少量位存多个小数据(比如等级、状态),省内存又方便。

渐进式遍历

对于数据量大的内容想要进行遍历,如果使用keys * 进行遍历可能会导致服务器阻塞,而渐进式遍历就是避免这一情况, 每一次只取到其中的一部分数据,多次遍历来获取所有数据。

渐进式遍历包含一组命令,但使用方法类似,只需了解最典型的scan命令即可掌握其他命令

scan cursor [MATCH pattern] [COUNT count] [TYPE type]

cursor:表示为光标,作为每一次遍历的其实位置,起始光标位置为0。

MATCH:通配符,和keys的参数一样

COUNT:给redis建议每一次需要得到的个数,redis不一定会按照设置count返回。

TYPE:指定遍历的key中value的类型。

返回值:返回下一次遍历的光标位置 和 输出的元素个数,返回值为0代表以及遍历结束了

注意光标不是下标,光标是对于计算机自己能够清除接下来要遍历的位置,返回的光标结果可能会和想象中数组的下标不一致。

这里的渐进式遍历,在遍历过程中,不会在服务器这边存储任何的状态信息,此处的遍历是课随时终止的,不会对服务器产生任何的副作用。

注意:scan虽然解决了遍历的阻塞问题,但是在遍历过程中存在对集合的修改增加删除,可能导致遍历重复或者遗漏

http://www.lryc.cn/news/604363.html

相关文章:

  • Three.js 与 WebXR:初识 VR/AR 开发
  • 国产化再进一步,杰和科技推出搭载国产芯片的主板
  • LoRaWAN协议,提升公用事业能源效率的“隐形引擎”
  • Ubuntu22.04.1搭建php运行环境
  • C++ 高性能容器:ankerl::unordered_dense::map
  • 元码智能“大眼睛”机器人首发,智启生活新纪元!
  • RabbitMQ 发送方确认的两大工具 (With Spring Boot)
  • Metering Solution for Solar + Storage光伏+储能计量解决方案 UL 2735 Certification功率表能源监测电表
  • 第2章 cmd命令基础:常用基础命令(2)
  • c++之基础B之sort排序(第三个参数没有)(第二课)
  • 在macOS上使用VS Code和Clang配置C++开发环境
  • 湖北大学暑期实训优秀作品:面向美丽中国的数据化可视平台
  • 涉及实验(随机分组)的一些概念
  • 【swoole Windows 开发(swoole-cli 开发 hyperf)】
  • 时间序列预测的自回归方法
  • Product Hunt 每日热榜 | 2025-07-30
  • tplink er2260t配置带vlan的pppoe拨号
  • Java学习第八十九部分——“层”(续)
  • 学会使用golang zap日志库
  • 【动态规划算法】斐波那契数列模型
  • 嵌入式开发学习———Linux环境下数据结构学习(五)
  • 服务器与电脑主机的区别,普通电脑可以当作服务器用吗?
  • 从结构到交互:HTML5进阶开发全解析——语义化标签、Canvas绘图与表单设计实战
  • MCP提示词工程:上下文注入的艺术与科学
  • 【机器学习11】“分类算法“评估矩阵:从对数损失、AUC和ROC、混淆矩阵与分类报告等角度来评估算法
  • 小架构step系列30:多个校验注解
  • Mysql事务基础
  • LeetCode Hot 100:15. 三数之和
  • 大模型赋能:台风“竹节草”精细化路径预测实践
  • 硬件电路设计(基本元器件)