热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

Redis原理再学习:动态字符串sds

Redis原理再学习:动态字符串sds字符字符就是英文里的一个一个英文字母,比如:a。中文里的单个汉字,比如:好。字符串就是多个字母或多个汉字组成,比如字符串:redis,中文字符

Redis原理再学习:动态字符串sds


字符

字符就是英文里的一个一个英文字母,比如:a。中文里的单个汉字,比如:好。

字符串就是多个字母或多个汉字组成,比如字符串:redis,中文字符串:你好吗。

英文字符,如果按照 ASCII 码计算,一个字符占用 1 个字节。

中文字符的编码就比较复杂点,一个字符占用空间一般是 2 个字节,有的也用 3-4 个字节。

它有很多格式编码,有 gb2312,gbk, utf8 等等。

具体可以看看这篇文章:常见的中文字符编码。


动态字符串sds定义

看看 redis3.0 中的字符数据结构定义,sds.h/sdshdr

// https://github.com/redis/redis/blob/3.0/src/sds.h#L41
// redis3.0 低版本容易理解
typedef char *sds;
struct sdshdr {
unsigned int len;
unsigned int free;
char buf[];
};


  • len:记录 buf 数组中字符的长度



  • free:记录 buf 中未使用的字节的数量



  • buf:字节数组,保存字符串




sdshdr为什么要这样设计

C 语言中的字符数组难道不够用吗?

对于普通的字符串操作,C 语言中的字符数组是够用的。但是,redis 定位是高性能 kv 数据库,所以对于 redis 是不够用的。

从哪些方面优化才能扣出一点点性能呢?



  1. 空间换时间:一次多分配一些空间,下次增加字符串时不需要在进行分配空间的操作了。这个叫预分配。

    ​ 还有,截断字符串时,也不需要归还空间,而是用 free 属性记录,下次可以在复用空间,这个叫惰性分配。



  2. 获取字符串长度复杂度 O(1):sdshdr 里面定义了一个属性 len,操作字符串时会自动计算字符串的长度并赋值给这个 len 属性。所以在 redis 的一些命令中,不需要在计算一次字符串长度,而计算这个长度复杂度是 O(N)。比如 strlen 命令。



除了上面的 2 点,还有哪些好处?



  1. 避免缓存区溢出:因为 SDS 的空间分配策略杜绝了发生缓冲区溢出的可能性。因为 SDS 的 API 会先检查空间是否满足修改所需的要求,不满足的话会自动扩展修改所需的空间大小。

  2. 二进制安全:得益于 sds api 的设计,所有 sds api 都会以处理二进制的方式处理 sds 存放在 buf 数组里的数据。因为 sdshdr 里有一个 len 属性。


sdshdr存储字符串示例

比如 sdshdr 存储一个字符串 Redis,如下图:

image-20220120004119462

​ (《Redis设计与实现》)

存储 Redis 字符串时 sdshdr 各属性解释:



  • free:值为 0,表示 sdshdr 中没有未使用的空间



  • len:值为 5,表示 sdshdr 保存了一个 5 字节长度的字符串



  • buf:char 类型的数组,数组前 5 个字节保存了 R, e, d, i, s 五个字符,结尾保存了空字符 '\0'。这个遵循了 c 语言中空字符串结尾惯例。保存这个空字符串的 1 字节长度不计算在 sdshdr 的 len 属性里。




参考



  • 《redis设计与实现》 作者:黄健宏

  • redis.io

== just do it ==



