Redis不同数据类型value存储

一、Strings

redis中String的底层没有用c的char来实现,而是使用SDS数据结构( char buf[])。

缺点:浪费空间

优势:

1.c字符串不记录自身的长度,所以获取一个字符串长度的复杂度是O(N),但是SDS记录分配的长度alloc,已使用长度len,获取长度的复杂度为O(1)。比如,为char,必须一个个遍历,直到遍历到\0,字符串越长,那么速度越慢

2.可以减少字符串修改带来的内存重分配次数

字符串更改必须要先申明内存,否则会导致内存溢出。trim(str)时,还需要把不再使用的空间回收,不然会内存泄漏,并且如果操作频率过多,还会导致性能下降。这两点redis是如何优化的呢?

2.1空间预分配:SDS长度如果小于1MB,预分配跟长度一样的,大于1M,每次跟len的大小多1M

2.2惰性空间释放:截取的时候,不马上释放空间,供下次使用!同时提供相应的释放SDS未使用空间的API

2.3二进制安全:C字符串中的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符串被误认为是字符串结尾。这是因为c的字符是以空字符来判断这个字符串是否结束的。这些限制使得C字符串只能保存文本数据,而不能保存像图像、音频、视频、压缩文件这样的二进制数据。   SDS字符串是否结束是根据len来, 所以也就不会有这样的问题

二、Hashes

存储结构为ziplist压缩列表,当超过某种条件时,会转换为hashtable

优势:节省内存空间。压缩列表会根据存入的数据的不同类型以及不同大小,分配不同大小的空间。

缺点:因为是一块完整的内存空间,因此当里面的元素发生变更时,会产生连锁更新,严重影响我们的访问性能。所以,只适用于数据量比较小的场景。

那么redis是如何处理该缺陷的呢?

redis中会有相关的配置,hashes只有小数据量时会用到ziplist,当hash对象同时满足以下两个条件的时候,才会使用ziplist编码:

a.hash对象保存的键值对的数量<512个

b.所有的键值对的键和值的字符串长度都<64byte(一个英文字母一个字节)

redis.conf配置

hash-max-ziplist-value 64 // ziplist中最大能存放的值长度
hash-max-ziplist-entries 512 // ziplist中最多能存放的entry节点数量

dict hashtable如图(在下篇博客讲到扩容会着重提到)

三、Lists

存储结构为quicklist快速列表(c源码)

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;

quicklist兼顾了ziplist的节省内存,并且一定程度上解决了连锁更新的问题,quicklistNode每个节点里面是一个ziplist,每个节点又是分开的,那么就算发生了连锁更新,也只会发生在一个quicklistNode节点

quicklist中的每个node的ziplist元素的大小也是可以配置的(redis.conf)

# 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

list-max-ziplist-size如果这个配置值是正数,就代表quickListNode的ziplist的node的数量;如果为负数 固定的是-5到-1,则代表ziplist的大小(上图注释中有说明)

四、Sets集合

Redis的数据类型及使用场景-CSDN博客这篇博客中提到了set中如果存储的是整数的话,会按顺序存储;那么sets集合的存储方式为inset或者hashtable存储。满足元素为整型,并且元素个数小于配置(redis.conf),就用inset存储。

a.如果不是整数类型,就用dict hashtable(数组+链表)

b.如果元素个数超过512个,也会用hashtale存储。

set-max-intset-entries 512

问题:set的key没有value,怎么用hashtable存储呢?value存null就好了

五、Sorted Sets(ZSet)

默认使用的是ziplist(hash的小编码,quicklist的Node都是ziplist)

在ziplist的内部,会按照score排序递增来存储。插入的时候要移动之后的数据。若元素数量大于等于128,或者任一member长度大于等于64字节 则会采用skiplist+dict(跳表)存储。

redis.conf配置

zset-max-ziplist-entries 128
zset-max-ziplist-value 64

skiplist跳表

结构定义(c源码)

* ZSETs use a specialized version of Skiplists */
typedef struct zskiplistNode {
sds ele; //sds数据
double score; //score
struct zskiplistNode *backward; //后退指针
//层级数组
struct zskiplistLevel {
struct zskiplistNode *forward; //前进指针
unsigned long span; //跨度
} level[];
} zskiplistNode;
//跳表列表
typedef struct zskiplist {
struct zskiplistNode *header, *tail; //头尾节点
unsigned long length; //节点数量
int level; //最大的节点层级
} zskiplist;

