《Redis - 基础数据结构 - 字符串(SDS)》

一:概述

  - Redis 源码版本为3.0.0.

  - Redis 没有直接使用C语言传统字符串表示,而是自己构建了一种 SDS(Simple dynamic string) 作为字符串代表

  - 目前官网的版本是 5.0发行版,6.0beat版本。对 SDS 又有了优化(主要优化了不同数据类型的存储)。

 

二:SDS 的定义

  - 结构定义(src/sds.h)

    - 

  - 示例展示

    - 

 

三:SDS 与 C 的区别。

  - 获取字符串长度

    - C 本身不记录字符串长度等信息,所以需要 O(N) 获取字符串长度

    - SDS 记录字符串长度信息(Len),所以通过 常数阶 O(1) 获取字符串长度

    - 意义

      - 通过 使用 SDS ,Redis 将获取字符串长度由  O(N) 变为 O(1) ,确保了获取字符串长度不会成为系统的瓶颈。(即使字符串很长)

      - 

  

  - 缓冲区溢出(buffer overflow)

    - C 在修改字符串时, 如果在修改字符串时没有调整内存分配

      - 拼接字符串未分配内存,则会造成缓冲区溢出

      - 缩短字符串忘记释放内存,则会造成内存泄露。 

    - SDS 需要修改时,会优先检查 SDS 的空间是否满足所需要的空间,根据需求动态的分配 free,使得在扩展空间时,不会发生溢出。

      - 优化策略 - 空间预分配(字符串扩张)

        - 因为系统分配内存涉及到复杂的算法,为了避免字符串连续增长导致内存来回分配。除了分配修改字符串的内存,同时也会分配 free(未使用空间)。

        - 字符串长度 < 1MB, 分配空间为 字符串长度 * 2

        - 字符串长度 > 1MB, 分配空间为 字符串长度 + 1MB

        -  

      - 优化策略 - 惰性空间释放(字符串缩减)

        - 同理,当字符串缩短,SDS 会回收多余分配的 free。

        - 

 

四:二进制安全

  - C 在保存 二进制/ASCIID等编码字符串时,除了末尾之外,字符不能包含空字符结尾(\0),会被认为是结尾,导致字符串不完整。

  - SDS 使用数组保存,不关心是否有问题。(可以保存视频,图像等) 

 

posted @ 2020-04-04 22:29  Zzz哈  Views(305)  Comments(0Edit  收藏  举报