Redis的embstr与raw编码方式不再以39字节为界了!

2023-11-03

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/XiyouLinux_Kangyijie/article/details/78045385

引言

从“中国软件杯”回来之后,一直对项目中没用到Redis以至于在存储上坑爹而耿耿于怀,心想一定要学一下Redis然后把之前的项目再改进一下,一边学习基本使用,一边对照《Redis设计与实现》深入,不禁感慨数据结构之美妙。。。

正文

结论

Redis的embstr编码方式和raw编码方式在3.0版本之前是以39字节为分界的,也就是说,如果一个字符串值的长度小于等于39字节,则按照embstr进行编码,否则按照raw进行编码。 
而在3.2版本之后,则变成了44字节为分界。

起因:一次失败的实验

在《Redis设计与实现》第八章对象中,有这样一段话

如果字符串对象保存的是一个字符串值,并且这个字符串值的长度小于等于39字节,那么字符串对象将使用embstr编码的方式来保存这个字符串值。

于是我就在自己的Redis上测试了一下 
这里写图片描述

这和书上说的不太对啊。。。而且为什么是39这个数字呢??

继续探究

根据知乎上的回答 怀疑在3.0和3.2版本之间的改动导致了39字节不再适用,于是直接在github查看object.c的改动。同时也希望能找到为什么是39而不是其他数。

源码面前,了无秘密

首先“为什么是39”这个问题的答案很清楚,来自这个commit 
这里写图片描述

作者大大的说明如下

REDIS_ENCODING_EMBSTR_SIZE_LIMIT set to 39. 
The new value is the limit for the robj + SDS header + string + 
null-term to stay inside the 64 bytes Jemalloc arena in 64 bits 
systems.

这里具体的分析可以参考@lhcpig的回答 ,非常的清晰,我就不再赘述。

而为什么现在39个字节不适用了呢? 
粗暴地回答,因为现在REDIS_ENCODING_EMBSTR_SIZE_LIMIT不再是39而是44了。 
那么为什么这个宏要变化呢? 
则是来自这个commit 
这里写图片描述

commit地址

这个commit改动相当大,主要就是对sds进行了内存优化。 
我们知道对于每个sds都有一个sdshdr,里面的len和free记录了这个sds的长度和空闲空间,但是这样的处理十分粗糙,使用的unsigned int可以表示很大的范围,但是对于很短的sds有很多的空间被浪费了(两个unsigned int 8个字节)。而这个commit则将原来的sdshdr改成了sdshdr16,sdshdr32,sdshdr64,里面的unsigned int 变成了uint8_t,uint16_t.。。。(还加了一个char flags)这样更加优化小sds的内存使用。

相信聪明的看官看到这里已经明白了为什么39变成了44.

本身就是针对短字符串的embstr自然会使用最小的sdshdr8,而sdshdr8与之前的sdshdr相比正好减少了5个字节(sdsdr8 = uint8_t * 2 + char = 1*2+1 = 3, sdshdr = unsigned int * 2 = 4 * 2 = 8),所以其能容纳的字符串长度增加了5个字节变成了44.

所以

看书还是要亲手实践一下,如果有问题,直接看源码~

相关链接

为什么redis小等于39字节的字符串是embstr编码,大于39是raw编码? 
Redis源码

 

