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.mzph.cn/pingmian/10427.shtml

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

相关文章

品味Fendi club:精酿啤酒的精致与与众不同

啤酒&#xff0c;作为世界三大饮料之一&#xff0c;其口感和品质的差异能给人们带来截然不同的体验。在众多啤酒中&#xff0c;Fendi club以其与众不同的精酿啤酒风格&#xff0c;吸引了无数热爱啤酒的人。 Fendi club啤酒的精致与与众不同&#xff0c;首先体现在其酿造工艺上。…

Nature子刊:常见口服药的副作用原来这么大!

哥伦比亚大学Harris H. Wang团队 在《Nature Microbiology》期刊上(IF28.3)发表了关于409种细菌-药物对揭示肠道微生物群扰动的驱动因素的文章&#xff0c;该研究通过对转录组学测定结果进行生信分析&#xff0c;强调了大规模转录组学在肠道微生物-外源化学物相互作用的功能发…

AI应用案例:供应链平台健康状况和发展趋势分析

某供应链平台在2019年就遍布了中国320个城市&#xff0c;为2600多家企业提供超40万个品类的供应链服务。它是通过直供城市终端销售门店&#xff0c;甚至是消费者&#xff0c;最大限度保证品牌和终端的销售利益。 但是平台交易市值较大、涉及的行业较多&#xff0c;而且打破了传…

6.数据库

1.实体用矩形表示&#xff0c;属性用椭圆表示&#xff0c;联系用菱形表示 2.层次模型用数表示 3.网状模型用图结构表示 4.关系模型用二维表格结构来表示 5.概念模式基本表 外模式视图 内模式存储 6.模式/内模式映像 外模式/模式映像 7.数据的物理独立性 跟内模式关系 逻辑是视图…

邦注科技给您解答 什么是注塑机模具保护器

模具监视器&#xff0c;这位制造业的守护神&#xff0c;时刻注视着模具的每一个细微变化。它的工作原理如同一位细心的侦探&#xff0c;利用传感器、数据采集系统和监控软件组成的精良装备&#xff0c;探寻模具的秘密。 传感器如同模具的耳目&#xff0c;敏锐地捕捉着模具的温度…

Github图片显示不出来?两步解决!

很多同学可能和我一样&#xff0c;在GitHub中找一些项目或者资料的时候&#xff1b;总是会看到一些图片显示不出来&#xff0c;或者数学公式乱码&#xff1a; 比如这样 还有这样 其实这个主要是因为DNS污染导致的&#xff0c;具体大家可以百度&#xff0c;这边不详细介绍。 解决…

LagentAgentLego智能体工具使用

1. lagent 参考文档 https://github.com/InternLM/Tutorial/blob/camp2/agent/lagent.md 使用 LMDeploy 部署 conda activate agent lmdeploy serve api_server /root/share/new_models/Shanghai_AI_Laboratory/internlm2-chat-7b \--server-name 127.0.0.1 \--model-name in…

JavaEE初阶-多线程4

文章目录 一、单例模式1.1 饿汉模式1.2 懒汉模式 二、阻塞队列1.1 生产者消费者模型1.1.1 现实生活举例1.1.2 生产者消费模型的两个优势1.1.2.1 解耦合1.1.2.2 削峰填谷 1.2 阻塞队列代码1.2.1 使用java标准库的阻塞队列实现生产者消费者模型1.2.2 实现自己的阻塞队列 一、单例…

30年赚1000亿美元--“量化之王”和他最传奇的基金“大奖章”的秘密

文艺复兴是华尔街最成功、最神秘的机构之一。从1988-2018年的30年里&#xff0c;文艺复兴仅向内部员工开放的旗舰基金“大奖章”累计创造了超过1000亿美元的收益&#xff0c;年均回报率高达39%。作为对比&#xff0c;同期“股神”巴菲特的年均回报率为20.5%。 而且&#xff0c;…

【Linux】-IP地址、主机名配置[5]

