Remote Dictionary Server(Redis)——基于 KV 结构的作为 Cache 使用的 NoSQL 数据库管理系统

Redis 是基于key-value存储结构的NoSQL 数据库,是内存数据库。

一、非关系型数据库NoSQL 和关系型数据库RDBMS

1)什么是关系型数据库和非关系型数据库?

答:
简单的说,关系型数据库就是数据库中的数据是相互关联的,MySQL就是关系型数据库。
非关系型数据库就是数据库中数据之间是无联系的,Redis是非关系型数据库。

2)两者有哪些区别?

答:
两者区别主要包括数据结构、数据关联性、事务特性、性能和存储

1.从存储的表结构上说:

RDBMS的表结构一般比较固定,不会轻易修改。
NOSQL的表结构比较随意,有key-value结构、json文档、图结构。
在这里插入图片描述
2.从表中数据的关联性上说:

RDBMS的表中数据一般存在关联性。
NOSQL的表中数据一般不存在关联性,因此往往需要消耗更多的存储空间。
在这里插入图片描述
在这里插入图片描述
3.从数据库查询上来说:

RDBMS的所有数据库查询语句有统一的语法
NOSQL的查询针对每一种数据库都有所不同。
在这里插入图片描述
4.从事务上来说:

RDBMS满足ACID,数据具有安全性。
NOSQL不满足ACID,数据不具有安全性。

总结区别:
在这里插入图片描述

3)两者的优缺点?

答:
由于关系型数据库和非关系型数据库它们的底层数据结构(表结构和数据类型)存在本质不同,导致它们在CURD、高并发、存储消耗存在很大不同。目前在互联网领域海量数据的项目中NoSQL应用非常广泛。

关系型数据库的瓶颈:
(1)无法应对每秒上万次的读写请求,无法处理大量集中的高并发操作关系型数据是 IO密集的应用,硬盘 IO 也变为性能瓶颈。

(2)表中存储记录数量有限,横向可扩展能力有限,一张表最大二百多列。纵向数据可承受能力也是有限的,一张表的数据到达百万级,读写的速度就会逐渐的下降。面对海量数据, 必须使用主从复制,分库分表。这样的系统架构是难以维护的。
大数据查询 SQL 效率极低,数据量到达一定程度时,查询时间会呈指数级别增长

(3)无法简单地通过增加硬件、服务节点来提高系统性能。数据整个存储在一个数据库中的。多个服务器没有很好的解决办法,来复制这些数据。

(4)关系型数据库大多是收费的,对硬件的要求较高。软件和硬件的成本花费比重较大。

非关系型数据库优势:

(1) 大数据量,高性能

NoSQL 数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。关系型数据库(例如 MySQL)使用查询缓存。这种查询缓存在更新数据后,缓存就是失效了。在频繁的数据读写交互应用中。 缓存的性能不高。NoSQL 的缓存性能要高的多。

(2) 灵活的数据模型

NoSQL 无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。尤其在快速变化的市场环境中,用户的需求总是在不断变化的。

(3) 高可用

NoSQL 在不太影响性能的情况,就可以方便的实现高可用的架构。

NoSQL 能很好的解决关系型数据库扩展性差的问题。弥补了关系数据(比如 MySQL) 在某些方面的不足,在某些方面能极大的节省开发成本和维护成本。

MySQL 和 NoSQL 都有各自的特点和使用的应用场景,两者结合使用。让关系数据库关注在关系上,NoSQL 关注在存储上。

(4) 低成本

这是大多数分布式数据库共有的特点,因为主要都是开源软件,没有昂贵的 License 成本

非关系型数据库劣势:

(1) 无关系,数据之间是无联系的。数据存在冗余,存储空间浪费。
(2) 不支持标准的 SQL,没有公认的 NoSQL 标准

(3) 没有关系型数据库的约束,大多数也没有索引的概念

(4) 没有事务,不能依靠事务实现 ACID.

(5) 没有丰富的数据类型(数值,日期,字符,二进制,大文本等)

二、Redis的五种基本数据类型和底层实现原理(数据结构)

答:
分别介绍一下Redis各个数据类型内部实现原理、以及应用场景

参考:Redis 常见数据类型和应用场景

Redis 数据结构并不是指 String(字符串)对象、List(列表)对象、Hash(哈希)对象、Set(集合)对象和 Zset(有序集合)对象,因为这些是 Redis 键值对中值的数据类型,也就是数据的保存形式,这些对象的底层实现的方式就用到了数据结构,因为数据类型就是对底层数据结构和合法操作进行了封装。

Redis 的键值对中的 key 就是字符串对象,而 value 可以是字符串对象,也可以是集合数据类型的对象,比如 List 对象、Hash 对象、Set 对象和 Zset 对象。
在这里插入图片描述
在这里插入图片描述