https://blog.csdn.net/XiyouLinux_Kangyijie/article/details/78045385

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis的embstr与raw编码方式不再以39字节为界了! 的相关文章

  • Spring RedisTemplate:8次调用后方法键挂起

    我使用 Spring RedisTemplate spring data redis 1 7 1 与 Redis 进行通信 我需要通过正则表达式获取然后删除键 例如 context user1 我用的方法 RedisTemplate key
  • 使用 AWS ElastiCache 请求中的 Airflow CROSSSLOT 密钥未散列到同一插槽错误

    我在 AWS ECS 上运行 apache airflow 1 8 1 并且有一个 AWS ElastiCache 集群 redis 3 2 4 运行 2 个分片 2 个启用多可用区的节点 集群 Redis 引擎 我已经验证气流可以毫无问题
  • 我的 Redis 自动生成的密钥

    我不知道我的 Redis 版本 4 0 9 到底发生了什么 我正在运行一个应用程序并使用 Redis 来存储我的数据库 但是 然后 Redis 自动创建 3 个新键 Backup1 Backup2 Backup3 并删除我的所有数据 这是我
  • Docker-compose Predis 不通过 PHP 连接

    我正在尝试使用 docker compose 将 PHP 与 redis 连接 docker compose yml version 2 services redis image redis 3 2 2 php image company
  • Spring Data Redis - Lettuce连接池设置

    尝试在 spring data redis 环境中设置 Lettuce 连接池 下面是代码 Bean LettuceConnectionFactory redisConnectionFactory GenericObjectPoolConf
  • 从redis中检索大数据集

    一台服务器上的应用程序查询另一台服务器上运行的 Redis 查询的结果数据集约为 250kzrangebyscore objects locations inf inf这在应用程序服务器上似乎需要 40 秒 当使用命令执行时redis cl
  • redis 阻塞直到 key 存在

    我是 Redis 新手 想知道是否有办法能够await get通过它的键来获取值 直到该键存在 最小代码 async def handler data await self fetch key async def fetch key ret
  • 在 sidekiq 上配置 redis 身份验证

    我想我错过了一些东西 因为我在文档中找不到如何编写 redis 实例的用户名和密码以与 sidekiq 一起使用 有没有办法做到这一点 或者是通过 ENV 变量 Sidekiq 将无法识别的 Redis 选项直接传递给 Redis 驱动程序
  • 如何将node.js管道传输到redis?

    我有很多数据要插入 SET INCR 到redis DB 所以我正在寻找pipeline http redis io topics pipelining 质量插入 http redis io topics mass insert通过node
  • SignalR 无法连接到 SSL 上的 Azure Redis

    我目前在 Azure 上托管我的 redis 缓存服务器 并让 signalR 依赖它作为骨干 使用以下内容 GlobalHost DependencyResolver UseRedis 服务器 端口 密码 eventKey 这可以在端口
  • 使用 Redis 命令 incr 和 expire 时的竞争条件

    根据redis文档 http redis io commands incr http redis io commands incr 在段落模式 速率限制器 2 较短的版本代码 value INCR ip IF value 1 THEN EX
  • 如何设置和获取Redis中存储的对象?

    我试图在 redis 中存储一个对象 当我获取该对象时 它似乎不起作用 I tried u User new u name blankman redis set test u x redis get test x name error 我想
  • 如何在Redis中从hmset()切换到hset()?

    我收到弃用警告 即 Redis hmset 已弃用 请改用 Redis hset 但是 hset 采用第三个参数 我不知道是什么name应该是 info users 10 timestamp datetime utcnow strftime
  • Lua中按字符分割字符串

    我有像这样的字符串 ABC DEF 我需要将它们分开 字符并将两个部分分别分配给一个变量 在 Ruby 中 我会这样做 a b ABC DEF split 显然Lua没有这么简单的方法 经过一番挖掘后 我找不到一种简短的方法来实现我所追求的
  • 2 个具有共享 Redis 依赖的 Helm Chart

    目前 我有 2 个 Helm Charts Chart A 和 Chart B Chart A 和 Chart B 对 Redis 实例具有相同的依赖关系 如Chart yaml file dependencies name redis v
  • Spring Data JPA Redis:无法编写基于自定义方法的查询

    我已经使用 Redis 配置了 Spring Data JPA 并使用RedisRepositorieswith 提供了类似的方法find findAll 所有这些方法似乎都工作得很好 但我无法编写我的自定义方法 RedisEntity f
  • 有没有办法让特定的key在集群模式下定位到特定的redis实例上?

    我想让我的多锁位于不同的redis实例上 我发现redission可以指定一个实例来执行命令 但是如果该命令与key相关 则指定的实例会将命令传输到另一个实例 你能给我一些建议吗 你可以 但这并不是微不足道的 首先 Redis 在键中使用大
  • StackExchange.Redis的正确使用方法

    这个想法是使用更少的连接和更好的性能 连接会随时过期吗 对于另一个问题 redis GetDatabase 打开新连接 private static ConnectionMultiplexer redis private static ID
  • 如何使 Redis 缓存中数据层次结构(树)的部分内容无效

    我有一些产品数据 需要在 Redis 缓存中存储多个版本 数据由 JSON 序列化对象组成 获取普通 基本 数据的过程很昂贵 将其定制为不同版本的过程也很昂贵 因此我想缓存所有版本以尽可能进行优化 数据结构看起来像这样 BaseProduc
  • 如何将“.csv”数据文件导入Redis数据库

    如何将 csv 数据文件导入 Redis 数据库 csv 文件中包含 id 时间 纬度 经度 列 您能否向我建议导入 CSV 文件并能够执行空间查询的最佳方法 这是一个非常广泛的问题 因为我们不知道您想要什么数据结构 您期望什么查询等等 为

