Redis-概论

简介: [Remote Dictionary Service],也就是「远程字典服务」,Redis。

[Remote Dictionary Service],也就是「远程字典服务」,Redis。

Redis我们都知道有5种基础数据结构:分别为:string (字符串)、list (列表)、set (集合)、hash (哈希) 和 zset (有序集合)。

再说这些基础数据结构的时候,我们先说说Redis的Key:

Key:

Redis的键是二进制安全的,也就是任何binary sequence都可以作为键,比如“foo”到到JPEG文件的内容,空字符串也是有效的值,Redis的键根据自身业务去设计,但不要过于长和短,它最大大小为512MB,当然关于键的设计,官网给出了hashing的处理方式。

string:

它的数据结构是Key-Value,通过key获取相应的值。Redis 的字符串是动态字符串,是可以修改的字符串,在内存中它是以字节数组的形式存在的。

Redis 的字符串叫着「SDS」,也就是 Simple Dynamic String。它的结构是一个带长度信息的字节数组。以'\0'结尾。SDS结构使用的是范型,为什么不直接用 int 呢,这是因为当字符串比较短时,存入的值 和 分配的空间 可以使用 byte 和 short 来表示,

struct SDS<T> {  T capacity; // 数组容量 T len; // 数组长度byte flags; // 特殊标识位byte[] content; // 数组内容}

Redis 为了对内存做极致的优化,不同长度的字符串使用不同的结构体来表示。它采用预分配冗余空间的方式来减少内存的频繁分配,Redis内部当前字符串实际分配的空间一般高于字符串长度。当字符串长度小于 1M 时,扩容都是加倍现有的空间,如果超过 1M,扩容时一次只会多扩 1M 的空间,

简单操作,格式 {SET 键 值,GET 键}.当批量SETGET的时候,会节省网络耗时开销.(Redis管道机制)。

过期事件,格式{EXPIRE  键 时间}. {setex 键 时间 值}。

计数:如果 value 值是一个整数,还可以对它进行自增操作。自增是有范围的,它的范围是signed long 的最大最小值,超过了这个值,Redis 会报错。格式{incr 键}.

list:

它是链表而不是数组,插入和删除操作都是O(1)级别,但是索引慢O(n)。当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。

Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。

右边进左边出:队列  右边进右边出:栈

我们会发现,Redis底层存储是一个快速链表的结构(quicklist).首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是压缩列表(支持双向遍历)。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的时候才会改成 quicklist。ziplist是列表键和哈希键的底层实现之一。当一个列表键只包含少量列表项,并且每个列表项要么是小整数值,要么就是长度较短的字符串,那么Redis就会使用压缩列表。

image.png

这里,注意观察 debug object 输出的 encoding 字段都是 ziplist,这就表示内部采用压

缩列表结构进行存储。

struct ziplist<T> { int32 zlbytes; // 整个压缩列表占用字节数int32 zltail_offset; // 最后一个元素距离压缩列表起始位置的偏移量,用于快速定位到最后一个节点 int16 zllength; // 元素个数T[] entries; // 元素内容列表,挨个挨个紧凑存储int8 zlend; // 标志压缩列表的结束,值恒为 0xFF}

zltail_offset就是用来快速定位到最后一个元素。倒着遍历。

entry 块随着容纳的元素类型不同,也会有不一样的结构。

struct entry {int<var> prevlen; // 前一个 entry 的字节长度int<var> encoding; // 元素类型编码optional byte[] content; // 元素内容}

encoding 字段存储了元素内容的编码类型信息,ziplist 通过这个字段来决定后面的content 内容的形式、通过前缀位来识别具体存储的数据形式,content 字段在结构体中定义为 optional 类型,表示这个字段是可选的,对于很小的整数而言,它的内容已经内联到 encoding 字段的尾部了。

因为 ziplist 都是紧凑存储,没有冗余空间 (对比一下 Redis 的字符串结构)。意味着插入一个新的元素就需要调用 realloc 扩展内存。取决于内存分配器算法和当前的 ziplist 内存大小,realloc 可能会重新分配新的内存空间,并将之前的内容一次性拷贝到新的地址,也可能在原有的地址上进行扩展,这时就不需要进行旧内容的内存拷贝。如果 ziplist 占据内存太大,重新分配内存和拷贝内存就会有很大的消耗。所以 ziplist 不适合存储大型字符串,存储的元素也不宜过多

 

当 set 集合容纳的元素都是整数并且元素个数较小时,Redis 会使用 intset 来存储结合元素。intset 是紧凑的数组结构,同时支持 16 位、32 位和 64 位整数。

struct intset<T> {  int32 encoding; // 决定整数位宽是 16 位、32 位还是 64 位 int32 length; // 元素个数int<T> contents; // 整数数组,可以是 16 位、32 位和 64 位}

hash

无序字典,数组+链表二位结构。第一维 hash 的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。

image.png

Set集合

它内部的键值对是无序的唯一的。它的内部实现相当于一个特殊的字典,字典中所有的 value 都是一个值 NULL。set 结构可以用来存储活动中奖的用户 ID,因为有去重功能,可以保证同一个用户不会中奖两次。

zset (有序列表)

一方面它是一个 set,保证了内部value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权重。它的内部实现用的是一种叫着「跳跃列表」的数据结构。zset 可以用来存粉丝列表,value 值是粉丝的用户 ID,score 是关注时间。我们可以对粉丝列表按关注时间进行排序。zset 内部的排序功能是通过「跳跃列表」数据结构来实现的,它的结构非常特殊,也比较复杂。

相关文章
|
机器学习/深度学习 人工智能 算法
机器学习是什么?
机器学习是什么?
736 4
|
4月前
|
敏捷开发 开发框架 测试技术
从零开始:如何快速开发一个软件?实用方法 + 避坑指南
本文介绍了如何在保证质量的前提下快速开发软件,涵盖从需求分析到上线推广的完整流程。内容包括敏捷开发、MVP设计、工具选择、团队协作与持续运营等关键环节,适合初创团队、企业试点及个人开发者参考,帮助高效验证产品价值,缩短开发周期,降低试错成本。
|
2月前
|
JSON 搜索推荐 API
拼多多商品详情API技术指南
拼多多商品详情API(pdd.goods.detail.get)支持通过商品ID获取商品标题、价格、销量、图片、库存及评价等详细信息,适用于电商数据分析、竞品监控与价格策略优化,返回标准JSON格式,便于集成开发。
|
4月前
|
前端开发 JavaScript
一刀999小网页的实现
这是一款使用HTML、CSS和JavaScript实现的简单网页游戏。玩家每次攻击造成999点伤害,目标是击败拥有10000血量的敌人。游戏包含血量条动画、点击特效和响应式设计,界面美观,交互体验良好,可直接在浏览器中运行。
136 1
|
4月前
|
Ubuntu Linux 开发者
Linux发行版比较:选择适合你的操作系统
在做出选择之前,建议您先在虚拟机或双系统环境中尝试不同的发行版,根据自己的体验和需求做出决策。选择适合自己的Linux发行版是一个个人化和主观的过程,最重要的是找到符合自己需求和喜好的发行版,让您在使用Linux系统时感到舒适和方便。
|
10月前
|
JavaScript 前端开发 数据可视化
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
615 2
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
675 4
|
网络协议 物联网 网络性能优化
物联网协议比较 MQTT CoAP RESTful/HTTP XMPP
【10月更文挑战第18天】本文介绍了物联网领域中四种主要的通信协议:MQTT、CoAP、RESTful/HTTP和XMPP,分别从其特点、应用场景及优缺点进行了详细对比,并提供了简单的示例代码。适合开发者根据具体需求选择合适的协议。
504 5
|
块存储
cephx认证及启用和禁用实战
这篇文章介绍了如何在Ceph集群中禁用和启用cephx认证协议,包括修改配置文件、重启服务以及验证配置更改的效果。
300 3
cephx认证及启用和禁用实战
|
存储 自然语言处理 数据可视化
3倍提升效率:医疗病理信息抽取与关系图谱展示系统解析
该项目旨在通过NLP技术将医疗病理报告中的非结构化文本转化为结构化数据,实现信息的高效抽取、存储及可视化展示。利用Python、JavaScript等技术栈,结合Echarts等工具,构建病理信息的关系图谱,支持多条件检索与图表互动,提高医生及研究人员的工作效率。预期成果包括数据结构化、关系图谱可视化、快速检索及数据统计分析等功能。项目预计2-4周完成。
245 0