redis五种数据类型具体时候的底层编码

redis随着值的类型不同,其在底层编码类型会不相同。目前现有的编码格式有

#define OBJ_ENCODING_RAW 0     /* Raw representation */
#define OBJ_ENCODING_INT 1     /* Encoded as integer */
#define OBJ_ENCODING_HT 2      /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3  /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6  /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7  /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8  /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */

1、redis中的string类型的值底层编码

1.1、string的底层编码

在redis中要对应string类型的value进行编码,有int、raw、embstr三种编码格式。
当value值为数字的时候,使用的是int类型进行编码,
当value为字符类型的时候且长度小于等于44时,使用的是embstr格式
当value为字符类型的时候且长度大于44时,使用的是raw类型的编码格式

1.2、 验证上面所说

  • 当value为int类型时候
127.0.0.1:6379> set intkey 122
OK
127.0.0.1:6379> strlen intkey
(integer) 3
127.0.0.1:6379> object encoding intkey
"int"
  • 当vule为字符串且长度小于等于44
 127.0.0.1:6379> set stringkey a1230123456789012345678901234567890123456789
OK
127.0.0.1:6379> strlen stringkey
(integer) 44
127.0.0.1:6379> object encoding stringkey
"embstr"
  • 当vule为字符串且长度大于44
127.0.0.1:6379> append stringkey 1
(integer) 45
127.0.0.1:6379> strlen stringkey
(integer) 45
127.0.0.1:6379> object encoding stringkey
"raw"

从上面我们可以看出当我们设置intkey的值为122时候,这个时候redis的底层编码使用的是int类型。
当我们设置stringkey的值为小于或者等于44个字节长度的时候,底层的编码使用的是embstr编码格式;当字符串的长度大于44的时候,编码格式就是使用RAW格式

2、list的底层编码

list这种数据类型在redis底层的编码格式只有quickList这一种编码格式。
兼顾了ziplist的节省内存,并且一定程度上解决了连锁更新的问题,我们的
quicklistNode节点里面是个ziplist,每个节点是分开的。那么就算发生了
连锁更新,也只会发生在一个quicklistNode节点

quicklist.文件中源码
typedef struct
{
struct quicklistNode *prev; //前指针
struct quicklistNode *next; //后指针
unsigned char *zl; //数据指针 指向ziplist
unsigned int sz; //ziplist大小 /* ziplist
size in bytes */
unsigned int count : 16; /* count of items in
ziplist */ //ziplist的元素
unsigned int encoding : 2; /* RAW==1 or LZF==2 */ //
是否压缩, 1没有压缩 2 lzf压缩
unsigned int container : 2; /* NONE==1 or ZIPLIST==2
*/ //预留容器字段
unsigned int recompress : 1; /* was this node previous
compressed? */
unsigned int attempted_compress : 1; /* node can't
compress; too small */
unsigned int extra : 10; /* more bits to steal for
future usage */ //预留字段
} quicklistNode;

在这里插入图片描述
我们可以redis.conf文件中通过参数list-max-ziplist-size配置QuickListNode的大小,如果参数配置为正数,那么代表每个quickListNode的ziplist的entry大小。如果配置为负数,代表的是一个ziplist的大小,具体数值固定为-5 ~ -1 ,默认配置是-2。-5到-1代表的值见下面:

# Lists are also encoded in a special way to save a lot of space.
# The number of entries allowed per internal list node can be specified
# as a fixed maximum size or a maximum number of elements.
# For a fixed maximum size, use -5 through -1, meaning:
# -5: max size: 64 Kb  <-- not recommended for normal workloads
# -4: max size: 32 Kb  <-- not recommended
# -3: max size: 16 Kb  <-- probably not recommended
# -2: max size: 8 Kb   <-- good
# -1: max size: 4 Kb   <-- good
# Positive numbers mean store up to _exactly_ that number of elements
# per list node.
# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
# but if your use case is unique, adjust the settings as necessary.
list-max-ziplist-size -2

一般来说推荐配置为-2,-1这两个值。不推荐使用其他的值

验证我们说的list结构使用的是quicklist

127.0.0.1:6379> lpush listKey acv jks
(integer) 2
127.0.0.1:6379> object encoding listkey
(nil)
127.0.0.1:6379> llen listKey
(integer) 2
127.0.0.1:6379> object encoding listKey
"quicklist"

