【Redis】数据结构---String
创始人
2024-03-02 22:28:46

文章目录

    • String(字符串)
      • 1.Redis 键(key)
      • 2.String(字符串)
        • 2.1常用命令
        • 2.2.String底层结构
      • 3.空间分配策略
        • 3.1空间预分配
        • 3.2惰性空间释放
        • 3.3为什么SDS的最大长度是512M?
      • 4.SDS面试题

String(字符串)

1.Redis 键(key)

  • keys *查看当前库所有key (匹配:keys *1)
  • exists key判断某个key是否存在
  • type key 查看你的key是什么类型
  • del key 删除指定的key数据
  • unlink key 根据value选择非阻塞删除。仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作。
  • expire key 10 10秒钟:为给定的key设置过期时间
  • ttl key 查看还有多少秒过期,-1表示永不过期,-2表示已过期

image-20221130014337304

执行上面的操作

image-20221130015234931

2.String(字符串)

String是Redis最基本的类型,一个key对应一个value。

String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。

String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M

2.1常用命令

set 添加键值对

image-20221130021209021

关于set的其他参数

  • NX:当数据库中key不存在时,可以将key-value添加数据库
  • *XX:当数据库中key存在时,可以将key-value添加数据库,与NX参数互斥
  • EX:key的超时秒数
  • PX:key的超时毫秒数,与EX互斥

get 查询对应键值

append 将给定的 追加到原值的末尾

strlen 获得值的长度

setnx 只有在 key 不存在时 设置 key 的值

image-20221130022154240

数字类型的命令:

incr

  • 将 key 中储存的数字值增1
  • 只能对数字值操作,如果为空,新增值为1

decr

  • 将 key 中储存的数字值减1
  • 只能对数字值操作,如果为空,新增值为-1

incrby / decrby <步长>将 key 中储存的数字值增减。自定义步长。

  • 注意:INCR类型的命令是原子的,Redis单命令的原子性主要得益于Redis的单线程。

image-20221130022352456

mset …

  • 同时设置一个或多个 key-value对

mget …

  • 同时获取一个或多个 value

image-20221130022635543

msetnx …

  • 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
  • 该命令具有原子性:其中有一个key是存在的,则都创建失败

image-20221130022855031

getrange <起始位置><结束位置>

  • 获得值的范围,类似C++中string类的substr。

setrange <起始位置>

  • 用 覆写所储存的字符串值,从<起始位置>开始(索引从0****开始)。

image-20221130023035175

setex <过期时间>

  • 设置键值的同时,设置过期时间,单位秒。

getset

  • 以新换旧,设置了新值同时获得旧值。

2.2.String底层结构

Redis是用C语言写的,但是对应Redis的Sting,并不是C 语言中的字符串(即以空字符’\0’结尾的字符数组);Redis自定义了数据结构SDS(simple dynamic string)【简单动态字符串】,并将 SDS 作为 Redis的默认字符串表示。

struct sdshdr{//记录 buf 数组中未使用字节的数量int free;//记录buf数组已使用字节的数量//等于 SDS 保存字符串的长度int len;//字节数组,用于保存字符串char buf[];	//柔性数组
}

image-20221130024613783

  • len为字符串的实际长度,保证了获取字符串长度时为O(1)操作
  • free为buf数组中剩余的空间大小
  • buf 保存字符串的数组
  • 如果长度不够,会主动申请空间
  • redis实际开辟的空间为len+free

优点:

减少修改字符串的内存重新分配次数

C语言字符串由于不记录字符串长度,所以如果要修改字符串,必须重新分配内存(先释放再申请)。因为如果没有重新分配,字符串长度增大时会造成内存缓冲区溢出,字符串长度减小时会造成内存泄露。

对于SDS,由于len属性和free属性的存在,对于修改字符串SDS实现了空间预分配和惰性空间释放两种策略:

  • **空间预分配:**对字符串进行空间扩展的时候,扩展的内存比实际需要的多,这样可以减少连续执行字符串增长操作所需的内存重分配次数。
  • **惰性空间释放:**对字符串进行缩短操作时,程序不立即使用内存重新分配来回收缩短后多余的字节,而是使用 free 属性将这些字节的数量记录下来,等待后续使用。

二进制安全

  • C字符串以空字符作为字符串结束的标识,而对于一些二进制文件(如图片等),内容可能包括空字符串,因此C字符串无法正确存取;
  • 而所有 SDS 的API 都是以处理二进制的方式来处理 buf 里面的元素,**并且 SDS 不是以空字符串来判断是否结束,而是以 len 属性表示的长度来判断字符串是否结束。**所以SDS可以保存图片、音频等文件内容。

3.空间分配策略

3.1空间预分配

C++中数组在进行扩容时,往往会申请一个更大的数组,然后把数组拷贝过去。Redis同样基于这种策略提高了空间预分配机制。

当执行字符串增长操作并且需要扩展内存时,程序不仅仅会给SDS分配必需的空间还会分配额外的未使用空间,其长度存到free属性中。具体如下:

  • **如果修改后len长度将小于1M,这时分配给free的大小和len一样;**例如修改过后为10字节, 那么给free也是10字节,buf实际长度变成了10+10+1 = 21byte(别忘记了\0的存在)
  • **如果修改后len的长度大于等于1M,这时分配给free的长度为1M;**例如修改过后为30M,那么给free是1M.buf实际长度变成了30M+1M+1byte

image-20221130031707362

3.2惰性空间释放

惰性空间释放用于字符串缩短的操作。当字符串缩短是,程序并不是立即使用内存重分配来回收缩短出来的字节,而是使用free属性记录起来,并等待将来使用。

image-20221130031932892

3.3为什么SDS的最大长度是512M?

Redis字符串使用int类型表示长度,一共有32个比特位。2^32字节=512M

4.SDS面试题

1.SDS如何兼容C语言字符串?如何保证二进制安全?

C99中提到,结构体的最后一个成员如果是一个数组,大小不确定,那么就是一个柔性数组。

SDS对象中的buf是一个柔性数组,上层调用时,SDS直接返回了buf。由于buf是直接指向内容的指针,所以兼容C语言函数。而当真正读取内容时,SDS会通过len来限制读取长度,而非“\0”,所以保证了二进制安全。

2.SDS是如何扩容的?

空间预分配。先判断扩容长度与free的大小关系,如果够就直接拼接字符串,如果不够使用空间预分配的方式扩容。

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...