Redis数据类型、数据库简要记录

数据类型

SDS(简单动态字符串)定义:

struct sdshdr{
    int len;         //buf已占用长度
    int free;        //buff剩余可用长度
    char buf[];
}

优点:
1. 获取SDS长度复杂度由O(n)降为O(1)
2. 防止缓冲区溢出(buffer overflow)

strcat(s, “cluster”) 可能会覆盖s后其他的数据 ——>改用sdscat()
带来的问题: 降低内存重分配次数
1. 内存与分配:
扩展SDS空间前,SDS API查free够用否:够用->用,不够用->分配未实用空间 = 修改后的len值(>1M只分1M),再多一字节(‘\0’)
2. 惰性空间释放
当SDS的API需缩短SDS保存的字符串,不立即使用内存重分配会收缩短后多的字节

buf:“字节数组”,不是用来存字符,而是一系列二进制数据,“二进制安全”

字典:

使用哈希表作为底层实现,每个哈希表有多个哈希表节点,每个哈希表节点保存了字典中的一个键值对
哈希表:
typedef struct dictht{
    dictEntry **table;       //哈希表数组
    unsigned long size;
    unsigned long sizemask;        //大小掩码,计算索引值(= size -1)
    unsigned long used;            //已有节点(键值对)的数量
}dictht;

哈希表节点:
typedef struct dictEntry{
    void *key;               //键
    union{                   //值:可为指针or u64 or s64
        void *val;
        uint64_t u64;
        int64_t s64;
    }v;
    struct dictEntry *next;    /*指向下一个哈希表节点,将多个哈希值相同的简直对在一起,解决链冲突问题*/
}dictEntry;

字典;
typedef struct dict{
    dictType *type;           //特定于类型的处理函数
    void *private;            //处理函数的私有数据
    dictt ht[2];              //ht[1]仅在rehash时使用
    int rehashidx;            //记录rehash(渐进式)进度标记,-1:未rehash
}

对象

typedef struct redisObject{
    unsigned type:4;
    unsigned encoding:4;
    void *ptr;                                       //指向实际值的指针
    int refcount;                                  //引用计数  -> 内存回收
    unsigned lru:REDIS_LRU_BITS;        //lrutime对象最后一次被访问的时间(空转时长)
}robj;

对象共享:
Redis初始化服务器时,创建含0–9999整数值,共1万个字符串对象,当用到该值时,共享对象,or创建新对象

eg:

redisObject
type                        (REDIS_STRING)
encoding            (REDIS_ENCODING_INT)
ptr                     (->100)
refcount                (2...

其中服务器程序引用一次,键A引用一次,当键B也引用值100时,refcount变为3

单机数据库的实现

redisDb *db; 一个数组,保存着服务器中的所有数据库,默认创建16个
可用 SELECT 切换目标数据库(默认为0号) 更改的为redisClient中的db指向,redisServer中的db一直指向db[0]
数据库主要由 dict 和 expires 两个字典组成:dict保存键值对,expires保存键的过期时间

    数据库的键:一个字符串对象, 值:任意一种Redis对象类型
    expires中的键:指向数据库中某个键, 值:该键的过期时间

RDB持久化
将内存中的数据库状态保存到磁盘中,or服务器退出就没了
RDB文件结构:

REDIS(5字节)   db_version(4)  databases EOF(1) check_sum(8,无符号,CRC)
保存REDIS5个字符  字符串记录的整数        标识RDB文件正文内容结束
            (0006)RDB文件的版本号

其中databases:

datebase0 datebase3 ...

每个datebase:

SELECTDB        db_number       key_value_pairs
1字节,开始标志    数据库号码         所有键值对

每个key_value_pairs:

不带过期时间的: TYPE           key(字符串对象)           value
带过期时间的:   EXPIRETIME_MS(1字节)     ms(8字节,带符号整数)   TYPE   key   value

AOF持久化:
通过保存Redis服务器所执行的写命令来记录数据库状态
AOF功能打开时:服务器执行完一写命令后,将该命令加至aof_buf缓冲区末尾:

struct redisServer{
    ...
    sds aof_buf;   //AOF缓冲区
    ...
}

AOF重写:(防止过大)

从数据库中读取键现在的值,--> 用一条命令去记录,取代之前多条对这个键值对的命令
AOF后台重写:
    使用子进程进行AOF重写(AOF重写缓冲区)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值