Redis基础学习 | 青训营

24 阅读5分钟

背景

NoSQL

随着互联网 web2.0 网站的兴起,传统的关系数据库在处理 web2.0 网站,特别是超大规模和高并发的纯动态网站已经显得力不从心,出现了很多难以克服的问题,而非关系型数据库(NoSQL)则由于其本身的特点得到了非常迅速的发展。NoSQL 数据库的产生就是为了解决大规模数据集带来的挑战。

什么是Redis

Redis,Remote Dictionary Server,远程字典服务,是一个使用 ANSI C 语言编写、支持网络、 可基于内存亦可持久化的日志型、NoSQL 开源内存数据库,其提供多种语言的API。

为什么需要Redis

  • 数据从单表,演化出了数据分表; MySQL从单机演进出了集群,读写数据的压力不断增加 image.png

  • 数据冷热分离,将热数据存储在内存中可以大大提高访问速度 image.png

Redis特性

  • 性能极高:Redis 读的速度可以达到 11w 次/s,写的速度可以达到 8w 次/s
  • 持久化:Redis 内存中的数据可以进行持久化,其有两种方式:RDB 与 AOF
  • 高可用集群:Redis 提供了高可用的主从集群功能,可以确保系统的安全性
  • 丰富的数据类型:Redis 是一个 key-value 存储系统。支持存储的 value 类型很多,包括 String(字符串)、List(链表)、Set(集合)、Zset(sorted set --有序集合)和 Hash(哈希类型) 等

Redis数据结构

简单动态字符串 SDS

SDS称为简单动态字符串,可以存储字符串、数字、二进制数据。其底层结构如下所示:

struct sdshdr {
    char buf[]; // 字节数组,用于保存字符串
    int len;  // buf[]中已使用字节数量,称为 SDS 的长度
    int free;  // buf[]中尚未使用的字节数量
}

C字符串使用 Len+1 长度的字符数组来表示实际长度为 Len 的字符串,字符数组最后以空字符’\0’结尾,表示字符串结束。这种结构简单,但不能满足 Redis 对字符串功能性、安全性及高效性等要求。

  • 优化字符串长度获取: C语言中获取字符串长度要遍历整个字符串,而SDS结构中直接存放着字符串长度。
  • 二进制安全: 由于C语言是以'\0'作为字符串结束标志,因此不能保存音频,图像等数据。而Redis不受此限制。
  • 减少内存再分配: 每次 SDS 进行空间扩展时,程序不但为其分配所需的空间,还会分配额外的未使用空间,以减少内存再分配次数。

image.png

应用场景

数据缓存, 计数器, 共享session, 限速器, 连续签到等

列表List

Redis 存储数据的 Value 可以是一个 String 列表类型数据。即该列表中的每个元素均为 String 类型数据。

List的数据结构为QuickList,Quicklist由一个双向链表和listpack实现

QuickList

image.png

ListPack

listPack 是一个经过特殊编码的用于存储字符串或整数的双向链表。其底层数据结构由三部分构成:head、element 与 end,且这三部分在内存上也是连续存放的。

image.png

应用场景

使用场景:消息通知,栈,队列,动态有限集合

Set

Redis 存储数据的 Value 可以是一个 Set 集合,且集合中的每一个元素均 String 类型。Set 与 List 非常相似,但不同之处是 Set 中的元素具有无序性与不可重复性,而 List 则具有有序 性与可重复性。

Redis 中的 Set 集合与 Java 中的 Set 集合的实现相似,其底层都是 value 为 null 的 hashtable。

应用场景 动态黑白名单,有限随机数,用户画像

Hash

Redis 存储数据的 Value 可以是一个 Hash 类型。Hash 类型也称为 Hash 表、字典等。 Hash 表就是一个映射表 Map,也是由键-值对构成,为了与整体的 key 进行区分,这里 的键称为 field,值称为 value。注意,Redis 的 Hash 表中的 field-value 对均为 String 类型。

Hash其底层的实现实际有两种:压缩列表listPack,与跳跃列表skipList。 这两种实现对于用户来说是透明的,但用户写入不同的数据,系统会自动使用不同的实现。 只有同时满足以配置文件 redis.conf 中相关集合元素数量阈值与元素大小阈值两个条件,使 用的就是压缩列表 zipList,只要有一个条件不满足使用的就是跳跃列表 skipList。

image.png

跳表 skipList,跳跃列表,简称跳表,是一种随机化的数据结构,基于并联的链表,实现简单, 查找效率较高。简单来说跳表也是链表的一种,只不过它在链表的基础上增加了跳跃功能。 也正是这个跳跃功能,使得在查找元素时,能够提供较高的效率。

image.png 应用场景

  • 计数
  • Hash 型 Value 非常适合存储对象数据。key 为对象名称,value 为描述对象属性的 Map, 对对象属性的修改在 Redis 中就可直接完成。

ZSet

Redis 存储数据的 Value 可以是一个有序 Set,这个有序 Set 中的每个元素均 String 类型。 有序 Set 与 Set 的不同之处是,有序 Set 中的每一个元素都有一个分值 score,Redis 会根据 score 的值对集合进行由小到大的排序。其与 Set 集合要求相同,元素不能重复,但元素的 score 可以重复。

zset的数据结构也是压缩列表listPack,与跳跃列表skipList

image.png

应用场景

排行榜,实时排名

引用资料

字节青训营课程:Redis-大厂程序员是怎么用的 bytedance.feishu.cn/file/TcbGb6…

动力节点:Redis学习教程
www.bilibili.com/video/BV1U2…