Redis7

Redis是基于内存的K-V键值对内存数据库

image-20231022161340540

浅谈Redis7新特性

  1. 主要是自身底层性能和资源利用率上的提高和优化。

  2. 多AOF文件支持

  3. config命令增强

  4. 限制客户端内存使用

  5. listpack紧凑列表调整

  6. 访问安全性增强

  7. Redis Functions(要抢Lua脚本的饭碗)

  8. RDB保存时间调整,保存规则发生变化。

  9. 命令新增和变动

Redis服务与客户端日常操作

redis.conf配置文件,改完后确保生效,记得重启

  1. 后台启动:默认daemonize no 改为 daemonize yes image-20231209102030291

  2. 关闭保护模式:默认protected-mode yes 改为 protected-mode no image-20231209102108303

  3. 注释掉bind 127.0.0.1 直接注释掉这行(默认bind 127.0.0.1只能本机访问)或改成本机IP地址,否则影响远程IP连接 image-20231209102126050

  4. 添加redis密码:打开注释并把requirepass foobared 改为 requirepass + 你自己设置的密码

指定配置文件并启动服务:redis-server /myredis/redis7.conf

查看一下是否启动成功:ps -ef |grep redis|grep -v grep

连接客户端 redis-cli -a 111111 -p 6379

Linux中关闭redis服务

  • 单实例关闭

redis-cli -a 111111 shutdown

  • 多实例关闭指定端口

redis-cli -p 6379 shutdown

redis客户端中关闭redis服务

直接 shutdown

Redis十大数据类型

这里说的数据类型都是指value,key的数据类型都是字符串!

image-20231022161309739

Redis键(key)的常用命令

  • keys * 查看当前库所有的key

  • exists key 判断某个key是否存在

  • type key 查看key是什么数据类型

  • del key 删除指定key的数据

  • unlink key 非阻塞删除,仅将keys从keyspace元数据中删除,真正的删除会在后续异步中操作

  • ttl key 查看还有多少秒过期,-1表示永不过期,-2表示已过期

  • expire key 为给定的key设置过期时间[EXPIRE-秒;PEXPIRE-毫秒;EXPIREAT-秒(时间戳)]

  • move key dbindex[0-15] 将当前数据库的key移动到给定的数据库db中

  • select dbindex 切换数据库[0-15],默认为0

  • dbsize 查看当前数据库key的数量

  • flushdb 清空当前库

  • flushall 通杀全部库

各类型常用命令

  • Redis命令是不区分大小写的,而key是区分大小写的

  • 永远的帮助命令help @类型 help@string help@list .....

String

最常用

GET key

 

SET key value [NX | XX] [GET] [EX seconds | PX milliseconds | EXAT unix-time-seconds | PXAT unix-time-milliseconds | KEEPTTL]

可选参数

  • NX:键不存在时设置

  • XX:键存在的时候设置

  • GET :返回指定键原本的值,若不存在时返回nil

  • EX:以秒为单位设置过期时间

  • PX:以毫秒为单位设置过期时间

  • EXAT:设置以秒为单位的UNIX时间戳所对应的时间为过期时间

  • PXAT:设置以毫秒为单位的UNIX时间戳所对应的时间为过期时间

  • KEEPTTL:保留设置前指定键的过期时间

    SET命令使用EX、PX、NX参数的效果等同于SETEX、PSETEX、SETNX命令(根据官方文档描述,未来版本中SETEX、PSETEX、SETNX命令可能会被淘汰)

返回值

OK:设置成功;

nil:未执行SET命令,如不满足NX、XX条件等。

若使用GET参数,则返回该键原来的值,或在键不存在时返回nil。

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

System.out.println(Long.toString(System.currentTimeMillis()/1000L));

 

同时设置/获取多个键值

MSET key value [k1 v1 k2 v2 k3 v3 .....]

MGET key [k1 k2 k3 ......]

MSETNX key value [k1 v1 k2 v2 k3 v3 ......]

注意:msetnx中但凡有一个key是存在的,那么整个msetnx将不会执行(返回0)

 

设定/获取指定区间范围内的值

setrange/getrange

getrange:类似 between...and 的关系

image-20231022181422065

0到-1表示全部

setrange:设置指定偏移位置的值

image-20231022181608981

数值增减(一定要是数字才能加减)

