redis 笔记01

文中内容摘自《redis设计与实现》

简单动态字符串

1. redis自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示

2. SDS属性:

1). free : 未使用的空间

2). len : 已保存字符串的长度

3). buf : char类型数组,字符串保存的内容,最后一个字节是一个空字符‘\0‘

3. SDS遵循C字符串以空字符串结尾的惯例,保存空字符的1字节空间不计算在SDS的len属性里面。遵循空字符串惯例的好处是,SDS可以直接重用一部分C字符串函数库里的函数。

4. SDS与C字符串的区别:

1). C字符串获取字符串的长度的复杂度为O(N),SDS获取字符串长度的复杂度为O(1)

2). C字符串的API是不安全的,可能会造成缓冲区溢出。SDS的API是安全的,不会造成缓冲区地溢出。

3). C字符串修改字符串的长度N次必然需要执行N此内存分配。SDS修改字符串长度N次最多需要执行N此内存重新分配。SDS减少修改字符串时带来的内存重新分配次数的方式:

a. 空间预分配

b. 惰性空间释放

4). C字符串只能保存文本数据。SDS可以保存或者二进制数据。

5). SDS只能兼容部分C字符串函数

5. 二进制安全:随热按数据库一般用于保存文本数据,但使用数据库来保存二进制数据的场景也不少见。为了确保Redis可以适用于各种不同的使用场景,SDS的API都是二进制安全的,

所有SDS API都会以二进制的方式来处理SDS存放在buf数组里的数据。程序不会对其中的数据做任何的限制、过滤、或者假设,数据写入时什么样的,他被读取就是什么样的。

链表:

Redis的链表实现的特征可以总结如下:

1. 双端:链表节点带有prev和next指针,获取某个节点的前置节点和后置节点的复杂度都是O(1)

2. 无环:表头节点的prev指针和表尾节点的next指针都指向NULL,对链表的访问以NULL为节点。

3. 带表头指针和表尾指针:通过list结构的head指针和tail指针,程序获取链表的表头节点和表尾节点的复杂度为O(1)

4. 带链表长度计数器:程序使用list结构的len属性来对list持有的链表节点进行计数,程序获取链表中节点数量复杂度为O(1)

5. 多态:链表节点使用void*指针来保存节点值,并且可以通过list结构的dup、free、match三个属性为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值。

6. 链表被广泛用于redis的各种功能,比如列表键、发布与订阅、慢查询、监视器等

字典:

1. 字典,又称为符号表,关联数组或映射,是一种用于保存键值对的抽象数据结构。

2. Redis的字典使用哈希表作为底层实现,一个哈希表里面可以有多个哈希表节点,而每个哈希表节点就保存了字典中的一个键值对。

3. 字典被广泛用于实现Redis的各种功能,其中包括数据库和哈希键。

4. Redis中的字典使用暗黑系表作为底层实现,每个字典带有两个哈希表,一个平时使用,另一个仅在进行rehash时使用。

5. 哈希表使用链地址法来解决键冲突,被分配到同一个索引上的多个键值对会连接成单向链表。最新的键值在最上面,便于访问。

6. 在对哈希表进行扩展或者收缩操作时,程序需要将现有的哈希表包含的所有键值对rehash到新哈希表里面,并且这个rehash过程并不是一次性完成的,而是渐进式的。

7. 因为在进行渐进式rehash的过程中,字典会同时使用ht[0]和ht[1]两个哈希表,所有在渐进式rehash进行期间,字典的删除、查找、更新等操作会在两个哈希表上进行。先找ht[0],再找ht[1].

另外,在渐进式rehash期间,新添加到字典中的键值对一律被保存到ht[1]中。

8. 哈希表的扩展与收缩:

满足一下任意条件时,执行扩展操作:

1). 服务器目前没有在执行BGSAVE或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于1。

2). 服务器目前正在执行BGSAVE或者BGREWRITEAOF命令,并且哈希表的负载因子大于等于5

另一方面,当哈希表的负载因子小于0.1时,程序自动开始对哈希表执行收缩操作。

跳跃表:

1. 跳跃表是以各种有序数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。

2. Redis只有两个地方用到跳跃表:一个是实现有序集合键,另一个是在集群节点中用作内部数据结构。

3. 跳跃表是有序集合的底层实现之一。

4. Redis的跳跃表实现由zskiplist和zskiplistNode两个结构组成,其中zskiplist用于保存跳跃表信息(比如表头节点、表尾节点、长度),而zskiplistNode则用于表示跳跃表节点。

