redis session java获取attribute_redis里的数据结构

Redis作为当前使用非常广泛的内存数据库,在代码层面做了很多极致的优化,已获取更好的性能。其中重要的一部分,就是对于底层数据结构的使用。Redis会根据数据量、数据大小等来优化对于不同结构的使用,从而获得更佳的运行效率和内存占用。Redis的核心数据结构包括简单动态字符串、列表、字典、跳跃表、整数集合、压缩列表。

接下来,我们就依次讲讲这些数据结构。

简单动态字符串(SDS)

Redis是用C语言实现的。先复习一下C,C里的字符串中不记录字符串长度,以空字符标记结尾。这样会显而易见的带来三个问题:1.获取字符串长度需要O(n)的复杂度;2.操作不慎会导致缓冲区溢出,例如内存中紧邻的两个字符串,如果对前一个调用strcat拼接其他字符串,就会造成溢出;3. 一些特殊内容,如图像、音频等转成二进制时,难免其中夹杂空字符等特殊字符,这样就无法被C字符串存储了,即C字符串不具备二进制安全性。

而这几点,对于Redis的应用场景来说,影响其实都是非常大的。因此,在redis中定义了一个新的结构,用来保存字符串,即SDS。

SDS的核心思想就是额外使用一个字段记录字符串的长度,这样,上面三个问题就都迎刃而解了。

此外,redis从4.0开始对SDS做了一个代码层面的优化,优化了内存占用,不过不影响其底层逻辑。

这是redis 3.0里SDS的源码:

struct sdshdr {unsigned int len;unsigned int free;char buf[];
};