INCR key 递增数值

INCRBY key increment 增加指定的整数

DECR key 递减数值

DECRBY key decrement 减少指定的整数

 

获得字符串长度和追加

STRLEN key 获取字符串长度

APPEND key value 追加字符串

 

分布式锁

set key value [EX seconds][PX milliseconds] [NX|XX]

image-20231022182453425

 

getset(先get再set)

getset 将给定key的值设为value,并返回 key 的旧value

image-20231022182710438

 

list

一个双端链表的结构,容量是n的32次方减1,大概40多亿,主要功能有push/pop等,一般用在栈、队列、消息队列等场景。

left、right都可以插入添加;

如果键不存在,创建新的链表;

如果键已存在,新增内容;

如果值全移除,对应的键也就消失了。

它的底层实际上是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。

image-20231022191541264

lpush、rpush、lrange()

lpush:先进后出

rpush:先进先出

lrange:遍历

image-20231022192200201

image-20231022192229308

image-20231022192250458

lpop、rpop

lpop:弹出第一个元素

rpop:弹出最后一个元素

image-20231022192521498

lindex

按照下标获得元素

image-20231023230341033

llen

获取list中元素个数

image-20231023230518663

Irem key count element

删除count个element元素

image-20231025215739197

ltrim key start stop

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

image-20231025220100282

rpoplpush 源列表 目的列表

把源列表中的最后一个元素放到目的列表的第一个元素位置

image-20231025221052244

lset key index value

给list中的指定索引设置一个新的value

image-20231025221622065

linsert key before/after 已有值 新的值

在已有值前面/后面插入一个新的值

image-20231025221941356

应用场景:

命令场景
lpush likearticle:userid 微信关注的公众号只要发布了新文章,就会放进我的list中
lrange likearticle:userid 0 9 查看我订阅的全部文章,类似分页,下面0-9就是一次显示10条

 

hash

类似于Map<String,Map<Object,Object>>,String是key;Map<Object,Object>是value

HSET / HGET

设置/获取

image-20231025225218250

HMSET / HMGET

