首页 > 数据库 >Redis底层数据类型

Redis底层数据类型

时间:2023-07-14 14:45:27浏览次数:37  
标签:1.2 SDS 数据类型 Redis 空间 API 字符串 长度 底层

Redis底层基础数据类型

1.SDS的定义

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

img

1.2 SDS 与 C 字符串的区别

1.2.1 常数复杂度获取字符串长度

因为c字符串并不记录自身长度信息,所以为了获取一个c字符串的长度,程序必须遍历整个字符串,对遇到的每个字符进行计数,直到遇到代表字符串结尾的空字符串为止,这个操作的复杂度为O(N),和c字符串不同,因为SDS在len属性中记录了SDS本身的长度,所以获取一个SDS长度的复杂度仅为O(1)。
img

设置和更新SDS长度的工作是由SDS的API在执行时自动完成的,使用SDS无需进行任何手动修改长度的工作,通过使用SDS而不是C字符串,Redis将获取字符串长度所需要的复杂度从O(N)降低到O(1),这确保了获取字符串长度的工作不会成为Redis性能的瓶颈。所以即使我们对一个非常长的字符串使用STRLEN命令,也不会对系统的性能造成任何的影响

1.2.2 杜绝缓冲区溢出

除了获取字符串长度的复杂度高之外,c字符串不记录自身长度带来的另一个问题是容易造成缓存区溢出,与c字符串不同,SDS的空间分配策略完全杜绝了这种可能性,当SDS API 需要对SDS进行修改的时候,API会首先检查SDS的空间是否满足修改的要求,如果不满足会自动的扩展到所需要的大小,

1.2.3 减少修改字符串时带来的内存重分配次数

c字符串总不记录自身长度,而是采用N+1个字符长度的数组,每次增长或者缩短一个c字符串,程序总要对保存这个c字符串的数组进行一次内衬重分配操作,通过未使用空间,SDS实现了空间预分配和惰性空间释放两种优化策略。

1.2.3.1 空间预分配

空间预分配用于优化SDS的字符串增长的操作,当SDS的API对一个SDS进行修改,并且需要对SDS进行空间扩展的时候,程序不仅会为SDS分配必要的空间,还会为SDS分配额外的空间。额外空间的分配原则是

  1. 如果对SDS进行修改后,SDS的长度将小于1MB,那么程序分配和len属性一样的大小的未使用空间,实际空间将变为 2len+1的空间
  2. 如果对SDS进行修改后,SDS的长度大于1MB,那么程序将分配1MB的未使用空间,空间大小将为 N+1MB+1byte的空间

1.2.3.2 二进制安全

c 字符串中的字符必须符合某种编码,并且除了字符串的末尾之外,字符串里面不能包括空字符,否则,最先被程序读入的空字符将会被认为是字符串的结尾,这些限制使得c字符串将只能保留文本数据,而不能保存图片,音频视频,压缩文件这样的二进制文件,为了确保redis可以适用于不同的场景,SDS的API都是二进制安全的,因为,SDS是使用len属性的值而不是空字符来判断字符串是否结尾,使用二进制安全的SDS,而不是c字符串,使得Redis不仅可以保存文本数据,还可以保存任意格式的二进制数据,

1.2.3.3 兼容部分C字符函数

虽然SDS的API都是二进制安全的,但是他们一样遵循c字符串,以空字符结尾的惯例,这些API,总会将SDS保存的数据的末尾设置空字符串,这是为了让那些保存文本数据的SDS可以重用一部分<string.h>库定义的函数

1.2.4 总结

img

标签:1.2,SDS,数据类型,Redis,空间,API,字符串,长度,底层
From: https://www.cnblogs.com/pf666nb/p/17553430.html

相关文章

  • 【HMS Core】Health Kit 步数数据查询步骤咨询,血压/血氧的原子采样统计数据类型问题咨
    ​【问题描述】1、在进行步数查询---多日统计数据查询的时候,postman测试,发现了采样数据类型不匹配问题多日统计查询时,数据类型为 "com.huawei.continuous.steps.total"报错。反而数据类型为明细采样数据类型时“com.huawei.continuous.steps.delta”,正常返回。2、血压/血氧的......
  • 项目中,redis被用在了哪些地方
    1、最常用用来当缓存使用,最常见缓存的是用户数据,毕竟基于springsecurity开发的话,默认的用户缓存方式就是直接jvm内存和外部缓存两种2、有些签到、排行榜功能会用,签到使用位图,因为用户数据量极大的时候用数据库记录存不太合适,签到数据也是几何倍数增长,但是其实数据库也能实现这......
  • springboot redis工具类之StringRedisTemplate 使用
    1、StringRedisTemplate是什么?StringRedisTemplate继承自RedisTemplate类,实现了BeanClassLoaderAware,Aware,InitializingBean,RedisOperations<K,V>接口。StringRedisTemplate是RedisTemplate以字符串为中心的扩展,由于针对Redis的大多数操作都是基于字符串的,因此此类提供了一个......
  • springboot中使用redis
    1、引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2、配置spring:redis:host:localhost#Redis服务器地址port:6379......
  • Redis底层数据结构
    Redis是什么?Redis是一个键值数据库,以“快”著称Redis是为什么这么快?我们都知道Redis很快,它在接收到一个键值对数据后,能以微妙级别的速度找到数据并快速完成操作。数据库这么多,为啥Redis能有这么突出的表现呢?一方面,这是因为它是内存数据库,所有操作都在内存上完成,内存的访问速......
  • Redis学习指南
    基础资料官方下载、安装、运行redis中文站thelittleredisbook(中文版)Redis几个认识误区 redis作者宣言建模Fast,easy,realtimemetricsusingRedisbitmaps监控、配置RedisCommander (在线运行命令。强烈不推荐,会把浏览器搞死!)RedisLive redmon(★推荐支持监控......
  • Java的数据类型
    标识符关键字  abstractassertbooleanbreakbyte      casecatchcharclassconstcontinue      defaultdodouble      elseforgotoifextends      finalfinallyfloatimplements      import......
  • mysql数据类型
    1、介绍mysql中实现了sql语法的数据类型,并有所增加。总的来说分为三类:数值、字符和时间日期。声明:字段名数据类型2、数值tinyint、smallint、mediumint、int和bigint分别表示1、2、3、4、8个字节的有符号整数。在数据类型后添加unsigned关键字,表示无符号是,比如intunsigne......
  • 31. Redis分布式锁
    我是javapub,一名Markdown程序员从......
  • Redis压测工具(redis-benchmark)
    redis性能测试工具可选参数如下所示:redis性能测试工具可选参数如下所示:序号选项描述默认值1-h指定服务器主机名127.0.0.12-p指定服务器端口63793-s指定服务器socket4-c指定并发连接数505-n指定请求数100006-d以字节的形式指定SE......