跳表原理图:

如图:已有数据3.7.11.19.22.27.35.40,假如我找27的数据。

只有一个链表的场景下:我需要一个一个遍历,随着数据量越大,效率就会越慢

随机多层跳表:找27,会从最外层开始找,在22-40之间,再找第二层,在22到35之间,就能找到27。在外层的数据,查询的速度越高,比如找22,只需要找一次。

跳表的层级是在redis.conf中配置的(默认为32)

#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^64elements */

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​​​【收录 Hello 算法】第 5 章 栈与队列

第 5 章 栈与队列 Abstract 栈如同叠猫猫&#xff0c;而队列就像猫猫排队。 两者分别代表先入后出和先入先出的逻辑关系。 本章内容 5.1 栈5.2 队列5.3 双向队列5.4 小结

Vue项目npm install certificate has expired报错解决方法

1.Vue项目 npm install 安装依赖突然报错&#xff1a; npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/zrender/download/zrender-4.3.0.tgz failed, reason: certificate has expired npm ERR! A com…

2024年汉字小达人活动还有4个多月开赛:来做18道历年选择题备考吧

不出特殊情况的话&#xff0c;距离2024年第11届汉字小达人比赛还有4个多月的时间&#xff0c;如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。②把历年真题刷刷熟…

Linux 进程信号【信号产生】

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux知识分享⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Linux知识   &#x1f51d; 目录 前言 信号概念 1. 生活角度的信号 2…

信息系统项目管理师0101:项目建议与立项申请(7项目立项管理—7.1项目建议与立项申请)

点击查看专栏目录 文章目录 第七章 项目立项管理7.1项目建议与立项申请1.立项申请概念2.项目建议书内容记忆要点总结第七章 项目立项管理 项目立项管理是对拟规划和实施的项目技术上的先进性、适用性,经济上的合理性、效益性,实施上的可能性、风险性以及社会价值的有效性、可…

【回溯 状态压缩 深度优先】37. 解数独

本文涉及知识点 回溯 状态压缩 深度优先 LeetCode37. 解数独 编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只…

算法day04

第一题 &#xff1a; 209. 长度最小的子数组 有上题可知&#xff0c;我们会采用双指针和单调性的思路来解决 我们本题采用左右双指针从数组的0位置同向前进&#xff0c;所以将此类模型称为滑块&#xff1b; 步骤思路如下&#xff1a; 步骤一&#xff1a; 定义所有双指针都指向…

MySQL中索引失效的问题

索引失效的情况 这是正常查询情况&#xff0c;满足最左前缀&#xff0c;先查有先度高的索引。 1. 注意这里最后一种情况&#xff0c;这里和上面只查询 name 小米科技 的命中情况一样。说明索引部分丢失&#xff01; 2. 这里第二条sql中的&#xff0c;status > 1 就是范围查…

Python框架Django入门教程

Django 是一个使用 Python 编程语言开发的、免费且开源的 Web 应用框架。它遵循 "DRY&#xff08;Dont Repeat Yourself&#xff09;" 原则&#xff0c;旨在简化创建功能丰富的、高效率的 Web 网站。Django 提供了模型-视图-控制器&#xff08;MVC&#xff09;架构的…

js 数据格式转换,对象转数组,数组转对象

1.对象转数组 // 对象obj转换成数组格式 let obj { orgCode:分局编码, alertId:告警ID, name:告警名称 } let arr [] for(let key in obj) { console.log(11,key,obj[key]); // 定义一个对象&#xff0c;赋值 let o { id: key, // key是obj对象的键值 label: obj[key] …

cocos中的meta文件有什么用?如何生成?

cocos中的.meta文件有什么用&#xff1f;如何生成&#xff1f; 1. .meta文件有什么用&#xff1f; Cocos Creator 会为 assets 目录下的每一个文件和目录生成一个同名的 meta 文件 示例 {"ver": "4.0.23", // 版本"importer": "typescr…

如何访问远程MySQL数据库服务器?

访问远程MySQL数据库服务器是一项常见的任务&#xff0c;它允许我们在不同的地点通过网络连接到MySQL服务器&#xff0c;并进行数据库管理和数据处理操作。我们将重点介绍一种名为【天联】的组网技术&#xff0c;该技术提供了一系列优势&#xff0c;使远程访问MySQL数据库服务器…