美文网首页
redis 基础

redis 基础

作者: 小张同学_loveZY | 来源:发表于2018-08-26 13:31 被阅读0次

    redis 的源码都是用C语言写的,而且,整个redis的大小都很小。本文主要参考redis设计与实现一书,书中部分数据与最新的redis源码有所出入,但不影响我们的使用学习。

    基本类型:

    建议这里的学习大家去参看一下源代码,或者相应的书籍,本节不对具体的细节做讨论,仅总结没种数据类型的作用。

    1.动态字符串
    struct sdshdr{
        // 记录字符长度,不计 “\0”
        int len;
        // 剩余空间
        int free;
        // 字符数组
        char buff[];
    }
    

    重定义c语言中的字符串,使得字符串的大小可以改变,减少因为字符串大小改变导致的频繁释放内存,分配内存。以适应数据库的使用场景。

    特点:
    - 惰性空间释放
    - 避免过多的字符串
    - 兼容底层的c字符串
    
    2.链表

    redis 内置实现了链表的结构。

    typedef struct listNode {
        struct listNode *prev;
        struct listNode *next;
        // 定义void指针是因为可以指向任何类型
        void *value;
    } listNode;
    
    
    typedef struct list {
        listNode *head;
        listNode *tail;
        //复制函数
        void *(*dup)(void *ptr);
        // 释放函数
        void (*free)(void *ptr);
        // 节点值对比函数
        int (*match)(void *ptr, void *key);
        // 节点数量
        unsigned long len;
    } list;
    
    3.字典

    键值对,redis使用时的键值关系就是靠它了!

    typedef struct dictht {
        // hash表数组
        dictEntry **table;
        unsigned long size;
        // 计算索引值的掩码,大小为 size - 1
        unsigned long sizemask;
        // 已使用节点数
        unsigned long used;
    } dictht;
    
    typedef struct dictEntry {
        // 键值对
        void *key;
        union {
            void *val;
            uint64_t u64;
            int64_t s64;
            double d;
        } v;
        struct dictEntry *next;
    } dictEntry;
    
    // 字典中自带了两个hash表,一个平常使用,一个rehash的时候使用。rehash不是一次完成的,而是渐进完成的。
    typedef struct dict {
        dictType *type;
        void *privdata;
        dictht ht[2];
        long rehashidx; /* rehashing not in progress if rehashidx == -1 */
        int iterators; /* number of iterators currently running */
    } dict;
    

    还有一些具体的类型定义等,可以参考源代码。

    4.跳跃表

    跳跃表是一个有序的结构,先安分数排序,再按对象大小排序,听起来是不是很像sorted set,我猜就是这种数据的底层结构。一个跳跃表的例子:

    5.整数集合

    该数据结构可以很便利的用于存取数据库中的整数集合。

    typedef struct intset {
        uint32_t encoding;
        uint32_t length;
        int8_t contents[];
    } intset;
    

    redis的整数集合还会有一定的升级和降级的操作以节省内存。

    6.压缩列表

    为了节约内存而开发的,对于可以压缩的小数值,小的字符串等进行键的压缩。

    7.对象

    redis基于以上各种数据结构,建立相应的对象结构,从而以对象构建数据库。对象包括:字符串对象,列表对象,集合对象,有序集合对象,哈希对象。除此之外,redis还引入引用计数和内存回收机制。

    8.数据库
    typedef struct redisDb {
        dict *dict;                 /* The keyspace for this DB */
        dict *expires;              /* Timeout of keys with a timeout set */
        dict *blocking_keys;        /* Keys with clients waiting for data (BLPOP) */
        dict *ready_keys;           /* Blocked keys that received a PUSH */
        dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
        struct evictionPoolEntry *eviction_pool;    /* Eviction pool of keys */
        int id;                     /* Database ID */
        long long avg_ttl;          /* Average TTL, just for stats */
    } redisDb;
    
    • struct redisServer
    • typedef struct client

    定义了客户端和服务器。

    Redis 持久化

    你可以理解为mysql一样的在内存留下的数据。

    1.RDB 持久化

    一定间隔内将内存的数据保存的本地的RDB文件中,它保存了某个时间点得数据集,非常适用于数据集的备份。

    优点:与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些。
    缺点:万一在Redis意外宕机, 你可能会丢失间隔时间内的数据.

    2.AOF 持久化

    一个只进行追加的日志文件,记录下每次执行的命令,复原的时候把所有命令执行一遍,不改变数据以及运行状态的命令不记录。过大的时候整理重写。

    优点:备份时间极短。数据丢失量小。
    缺点:AOF 文件的体积通常要大于 RDB 文件的体积。

    关于持久化的详细信息可参考官网指南

    事务

    MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令。事务可以一次执行多个命令, 并且带有以下两个重要的保证:

    • 事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
    • 事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

    Redis 不支持回滚(roll back):

    Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中。

    因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

    有种观点认为 Redis 处理事务的做法会产生bug, 然而需要注意的是, 在通常情况下, 回滚并不能解决编程错误带来的问题。 举个例子, 如果你本来想通过 INCR 命令将键的值加上 1 , 却不小心加上了 2 , 又或者对错误类型的键执行了INCR , 回滚是没有办法处理这些情况的。

    本人对于redis的 实操尚少,更多的知识来自书籍和官网,本文尚介绍部分redis的特性,更多的学习可以参考官网文档

    相关文章

      网友评论

          本文标题:redis 基础

          本文链接:https://www.haomeiwen.com/subject/ggkoiftx.html