推荐阅读
  • 本文提供了详细的 Filebeat 部署指南,涵盖了解压安装包、配置文件编辑以及启动服务等关键步骤。具体操作包括使用 `tar -zxvf filebeat-6.1.1-linux-x86_64.tar.gz` 解压安装包,并通过 `vi /home/elk/filebeat-6.4.2-linux/filebeat.yml` 编辑配置文件。此外,文章还介绍了最佳实践,帮助用户确保 Filebeat 的高效运行和数据传输的可靠性。 ... [详细]
  • 美团优选推荐系统架构师 L7/L8:算法与工程深度融合 ... [详细]
  • 字节跳动深圳研发中心安全业务团队正在火热招募人才! ... [详细]
  • 人人租机作为国内领先的信用免押租赁平台,为企业和个人提供全方位的新租赁服务。通过接入支付宝小程序功能,该平台实现了从零到百的迅猛增长,成为全国首家推出“新租赁小程序”开发服务的阿里巴巴小程序服务商(ISV)。这一创新举措不仅提升了用户体验,还显著增强了平台的市场竞争力。 ... [详细]
  • 深入解析 Redis 源码阅读方法与技巧
    在深入解析 Redis 源码的过程中,建议首先从数据结构的实现入手。这是因为在 Redis 的整体架构中,数据结构相关的代码与其他模块的耦合度较低,有助于初学者快速理解和掌握核心概念。通过阅读这些基础文件,可以为后续深入研究打下坚实的基础。 ... [详细]
  • 如何在Oracle ASM_Diskgroup中重命名现有磁盘
    如何在Oracle ASM_Diskgroup中重命名现有磁盘 ... [详细]
  • 基于Node.js的高性能实时消息推送系统通过集成Socket.IO和Express框架,实现了高效的高并发消息转发功能。该系统能够支持大量用户同时在线,并确保消息的实时性和可靠性,适用于需要即时通信的应用场景。 ... [详细]
  • 从无到有,构建个人专属的操作系统解决方案
    操作系统(OS)被誉为程序员的三大浪漫之一,常被比喻为计算机的灵魂、大脑、内核和基石,其重要性不言而喻。本文将详细介绍如何从零开始构建个人专属的操作系统解决方案,涵盖从需求分析到系统设计、开发与测试的全过程,帮助读者深入理解操作系统的本质与实现方法。 ... [详细]
  • 掌握PHP框架开发与应用的核心知识点:构建高效PHP框架所需的技术与能力综述
    掌握PHP框架开发与应用的核心知识点对于构建高效PHP框架至关重要。本文综述了开发PHP框架所需的关键技术和能力,包括但不限于对PHP语言的深入理解、设计模式的应用、数据库操作、安全性措施以及性能优化等方面。对于初学者而言,熟悉主流框架如Laravel、Symfony等的实际应用场景,有助于更好地理解和掌握自定义框架开发的精髓。 ... [详细]
  • Go语言实现Redis客户端与服务器的交互机制深入解析
    在前文对Godis v1.0版本的基础功能进行了详细介绍后,本文将重点探讨如何实现客户端与服务器之间的交互机制。通过具体代码实现,使客户端与服务器能够顺利通信,赋予项目实际运行的能力。本文将详细解析Go语言在实现这一过程中的关键技术和实现细节,帮助读者深入了解Redis客户端与服务器的交互原理。 ... [详细]
  • 2019年后蚂蚁集团与拼多多面试经验详述与深度剖析
    2019年后蚂蚁集团与拼多多面试经验详述与深度剖析 ... [详细]
  • 数据结构与算法:HyperLogLog 统计、布隆过滤器应用、缓存机制挑战及解决方案、Redis 性能优化与监控、哨兵模式、版本控制工具 Git
    本文探讨了数据结构与算法在实际应用中的多个方面。首先介绍了HyperLogLog算法,用于高效地进行基数统计,能够准确估算大规模数据集中的唯一元素数量。接着讨论了布隆过滤器的应用,该过滤器在空间效率和查询速度上具有显著优势,适用于大数据场景下的快速成员检测。此外,文章分析了缓存机制面临的挑战及其解决方案,包括LRU和LFU等策略,并详细阐述了Redis的性能优化与监控方法,如使用哨兵模式实现高可用性。最后,介绍了版本控制工具Git的基本操作和最佳实践,帮助开发者有效管理代码版本。 ... [详细]
  • Jedis接口分类详解与应用指南
    本文详细解析了Jedis接口的分类及其应用指南,重点介绍了字符串数据类型(String)的接口功能。作为Redis中最基本的数据存储形式,字符串类型支持多种操作,如设置、获取和更新键值对等,适用于广泛的应用场景。 ... [详细]
  • 修复一个 Bug 竟耗时两天?真的有那么复杂吗?
    修复一个 Bug 竟然耗费了两天时间?这背后究竟隐藏着怎样的复杂性?本文将深入探讨这个看似简单的 Bug 为何会如此棘手,从代码层面剖析问题根源,并分享解决过程中遇到的技术挑战和心得。 ... [详细]
  • 优化后的标题:PHP分布式高并发秒杀系统设计与实现
    PHPSeckill是一个基于PHP、Lua和Redis构建的高效分布式秒杀系统。该项目利用php_apcu扩展优化性能,实现了高并发环境下的秒杀功能。系统设计充分考虑了分布式架构的可扩展性和稳定性,适用于大规模用户同时访问的场景。项目代码已开源,可在Gitee平台上获取。 ... [详细]
author-avatar
闫小芽_209
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有