设置/批量获取字段(目前版本hset与hmset作用完全相同

image-20231025225258734

HGETALL

获取指定hash的所有字段

HDEL

删除指定hash的指定字段

HLEN

获取某个key内的全部数量

image-20231025225607613

HEXISTS key field

key中是否存在field字段

HKEY /HVALS key

得到key中所有的键/值

HINCRBY key field increment(整数)

key中的field字段增加一个整数

HINCRBYFLOAT key field increment(小数)

key中的field字段增加一个小数

HSETNX

添加字段,若未存在添加成功;已存在,添加失败。

image-20231026233546996

应用场景:购物车

 

set

无序、不可重复的集合

SADD key member[member...]

添加元素

image-20231026234642508

SMEMBERS key

遍历集合中所有元素

SISMEMBER key member[member...]

判断元素是否在集合中

image-20231026234804318

SREM key member [member....]

删除元素

image-20231026234923545

SCARD key

获取集合里的元素个数

srandmember key

 

SRANDMEMBER key [count]

从集合中随机展现出count个元素(元素不删除)

image-20231026235230165

 

SPOP key [count]

从集合中随机弹出count个元素,弹一个删一个

 

SMOVE key1 key2 member

把key1中的member元素移动到key2

image-20231026235830989

集合运算

SDIFF key1 key2

差集 ,属于key1集合但不属于key2集合的元素构成的集合(key1-key2)

image-20231028114032952

SUNION key1 key2

并集,属于key1集合或者属于key2集合的元素合并后的集合(A ∪ B)

image-20231028114237862

SINTER key1 key2

交集,属于key1集合同时也属于key2集合的共同拥有的元素构成的集合

image-20231028114348913

SINTERCARD numkeys key [key...] [LIMIT limit]

返回结果集的基数。返回由所有给定集合的交集产生的集合的基数

image-20231028115708899

应用场景:

微信抽奖小程序

image-20231028120348081

命令场景
SADD key userid 用户ID,立即参与按钮
SCARD key 显示已经有多少人参与了,上图23208人参加
SRANDMEMBER key2 随机抽奖2个人,元素不删除
SPOP key 3 随机抽奖3个人,元素会删除

微信朋友圈点赞查看同赞朋友

命令场景
sadd pub:msgID 点赞用户ID1 点赞用户ID2 新增点赞
srem pub:msgID 点赞用户ID 取消点赞
SMEMBERS pub:msgID 展现所有点赞过的用户
scard pub:msgID 点赞用户数统计,就是常见的点赞红色数字
SISMEMBER pub:msgID 用户ID 判断某个朋友是否对楼主点赞过

QQ推送可能认识的人

SDIFF user1 user2

zset

在set基础上,每个val值前加一个score分数值;

set是 key v1 v2 v3...

zset是 key score1 v1 score2 v2 score3 v3

 

ZADD key score member[score member]

添加元素

image-20231028130311472

ZRANGE key start stop [WITHSCORES]

按照元素分数从小到大的顺序,返回索引从start到stop之间的所有元素(0 ,-1 代表全部)

加上WITHSCORES 表示带上分数

image-20231028130534413

image-20231028130647075

ZREVRANGE

按照元素分数从大到小的顺序,返回索引从start到stop之间的所有元素(0 ,-1 代表全部)

加上WITHSCORES 表示带上分数

image-20231028131014790

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

获取指定分数范围的元素;

加上(:不包含

LIMIT作用是限制返回 limit 开始下标步 多少步

image-20231028131740415

image-20231028132108155

ZSCORE key member

获取元素的分数

 

ZCARD KEY

获取集合中元素的数量

 

ZREM key member [member...]

删除元素

image-20231028135104336

ZINCRBY key increment member

增加某个元素的分数

image-20231028220506251

ZCOUNT key min max

获得指定分数范围内的元素个数

image-20231028220859328

ZMPOP numkeys key [key...] MIN/MAX [COUNT count]

从键名列表中的第一个非空排序集中弹出一个或多个元素,他们是成员分数对

image-20231028222306510

image-20231028222556412

ZRANK key member

获得指定元素的下标值

image-20231028222955575

ZREVRANK key member

逆序获得下标值

image-20231028223407093

应用场景:

思路:定义商品销售排行榜(soreted set集合),key 为 goods:sellsort,分数为商品销售数量

商品编号1001的销量是9,商品编号1002的销量是15, zadd goods:sellsort 9 1001 15 1002

有一个客户又买了2件商品1001,商品编号1001销量加2 zindrby goods:sellsort 2 1001

求商品销量前10名 zrange goods:sellsort 0 9 withscores

 

bitmap(位图)

说明:用String类型作为底层数据结构实现的一种统计二值状态的数据类型

位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们称之为一个索引)。

Bitmap支持的最大位数是23位,它可以极大的节约存储空间,使用512M内存就可以存储多达42.9亿的字节信息(232 = 4294967296)

概述:由0和1状态表现的二进制位的bit数组

通过需求理解其作用:

  • 用户是否登录过,比如京东每日签到领京豆

  • 电影、广告是否被点击过

  • 钉钉打卡上下班、签到统计

  • .......

image-20231029150133981

 

SETBIT key offset value

setbit 键 值(只能0/1)

bitmap的偏移量是从0开始算的

 

GETBIT key offset

获取位图的值

image-20231029150723937

 

STRLEN key

获取位图占用的字节数,不是根据字符串长度计算的!凡是超过8位(0-7)后都是按照8位一组(1 byte)再扩容的!

image-20231029151437751

 

BITCOUNT key

当前位图中含有1的有多少

image-20231029151731397

BITOP operation destkey key [key...]

operation:AND / OR / NOT / XOR

案例一:

某个网站的用户有1000万,做个用户id和位置的映射

0号位对应用户id:uid:055d-ddf

1号位对应用户id:uid:dfd5-05d

......

签到了代表1,没签到代表0

image-20231029154526554

 

1号签到人数:4

2号签到人数:2

image-20231029154612059

 

连续两天都完成签到的用户有2个

image-20231029154425288

 

案例二:

sign:u1:202401 表示u1用户2024年1月签到信息

image-20231029160053494

查看该用户3号和31号是否签到:

image-20231029160246877

查看该用户2024年1月总计签到的天数:

image-20231029160334901

 

一年365天,全年天天签到占用多少字节?46

image-20231029160546616

按年去存储一个用户的签到情况,365 天只需要 365 / 8 ≈ 46 Byte,1000W 用户量一年也只需要 44 MB 就足够了。

假如是亿级的系统,

每天使用1个1亿位的Bitmap约占12MB的内存(108/8/1024/1024),10天的Bitmap的内存开销约为120MB,内存压力不算太高。

此外,在实际使用时,最好对Bitmap设置过期时间,让Redis自动删除不再需要的签到记录以节省内存开销。

 

HyperLogLog(基数统计)

看需求:

统计某个网站、文章的的UV(Unique Visitor)、一般理解为客户端IP,需要去重的。

用户搜索网站关键词的数量;统计用户每天搜索不同词条的个数

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

在 Redis 中,每个HyperLogLog键只需要花费12kb内存,就可以计算接近264 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比

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

案例Case:

全集 I = {2,4,6,8,11,22,44,4,8,10} 去掉重复的内容后: 基数 = {2,4,6,8,11,22,44,10} = 8

基数统计:用于统计一个集合中不重复的元素个数,就是对集合去重复后剩余元素的计算

总结:去重脱水后的真实数据

PFADD key element [element...]

添加指定元素到 HyperLogLog 中

PFCOUNT key [key...]

返回给定HyperLogLog 的基数估算值。

PFMERGE destkey sourcekey [sourcekey...]

将多个HyperLogLog合并为一个HyperLogLog

image-20231029163803081

 

GEO(地理空间)

移动互联网时代LBS(Location Based Service)应用越来越多,交友软件中附近的人、外卖软件中附近的美食店铺、高德地图附近的核酸检查点等等,那这种附近各种形形色色的XXX地址位置选择是如何实现的?

 

地球上的地理位置是使用二维的经纬度表示,经度范围 (-180, 180],纬度范围 (-90, 90],只要我们确定一个点的经纬度就可以名取得他在地球的位置。

例如滴滴打车,最直观的操作就是实时记录更新各个车的位置,然后当我们要找车时,在数据库中查找距离我们(坐标x0,y0)附近r公里范围内部的车辆

 

使用如下伪SQL即可:

select taxi from position where x0-r < x < x0+r and y0-r < y < y0+r

但是这样会有什么问题呢?

1.查询性能问题,如果并发高,数据量大这种查询是要搞垮数据库的

2.这个查询的是一个矩形访问,而不是以我为中心r公里为半径的圆形访问。

3.精准度的问题,我们知道地球不是平面坐标系,而是一个圆球,这种矩形计算在长距离计算时会有很大误差

核心思想就是将球体转换为平面,将平面中每一个区块转换为一点

image-20231029171405926

主要分为三步:

  1. 将三维的地球变为二维的坐标

  2. 再将二维的坐标转换为一维的点块

  3. 最后将一维的点块转换为二进制再通过base32编码

 

image-20231029173735244

GEOADD key longitude latitude member [longitude latitude member ...]

geoadd用于存储指定的地理空间位置,可以将一个或多个经纬度和该经纬度的位置名称添加到指定key中

longitude :经度

latitude:纬度

member:位置名称

 

GEOPOS key member [member ...]

用于从给定的key里返回所有指定名称(member)的经纬度,不存在的返回null

 

解决中文乱码

--raw

image-20231029174352653

 

GEOHASH key member [member ...]

返回坐标的geohash表示

 

GEODIST key member1 member2 [M|KM|FT|MI]

两个位置之间的距离;m 米 km 千米 ft 英尺 mi 英里

 

GEORADIUS key longitude latitude radius M|KM|FT|MI [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count [ANY]] [ASC|DESC] [STORE key] [STOREDIST key]

以给定的经纬度为中心,返回键包含的位置元素当中,与中心的距离不超过给定最大距离的所有位置元素

当前位置:116.418017 39.914402

image-20231029174419780

WITHDIST: 在返回位置元素的同时, 将位置元素与中心之间的距离也一并返回。 距离的单位和用户给定的范围单位保持一致。

WITHCOORD: 将位置元素的经度和维度也一并返回。

WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。 这个选项主要用于底层应用或者调试, 实际中的作用并不大

COUNT 限定返回的记录数。

 

GEORADIUSBYMEMBER key member

根据位置名称找出位于指定范围内的元素,与GEORADIUS 类似

image-20231029175201419

 

 

Stream

Redis5之前的痛点:

Redis消息队列的2种方案:

  1. List实现消息队列

按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

所以常用来做异步队列使用,将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。

List实现方式其实就是点对点的方式,它对于一对多的情况力不从心。

image-20231029180351772

LPUSH、RPOP 左进右出 RPUSH、LPOP 右进左出

image-20231029180517267

  1. 发布订阅(Pub/Sub)

Redis发布订阅有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。而且也没有 Ack 机制来保证数据的可靠性,假设一个消费者都没有,那消息就直接被丢弃了。

image-20231029180933945

Redis 5.0版本新增了一个更强大的数据结构-----Stream -> 一句话:Redis版的MQ消息中间件+阻塞队列

Stream 能干嘛

实现消息队列,它支持消息持久化、支持自动生成全局唯一ID、支持ack确认消息的模式、支持消费组模式等,让消息队列更加稳定和可靠

Stream的结构

image-20231029181711012

一个消息链表,将所有加入的消息都串起来,每个消息都有一个唯一的ID和对应的内容。

名词解释
Message Content 消息内容
Consumer group 消费组,通过XGROUP CREATE 命令创建,同一个消费组可以有多个消费者
Last_delivered_id 游标,每个消费组会有个游标 last_delivered_id,任意一个消费者读取了消息都会使游标 last_delivered_id 往前移动。
Consumer 消费者,消费组中的消费者
Pending_ids 消费者会有一个状态变量,用于记录被当前消费已读取但未ack的消息Id,如果客户端没有ack,这个变量里面的消息ID会越来越多,一旦某个消息被ack它就开始减少。这个pending_ids变量在Redis官方被称之为 PEL(Pending Entries List),记录了当前已经被客户端读取的消息,但是还没有 ack (Acknowledge character:确认字符),它用来确保客户端至少消费了消息一次,而不会在网络传输的中途丢失了没处理

特殊符号:

符号解释
- + 最小和最大可能出现的id
$ $表示只消费新的消息,当前流中最大的id,可用于将要到来的消息
> 用于XREADGROUP命令,表示迄今为止还没有发送给组中使用者的消息,会更新消费者组的最后ID
* 用于XADD命令中,让系统自动生成id

队列相关指令:

XADD

XADD 用于向Stream 队列中添加消息,如果指定的Stream 队列不存在,则该命令执行时会新建一个Stream 队列

* 号表示服务器自动生成 MessageID(类似mysql里面主键auto_increment),后面顺序跟着一堆 业务key/value

image-20231029184128275

image-20231029183819187

  1. 信息条目指的是序列号,在相同的毫秒下序列号从0开始递增,序列号是64位长度,理论上在同一毫秒内生成的数据量无法到达这个级别,因此不用担心序列号会不够用。millisecondsTime指的是Redis节点服务器的本地时间,如果存在当前的毫秒时间戳比以前已经存在的数据的时间戳小的话(本地时间钟后跳),那么系统将会采用以前相同的毫秒创建新的ID,也即redis 在增加信息条目时会检查当前 id 与上一条目的 id, 自动纠正错误的情况,一定要保证后面的 id 比前面大,一个流中信息条目的ID必须是单调增的,这是流的基础。

  2. 客户端显示传入规则:Redis对于ID有强制要求,格式必须是时间戳-自增Id这样的方式,且后续ID不能小于前一个ID

  3. Stream的消息内容,也就是图中的Message Content它的结构类似Hash结构,以key-value的形式存在。

 

XRANGE

遍历

image-20231029184355740

 

XREVRANGE

反转遍历

image-20231029184804484

 

XDEL

删除

image-20231029185237918

XLEN

获取Stream队列的消息的长度

image-20231029192046918

 

XTRIM key MAXLEN| MINID [LIMIT count]

用于对Stream的长度进行截取

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

MINID:允许的最小id,从某个id值开始比该id值小的将会被抛弃

MAXLEN

image-20231029192650891

截取后:

image-20231029192707800

 

MINID

image-20231029193103660

XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key...] id [id...]

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