3、hash类型的底层编码

我们可以使用hash类型来存储json对象的时候,需要同时满足下面两个条件时,使用的是ziplist来存储,否则使用dict来进行存储
使用ziplist需要满足的两个条件是:
1、哈希对象保存的键值对数量<512个
2、每一个字段值的都小于64B
验证上述的说法是否正确

  • 设置一个字段时且值的长度小于64B
127.0.0.1:6379> hset hkey name 123
(integer) 1
127.0.0.1:6379> type hkey
hash
127.0.0.1:6379> object encoding hkey
"ziplist"

这个时候我们使用的是ziplist进行编码的

  • 设置一个字段时但字段的值大于64
127.0.0.1:6379> hset hkey2 name a123012345678901234567890123456789012345678901234567890123456789
(integer) 1
127.0.0.1:6379> object encoding hkey2
"ziplist"
127.0.0.1:6379> hstrlen hkey2 name
(integer) 64
127.0.0.1:6379> hset hkey2 name a1230123456789012345678901234567890123456789012345678901234567890
(integer) 0
127.0.0.1:6379> object encoding hkey2
"hashtable"
127.0.0.1:6379> hstrlen hkey2 name
(integer) 65

从上面可以看出,当字段的大小为64的时候其编码格式为"ziplist",字段值再增大一个时候,编码格式就变成了hashtable。

  • ziplist编码具有什么优势?
    ziplist的编码格式如下:
    <zl总字节数><zl的最后一个字节偏移量><zl的entry数> <zllen个entry >
    ziplist可以根据不同的类型及不同大小来分配不同大小的空间,达到节省内存的目的
  • ziplist缺点是什么?
    由于ziplist使用的是一个完整的内存块,如果遇到一个元素需要进行更新的会导致联动更新,严重影响到性能,所以只适合数据量比较小的场景。

4、set类型的底层编码

Redis用intset或hashtable存储set。满足下面条件,就用inset存储

  • 1、存储的所有元素都是整数
  • 2、 如果元素个数超过512个,也会用hashtable存储。跟一个配置有关:
set-max-intset-entries 512

验证上面所说,当skey中只有整数时且数量在512个内,使用的是intset。

127.0.0.1:6379> sadd skey 1 2 3 4 3
(integer) 4
127.0.0.1:6379> object encoding skey
"intset"

给上面的集合中添加一个非整数的值,当添加完成后我们再次进行查看的时候发现其数值变成了hashtable

127.0.0.1:6379> sadd skey a
(integer) 1
127.0.0.1:6379> object encoding skey
"hashtable"

512个整数时候编码是intset,然后当我们再新增一个时候,发现其编码编程了hashtable了。

127.0.0.1:6379> sadd skey 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511
(integer) 512
127.0.0.1:6379> scard skey 
(integer) 512
127.0.0.1:6379> object encoding skey
"intset"
127.0.0.1:6379> sadd skey 512
(integer) 1
127.0.0.1:6379> object encoding skey
"hashtable"
127.0.0.1:6379> scard skey
(integer) 513

那我们这里hashtable是一个k-v键值对,这只存储一个元素需要怎么处理呢?这里的元素存储在key上,然后v赋值为null就可以了。
在这里插入图片描述

5、zset类型的底层编码

默认使用ziplist编码(第三次见到了,hash的小编码,quicklist的Node,
都是ziplist)。
在ziplist的内部,按照score排序递增来存储。插入的时候要移动之后的数据。
如果元素数量大于等于128个,或者任一member长度大于64字节使用skiplist存储。

  • 当数量少于128个时候且单个member的长度小于64字节的使用ziplist
127.0.0.1:6379> zadd zkey 1 a 
(integer) 1
127.0.0.1:6379> zadd zkey 2 b
(integer) 1
127.0.0.1:6379> object encoding zkey
"ziplist"
  • 单个元素的长度等于64字节的时候
127.0.0.1:6379> zadd zkey 3 a123012345678901234567890123456789012345678901234567890123456789
(integer) 1
127.0.0.1:6379> object encoding zkey
"ziplist"
  • 单个元素大于64字节的时候
