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方法,两个对象头在内存地址上一般是不连续:

  • 相关阅读:
    TCP性能调优
    Qt 实现应用程序单实例运行
    table多选
    多选删除最佳处理
    获取路由或路径
    当前页面打开新页面
    vue版本更新index.html缓存
    vue项目js和css文件名避免浏览器缓存再vue.config.js中配置
    vue动态表格
    IE网页被缓存,get接口缓存
  • 原文地址:https://www.cnblogs.com/joimages/p/12956850.html
Copyright © 2011-2022 走看看