【redis前传】 redis五大天王值list基本数据如何成长 | 由内以外深刻学习

这是我参与更文挑战的第24天,活动详情查看: 更文挑战node

前言

  • 在【数据结构】学习中,绕不过的就是链表和数组的学习了!数组应该更容易理解点!由于他和咱们平时的逻辑同样。可是链表在刚入门的同窗中应该算是比较抽象的了!尤为是指针交换位置更是容一部分同窗望而却步!
  • 今天咱们来学习下Redis中的经常使用的链表数据结构

list

  • Redis低版本(3.2以前)中list数据结构底层就是使用链表来进行串联数据的!

image-20210621154225866

  • 上图就是Redis中在操做List数据结构时的结构图!在redis中并非仅仅使用这一种双向的链表结构.关于ziplist等其余结构咱们这里暂时不讨论。
  • 而针对一整条链条redis有将它 抽象化一个list对象

image-20210621154708172

  • node是链条中重要的组成部分,而list咱们能够理解成对整个链条的描述。list中包含头结点、尾结点、链条中节点个数、节点的复制释放比对等功能!
typedef struct listNode {
    struct listNode *prev;
    struct listNode *next;
    void *value;
} listNode;

typedef struct listIter {
    listNode *next;
    int direction;
} listIter;

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;
复制代码
函数 做用
dup 复制链表节点值
free 释放链表节点值
match 比对链表节点值与指定值是否想的相等

image-20210621155615574

小结

  • 很明显在redis中链表是一种双指针链表,能够经过当前节点轻松定位先后节点!
  • list中能够轻松获取链表头尾节点!这也就解释redis中的lpush 、 rpush命令最终的实现了。就是经过改变头、尾指针就能够了。操做那是很是迅速的
  • list中len表示链表长度。就是一个节点计数器。对应着llen 命令
  • 了解数据结构后基本上就能够理解redis对应的操做命令在内存中的结构了

list其余数据结构

  • 上面咱们提到在3.2以前的版本中redis采用链表结构进行存储list数据。在3.2以后开始出现一种ziplist结构的数据结构!
  • 首先咱们思考下listnode用的好好的为何要改用ziplist结构。由于list结构中存储了头尾节点方便了咱们寻址可是牺牲了内存说白了就是空间换时间
  • ziplist就是针对内存浪费的问题进行了优化。
  • 我們看下ziplist的存储内存分布图(如下图片来源于网络)

image-20210621173157390

位置 做用
zlbytes ziplist字节长度;长度最长为(2^32)-1
zltail 整个ziplist偏移量;四个字节
zllen ziplist中存储的元素个数;两个字节
entryX ziplist中元素
zlend 结束位 。固定值0xFF=255
typedef struct zlentry {
    unsigned int prevrawlensize, prevrawlen;
    unsigned int lensize, len;
    unsigned int headersize;
    unsigned char encoding;
    unsigned char *p;
} zlentry;
复制代码

小结

  • ziplist又称为压缩列表本质上就是一个数组。除了list之外还有hash也都使用了ziplist. 压缩列表虽然节省了内存的开销可是随之而来的问题就是连锁更新。关于什么是连锁更新咱们之后在分析!本文是一篇入门级的文章。到这里就结束啦

欢迎点个赞呗redis

相关文章
相关标签/搜索