127.0.0.1:6379> zadd zkey 4 a1230123456789012345678901234567890123456789012345678901234567890
(integer) 1
127.0.0.1:6379> object encoding zkey
"skiplist"
127.0.0.1:6379> zcard zkey
(integer) 4

总结

  • string 类型的数据在redis中都是按照sds格式进行存储的
  • hash类型在字段数量不大于512个及单个字段值不大于64B的时候采用ziplist,否则使用hashTable来进行存储
  • list类型是采用quickList列表来进行存储的,其是一个包含ziplist的双向链表组成的
  • set类型在满足所有元素都是整数且元素个数不超过512个的时候采用的intset编码,否则使用hashTable来进行存储
  • zset类型在同时满足元素不大于128个及单个元素的长度不超过64B的时候采用ziplist来进行存储的,否则使用skipList来进行存储
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/29983.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2023年打印机电商市场数据分析

近年来&#xff0c;伴随自动化办公及在线教育等场景的常态化&#xff0c;文件或学习资料等的打印需求不断增长&#xff0c;这也使得打印机需求暴增&#xff0c;打印机市场的市场规模也越来越大。 根据鲸参谋电商平台的相关数据显示&#xff0c;今年1月份至4月份&#xff0c;打印…

Unity UGUI1——基础组件概述

一、UGUI 介绍 ​ UGUI 是 Unity 引擎内自带的 UI 系统&#xff0c;官方称之为&#xff1a;Unity UI ​ 是目前 Unity 商业游戏开发中使用最广泛的 UI 系统开发解决方案 ​ 它是基于 Unity 游戏对象的 UI 系统&#xff0c;只能用来做游戏 UI 功能 ​ 不能用于开发 Unity 编…

简单的TCP网络程序·单进程(后端服务器)

目录 文件1&#xff1a;tcpServer.cc 文件2&#xff1a;tcpServer.hpp 1.提出日志概念 -- 在后续完善 日志格式 -- 暂定简单的打印功能 2.创建套接字 SOCK_STREAM -- socket参数 3.bind自己的套接字 4.设置socket 为监听状态 * 新接口1&#xff1a;listen 函数1&…

linux服务器上,docker安装nginx

如果出现 Using default tag: latest Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/create?fromImagenginx&taglatest": dial unix /va…

Python 中常用的数据类型及相关操作详解

文章目录 列表&#xff08;Lists&#xff09;创建列表访问列表元素添加元素到列表删除列表元素切片&#xff08;Slicing&#xff09;其他常用操作 元组&#xff08;Tuples&#xff09;创建元组访问元组元素元组长度其他常用操作 字符串&#xff08;Strings&#xff09;创建字符…

Three.js--》实现图片转3D效果展示

目录 项目搭建 初始化three.js基础代码 加载图片纹理 设置着色器 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还是借助框架书写th…

【Qt】Ubuntu安装GCC9.3.0版本的Qt5.15.5

目录 一、安装GCC9.3.0 1.下载GCC9.3.0源码 2.获取依赖项的包 3.生成Makefile文件 4.编译并安装 5.生成软链接 6. 查看GCC版本 二、安装Qt 1.下载Qt安装包 2.创建Qt项目并运行 一、安装GCC9.3.0 1.下载GCC9.3.0源码 https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3…

excel爬虫相关学习1:简单的excel爬虫

目录 1 什么是excel 爬虫 2 EXCEL爬虫 2.1 excel 爬虫的入口 2.2 需要配置的信息 2.2.1 如何获得 ua信息 2.3 获取的信息 2.3.1 获取信息的基本内容 2.3.2 获取过程 2.3.3 我们只用关注“表视图 ” 即可 2.4 EXCEL获得的爬虫数据 加载到excel里 2.5 数据到了excel表后…

Three.js--》实现3d汽车模型展览搭建

目录 项目搭建 初始化three.js基础代码 添加汽车模型展示 动态修改汽车模型 今天简单实现一个three.js的小Demo&#xff0c;加强自己对three知识的掌握与学习&#xff0c;只有在项目中才能灵活将所学知识运用起来&#xff0c;话不多说直接开始。 项目搭建 本案例还是借助…

flink主要组件及高可用配置