目录 一、IP和主机名 1、IP地址 2、特殊IP地址 3、主机名 4、在Linux中修改主机名 5、配置主机名映射 二、虚拟机配置固定IP 1、为什么需要固定IP 2、在VMware Workstation中配置固定ip 一、IP和主机名 1、IP地址 每一台联网的电脑都会有一个地址&#xff0c;用于和…

大模型面试常考知识点1

文章目录 1. 写出Multi-Head Attention2. Pre-Norm vs Post-Norm3. Layer NormRMS NormBatch Norm 4. SwiGLU从ReLU到SwishSwiGLU 5. AdamW6. 位置编码Transformer位置编码RoPEALibi 7. LoRA初始化 参考文献 1. 写出Multi-Head Attention import torch import torch.nn as nn …

QT6 android程序界面强制横屏显示不旋转

QT6开发的Android程序有时候旋转后程序会变形&#xff0c;比如想让其固定位横屏显示&#xff0c;就需要进行特殊设置&#xff0c;本文提供一种简便的设置方法。 一.AndroidManifest.xml文件介绍 Android的Manifest.xml文件是一个重要的配置文件&#xff0c;用于描述应用程序的…

2024最新从0部署Django项目(nginx+uwsgi+mysql)

云服务器 我这里用的是腾讯云免费试用的2H4Gcentos服务器&#xff08;后升级为2H8G&#xff0c;保险一点提高内存&#xff09; 因为网上很多关于django部属的教程都是宝塔啊&#xff0c;python版本控制器啊这种的&#xff0c;我也误打误撞安装了宝塔面板&#xff0c;但这里我…

浅谈运维数据安全

在数字化日益深入的今天&#xff0c;运维数据安全已经成为企业信息安全体系中的核心要素。运维工作涉及到企业信息系统的各个方面&#xff0c;从硬件维护到软件升级&#xff0c;从网络配置到数据备份&#xff0c;无一不需要严谨的数据安全保障措施。本文将从运维数据安全的重要…

民航电子数据库:select查询时部分字段缺失

目录 前言异常排查原因解决使用systemPath标签引入本地Jar包后无法打包 前言 1、对接民航电子数据库 2、框架为shardingsphere caedb mybatis 3、部分SQL查询时&#xff0c;会出现字段缺失的情况 4、查看日志打印出来的SQL&#xff0c;字段并未缺失 异常 这里省略SQL语句…

FreeRTOS事件组

什么是事件标志组? 事件标志位 :表明某个事件是否发生,联想:全局变量 flag 。通常按位表示,每一个位表示一个事件(高8 位不算) 事件标志组 是一组事件标志位的集合, 可以简单的理解事件标志组,就是一个整数。 事件标志组本质是一个 16 位或 32 位无符号的数据类型…

鸿蒙开发接口Ability框架:【DataAbilityHelper模块(JS端SDK接口)】

DataAbilityHelper模块(JS端SDK接口) 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在FA模型下使用。 使用说明 使用前根据具体情况引入如下模块 import featureAbility from …

Excel中实现md5加密

1.注意事项 (1)在Microsoft Excel上操作 (2)使用完&#xff0c;建议修改的配置全部还原&#xff0c;防止有风险。 2.准备MD5宏插件 MD5加密宏插件放置到F盘下&#xff08;直接F盘下&#xff0c;不用放到具体某一个文件夹下&#xff09; 提示&#xff1a;文件在文章顶部&…

【教程向】从零开始创建浏览器插件(三)解决 Chrome 扩展中弹出页面、背景脚本、内容脚本之间通信的问题

第三步&#xff1a;解决 Chrome 扩展中弹出页面、背景脚本、内容脚本之间通信的问题 Chrome 扩展开发中&#xff0c;弹出页面&#xff08;Popup&#xff09;、背景脚本&#xff08;Background Script&#xff09;、内容脚本&#xff08;Content Script&#xff09;各自拥有独立…

互联网轻量级框架整合之HibernateMyBatis

持久层框架 Hibernate 假设有个数据表&#xff0c;它有3个字段分别是id、rolename、note, 首先用IDEA构建一个maven项目Archetype选择org.apache.maven.archetypes:maven-archetype-quickstart即可&#xff0c;配置如下pom <project xmlns"http://maven.apache.org/…