redis虽说是用C语言开发的,但是redis考虑了性能、安全性、效率性、功能等要,redis底层存储字符串实现,自己实现了名为简单动态字符串(Simple dynamic string)简称SDS的结构来存储字符串,这个结构有int len(当前字符串长度), int free(未使用的字符串长度可以说是缓冲), char buf[](存储的字符串数组)这几个变量。

接下来我们开始分析C语言默认字符串和SDS字符串的区别以及redis为什么要使用SDS。

1、C语言的字符串存储并不能记录自身字符串长度,且在内存中实现的方式是|r|e|d|i|s|\0   最后的'\0'表示C语言的结束符,每次调用strlen方法取字符串长度无可避免得去搜索'\0'结束的字符串从而使复杂度变成O(N),redis作为一个高性能的代名词是无法容忍这个缺陷的,所以SDS结构的len变量就有用了直接可以知道这个变量大小是多少,从而使软件的复杂度变成O(1)。

2、C语言的2个字符串在连接得时候容易发生内存溢出问题,比如现在有2个连续的C字符串 a(len=6),b(实际长度8)在内存中分配的地址如下:

|r|e|d|i|s|\b|m|o|n|g|o|d|b|\b|

假如我现在执行strcat(a,"666")操作如果忘记了给a分配新长度的话,内存就会溢出,从而影响b的值,而SDS避免了这个问题,当执行给SDS添加字符串会自动检查当前的free长度是否够用,如果不够会自动分配新空间,从而避免了内存溢出问题,其实说到这里其实SDS作为Redis存储的最细节关键的还是这个free缓冲,因为Redis的使用场景中大部分速度要求苛刻,且经常会发生字符串增加或者减少的事情,而如果每次都调用系统类库来分配内存空间,会很耗时,降低性能,而Redis考虑到了这一点,使用了free,大大减少了内存分配的次数,从而提高了性能。

3、C语言字符串不能用来存储二进制文件,因为c语言字符串利用了'\0'作为字符串结尾,但是二进制文件结尾是-1,而SDS有一个len变量,就解决了这个问题,可以包含多个'\0',从而可以存储任意二进制数据。

4、SDS也遵循了C语言字符串'\0'结尾的规则,使得SDS也可以使用一部分系统的类库。

区别图片

redis数据结构存储SDS设计细节(redis的设计与实现笔记)的更多相关文章

  1. Redis数据结构之sds基本操作函数

    本文及后续文章,Redis版本均是v3.2.8 本篇文章讲解sds基本操作函数,我们从源码角度来进一步理解. 一.sds创建函数和销毁 sds创建函数 /* Create a new sds stri ...

  2. Redis数据结构:SDS

    1. 简单动态字符串(simple dynamic string,SDS)是Redis的默认字符串表示结构,底层的string都是基于SDS实现.Redis基于C语言,并引用了部分C函数. 使用场景: ...

  3. Redis 数据结构 之 SDS

    SDS(simple dynamic string),简单动态字符串.s同时它被称为 Hacking String.hack 的地方就在 sds 保存了字符串的长度以及剩余空间.sds 的实现在 sd ...

  4. redis数据结构存储Dict设计细节(redis的设计与实现笔记)

    说到redis的Dict(字典),虽说算法上跟市面上一般的Dict实现没有什么区别,但是redis的Dict有2个特殊的地方那就是它的rehash(重新散列)和它的字典节点单向链表. 以下是dict用 ...

  5. redis数据结构存储Linked List设计细节(redis的设计与实现笔记)

    redis里拥有一个灵活扩展且获取表头表尾复杂度为O(1)的双端列表,分为list和listNode2部分组成. list: typedef struct list {//链表 listNode *h ...

  6. Redis—数据结构之sds

    Redis是一个Key Value数据库.Redis有5种数据类型:字符串.列表.哈希.集合.有序集合.而字符串的底层实现方法之一就是使用sds.以下描述中请读者注意区分sds是指简单动态字符串这一数 ...

  7. redis数据结构之SDS

    简介 redis源码虽然是C语言实现的,但是Redis没有直接采用C语言传统的字符串表示,而是构建了一种名叫简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用 ...

  8. Redis数据结构和使用场景,redis内存淘汰策略

    什么样的数据适合放入Redis? sql执行耗时特别久,且结果不频繁变动的数据,适合放入Redis. Redis是单线程的,为什么会这么快? 纯内存操作 单线程操作,避免频繁的上下文切换 采用了非阻塞 ...

  9. 为了拿捏 Redis 数据结构,我画了 40 张图(完整版)

    大家好,我是小林. Redis 为什么那么快? 除了它是内存数据库,使得所有的操作都在内存上进行之外,还有一个重要因素,它实现的数据结构,使得我们对数据进行增删查改操作时,Redis 能高效的处理. ...

随机推荐

  1. [译]ZOOKEEPER RECIPES-TWO PHASED COMMIT

    两段式提交 两段式提交协议可以让所有分布式系统中的客户端达成协议同时提交或回滚事务. 在ZooKeeper中你可以通过协调者(coordinator)创建一个事务节点来实现两段式提交.例如" ...

  2. xamarin优化listView.ScrollTo

    在xamarinz中关于listview的滚动,我这里有点小优化,我做了一个类似QQ的聊天页面,上面是一个listview,下面时一个editText,当在手机上使用时,发现在android平台下,如 ...

  3. Ajax 加载数据 练习 自我有些迷糊了,写的大概请谅解 ^ _ ^

    查询表的显示,查询显示如果不嵌入PHP代码的话,用ajax怎么实现?   <h1>显示数据</h1> <table width="100%" bord ...

  4. HTML5移动开发学习笔记之CSS3基础学习

    CSS回顾 在学CSS3之前首先巩固下CSS的基础知识. 1.CSS框模型 举例子: #box { width: 70px; margin: 10px; padding: 5px; } 这个代码将出现 ...

  5. Java 位运算2-LeetCode 201 Bitwise AND of Numbers Range

    在Java位运算总结-leetcode题目博文中总结了Java提供的按位运算操作符,今天又碰到LeetCode中一道按位操作的题目 Given a range [m, n] where 0 <= ...

  6. LinqToDB 源码分析——设计原理

    我们知道实现了IQueryable<T>接口和IQueryProvider接口就可以使用Linq To SQL的功能.关于如何去实现的话,上一章也为我们引导了一个方向.LinqToDB框架 ...

  7. 类型基础---CLR Via C#笔记一

    一.所有类型都是从System.Obejct派生 1.下面两个类型定义是完全一致的: class Employee{ ... } class Employee:System.Object{ ... } ...

  8. WIN7下查看CPU核心数

    方法一 WIN+R输入cmd,输入wmic,输入cpu get *(注意空格),找到numberofcores和numberoflogicalprocessors,如下图为双核4线程,真核心数是2,使 ...

  9. 「译」JUnit 5 系列:基础入门

    原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...

  10. Devexress XPO xpPageSelector 使用

    在官网找到的.在这里做个备注. private void simpleButton1_Click(object sender, EventArgs e) { ) return; xpPageSelec ...