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

来源:互联网 发布:java 线程同步机制 编辑:程序博客网 时间:2024/05/17 02:10

数据类型

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:

redisObjecttype                        (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_pairs1字节,开始标志    数据库号码         所有键值对

每个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重写缓冲区)
0 0
原创粉丝点击