COUNT 最多读取多少条消息

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

  • $代表特殊ID,表示以当前Stream已经存储的最大的ID作为最后一个ID,当前Stream中不存在大于当前最大ID的消息,因此此时返回nil

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

非阻塞式:

image-20231029203115867

阻塞式:

案例需要两个Redis客户端

第一个客户端输入阻塞获取消息的指令,此时客户端进入阻塞状态

image-20231029204856530

直到第二个客户端执行完成添加消息指令,第一个客户端才可获取到消息从而退出阻塞状态

image-20231029205234891

image-20231029205417497

Stream的基础方法,使用xadd存入消息和xread循环阻塞读取消息的方式可以实现简易版的消息队列,交互流程如下

image-20231029205500753

对比List结构

image-20231029205534231

 

 

消费组相关指令:

XGROUP CREATE key groupname

创建消费组

$表示从Stream尾部开始消费

0表示从Stream头部开始消费

创建消费者组的时候必须指定 ID, ID 为 0 表示从头开始消费,为 $ 表示只消费新的消息,队尾新来

image-20231029213729977

XREADGROUP GROUP

读取消息

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

消费组groupA内的消费者

stream中的消息一旦被消费组里的一个消费者读取了,就不能再被同组的其他消费者读取了,即同一个消费组里的消费者不能消费同一条消息:

