首页 > 数据库 >redis自学(1) 动态字符串SDS

redis自学(1) 动态字符串SDS

时间:2024-02-20 15:27:50浏览次数:29  
标签:SDS redis 内存空间 C语言 内存 字符串 自学

  字符串是redis最常见的数据结构,但redis并没有直接使用C语言的字符串,是因为C语言本身其实是没有字符串的,所谓的字符串其实是字符数组(Java语言中的字符串是一个对象),所以C语言的字符串有很多问题: ① 获取字符串长度需要通过运算 C语言的字符串数组都是以’\0’结尾,这是一个字符串的结束标识,表示字符串到此为止。但是要想获取这个字符串的长度,就只能运算减去’\0’以后才能获得字符串的长度。或者就是一个一个遍历,用计数器计数直到’\0’停止。这样时间复杂度会很高,有可能会达到O(N)。 ② 非二进制安全 如果因为需求,需要字符串中间包含’\0’,那么C语言的字符串就不能用了,因为C语言的字符串中间不能包含’\0’这样的特殊字符,所以C语言的字符串是非二进制安全的。 ③ 不可修改 C语言的字符串是存在常量池里的,要想拼接需要申请新的内存空间,很麻烦。(Java中的字符串是不可变的,也就是说,一旦创建了字符串对象,其内容是不可修改的。如果对一个字符串进行修改,实际上是生成了一个新的字符串对象。当我们对一个字符串进行修改时,Java会先检查这个字符串是否与其他对象共享同一块内存,即是否存在其他的字符串对象与其指向同一块内存地址。如果存在,则不是在原来的字符串对象中直接进行修改,而是创建一个新的字符串对象,将修改后的值存储在新的字符串对象中。如果不存在,那么直接在原字符串对象中进行修改,并返回该对象的引用。这种操作被称为"String共享优化",可以提高字符串性能和节约内存。)   因此redis自己构建了一个新的字符串结构,简单动态字符串SDS(simply dynamic string)  

 

SDS本质是一个结构体,类似于java里面的类 uint8_t 的意思是无符号整型8个比特位 能存2的8次方减1=255个字节 len 保存的是buf数组的字节数,因为buf数组其实还是有’\0’这个特殊字符,所以实际上buf能存的字节到不了255个 而是254个,这是为了兼容C语言字符串,实际读取的时候’\0’用不上。长度已经在len存储了,读取的时候读取len长度的字节就行了,也保证了二进制安全。同样的获取字符串长度,直接取len就行了,不用运算。 alloc是buf申请的总字节数,C语言的内存空间是手动申请的,而buf的内存申请有多大是存在alloc里的。因为数组申请的空间和使用的空间不一定一样,所以才会有len和alloc两个变量。 flags表示这个SDS是什么类型的,上面的SDS只是多种SDS的一种。如下  

 

uint8_t和uint64_t的内存空间大小不同,是因为它们定义了不同位数的整型变量。 uint8_t是一种8位无符号整数类型,占用1个字节(8位)的内存空间,可以存储0~255之间的整数。 而uint64_t是一种64位无符号整数类型,占用8个字节(64位)的内存空间,可以存储0~18446744073709551615之间的整数。   flag的类型  

 

SDS结构  

 

SDS具备动态扩容能力 内存预分配规则: 1、如果新字符串小于1M,则新空间为扩展后字符串长度的两倍+1。(这个+1是留给’\0’的) 2、如果新字符串大于1M,则新空间为扩展后字符串长大+1M+1。 为什么要有内存预分配:   Linux分为用户态和内核态,申请内存需要从用户态切换到内核态,但申请内存这个动作非常消耗资源。而内存预分配减少了之后变动申请内存的次数,提高性能。 SDS优势 ① 获取字符串长度的时间复杂度O(1) ② 支持动态扩容 ③ 减少内存分配次数 ④ 二进制安全

标签:SDS,redis,内存空间,C语言,内存,字符串,自学
From: https://www.cnblogs.com/bulesea/p/18023167

相关文章

  • 认识Redis:不只是缓存,还有这些厉害的功能!
    在当今数据驱动的世界中,快速存取信息成为了技术发展的关键。而在众多存储解决方案中,Redis以其独特的魅力和强大的功能,成为了开发者们的宠儿。今天,就让我们一起来认识一下Redis。一、Redis是什么,可以用来干什么?Redis,英文全称是RemoteDictionaryServer(远程字典服务),是一个开源......
  • 4-Redis十大关系之哈希Hash
    Redis十大关系之哈希Hash:Map<String,Map<Object,Object>>HSETkeyfieldvaluefieldvalue...:设置属性值HGETkeyfield:获取对应属性值HGETALLkey:遍历哈希HDELkeyfield:删除field对应的属性HLENkey:获取某个key内的全部数量HEXISTSkeyfield:判断key中有没有fie......
  • NoSQL 数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数
    NoSQL数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数据存储提供无与伦比的灵活性与性能!【官网地址】:http://www.redisant.cn/nosql介绍直观的用户界面从单一应用程序中同时连接Redis、Memcached、SSDB、LevelDB、RocksDB,你可以快速轻松地创建......
  • Redis3主3从+pg1主2从
    目录一、环境准备二、安装服务器部署redis集群1.安装需求2.创建redis3.上传软件4.编译安装4.1编译安装root用户编译否则问题一4.2验证安装是否成功4.3操作过程5.新建redis集群配置文件5.1新建配置文件目录,复制模板配置文件5.2修改默认配置文件6.部署步骤6.1启动redi......
  • 3-Redis十大关系之列表List
    Redis十大类型之ListList适用于单key多value的情况。底层是由双端链表组成。LPUSH:LPUSHkeyv1v2v3...从左边插入RPUSH:RPUSHkeyV1V2V3V4V5...从右边插入LRANGEkeystartend:进行遍历,注意不存在RRANGE!LPOP和RPOP:分别是从左边移除一个元素和右边移除一个元素......
  • redis高频问题--redis单线程
    redis单线程问题引入●Redis是纯内存操作,执行速度非常快●采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题●使用I/O多路复用模型,非阻塞IORedis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,I/O多路复用模型主要就是实现......
  • redis高频问题--哨兵模式
    哨兵模式运行原理redis哨兵模式脑裂主节点的网络问题导致暂时断开连接了,哨兵重新选举了一个主节点,等到老的主节点重新连上时,将会降级为从节点,它清空自身的数据从主节点重新同步此时,在老的主节点网络出问题期间收到的数据将会丢失。需要避免这个问题,可以对redis进行配置......
  • Docker安装Redis容器
    Docker安装Redis容器查看原文安装Redis#下载redis镜像dockerpullredis:5#检查当前所有Docker下载的镜像dockerimagesredis配置文件创建以下文件及文件夹,方便配置及管理redismkdir-p/docker/redismkdir-p/docker/redis/datatouch/docker/redis/redis.conf......
  • windows下安装Redis
    一、下载 二、安装、1双击运行: 2agree: 3修改路径勾选环境变量: 4配置端口勾选防火墙 5设置内存限制 6安装完成 三、修改配置,启动打开配置文件:redis.windows.conf1修改访问IP 2修改密码 3启动redis-serverredis.windows.conf ......
  • 06 高级应用-Redis Sentinel 和高可用性
    在Redis的应用中,高可用性是一个重要的考虑因素。RedisSentinel提供了监控、通知、自动故障转移和服务发现的机制,确保Redis的高可用性。以下是关于RedisSentinel的详细介绍:RedisSentinel的主要功能监控:Sentinel不断检查Redis主服务器和从服务器是否正常运行。通......