Blage's Coding Blage's Coding
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
Home
算法
  • 手写Spring
  • SSM
  • SpringBoot
  • JavaWeb
  • JAVA基础
  • 容器
  • Netty

    • IO模型
    • Netty初级
    • Netty原理
  • JVM
  • JUC
  • Redis基础
  • 源码分析
  • 实战应用
  • 单机缓存
  • MySQL

    • 基础部分
    • 实战与处理方案
    • 面试
  • ORM框架

    • Mybatis
    • Mybatis_Plus
  • SpringCloudAlibaba
  • MQ消息队列
  • Nginx
  • Elasticsearch
  • Gateway
  • Xxl-job
  • Feign
  • Eureka
  • 面试
  • 工具
  • 项目
  • 关于
🌏本站
🧸GitHub (opens new window)
  • Redis基础

  • 源码分析

    • 数据结构
      • 简单动态字符串SDS
      • IntSet
      • Dict
      • ZipList-quicklist-listpack
      • SkipList跳表
      • RedisObject
    • Redis网络模型
    • 内存策略
    • 优化
  • 实战应用

  • 单机缓存

  • Redis
  • 源码分析
phan
2023-05-15
目录

数据结构

# 数据结构

# 简单动态字符串SDS

①字符串长度②申请的总的内存大小

内存预分配扩容机制:追加新的字符串时,如果新字符串小于1M,则新的空间扩展为字符串长度2倍+1

# IntSet

①编码方式②数组长度

编码方式动态升级:当添加的数字超过出int16的范围,那么IntSet会自动升级编码方式存储数组,然后倒序依次将数组元素拷贝到扩容后的位置,如果插入的数小于0,则他比所有元素都小,插入数组头部;如果他大于0则添加的元素添加到数组的尾部。整个数组保证有序,底层是二分查找。

# Dict

添加键值对时,首先根据key计算出hash值,然后通过hash&(size-1)计算元素存储到的索引位置。

有两个哈希表ht[2],一个平常用,另一个rehash用

image-20230315084117947

添加元素时,根据负载因子(used/size)触发哈希扩容(扩容大小比当前size大1的最近的2的倍数);删除元素时会检查是否收缩。无论是扩容还是收缩,当哈希表的大小变化时,需要计算所有key的索引,并插入到新的哈希表中。数据迁移时采用渐进式rehash,仅在每次增删改查时迁移一个角标的元素到ht[1]上。

# ZipList-quicklist-listpack

  • ZipList

双端链表每个节点结构:①前一个节点长度prevlen②编码方式③节点数据

问题:新增或者修改某个元素时,会导致内存占用空间重新分配,并且后续元素的prevlen占用空间发生变化,引起连锁更新问题。

image-20230315193053244

  • QuickList

解决ZipList存储大量数据,同时内存申请效率比较低。

使用QuickList双端链表来将所有ZipList串起来,每个节点包含一个前向指针,后向指针,ZipList指针。每个节点还可以设置是否对ZipList压缩。

# SkipList跳表

  • 元素按照得分score升序排列存储
  • 每个节点包含多个指针,指针跨度不同。查找时根据不同指针跨度的score和要查询的score进行比较,如果比所要查询的score小,那就找跨度更大的指针。

image-20230315110303172

  • 跳表中,每个节点出了包含下个节点的指针外,还可能包含多个后面节点的指针,越高层的指针跨越的节点数越多。跳表一个重要性质是一个节点如果在第i层链表出现,那么在第1到i-1层链表中也会出现。比如要在一个有序链表中查找元素,可以通过跳表跳过查找一些中间元素,从而减少查找时间。其实是一种空间换时间的做法。

    Snipaste_2022-02-27_10-22-08

# RedisObject

  • set:HT,Intset(如果是数值类型)

使用HT的key存储元素,value统一设置为null,底层跟java的hashmap和hashset一致。

  • Zset:HT+SkipList,ZipList(数据量少时节省内存使用ziplist,让element和score紧挨保存在相邻的entry中)。通过一个哈希表(维护姓名->分数的一个映射关系)和一个跳表(存储分数)来实现,查找某个节点排名时,只需从高层到底层把跨度相加起来,得到排名结果。它的查询次数是远比普通链表要小的。

  • Hash:HT,ZipList

编辑 (opens new window)
#Redis
上次更新: 2023/12/15, 15:49:57
Redis分布式缓存
Redis网络模型

← Redis分布式缓存 Redis网络模型→

Theme by Vdoing | Copyright © 2023-2024 blageCoder
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式