image-20231029215207248

但是,不同消费组的消费者可以消费同一条消息:

image-20231029215455282

but,please thinking why we need 消费组?

让组内的多个消费者共同分担读取消息,所以,我们通常会让每个消费者读取部分消息,从而实现消息读取负载在多个消费者间是均衡分布的

 

image-20231029220222370

image-20231029220244090

 

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

  1. Streams 会自动使用内部队列(也称为 PENDING List)留存消费组里每个消费者读取的消息保底措施,直到消费者使用 XACK 命令通知 Streams“消息已经处理完成”。

  2. 消费确认增加了消息的可靠性,一般在业务处理完成之后,需要执行 XACK 命令确认消息已经被消费完成

image-20231029221158831

 

XPENDING

查询每个消费组内所有消费者【已读取、但尚未确认】的消息

image-20231029222010789

一旦某条消息被某个消费者处理了该消费者就可以使用 XACK 命令通知 Streams,然后这条消息就会被删除

XACK key group id

向消息队列确认消息处理完成

image-20231029222755716

XINFO STREAM key

用于打印Stream/Consumer/Group的详细信息

image-20231029223223064

 

Stream 使用建议:

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

仅代表本人愚见,非权威!

 

bitfield 位域(了解)

bitfield命令可以将一个Redis字符串看作是一个由二进制位组成的数组,并对这个数组中任意偏移进行访问。可以使用命令对一个有符号的5位整型数的第1234位设置指定值,也可以对一个31位无符号整型数的第4567位进行取值。类似地,本命令可以对指定的整数进行自增和自减操作,可配置的上溢和下溢处理操作。