背景 flink不论运行在哪种环境&#xff0c;例如Yarn&#xff0c;Mesos&#xff0c;Kebernute以及独立集群&#xff0c;每个应用都会包含重要的几个组件&#xff0c;本文就来讲述下flink的主要组件以及如何实现flink的高可用配置 flink主要组件 如图所示&#xff0c;flink主要…

Java实训日志02

文章目录 八、项目开发实现步骤&#xff08;二&#xff09;创建项目1、创建Java项目2、创建目录&#xff0c;添加素材&#xff08;1&#xff09;创建help目录添加帮助文档&#xff08;2&#xff09;创建images目录添加图像素材&#xff08;3&#xff09;创建lib目录添加数据库驱…

Dockerfile创建镜像

一、Docker镜像的创建 创建镜像有三种方法&#xff0c;分别为【基于已有镜像创建】、【基于本地模板创建】以及【基于Dockerfile创建】。 1.1 基于现有镜像创建 &#xff08;1&#xff09;首先启动一个镜像&#xff0c;在容器里做修改docker run -it centos:7 /bin/bash …

设计模式之工厂方法模式笔记

设计模式之工厂方法模式笔记 说明Factory Method(工厂方法)目录UML抽象工厂示例类图咖啡抽象类美式咖啡类拿铁咖啡类 咖啡工厂接口美式咖啡工厂类拿铁咖啡工厂类 咖啡店类测试类 说明 记录下学习设计模式-工厂方法模式的写法。 Factory Method(工厂方法) 意图:定义一个用于创…

主从架构lua脚本-Redis(四)

上篇文章介绍了rdb、aof持久化。 持久化RDB/AOF-Redis&#xff08;三&#xff09;https://blog.csdn.net/ke1ying/article/details/131148269 redis数据备份策略 写job每小时copy一份到其他目录。目录里可以保留最近一个月数据。把目录日志保存到其他服务器&#xff0c;防止机…

专业的知识图谱应用门槛正在被不断降低

前⾔ 知识图谱&#xff08;knowledge graph&#xff09;⼀度被专家称为“AI皇冠上的明珠”&#xff0c;因为知识图谱技术是⼈⼯智能技术⽅向中的重要⼀环。它不仅可以为其他⼈⼯智能应⽤提供⽀持&#xff0c;如⾃然语⾔处理、推荐系统等&#xff0c;更可以帮助⼈⼯智能系统⾃主…

《微服务实战》 第三十一章 ShardingSphere - ShardingSphere-JDBC

前言 Apache ShardingSphere 是一款分布式的数据库生态系统&#xff0c; 可以将任意数据库转换为分布式数据库&#xff0c;并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 Apache ShardingSphere 设计哲学为 Database Plus&#xff0c;旨在构建异构数据库上层的…

【Python 随练】统计字符类型个数

题目&#xff1a; 输入一行字符&#xff0c;分别统计出其中英文字母、空格、数字和其它字符的个数。 简介&#xff1a; 在本篇博客中&#xff0c;我们将解决一个字符统计问题&#xff1a;输入一行字符&#xff0c;统计其中英文字母、空格、数字和其他字符的个数。我们将提供…

NoSQLBooster 8.0.11 for MongoDB

MongoDB最智能的IDE。 NoSQLBooster 是适用于 MongoDB Server 3.6-6.0 的跨平台 GUI 工具&#xff0c;它提供了内置的 MongoDB 脚本调试器、全面的服务器监控工具、链接流畅查询、SQL 查询、查询代码生成器、任务调度、ES2020 支持和高级 IntelliSense 体验。 嵌入式MongoDB S…

强化学习从基础到进阶-常见问题和面试必知必答[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验

【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧&#xff08;调参、画图等、趣味项目实现、学术应用项目实现 专栏详细介绍&#xff1a;【强化学习原理项目专栏】必看系列&#xff1a;单智能体、多智能体算法原理项目实战、相关技巧…

redis键值对映射关系存储-Dict

基本概述 Redis是一个键值型&#xff08;Key-Value Pair&#xff09;的数据库&#xff0c;可以根据键实现快速的增删改查。而键与值的映射关系正是通过Dict来实现的。 Dict由三部分组成&#xff0c;分别是&#xff1a;哈希表&#xff08;DictHashTable&#xff09;、哈希节点&a…