**第4章,压缩列表;**压缩列表ziplist本质上就是一个字节数组,是Redis为了节约内存而设计的一种线性数据结构,可以包含多个元素,每个元素可以是一个字节数组或一个整数。
Redis 的有序集合、散列和列表都直接或者间接使用了压缩列表。当有序集合或散列表的元素个数比较少,且元素都是短字符串时,Redis便使用压缩列表作为其底层数据存储结构。列表使用快速链表( quicklist)数据结构存储,而快速链表就是双向链表与压缩列表的组合。
例如,使用如下命令创建一个散列键并查看其编码。
127.0.0.1:6379> hmset person name zhangsan gender 1 age 22
OK
127.0.0.1:6379> object encoding person
" ziplist"
本章将从源码层次详细介绍压缩列表的存储结构及基本操作。
**第5章,字典;**本章讲解了字典的基本概念,并对其实现进行深入解读,字典在Redis数据库中起到了举足轻重的作用,想必读者读完这章之后,对字典的概念及Redis数据库底层是如何存储数据都会有一个较为清晰的了解。请思考,在5.2.1节中介绍字典的基本实现中为什么Hash表数组中存放的是每个dictEntry 的指针地址,而不是直接把dictEntry嵌入到Hash表数组中去?
**第6章,整数集合;**整数集合(intset)是一个有序的、存储整型数据的结构。我们知道Redis是一个内存数据库,所以必须考虑如何能够高效地利用内存。当Redis集合类型的元素都是整数并且都处在64位有符号整数范围之内时,使用该结构体存储。
**第7章,quicklist的实现;**quicklist是Redis底层最重要的数据结构之一,它是Redis对外提供的6种基本数据结构中List的底层实现,在Redis 3.2版本中引入。在引入quicklist之前,Redis采用压缩链表(ziplist)以及双向链表( adlist)作为List的底层实现。当元素个数比较少并且元素长度比较小时,Redis采用ziplist作为其底层存储;当任意一个条件不满足时,Redis采用adlist作为底层存储结构。这么做的主要原因是,当元素长度较小时,采用ziplist可以有效节省存储空间,但ziplist的存储空间是连续的,当元素个数比较多时,修改元素时,必须重新分配存储空间,这无疑会影响Redis的执行效率,故而采用一般的双向链表。
quicklist是综合考虑了时间效率与空间效率引入的新型数据结构,本章将对其具体实现细节为读者——展现。
**第8章,Stream;**消息队列是分布式系统中不可缺少的组件之一,主要有异步处理、应用解耦、限流削峰的功能。目前应用较为广泛的消息队列有RabbitMQ、RocketMQ、Kafka等。Redis在最新的5.0.0版本中也加入了消息队列的功能,这就是Stream。本章将详细介绍Redis Stream相关的底层数据结构,帮助读者探索Stream实现的秘密。
**第9章,命令处理生命周期;**第2~8章介绍了Redis 的基本数据结构,接下来主要讲解所有命令的源码实现。在讲解命令实现之前,需要先了解一下服务器处理客户端命令请求的整个流程,包括服务器启动监听,接收命令请求并解析,执行命令请求,返回命令回复等,这也是本章的主题“命令处理的生命周期”。
Redis服务器是典型的事件驱动程序,因此事件处理显得尤为重要,而Redis将事件分为两大类:文件事件与时间事件。文件事件即socket的读写事件,时间事件用于处理一些需要周期性执行的定时任务,本章将对这两种事件作详细介绍。
**第10章,键相关命令的实现;**在前面的章节里,我们主要讲了Redis常用的底层数据结构以及命令处理的生命周期,本章将介绍键相关命令的源码实现。命令实现的过程中不是直接操作这些数据结构,我们将在10.1节讲解这两个结构。
在理解了redisDb和redisObject对象之后,我们按照查看键信息、设置键信息、查找和操作键将本章命令进行分类讲解,10.2节讲解查看键信息相关命令,其中 object和 type命令是获取redisObject对象相关属性的操作,过期时间读取和修改相关命令是对redisDb的expires字典的操作,除此之外本章的命令都是对redisDb的dict字典的操作。
**第11章,字符串相关命令的实现;**字符串命令是Redis最常见的命令,相对其他命令来说,字符串命令操作简单,参数较少。字符串命令虽然简单但作用强大,我们可以用字符串命令实现key-value的设置与获取,也可以实现计数器功能,甚至可以实现位操作。
**第12章,散列表相关命令的实现;**散列表是Redis数据组织的基本结构。针对key-value中的value,Redis提供了6种结构——字符串(string)、散列表(Hash)、数据流(stream)、列表(list)、集合(set)、有序集合(sortedset)。针对不同的value结构,Redis提供了不同的命令供用户使用。
当value为散列结构时,我们称之为散列相关命令。为了与Redis中的key-value散列做区分,我们称value的散列结构的键值对为field-value(域值对)。
**第13章,列表相关命令的实现;**Redis列表对象的底层数据结构是quicklist,我们在第7章已经详细讲述了quicklist的数据结构以及常见操作,本章我们主要讲解如何使用quicklist实现列表相关的命令。
**第14章,集合相关命令的实现;**Redis的set实现了无序集合,集合成员唯一。set底层基于dict和intset,在学习集合命令前,需要先了解dict和intset的结构,详见相关章节的介绍。
**第15章,有序集合相关命令的实现;**在第14章中,主要讲解了集合(Set)相关的命令,集合是无序的,而本章主要介绍有序集合(SortedSet)相关命令的实现,包括基本操作,比如zadd/zrem/zscan等,批量的操作(zrange/zremrange),以及集合相关的操作(交集zinterstore和并集zunionstore)。
有序集合中,用到的关键数据结构是ziplist以及 dict和skiplist,当服务器属性server.zset_max_ziplist_entries的值大于0且元素的member长度小于服务器属性server.zset_max_ziplist_value的值(默认为64)时,使用的是ziplist,否则使用的是dict和skiplist。对于这三种数据结构,请参考第3、4和5章。
**第16章,GEO相关命令;**在生活中,位置信息十分重要,精确地对每个物体进行定位是我们进行其他相关操作的基础。Redis提供了一些命令来帮助我们有效地处理位置信息,比如计算两点间的距离,这类命令统称为GEO相关的命令,本节将详细介绍这类命令是如何实现的。
geohash算法在2008年公开,该算法可以把二维的经纬度信息降维到一维,并通过Base32编码将其转换为字符串。Ardb的作者提供了geohash-int的实现。Redis的核心开发者Matt借鉴Ardb的GEO功能,于2014年以module方式开发了Redis的GEO。2016年,在Redis 3.2中正式加入了GEO。本节主要学习geohash算法的实现,以及Redis中是如何使用该算法的。
**第17章,HyperLogLog相关命令的实现;**在工作当中,我们经常会遇到与统计相关的功能需求,比如统计网站PV (Page View,页面访问量)或者URL的访问次数,可以使用Redis提供的incr或incrby命令轻松实现,但像UV (Unique Visitor,独立访客)、独立IP数、搜索记录数等需要去重和计数的问题该如何解决呢?我们把这类求集合中不重复元素个数的问题称为基数计数。
解决基数计数有多种方法,简单来说,可以将数据存储在MySQL表中,使用distinctcount语句来计算不重复个数,也可以使用Redis提供的hash、set、bitmap等数据结构来处理,而且结果数据都非常精确,但是这些方法都会随着数据的不断增多,而导致占用的空间越来越大,对于非常大的数据集是不切实际的。那么是否能够降低一定的精度来平衡存储空间呢。有一类算法基于概率,仅使用常量和小量的内存来提供集合中唯一元素数量的近似值。
**第18章,数据流相关命令的实现;**Redis 5.0.0引入了Stream,本章主要介绍Stream相关命令的底层实现。
在Stream的实现中,用到的关键数据结构是rax、listpack。其中rax用于快速索引;listpack用于存储具体的消息,这些数据结构的详细介绍请参见第8章。
**第19章,其他命令;**该章节主要讲解事务命令、发布-订阅命令和Lua脚本命令3个部分。通过该章的学习,读者可以了解Redis中事务、发布–订阅的实现原理及其适用范围,以及Redis如何执行Lua脚本命令。
**第20章,持久化;**Redis是一个内存数据库,当机器重启之后内存中的数据都会丢失。所以对Redis来说,持久化显得尤为重要。Redis有两种持久化方式:一种为RDB方式,RDB保存某一个时间点之前的数据;另一种为AOF方式,AOF保存的是Redis 服务器端执行的每一条命令。两种方式各有优劣,在接下来的章节中会详细介绍。我们先通过在客户端输入info命令,查看Redis服务端记录的相关持久化状态信息,然后分别详细介绍RDB和AOF。
**第21章,主从复制;**Redis支持主从复制功能,用户可以通过执行slaveof命令或者在配置文件中设置slaveof选项来开启复制功能。例如,现在有两台服务器——127.0.0.1:6379和127.0.0.1:7000,向服务器127.0.0.1:6379发送下面命令:
127.0.0.1:6379>slaveof 127.0.0.1 7000
OK
此时服务器127.0.0.1:6379会成为服务器127.0.0.1:7000的从服务器(slaver),服务器127.0.0.1:7000会成为服务器127.0.0.1:6379的主服务器( master);通过复制功能,从服务器127.0.0.1:6379的数据可以和主服务器127.0.0.1:7000的数据保持同步。
本章将为读者详细介绍主从复制功能的源码实现。
**第22章,哨兵和集群;**哨兵是Redis 的高可用方案,可以在Redis Master发生故障时自动选择一个Redis Slave切换为Master,继续对外提供服务。集群提供数据自动分片到不同节点的功能,并且当部分节点失效后仍然可以使用。
本章首先介绍Redis哨兵的实现,然后介绍集群的实现。
这份【Redis5设计与源码分析】宝典总共有433页,需要完整版的朋友,可以转发此文关注小编,扫码来获取!!!
总结
==
本书讲了什么?
-
Redis架构与源码设计
-
Redis数据结构与命令实现
-
业务所需关键实现解读
你能得到什么?
- 吸收设计精髓,提升技术素养
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/4ab3c5136cef0d2ab12ac4bf6a78dbc9.jpeg)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
u59hD1-1713692612679)]
上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)
[外链图片转存中…(img-KyCEKEDC-1713692612679)]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!