Redis如何存储对象

一 概述

Redis中String类型是组基本的数据类型,最大值可以存储512M的数据,同时String是二进制安全的,也就是说Redis中的String可以包含任何数据,如jpg图片或者序列化的对象。Redis是基于内存中的数据进行操作。

二 Redis保存对象的结构

Redis底层是由C语言编写的,但是其并没有使用C语言传统的字符串表示(即以空字符\0结尾的字符数组)。而是自己构建了一种名为简单动态字符串(SimpleDynamicString,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。

set name value  的命令会产生值为“name”和“value” 的两个sdshdr对象

Redis中对象的属性:

//String是最基本的数据类型,属于二进制安全
struct sdshdr {

	//buf 中已占用空间的长度
	int len;
	
	//buf中剩余可用空间的长度
	int free;
	
	//数据空间
	char buf[];
};

三 Redis不用C字符串作为字符存储对象的原因

  1. 二进制安全(即SDS中存入什么类的数据,取出来还是什么数据,不会对数据进行任何的修改,限制和过滤等),在C字符串中,遇到空格就会认为是一个新的字符串,这样导致无法存储图片的二进制数据,而Redis中的SDS兼容二进制,不仅能够保存一般的字符串,还可以保存图片的二进制数据,还可以保存对象。同时兼容C字符串,并且可以使用C字符串相关的函数,可以避免代码重复。
  2. Redis中可以通过直接获取len的值而获得字符串的长度,时间复杂度为O(1),而C字符串获取长度的时候需要遍历字符,时间复杂度为O(n)。
  3. [空间预分配]减少内存分配操作,因为C字符串直接加长可能导致缓冲区被覆盖,需要重新分配内存,然而内存分配时比较耗时,Redis为了减少内存分配的操作,每次修改字符串,如果buf[]的长度不够存储修改后的字符串的时候,会分配新字符串两倍的容量给buf[],即会使得len == free。  如属性 buf[]的长度为: 6,值为:sdshdr,len = 6,free = 0 ; 修改后:值为:RedisNoSQLDB,发现缓冲区不够,需要重新分配内存,需要的内存为12,此时buf[] = 24,len = 12,free = 12。 如果再对数据进行修改,但是此时的长度未超过24,则不会重新分配缓冲区,这样会大大提升写入性能。这是字符串长度均为小于1MB的情况,当字符串长度超过1MB的时候,此时的内存分配机制为字符串需要多少内存就分配多少内存。
  4. [惰性空间释放]减少内存分配操作,SDS用free记录buf中剩余的可用空间长度,当需要缩短字符串的时候,SDS是不会立即释放多余的内存空间,而是保留,然后修改free中的值。当free的长度够下次扩容的时候就可以直接使用,而不需要重新分配内存,从而减少内存的分配次数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值