随机推荐

  • MFC学习笔记 — XP系统写文件失败问题

    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XX 作 者 文化人 XX 联系方式 XX 版权声明 原创文章 欢迎评论和转载 转载时能告诉我一声就最好了 XX 要说
  • 层序输出二叉树

    package Leetcode import java util ArrayList import java util Arrays import java util LinkedList import java util Queue A
  • java.net.SocketException: Software caused connection abort: socket write error

    最近碰到一个莫名的BUG ClientAbortException java net SocketException Software caused connection abort socket write error at org ap
  • CUDA编程: GPU与CPU之间使用全局统一内存的完整代码及编译

    CUDA编程 GPU与CPU之间使用全局统一内存的完整代码及编译 最近碰到一个应用场景 需要从GPU访问host上创建的 一个很大的布隆过滤器 准确说是改进后的布谷鸟过滤器 由于GPU卡上的显存有限 把整个过滤器复制到GPU卡显然不可能 于
  • css grid随页面大小_基于VUE、echarts和Grid的大屏数据可视化实现技术

    简介 数据可视化技术是将把比较复杂 抽象的数据通过可视的技术以人们更易理解的形式展示出来 数据可视化技术促进了数据信息的传播和应用 数据可视化技术是抽象数据的具象表达 大屏数据可视化是以大屏为主要展示载体的数据可视化 目前市场上大屏设备有1
  • MySQL数据表查询

    作者介绍 一个有梦想 有理想 有目标的 且渴望能够学有所成的追梦人 学习格言 不读书的人 思想就会停止 狄德罗 个人主页 进入博主主页 专栏系列 进入MySQL知识专栏 欢迎小伙伴们访问到博主的文章内容 在浏览阅读过程发现需要纠正的地方 烦
  • 不同服务器的servlet之间使用url传输xml文件?,详解WEB应用的部署文件web.xml

    本文使用的服务器是Tomcat服务器 Web应用发布描述文件web xml是在Servlet规范中定义的 web xml存放在WEB INF 目录下 在分析web xml文档之前我想先说一下web xml中根元素各子元素的顺序问题 因为在w
  • vue组件内动态改meta.title浏览器头部提示信息

    前言 vue中我们经常见的是随着切换不同的页面可以修改页面上的meta title 但是还有另一种情况是我们要在组件内部改动他的提示信息 比如 我们封装了一个详情组件 然后需要每次进来的时候获取后台数据 然后根据数据来修改我们页面上的标题信
  • Python爬取京东商品信息-cookie登录、二次请求、来源检查

    Python爬虫 爬取京东商品 因为要教实验室的其他 小朋友 所以自己要在课余时间学下 Python 昨天突发奇想 之前在爬取淘宝的过程中免不了遇到问题 那么在爬取其他网站的时候也会遇到问题 俗话说 问题才是最好的老师 PS 编的 那么就不
  • C++的使用小教程7——类的静态成员

    C 的使用小教程7 类的静态成员 1 什么是静态成员 2 类的静态数据实例 3 类的静态函数实例 学习好幸苦 1 什么是静态成员 当我们声明一个类的成员为静态时 无论创建多少个类的对象 静态成员是共享的 我们可以在类的外部对静态成员进行初始
  • ue材质球就有hlsl代码面板,不需要按照迪士尼pbr自己推导,然后HLSL转GLSL,这样就可以把ue的效果转到GLSL上了。或者用shadertoy

    突然想起 ue材质编辑器就有HLSL代码面板 照抄就行 我去年用迪士尼套公式写到Osg是有问题的 原因就是参数设置不对 应该现在虚幻引擎编辑器里调试OK后 再传递 迪士尼PBR的附加代码还是不简练 应该直接抄UE
  • Python编译器及第三方库

    Python是一种解释型语言 因此没有直接的编译器 相反 Python解释器会逐行解析和执行源代码 然而 存在一些将Python代码转换为其他语言 如C或机器码 的工具 以提高执行速度 文件 url80 ctfile com f 25127
  • 课堂作业--物不知数

    物不知数 出自 孙子算经 题目如下 今有物不知其数 一一数之剩零 二二数之剩一 三三数之剩零 四四数之剩一 五五数之剩一 六六数之剩三 七七数之剩零 八八数之剩一 九九数之剩零 问物几何
  • BUUCTF Misc [ACTF新生赛2020]NTFS数据流 & john-in-the-middle & [ACTF新生赛2020]swp & 喵喵喵

    目录 ACTF新生赛2020 NTFS数据流 john in the middle ACTF新生赛2020 swp 喵喵喵 ACTF新生赛2020 NTFS数据流 下载文件 得到500个txt文件 提示了NTFS流隐写 所以使用NtfsSt
  • OpenLDAP学习笔记

    LDAP协议 目录是一组具有类似属性 以一定逻辑和层次组合的信息 常见的例子是通讯簿 由以字母顺序排列的名字 地址和电话号码组成 目录服务是一种在分布式环境中发现目标的方法 目录具有两个主要组成部分 第一部分是数据库 数据库是分布式的 且拥
  • C++运行栈与函数调用的执行

    1 运行栈工作原理 C 变量在运行时依靠地址加以区分 变量的定义全部写在函数以外 这样的变量叫做全局变量 变量的定义放在一个函数之内 这样的变量叫做局部变量 全局变量 在目标代码中都是用一个唯一确定的地址定位的 然而 对于全局变量却不能如此
  • extern和static对变量的作用

    一 extern对变量的作用 1 引言 在java中 我们都知道 定义在前的变量可以调用定义在后的变量 但是在c中 这是不被允许的 我们有以下几个解决途径 1 将变量c的定义提前 2 对变量c进行声明操作 3 进行重复定义操作 有点奇怪 这
  • Easy Code Mybatis-plus自用模板

    1 idea先安装插件 EasyCode 2 设置模板信息 通过设置找到插件 点击添加模板具体配置看如下 Controller 导入宏定义 define vm define init 设置表后缀 宏定义 setTableSuffix Con
  • EasyExcel--基础--03--读Excel

    EasyExcel 基础 03 读Excel 代码位置 https gitee com DanShenGuiZu learnDemo tree master easyExcel learn 1 依赖
  • Redis的embstr与raw编码方式不再以39字节为界了!

    版权声明 本文为博主原创文章 未经博主允许不得转载 https blog csdn net XiyouLinux Kangyijie article details 78045385 引言 从 中国软件杯 回来之后 一直对项目中没用到Red