zoukankan      html  css  js  c++  java
  • Redis知识梳理(2)当我们谈到string的时候,我们在谈什么?

    数据结构

    Redis中的string数据类型的数据结构类似Java中的ArrayList,是一个字符数组。

    扩容机制

    当字符串大小 > 1MB的时候,每次扩容都会扩容一倍。当字符串大小 < 1MB的时候,每次扩容就扩容1MB。Redis约定Redis中的String大小最大为512MB

    计数器

    如果Redis中的String存储的值的类型是num,那么可以使其自增。但是自增的最大值为Long.MAX_VALUE

    可修改性

    Redis你给的字符串是可修改的,换而言之,他不是每次赋值或者修改都是重新建一个String对象在内容中。

    源码分析

    struct SDS<T> {
        T capacity;					// 数组的容量
        T len;						// 数组的长度
        byte flags;					// 数组的特殊标志位
        byte[] content;				// 数组的内容
    }
    

    创建字符串的时候,初始化的数组容量和数组的长度是一样的长的。

    存储方式

    redis中String又两种存储方式:

    1. embstr
    2. raw

    (如果希望查看redis中的String使用了那种存储方式可以通过debug object keyName的方式来进行查询)

    redis1.cluster.oilchem.local:0>set test77 01234567890123456789012345678901234567891234
    "OK"
    
    redis1.cluster.oilchem.local:0>debug object test77
    "Value at:0x7f2dadae5240 refcount:1 encoding:embstr serializedlength:22 lru:13329039 lru_seconds_idle:1"
    
    
    
    redis1.cluster.oilchem.local:0>set test77 012345678901234567890123456789012345678912345
    "OK"
    
    redis1.cluster.oilchem.local:0>debug object test77
    "Value at:0x7f2d98961060 refcount:1 encoding:raw serializedlength:23 lru:13328992 lru_seconds_idle:2"
    

    根据上面的例子可以看出,当字符串的内容长度超过44之后,string 的存储方式会从embstr转换为raw。但是为什么分界值是44呢?

    为了解释这种现象,需要先了解一下Redis对象的定义

    struct RedisObject {
    	int4 type;			// 4bit 对象的类型
        int4 encoding;		// 4bit 对象的存储形式
        int24 lru;			// 24bit LRU信息
        int32 refcount;		// 4bytes 引用计数器,其为0时,对象被回收
        void *prt;			// 8bytes 64-system 指针,指向对象内容存储位置
    } robj;					// 其总大小是为16 bytes
    

    接着你来看一下SDS结构体的大小,存储字符串比较小的时候,SDS对象头结构大小为3字节

    struct SDS{
        int8 capacity;		// 8bit	数组的容量
        int8 len;			// 8bit 数组长度
        int8 flags;			// 8bit 特殊标志位
        byte[] content;
    }						// 其总大小为 3byte
    

    这意味着分配一个字符串的最小空间占用为 16bytes + 3bytes = 19bytes

    Redis认为一个字符串总体超出了64字节为一个大字符串,不适合使用embstr,那当内存分配了64字节空间的时候,字符串的最大长度为:

    	64bytes - 19bytes = 45bytes;
    

    但SDS结构体中content中的字符串是以字节null结尾的字符串,所以embstr的最大能容纳的字符串长度为

    	64bytes - 19bytes - 1bytes = 44bytes;
    

    embstr和raw在内存上的区别

    embstr,它将RedisObject对象头结构和SDS对象连续存储在一起的,使用malloc方法一次分配:

    raw的存储形式不一样,它想需要使用两次malloc方法,两个对象头在内存地址上一般是不连续:

  • 相关阅读:
    C语言 sprintf 函数 C语言零基础入门教程
    C语言 printf 函数 C语言零基础入门教程
    C语言 文件读写 fgets 函数 C语言零基础入门教程
    C语言 文件读写 fputs 函数 C语言零基础入门教程
    C语言 fprintf 函数 C语言零基础入门教程
    C语言 文件读写 fgetc 函数 C语言零基础入门教程
    C语言 文件读写 fputc 函数 C语言零基础入门教程
    C语言 strlen 函数 C语言零基础入门教程
    Brad Abrams关于Naming Conventions的演讲中涉及到的生词集解
    适配器模式
  • 原文地址:https://www.cnblogs.com/joimages/p/12956850.html
Copyright © 2011-2022 走看看