共有 8 种数据结构:SDS、双向链表、压缩列表、哈希表、跳表、整数集合、quicklist、listpack。

1)底层数据结构

1.简单动态字符串(simple dynamic string,SDS)

答:

字符串在 Redis 中是很常用的,键值对中的键是字符串类型,值有时也是字符串类型。

Redis 是用 C 语言实现的,但是它没有直接使用 C 语言的 char* 字符数组来实现字符串,而是自己封装了一个名为简单动态字符串(simple dynamic string,SDS) 的数据结构来表示字符串,也就是 Redis 的 String 数据类型的底层数据结构是 SDS。

既然 Redis 设计了 SDS 结构来表示字符串,肯定是 C 语言的 char* 字符数组存在一些缺陷。
●获取字符串长度的时间复杂度为 O(N);
●字符串的结尾是以 “\0” 字符标识,字符串里面不能包含有 “\0” 字符,因此不能保存二进制数据;
●字符串操作函数不高效且不安全,比如有缓冲区溢出的风险,有可能会造成程序运行终止;

Redis 实现的 SDS 的结构就把上面这些问题解决了
在这里插入图片描述

	记:
	简单动态字符串对C语言中的字符串进行了优化。其封装了字符串长度、空间分配长度、SDS类型、字符数组,能画出SDS的数据结构封装图。
	
	针对C语言中字符串,在获取字符串长度的时间复杂度为O(n)的问题上,SDS通过成员变量len记录字符串长度,因此在获取字符串长度时,不需要再遍历一遍字符串,而是直接返回len的值,时间复杂度为O(1)。
	针对C语言中字符串,在进行字符串修改或者字符串拼接时,容易发生缓冲区溢出问题。SDS通过成员变量alloc记录分配的空间长度,每次修改字符串时,都能通过alloc-len计算剩余空间,因此不会发生溢出问题。
	针对C语言中字符串,会将“\0”视为字符串结尾标志,使得无法记录二进制数据的问题。SDS因为有成员变量len记录字符串长度,因此可以不通过“\0”来记录字符串结尾标志,从而使得SDS不仅可以记录文本数据,还可以记录二进制数据(如图片、音频、视频这样的二进制数据)
	还有一些节省内存空间的方法,针对大小不同的字符串,设计不同数据类型的结构体。以及对字节对齐方式进行了优化。

2.双向链表

答:
redis的链表具有前置结点和后置结点,并且数据域也采用指针形式。
在这里插入图片描述
Redis 在 listNode 结构体基础上又封装了 list 这个数据结构,list 结构为链表提供了链表头指针 head、链表尾节点 tail、链表节点数量 len、以及可以自定义实现的 dup、free、match 函数。
在这里插入图片描述
在这里插入图片描述

	记:
	能记住或画出双向链表的结构,以及封装了list的链表结构(可以认为是基本数据类型列表的双向列表具体实现),再说一下它的优缺点。
	优点主要是在获取前后置结点、表头表尾结点、链表结点数量的时间复杂度都为O(1)。且链表结点数据域采用指针存储,使得可以保存各种不同类型的值。
	缺点是链表结点的内存不连续性,无法很好使用CPU缓存。而且保存当前结点时,需要保存前后置结点的指针,因此开销比较大。

3.压缩列表(ziplist)

答:
在这里插入图片描述
在这里插入图片描述

压缩列表的最大特点,就是它被设计成一种内存紧凑型的数据结构,占用一块连续的内存空间,不仅可以利用 CPU 缓存,而且会针对不同长度的数据,进行相应编码,这种方法可以有效地节省内存开销。

但是,压缩列表的缺陷也是有的:

●不能保存过多的元素,否则查询效率就会降低;
●新增或修改某个元素时,压缩列表占用的内存空间需要重新分配,甚至可能引发连锁更新的问题。

(连续更新发生的原因是:后一节点会记录前一个结点所占内存的字节长度大小,如果新增结点所占字节数大于等于255,会导致后一节点的prelen属性所占内存重新分配,进而导致后一节点的整个字节数增大,又会再影响下下个结点,因此产生各个结点内存大小需要更新的连锁反应)

因此,Redis 对象(List 对象、Hash 对象、Zset 对象)包含的元素数量较少,或者元素值不大的情况才会使用压缩列表作为底层数据结构。

	记:
	首先,能记住或画出压缩列表的结构图。
	压缩列表是一块连续内存块组成的顺序型数据结构,有点类似于数组。包含表头表尾,中间存储数据的各个节点,他们的数据类型可以不相同。
	再说一下优缺点。压缩列表的优点是可以利用 CPU 缓存,而且会针对不同长度的数据,进行相应编码,有效节省内存开销。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值