而这是redis 4.0之后SDS的源码:

  struct __attribute__ ((__packed__)) sdshdr5 {unsigned char flags; /* 3 lsb of type, and 5 msb of string length */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr8 {uint8_t len; /* used */uint8_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr16 {uint16_t len; /* used */uint16_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr32 {uint32_t len; /* used */uint32_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};
struct __attribute__ ((__packed__)) sdshdr64 {uint64_t len; /* used */uint64_t alloc; /* excluding the header and null terminator */unsigned char flags; /* 3 lsb of type, 5 unused bits */char buf[];
};

可以看到,在新版的源码里,数据存储会根据情况使用uint8,uint16等不同类型。在C里,一个int占用4个字节,因此,对于原版的SDS来说,即使存储的信息非常少,也会固定占到8个字节。而uint8只占一个字节,uint16只占2个字节,对于小数据来说,redis的内存占用会有明显优化。

此外,redis会有空间预分配、惰性释放等机制,减少内存分配的次数。SDS的实现方式也保证了大部分方法可以兼容C字符串,减少了大量实现成本。

链表

Redis里的链表是一个普通的双向无环链表,相信大家都很熟悉了,就不细说了,结构如下。

typedef struct listNode {struct listNode *prev;struct listNode *next;void *value;} listNode;

Redis中的列表对象,底层就是链表。

字典

字典也就是我们常说的map。

typedef struct dictht {dictEntry **table;unsigned long size; //hash表长度unsigned long sizemask;unsigned long used; //已有的长度} dictht;

Redis中的字典是hash表,使用链地址法解决hash地址冲突。

类似于java等语言中的hashMap, redis的字典也会有rehash的机制,保证其负载因子维持在合理的范围内。

跳跃表 (skiplist)

Skiplist是一种应用非常广的数据结构,通常是作为AVL树的一种替代选择,和AVL树一样,skiplist的查找复杂度也是O(logn), 但是实现会简单的多,下边我们用短短的几行字就能把SkipList的所有内容讲的非常清楚。此外,在并发环境下,SkipList也会有很大优势,因为AVL数在平衡过程中,可能会涉及到很多节点,也就需要锁住很多节点,SkipList则完全不存在这种问题。

c737fe2aaee5184c819ef6aeb016fb8f.png

从网上找了一张示意图,可以很清楚的展示出SkipList的结构。跳跃表说白了就是一个多层的列表,每一个元素会随机的出现在某一层上,然后某一层的链表中会包含所有高于或等于本层的元素。

跳跃表的查找就是从高层查起,逐步降层,定位到具体元素。比如要查询7, 其顺序就是9->6->7.

跳跃表的插入也是先做一次查找,然后直接给元素设置一个随机的层数,再调整指针。

删除则是删除节点,然后调整指针。

Redis中的有序集合,就是基于跳跃表实现的。

整数集合(intset)和压缩列表(ziplist)

这两个结构非常像,因此就放在一起讲了。它们都是针对特定条件下的小数据集做的特定优化。

整数集合是一个有序集合,使用的条件是集合中只包含整数,且元素个数不多。

压缩列表同样是针对列表项非常少的情况,且要求元素只能是小整数值或短字符串。它可以提供类似双向链表的功能。

因为整数集合和压缩列表都是针对小数据集的,所以可以使用连续的内存空间去保存,实现也就简单了很多,这里就不细说了。

在实际应用中,zipList可以作为链表或者字典的替代品,应用在redis的列表、哈希、有序集合中。整数集合则作为字典的替代品,用在集合对象中。

以上就是redis中主要的数据结构,在这些结构的基础上,redis实现了大量功能完善的对象,供我们使用。理解了redis这些底层结构的原理,也可以帮助我们更好的发挥redis的价值。

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

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

相关文章

.NET 云原生架构师训练营(模块二 基础巩固 安全)--学习笔记

2.8 安全认证 VS 授权ASP .NET Core 认证授权中间件认证JWT 认证授权认证 VS 授权认证是一个识别用户是谁的过程授权是一个决定用户可以干什么的过程401 Unauthorized 未授权403 Forbidden 禁止访问ASP .NET Core 认证授权中间件在接收到请求之后,认证(A…

java超长字符序列化_String 字符串最长可以有多长?

Java技术栈www.javastack.cn打开网站看更多文章String 类可以说是在 Java 中使用最频繁的类了,就算是刚刚接触 Java 的初学者也不会陌生,因为对于 Java 程序来说,main 方法就是使用一个 String 类型数组来作为参数的(String[] args)。对于这样…

一文读懂 AVL 树

背景AVL 树是一棵平衡的二叉查找树,于 1962 年,G. M. Adelson-Velsky 和 E. M. Landis 在他们的论文《An algorithm for the organization of information》中发表。所谓的平衡之意,就是树中任意一个结点下左右两个子树的高度差不超过 1。&am…

欧几里得范数_从范数到正则化

范数是一个在数学领域中常用的工具,同时也是学习机器学习原理中经常碰到的概念。本文将从范数的定义出发,逐步带你理解其在机器学习中的应用。首先需要明确的是,范数是一个函数,在机器学习中我们通常用它来衡量向量的大小。 范数定…

IdentityServer4之持久化很顺手的事

前言原计划打算在春节期间多分享几篇技术文章的,但到最后一篇也没出,偷懒了吗?算是吧,过程是这样的:每次拿出电脑,在孩姥姥家的院子总有阳光沐浴,看不清屏幕,回屋又有点冷(在强行找理…

手写体识别代码_Python识别图片中的文字

一、前言不知道大家有没有遇到过这样的问题,就是在某个软件或者某个网页里面有一篇文章,你非常喜欢,但是不能复制。或者像百度文档一样,只能复制一部分,这个时候我们就会选择截图保存。但是当我们想用到里面的文字时&a…

递推与储存,是动态规划的关键

小智最近由于项目需要,经常要接触到一些规划类的问题。那今天就给大家讲一讲旅行商问题及其解法吧。旅行商问题,即TSP问题(Travelling Salesman Problem)。问题是,有一个旅行商人要拜访n个城市,每个城市只能…

dotnet core TargetFramework 解析顺序探索

dotnet core TargetFramework 解析顺序测试Intro现在 dotnet 的 TargetFramework 越来越多,抛开 .NET Framework 不谈,如果一个类库支持多个 TargetFramework 应用实际运行的时候会使用哪个版本的 API 呢,之前一直都是想当然的自以为是了&…

大数据时代,掌握数据分析需要做到这几点

这些年来,随着进入大数据时代,各行各业均有一个词频频被提到,那就是数据分析。那么数据分析究竟是什么呢?数据分析就是指用适当的统计分析方法对收集来的大量数据进行处理分析,提取有用信息并形成结论,从而…

93.7%的程序员!竟然都不知道Redis为什么默认16个数据库?

背景在实际项目中redis常被应用于做缓存,分布式锁/消息队列等。但是在搭建配置好redis服务器后很多朋友应该会发现和有这样的疑问,为什么redis默认建立了16个数据库,16个数据库的由来redis是一个字典结构的存储服务器,一个redis实…

“一边熬夜一边求不要猝死”,90后养生朋克指南,条条扎心!

随着一批又一批的90后步入中年秃头、失眠、衰老...健康的压力如影如随是时候开始养生朋克了当代青年:养生朋克指南养生朋克一边作死一边自救的养生方式比如一边熬夜一边涂贵价护肤品用最贵的眼霜 熬最长的夜心理活动经常是:一边熬夜一边祈祷自己不要猝死…

万级 K8S 集群背后,etcd 如何保持稳定性?

这几年,随着 Kubernetes 成为容器编排领域霸主,etcd 越来越火,GitHub star 已超过 34.2K。这与它的应用场景广泛密不可分,从服务发现到分布式锁,从配置存储到分布式协调,可以说,etcd 已成为云原…

qdialog 只有点击才能获得焦点_4 个突破点,让你的 Banner 点击率提升10倍

双 11 刚过,双 12又来了每年这个时候作为一名设计师,真的很难...老板压着做电商 banner还有很多人指指戳戳让你改稿好不容易按照别人的想法过稿结果banner 的点击率还不高其实,只需要稍微调整视觉重点你的电商banner 就会变得变得更吸引人&am…

穿背心的老院士,86岁,重病,还在敲代码,单手!

昨天有幸看到了一个视频,视频中,一位老先生穿着朴素的白背心,伏在桌上,对着电脑,一手按着写满密密麻麻数学公式的本子,另一只手仅用单指吃力又缓慢地按着键盘。老先生全神贯注地研究他是 “背心院士” 高伯…

百度广告点击软件_结束了,百度 “毒瘤” 广告!

“ 通过本文,你可以获取一款上网必备的插件,让你摆脱各种"毒瘤"广告。”大家天天逛网页,最恼人的也就是广告了吧。尤其是百度搜索时。01—毒瘤广告有多愁?百度广告有多可怕,小哥哥给你演示一下。百度搜“智齿…

java跳转画面后画面白了_如何跳转指定页面后再次跳转到另一页面或原来的页面...

c#图解教程第5版数万读者认可的新99.33元(需用券)去购买 >这里可以采用redirect以get形式向指定页面发出get请求,指定页面完成后会再次跳转到redirect后边指定的页面(注意:这里的redirect只是一个自定义参数,并不是自带的,名称…

【基础数学知识】带你理解泰勒展开式本质

推荐阅读时间:5min~8min主要内容:更好的理解,并且记忆泰勒展开式我们学习泰勒展开,本质上就是为了在某个点附近,用多项式函数取近似其他函数。可能有些童鞋就要问了,既然有一个函数了,为什么还需…

C#使用NPOI进行word的读写

目录一、简介1、操作Word的类库:二、简单使用1、XWPFDocument类的实例化2、设置页面的大小3、段落处理4、表格处理5、页眉页脚处理三、综合示例四、参考一、简介1、操作Word的类库:二、简单使用1、XWPFDocument类的实例化该类的实例对应一个word文档XWPF…

weblogic修改控制台ip_「Weblogic学习」Weblogic知识要点之JNDI/JTA编程开发

给它一个名字,它就能提供你要的服务,JNDI就是这么地任性。想任性的霸占数据?JTA为你把风。这期,谈谈JNDI和JTA的简单介绍,一起看看吧……JNDI编程JNDI(Java Naming and Directory Interface)是SUN公司提供的一种标准的…

java不适合开发cv吗_JavaCV开发环境的配置

一.安装opencv2.4.4、测试运行OpenCV-2.4.4.exe,就是解压,把它解压到一个你喜欢的地方 ——1.1 路径最好不要太深,点啊点的最讨厌了2. 添加 ***\OpenCV2.4.4\build\x64\vc11\bin; 到环境变量的PATH后面 ——2.1 ***是你放OpenCV2.4.4的地方…