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://xiahunao.cn/news/3030523.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

MOS管栅极驱动自举电路设计

自举式驱动电路工作原理 自举式电路在高电压栅极驱动电路中是很有用的,其工作原理如下: 当 VS 降低到 IC 电源电压 VDD以下(至少要比VDD低一个二极管压降) 或下拉至地时 (低端开关导通,高端开关关断),电源 VDD 通过自举电阻RBOOT,和自举二极管DBOOT,对自举电容CBOOT…

产业互联网助力预制菜出海 云创科技数据资产入表获批融资500万 新能源装备新质供应链创新协同平台启动 | 产业互联网观察第173期

产业互联网助力预制菜迈向国际市场 在第135届广交会上&#xff0c;一场聚焦“产业互联网赋能预制菜出海”的高端对话会隆重举办。本次活动由中国食品土畜进出口商会主办&#xff0c;云食界网络科技有限公司承办&#xff0c;吸引了众多政府领导、行业专家和企业代表参与。各界共…

跨境电商行业蓬勃发展,武汉星起航引领卖家孵化新潮流

近年来&#xff0c;我国跨境电商行业在政府的大力扶持下呈现出强劲的发展势头。随着国内制造业结构的加速调整与居民消费需求升级态势的持续凸显&#xff0c;跨境出口规模占比稳步提升&#xff0c;跨境进口规模同样不断扩大&#xff0c;行业市场规模持续增长。在这一背景下&…

计算概论学习笔记(1)

感谢北大李戈老师讲解的计算概论。 【道阻且长&#xff0c;行则将至】 很多年没有intensive coding&#xff0c;现在这个系列是coding retake&#xff0c;一点点回忆之前的知识&#xff0c;希望能重回到一线。主要内容包括C,C,Pytorch学术前沿项目学习和实践&#xff0c;预计…

ESLint: Unexpected ‘debugger‘ statement.(no-debugger)(debugger报红)

ESLint: Unexpected debugger statement.(no-debugger) 解决办法&#xff1a; 找到.eslintrc.js文件中rules的no-debugger更改为0即可

【35分钟掌握金融风控策略18】贷前风控策略详解-3

目录 ​编辑 贷前风控数据源 第三方数据 贷前风控数据源 第三方数据 在金融风控过程中&#xff0c;金融机构通常会引入一些第三方的风控数据&#xff08;或第三方金融技术&#xff09;来辅助识别贷款个人或贷款企业的风险状况&#xff0c;帮助金融机构进行风控决策&#x…

Linux vscode push报错fatal: Authentication failed

注意啊&#xff0c;Git基于密码的身份验证已经被删除了&#xff0c;所以这个报错发生时无论密码正确与否&#xff0c;以及参考比较旧的改bug教程&#xff0c;都没法提交。进入提示的网址&#xff0c;生成个人访问令牌就好了

【qt】联合容器和集合容器

联合容器和集合容器 一.QMap1.应用场景2.添加数据3.删除数据4.修改数据5.查找数据6.数据个数7.是否包含8.返回所有的键名 二.QHash1.应用场景&#xff1a; 三.QMultiMap四.QMultiHash五.QSet1.应用场景2.交集3.并集4.差集 总结&#xff1a; 一.QMap 1.应用场景 QMap的底层实现…

字符以及字符串函数

字符以及字符串函数 求字符串长度strlen 长度不受限制的字符串函数strcpystrcatstrcmp 长度受限制的字符串函数strncpystrncatstrncmp 字符串查找strstrstrtok 错误信息报告strerror 字符分类函数字符转换函数tolowertoupper 内存操作函数memcpymemmovememcmpmemset 这篇文章注…

Ubuntu(Linux)Windows 网络连接问题

需求&#xff1a;实现Ubuntu和Windows系统间以太网连接。 Windows端口以太网配置选择IPv4&#xff0c;配置自己的IP&#xff0c;子网掩码不需要填&#xff0c;系统自动补全&#xff0c;默认网关不需要填。 Ubuntu系统为22.04&#xff0c;如果使用网络设置完成IPv4地址设置&…

