• redis-原理-数据结构-SDS(一)


    什么是SDS

    1.redis没有直接使用C的字符串,而是自己实现了字符串的实现名叫SDS

    2.c的字符串只会用在值不会改变的地方,比如redislog打印

    SDS的应用场景

    1.

    本地:0>set msg hellowrd
    OK

    键和值都是字符串对象,底层通过SDS实现

    2.

    本地:0>rpush fruits apple banana cherry
    3

    键是字符串对象 由SDS实现, 值是列表对象,列表对象包含三个字符串对象 分别由SDS实现

    SDS结构定义

    SDS遵循C的字符串定义,以空字符串()作为字符串的结尾,空字符串1字节不计算在len里面,好处就是直接使用C字符串的函数如:print(%,s-buf)

    带有未使用字节数量的SDS

    SDS和C字符串的区别

    1. C字符结构是没有记录长度的,如果要获取长度必须遍历字符,复杂度是0(N)

    2.SDS是记录了字符串长度获取字符串长度是0(1)如:

    本地:0>strlen msg
    8

    缓冲区溢出

    因为C不记录字符长度,如果在进行扩容时,只能假定内存足够,如果不足够则会造成缓冲区溢出

    扩容前 S1 和S2 2个字符紧邻,我们要对S1进行扩容,因为没有记录长度我们并不知道内存是否足够,执行:strcat(s1,"cluster")

    扩容前:

    扩容后

    SDS如何解决缓冲区溢出 

    与C不同因为SDS记录了未使用空间,在扩容前会先判断空间是否足够,如果不够sdscat(redis SDS的拼接API)先扩容空间

    如执行

    strcat(s1,"cluster")

    扩容前

    扩容后

    二进制安全

    C的字符必须符合某种编码(ASCII),并且除了字符串末尾之外字符串里面不能包含空字符,否则会误认为字符串结尾,这些使得C只能保存文本而不能保存图片、视频、音频、压缩文件这样的二进制数据

    因为SDS并没有使用空字符()判断字符的结尾而是len来判断,使用SDS可以保存图片 视频 音频等二进制数据

    SDS对于扩容的优化

    空间预分配

    当我们对SDS空间进行扩展的时候,SDS除了分配必要的空间,还会为SDS分配额外的未使用空间 free记录。

    公式:

          1.如果对SDS进行修改后,len长度小于1M则分配len同样大小的未使用空间 len+free+1为当前SDS占用空间 1为结尾空字符占用空间

          2.如果对SDS进行修改有len长度大于1M则会额外分配1M未使用空间   len+1m+1为当前SDS占用空间 1为结尾空字符占用空间

    当每次扩展SDS API都会检查free是否有足够空间,如果有则不执行扩展 直接使用 减少了分配次数,

    通过空间预分配优化,将连续增长N次字符串需要扩展N次,变为最多N次

    惰性分配

    当SDS缩短字符长度时候,并不会完全释放,只是将多出来的空间记录到free

    如果移除字符串中所有的 x和y

    移除前

    移除后

     将来需要拼接字符时则可以减少扩容

    预分配和惰性分配空间浪费解决方式

    通过上面的意思,会让我们觉得会浪费空间,其实SDS也提供了API让我们可以真正的释放SDS未使用空间,所以不用担心预分配和惰性分配造成的浪费

    SDS的优点

    1.比起C字符串,SDS获取字符串长度是O(1)

    2.比起C字符串,不会缓冲区溢出

    3.减少字符串扩容时的分配次数

    4.二进制安全

    5.兼容C字符串,可以重用C字符串的函数库

  • 相关阅读:
    [redis] 普通 RedisPool 的 CRUD 实现
    [maven] 常用仓库地址
    [saiku] 通过 saiku 的 DEMO 分析 connection
    [backbone]backbone.js
    [saiku] JCR在saiku中的运用原理
    [redis] 分布式 Redis 的 CRUD 实现
    [redis] session 保存到 redis 简单实现
    [redis] redis 存取键值对常用的三种使用方式
    226. Invert Binary Tree
    225. Implement Stack using Queues
  • 原文地址:https://www.cnblogs.com/LQBlog/p/14477370.html
Copyright © 2020-2023  润新知