zoukankan      html  css  js  c++  java
  • 02 Redis的数据结构

    1. Redis——“快”:μs速度找到KV并完成操作。依赖于

      a. 内存

      b. 数据结构

    2. 6种底层数据结构 & 5种Redis数据类型

    dataStructure

    1. Redis的“快”中的“慢操作”
    • KV用哈希表存储,哈希表结构=数组+哈希桶

    哈希表是一个指针数组,每个元素是一个指向entry结构体的指针(哈希桶)
    entry包含两个元素:

    • *key——指向key的指针
    • *value——指向value的指针
    • 哈希表查找过程主要依赖于哈希计算,与数据量多少无直接关系
      hashTable_
    1. 哈希表存储要解决的问题

    哈希冲突——链式哈希

    rehash可能带来的操作阻塞——渐进式rehash

    • 哈希冲突
      • 解决:链式哈希——同一个哈希桶中多个entry用链表连接
      • entry结构体中增加*next指针指向下一个entry
      • hashTable
    • rehash可能带来的操作阻塞
      • 背景:链式哈希潜在问题——同一哈希桶内链接元素过多(同一桶内的冲突过多),导致查找KV时的时间消耗增加。
      • 解决:rehash——增加现有哈希桶数量,对entries进行重排,以减少单个桶内的冲突
      • rehash具体操作

        Redis默认使用两个全局哈希表,表1rehash


        a. 给表2分配比表1更大的空间(比如表1的2倍大小)

        b. 将表1数据重映射&copy到表2

        c. 释放表1空间

      • rehash中处理重映射&copy的时间会随着entries的增加而增加,涉及到了大量的数据copy操作,数据量大的情况下,极有可能阻塞Redis主线程,因此Redis采用渐进式rehash
    • 渐进式rehash

      原理:将表1每个桶的“重映射&copy”分散到Redis的每次请求上

    1. 集合数据的操作效率

    集合数据的操作效率取决于两个因素:集合类型的底层数据结构、具体的操作

    • 集合类型的底层数据结构:整数数组、双向链表、哈希表、压缩列表、跳表

      • 压缩列表:

        有序数组

        表头增加3个字段:zlbytes——列表长度、zltail——列表尾偏移、zllen——列表中的entry个数

        表尾用zlend——列表结束标志

        ziparray

      • 跳表:

        有序链表上加多级序列

        通过索引位置的跳转实现数据快速定位

        索引通过链表连接

        jumpTable

      • 查找时,各个集合类型底层数据结构的时间复杂度表

        底层数据结构 时间复杂度
        哈希表 O(1)
        跳表 O(logN)
        双向链表 O(N)
        压缩列表 O(N)
        整数数组 O(N)
    • 不同操作的复杂度

      单元素操作是基础
      范围操作非常耗时
      统计操作通常g高效
      例外情况只有几个

      • 范围操作: 集合类型中的遍历操作
      • 统计操作:比如集合中元素个数的统计

    图片来源于极客时间专栏《Redis核心技术与实战》

  • 相关阅读:
    CodeForces 459D Pashmak and Parmida's problem
    cf 459c Pashmak and Buses
    hdu 1006 Tick and Tick 有技巧的暴力
    hdu 1005 Number Sequence
    hdu 1004 Let the Balloon Rise
    c++ 单引号和双引号
    c++一些总结
    剑指offer23 从上往下打印二叉树
    E: Unable to locate package
    vector
  • 原文地址:https://www.cnblogs.com/GuoYuying/p/15056629.html
Copyright © 2011-2022 走看看