bitfield命令可以在一次调用中同时对多个位范围进行操作:它接受一系列待执行的操作作为参数,并返回一个数组,数组中的每个元素就是对应操作的执行结果。

用途:

BITFIELD命令的作用在于它能够将很多小的整数储存到一个长度较大的位图中,又或者将一个非常庞大的键分割为多个较小的键来进行储存,从而非常高效地使用内存,使得Redis能够得到更多不同的应用——特别是在实时分析领域:BITFIELD能够以指定的方式对计算溢出进行控制的能力,使得它可以被应用于这一领域。

当需要一个整型时,有符号整型需在位数前加 i,无符号在位数前加 u。例如,u8是一个8位的无符号整型,i16是一个16位的有符号整型。

GET type offset

返回指定的位域

 

image-20231031211942593

image-20231031212014009

hello 等价于 0110100001100101011011000110110001101111;

SET type offset value

设置指定位域的值并返回它的原值

image-20231031213019131

 

溢出控制:

  • WRAP(默认):使用回绕(wrap around)方法处理有符号整数和无符号整数的溢出情况

  • SAT:使用饱和计算(saturation arithmetic)方法处理溢出,下溢计算的结果为最小的整数值,而上溢计算的结果为最大的整数值。

  • FAIL:命令将拒绝执行那些会导致上溢或者下溢情况出现的计算,并向用户返回空值表示计算未被执行。

 

INCRBY type offset increment

WRAP

image-20231031231119197

SAT

image-20231031231318584

FAIL

image-20231031231527607

 

十大数据类型结束啦!

 

posted @ 2023-10-19 23:46  小陈_winwah  阅读(36)  评论(0编辑  收藏  举报