5. 每个跳跃表节点的层高都是1至32之间的随机数。

6. 在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的。

7. 跳跃表的节点按照分值大小进行排序,当分值相同时,节点按照成员对象的大小进行排序。

时间: 2024-10-10 05:08:13

redis 笔记01的相关文章

Redis笔记整理(二):Java API使用与Redis分布式集群环境搭建

[TOC] Redis笔记整理(二):Java API使用与Redis分布式集群环境搭建 Redis Java API使用(一):单机版本Redis API使用 Redis的Java API通过Jedis来进行操作,因此首先需要Jedis的第三方库,因为使用的是Maven工程,所以先给出Jedis的依赖: <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactI

Redis笔记整理(三):进阶操作与高级部分

[TOC] Redis笔记整理(三):进阶操作与高级部分 Redis发布订阅 Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis客户端可以订阅任意数量的频道. 下图展示了频道channel1,以及订阅这个频道的三个客户端--client1,client2,client5之间的关系. 当有新消息通过PUBLISH命令发送给频道channel1时,这个消息就会被发送给订阅它的三个客户端: 相关操作命令如下: 命令 描述 PSUBS

redis笔记

redis笔记 下载完redis,执行make命令. 然后启动redis就进src文件夹,执行./redis-server就可以了. 再在文件夹下执行 ./redis-cli 就可以执行redis的命令了. pipelining  一次请求发送多个命令,以提高性能.我们在使用redis时都是向它发送命令,每次都是需要和redis建立tcp连接,然后发送命令信息,redis执行命令后,客户端等待着redis的响应.这个我们当然知道,就像访问db,IO开销都是消耗资源的大头,所以redis提供了pi

【opengl 学习笔记01】HelloWorld示例

<<OpenGL Programming Guide>>这本书是看了忘,忘了又看,赶脚还是把笔记做一做心里比较踏实,哈哈. 我的主题是,好记性不如烂笔头. ================================================================ 1. 下载glut库 glut库地址为:www.opengl.org/resources/libraries/glut/glutdlls37beta.zip glut全称为:OpenGL Utilit

《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!

<30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的装载地址 5 6 ; 以下这段是标准FAT32格式软盘专用的代码 7 8 JMP entry 9 DB 0x90 10 DB "HELLOIPL" ; freeparam 启动区的名称可以是任意的字符串(8字节) 11 DW 512 ; 每个扇区(sector)的大小(必须为512字节)

HTTP 学习笔记01

HTTP   hypertext transfer protocol (超文本传输协议) TCP/IP 协议集中的一个应用层协议 用于定义WEB浏览器与WEB服务器之间交换数据的过程以及数据本身的格式 HTTP 1.0  会话方式 HTTP 1.1 方式 HTTP 请求消息结构 一个请求行,若干消息头,以及实体内容 其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开. GET   方式下是没有实体内容的 POST .PUT.DELETE 方式下请求消息才可以包含实体内容 HT

SWIFT学习笔记01

1.Swift,用来判断option是不是nil,相当于OC的 if(option) if let name = option{ greeting = "if=====" }else{ greeting = "else===" } 2.运行switch中匹配到的子句之后,程序会退出switch语句,并不会继续向下运行,所以不需要在每个子句结尾写break. 3.//使用..创建的范围不包含上界,如果想包含的话需要使用...,集合上,就是[)与[]的关系 for i

C++ GUI Qt4学习笔记01

C++ GUI Qt4学习笔记01 qtc++signalmakefile文档平台 这一章介绍了如何把基本的C++只是与Qt所提供的功能组合起来创建一些简单的图形用户界面应用程序. 引入两个重要概念:一个是“信号和槽”,另一个是“布局”. 窗口部件(widget)是用户界面的一个可视化元素,相当于windows系统中的“控件”和“容器”.任意窗口部件都可以用作窗口. 1.1Hello Qt 正确安装Qt4开发环境,创建工程目录hello,源代码文件名为hello.cpp,进入hello目录 (1

【VB6笔记-01】 读取Excel绑定到DataGrid

Private Sub cmdOpen_Click() CommonDialog1.Filter = "Excel???t(*.xlsx)|*.xlsx" CommonDialog1.DialogTitle = "????" CommonDialog1.ShowOpen Me.txtFilePath.Text = CommonDialog1.FileName Dim DBconn As ADODB.Connection Dim strSQL As String Di