Redis数据结构
本博客基于《Redis设计与实现》进行整理和补充,该书依赖于Redis 3.0版本,但是Redis6.0版本在一些底层实现上仍然没有明显的变动,因此本文将在该书的基础上,对于后面进行变更的一些技术项进行额外说明,当然我相信大家学习Redis,可能更多的是进行面试,本博客的一个功利目的,也是希望读完本书之后对于市面上常见的redis面试题能做到心中有数,直接秒杀。
引言
Redis是什么,大家可能会不假思索的说出 是个缓存中间件,但是如果只是缓存的话,我们为什么不能直接使用本地缓存,或者mongo这样的nosql呢,那么这里呢,我们就要从一个更高更抽象的角度去理解Redis,Redis并不是在开发过程中必须存在的中间件,甚至在最开始单机开发的场景,我们可以完全不用Redis,我们从Redis这几个字母上来理解一下Redis的含义,Re- Remote Di- dictionary S-server 远程字典服务,也就是他其实就是一个远程的本地字典存储。
本地缓存的缺点是很明显的,如果我们不使用比如guava或者caffine这样的本地缓存管理包, 那么在本地仅仅是管理缓存就是一件很困难的事情,更何况 本地缓存也更加不适合分布式的开发环境,重启服务缓存消失这样的问题。而mongo将数据存储在磁盘上,从而导致,读写速度可能会成为mongo的瓶颈。正是因为有着这样的问题,因此我们才单独将一些需要进行告诉读取写入存储一些字典的功能交给了一个更合适的远程服务 即是 Redis。
而在使用上,我们甚至可以直接理解为Redis就是一个远程的Hash,我们能像使用本地缓存那样使用Redis,而不需要单独考虑数据会不会丢失,数据一致性问题等等。
当然我们现在还是要看一个更加学术并且权威的介绍,这里我直接给到Redis最新的intro:
Redis is an open source (BSD licensed), in-memory data structure store used as a database, cache, message broker, and streaming engine. Redis provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams
Redis是一款拥有BSD授权的开源软件,可以存储一些内存数据结构数据,你可以把它用作数据库缓存,消息中间存储,流引擎。 Redis支持的数据结构有字符串,hash,列表,集合,带范围的有序列表,位图,hyperloglogs,gis存储和流。
好,那么经过上面的简单介绍,我们接下来将继续更加深入的学习Redis的数据结构。
数据结构
redis所有的存储类型都是一个的键值对类型,其中key的类型肯定是一个字符串,而value的存储对象则有 string,hash,set等类型,下面我们会对这些类型的底层实现进行更详细的探讨。
string
redis是使用c语言编写的,在c语言中,并没有string这个内置类型,而是使用char[]来代替string,但是很显然[]char类型有很多问题,所以redis采用SDS来实现字符串。
SDS数据结构
在开始之前我们有必要首先了解一下SDS的数据结构
c
struct sdshdr {
int len; //记录使用长度
int free; // 记录还没有使用的长度
char buf[] // 实际进行的数据存储
}
我们下面详细探讨一下char[]可能存在的问题,以及SDS是如何通过自身的数据结构解决的
原生string的不足
- 获取字符串长度原生char[]时间复杂度为O(N)