日本住宅IP:安全、高效的新选择

在信息化社会&#xff0c;网络已成为人们工作、生活不可或缺的一部分。而IP地址&#xff0c;作为网络中的身份证&#xff0c;其重要性不言而喻。近年来&#xff0c;随着跨境业务、网络安全需求以及个人隐私保护意识的增强&#xff0c;日本住宅IP代理逐渐进入人们的视野&#xf…

分布式事务技术方案

什么是分布式事务 一次课程发布操作需要向数据库、redis、elasticsearch、MinIO写四份数据&#xff0c;这里存在分布式事务问题。 什么是分布式事务&#xff1f; 首先理解什么是本地事务&#xff1f; 平常我们在程序中通过spring去控制事务是利用数据库本身的事务特性来实现…

如何远程控制另一部手机:远程控制使用方法

在现今高科技的社会中&#xff0c;远程控制手机的需求在某些情境下变得越来越重要。不论是为了协助远在他乡的家人解决问题&#xff0c;还是为了确保孩子的在线安全&#xff0c;了解如何实现这一功能都是有益的。本文将为您简要介绍几种远程控制手机的方法及其使用要点。 KKVi…

模电·场效应管放大电路的三种接法

场效应管放大电路的三种接法 场效应管的源极、栅极和漏极与晶体管的发射极、基极和集电极相对应因此在组成放大电路时也有三种接法&#xff0c;即共源放大电路、共漏放大电路和共栅放大电路。以N沟道结型场效应管为例&#xff0c;三种接法的交流通路如图1.所示。 图1. 场效应管…

每日一题8:Pandas-改变数据类型

一、每日一题 编写一个解决方案来纠正以下错误&#xff1a; grade 列被存储为浮点数&#xff0c;将它转换为整数。 返回结果格式如下示例所示。 解答&#xff1a; import pandas as pddef changeDatatype(students: pd.DataFrame) -> pd.DataFrame:students[grade] studen…

python爬虫(三)之虎嗅网汽车文章爬虫

python爬虫&#xff08;三&#xff09;之虎嗅网汽车文章爬虫 闲来没事&#xff0c;闲鱼上有个好兄弟要我从虎嗅网上抓一些汽车文章的爬虫&#xff0c;于是大力出奇迹&#xff0c;我写了一个python程序&#xff0c;将这个网站上所有的汽车文章全部抓取下来了&#xff0c;存储到…

【程序设计和c语言-谭浩强配套】(适合专升本、考研)

一晃大半年没更新了&#xff0c;这一年一直在备考&#xff0c;想着这几天把前段时间学的c语言给大家分享一下&#xff0c;在此做了一个专栏&#xff0c;有需要的小伙伴可私信获取o。 简介&#xff1a;本专栏所有内容皆适合专升本、考研的复习资料&#xff0c;本人手上也有日常…

泰迪智能科技企业数据挖掘流程分析及特色服务优势

企业发展会沉淀大量的数据&#xff0c;数据中囊括了企业业务各种维度指标&#xff0c;通过数据挖掘和数据分析 &#xff0c;让企业业务了解过去、现在和未来将要发生什么&#xff0c;从而更好的调整企业发展方向。泰迪智能科技企业数据挖掘平台是面向企业级用户快速处理数据构建…

《引爆流量获客技术》实操方法,手把手教你搭建盈利流量池

[1]-先导课.mp4 [2]-第1节&#xff1a;设计客户终身价值的方法和买客户思维.mp4 [3]-第2节&#xff1a;【渠道模型】解决谁是我的客户如何找到.mp4 [4]-第3节&#xff1a;【诱饵模型】解决 如何获得更多的客户.mp4 [5]-第4节&#xff1a;【钩子模型】解决让目标客户主动找你…

华为OD机试 - 反射计数 - 矩阵(Java 2024 C卷 200分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…