Redis设计与实现-数据结构(建设进度20%)

本博客基于《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的数据结构

struct sdshdr {
	int len; //记录使用长度
	int free; // 记录还没有使用的长度
	char buf[]	// 实际进行的数据存储
}

我们下面详细探讨一下char[]可能存在的问题,以及SDS是如何通过自身的数据结构解决的

原生string的不足
  1. 获取字符串长度原生char[]时间复杂度为O(N)

c语言中,char[]数组的结尾事’\0’,我们如果想要获取一个char[]数组的长度的话唯一的方法就是,不断的从头遍历,直到读到空字符,所以为了防止仅仅是获取数组长度这个功能成为性能瓶颈,我们采用len字段记录了char[]数组的长度

  1. 可以存储 空字符,也就是所谓的二进制安全

在char[]我们显然没有办法直接存储’\0’,则是因为写入char里面的数据必须要严格遵循因为我们一读到空白符,就默认无法已经结束了,但是sds本身实现了一套属于sds的字符串函数,其中并不以’\0’结尾座位结束符号,而是根据len长度,从而可以保证可以存储任意字符,从而方便我们在写入值时,更加灵活多样。

  1. 内存分配优化

    SDS通过自动扩展来减少内存的重新分配次数,从而提高了内存分配的性能。此外,SDS还采用惰性空间释放策略,即在执行删除和截断操作后不会立即释放被删除的空间,仅仅需要对len和free两个字段进行操作就能实现这一点,在内存不够的时候可以对这部分数据进行统一的释放整理。

  2. 安全性

在这一点上主要是char[]类型在连续的进行写的时候可能会出现内存溢出或者空间不足的情况,对于这种情况,使用sds我们可以更好的首先使用len进行检查 是否还有足够的空间,如果没有的话则首先分配足够的内存空间,在进行写入。

hash

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值