作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C++及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。

热衷分享,喜欢原创~ 关注我会给你带来一些不一样的认知和成长。

InfoQ签约作者、CSDN专家博主/后端领域优质创作者/内容合伙人、阿里云专家/签约博主、51CTO专家

如果此文还不错的话,还请关注、点赞、收藏三连支持一下博主~


专栏系列(点击解锁)

学习路线(点击解锁)

知识定位

MySQL从入门到精通

MySQL从入门到精通

全面讲解MySQL知识与实战

计算机底层原理

深入理解计算机系统CSAPP

构件计算机体系和计算机思维

Linux内核源码解析

围绕Linux内核讲解计算机底层原理与并发

数据结构与企业题库精讲

数据结构与企业题库精讲

结合工作经验深入浅出,适合各层次,笔试面试算法题精讲

互联网架构分析与实战

企业系统架构分析实践与落地

行业前沿视角,专注于技术架构升级路线、架构实践

互联网企业防资损实践

金融公司的防资损方法论、代码与实践。

本文目录

本文导读

一、什么是Redis

1、Redis简介

2、Redis特性

二、Redis的安装步骤

1、Docker安装

2、Github编译

3、直接安装

三、Redis 支持的10种数据类型

1、字符串(Strings)

2、散列(Hashes)

3、列表(Lists)

4、集合(Sets)

5、有序集合(Sorted sets)

6、流(Streams)

7、位图(Bitmaps)

8、位域(Bitfields)

9、地理空间索引(Geospatial indexes)

10、HyperLogLog

11、Bitmaps、Bitfields、Geospatial、HyperLogLog的底层

四、源码中的7种数据类型

总结


本文导读

本文作为Redis的开篇,简单介绍Redis以及其数据类型、存储、事务、lua、集群等等特性,展开讲解Redis的10中数据类型,并给出源码中的7种数据类型的结构,

所以当回答的时候,建议先说10种,再说7种,并展开官网和源码中的注释进行回答。让面试官看到你的理解和你对基本逻辑的掌握更系统和专业。

一、什么是Redis

1、Redis简介

Redis是一个日志类型的键值存储组件,使用ANSI C语言编写。它的所有数据结构都存储在内存中,可以用作缓存、数据库和消息中间件。

Redis(Remote dictionary server)是远程字典服务器的缩写。一个Redis实例可以有多个存储数据的字典,客户端 select 字典(即DB)来存储数据。

2、Redis特性

Redis有许多数据类型。它有10种核心数据类型,strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes,bitfields, and streams.,每种类型都有一系列操作指令。Redis具有高性能,单线程压测可以达到10~11w的QPS。

Redis中的所有数据读写操作都在内存中执行,但也可以下载所有数据进行持久化。Redis提供了两种持久性方法。一、快照模式,在某一时间将所有数据写入硬盘的RDB文件;二、追加文件模式,即所有写入命令都以追加模式写入硬盘的AOF文件。

Redis从2.6版开始就支持Lua,Lua是一种高效、简洁、可扩展的脚本语言,可以很容易地嵌入到其他语言中。通过在客户端支持定制的Lua脚本,Redis可以减少网络开销,提高处理性能,并整体操作脚本中的多个操作,以实现原子更新。

Redis支持事务。在多指令之后,指定多个操作,然后通过exec指令一次执行它们。如果在执行过程中发生异常,请不要执行所有命令操作。否则,一次按顺序执行所有操作,在执行过程中不会执行其他指令。

Redis还支持Cluster集群功能所有 key 都可以通过哈希自动或手动分散到不同的节点。当容量不足时,一些 key 也可以通过 Redis 迁移指令迁移到其他节点。

二、Redis的安装步骤

Redis 需要使用 Linux 环境。如果使用Windows操作系统,可以考虑使用虚拟机。如果不想安装也可以使用网页版Redis进行学习。

1、Docker安装

# 拉取 Redis 镜像docker pull redis# 运行 Redis 容器,6379是Redis端口号docker run --name myredis -d -p6379:6379 redis# 执行容器中的 redis-cli,docker exec -it myredis redis-cli

2、Github编译

# Github 源码编译,下载源码git clone --branch 5.0 --depth 1 git@github.com:antirez/redis.gitcd redis# 编译makecd src# 运行服务器,daemonize 表示在后台运行./redis-server --daemonize yes# 运行命令行./redis-cli

3、直接安装

# 直接安装方式# mac系统brew install redis# ubuntu操作系统apt-get install redis#运行客户端redis-cli

三、Redis 支持的10种数据类型

我们经常见到网络上的博客和书籍,资料有很多都比较老久了,很多新的资料也不负责任,这里博主基于官网给出的标准进行讲解。

Redis provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes,bitfields, and streams.

Redis、Redis data types | Redis

1、字符串(Strings)

Redis 字符串(String)存储字节序列,包括文本、序列化对象和二进制数组。因此,字符串是最基本的 Redis 数据类型。通常用于缓存,但它们支持额外的功能,也可以实现计数器和执行按位运算。默认情况下,单个 Redis 字符串最大为 512 MB。

# 添加缓存:在 Redis 中存储然后检索字符串> SET user:1 salvatore# 查询缓存> GET user:1# 存储序列化的 JSON 字符串并将其设置为从现在起 100 秒后过期:> SET tuser:1 "\"{'username': 'priya', 'ticket_id': 321}\"" EX 100# 增加一个计数器> INCR tuser:11> INCRBY tuser:1 1011

SET存储一个字符串值。

SETNX仅当键不存在时才存储字符串值。用于实现锁。

GET检索字符串值。

MGET在单个操作中检索多个字符串值。

大多数字符串操作的复杂度为 O(1),这意味着它们非常高效。但是 SUBSTR复杂GETRANGE度SETRANGE可能为 O(n)。这些随机访问字符串命令在处理大字符串时可能会导致性能问题。

如果将结构化数据存储为序列化字符串,可能还需要考虑Redis 哈希或RedisJSON。

2、散列(Hashes)

Redis Hashes 是以字段值对集合的形式构造的记录类型。可以使用散列来表示基本对象和存储计数器分组等。大多数Redis哈希命令都是O(1)。

# 将基本用户配置文件表示为散列:> HSET user:1 username(integer) 4> HGET user:1 username"martina"> HGETALL user:11) "username"

HSET设置哈希上一个或多个字段的值。

HGET返回给定字段的值。

HMGET返回一个或多个给定字段的值。

HINCRBY将给定字段的值增加提供的整数。

例如HKEYS、HVALS和HGETALL 是O(n),其中n是字段值对的数量。每个哈希可以存储多达4294967295(2^32-1)个字段值对,Redis 部署的VM上的总内存的限制。

3、列表(Lists)

Redis Lists 是字符串值的链接列表。Redis列表通常用于:实现堆栈和队列。为后台工作系统构建队列管理。

Redis 列表的最大长度为 2^32 – 1 (4,294,967,295) 个元素。

# 将列表视为队列(先进先出):> LPUSH user:1 101(integer) 1> RPOP user:1"101"# 将列表视为堆栈(先进后出):> LPUSH user:1 101(integer) 1> LPOP user:1"101"# 检查列表的长度:> LLEN user:1(integer) 0

​LPUSH添加一个新元素到列表的头部;RPUSH添加到尾巴。

LPOP从列表的头部移除并返回一个元素;RPOP做同样的事情,但从列表的尾部开始。

LLEN返回列表的长度。

LMOVE原子地将元素从一个列表移动到另一个列表。

LTRIM将列表减少到指定的元素范围。

4、集合(Sets)

Redis Set 是由字符串(成员)组成的无序集合。

可以使用 Redis set 来高效地:跟踪唯一项目(例如,跟踪访问给定博客文章的所有唯一 IP 地址)。表示关系(例如,具有给定角色的所有用户的集合)。执行常见的集合运算,例如交集、并集和差集。

Redis Set 的最大大小为 2^32 – 1 (4,294,967,295) 个成员。

存储用户 1> SADD user:1(integer) 1# 获取用户 1> SISMEMBER user:1:favorites 742(integer) 1# 用户 1 和 2 有没有共同的> SINTER user:1 user:21) "561"# 统计 user:1> SCARD user:1(integer) 3

​SADD将新成员添加到集合中。

SREM从集合中删除指定的成员。

SISMEMBER测试集合成员的字符串。

SINTER返回两个或多个集合共有的成员集合(即交集)。

SCARD返回集合的大小(又名基数)。

大多数集合操作,包括添加、删除和检查项是否为集合成员,都是O(1)。这意味着他们的效率很高。但是,对于具有数十万或更多成员的大型集合,在运行SMEMBERS命令时应谨慎。此命令为O(n),并在单个响应中返回整个集合。作为替代方案,考虑SSCAN,它允许迭代检索集合的所有成员。

5、有序集合(Sorted sets)

Redis Sorted sets是按关联分数排序的唯一字符串(成员)的集合。当多个字符串具有相同的分数时,这些字符串按字典顺序排列。

Sorted sets 的一些用例包括:排行榜。例如,可以使用 Sorted sets 轻松维护大型在线游戏中最高分数的有序列表。费率限制器。可以使用 Sorted sets 来构建滑动窗口速率限制器,以防止过多的API请求。

# 随着玩家分数的变化更新实时排行榜:> ZADD leaderboard:455 100 user:1(integer) 1# 获取 user:1 的分数:> ZRANGE leaderboard:455 0 2 REV WITHSCORES1) "user:1"2) "100"# 返回用户1的排名,假设排序集按降序排列。> ZREVRANK leaderboard:455 user:2(integer) 0

ZADD将新成员和关联的分数添加到已排序的集合中。如果该成员已经存在,则更新分数。

ZRANGE返回在给定范围内排序的有序集合的成员。

ZRANK返回所提供成员的排名,假设排序是按升序排列。

ZREVRANK返回所提供成员的排名,假设 Sorted sets 按降序排列。

大多数有序集合操作的复杂度为 O(log(n)),其中n是成员数。ZRANGE运行具有较大返回值(例如,数万或更多)的命令时要小心。此命令的时间复杂度为 O(log(n) + m),其中m是返回的结果数。Redis Sorted sets 有时用于索引其他 Redis 数据结构。如果需要索引和查询数据,请考虑RediSearch和RedisJSON。

6、流(Streams)

Redis 5.0 引入了 Stream 数据结构。Redis 流是一种数据结构,其作用类似于仅附加日志。可以使用流实时记录和同时联合事件。

Redis 流用例示例包括:事件溯源(例如,跟踪用户操作、点击等);传感器监控(例如,现场设备的读数);通知(例如,将每个用户的通知记录存储在单独的流中)

Redis 为每个流条目生成一个唯一的 ID。可以使用这些 ID 稍后检索它们的关联条目,或者读取和处理流中的所有后续条目。

Redis 流支持多种修剪策略(以防止流无限制地增长)和不止一种消费策略(请参阅XREAD、XREADGROUP和XRANGE)。

7、位图(Bitmaps)

Bitmap 底层是 String 实现,赋值的每一个 bit 均对应 ASCII 码的二进制位。

Redis Bitmap 位图是字符串数据类型的扩展,可将字符串视为位向量。还可以对一个或多个字符串执行按位运算。

位图用例的一些示例包括:集合成员对应于整数 0-N 的情况的有效集合表示。对象权限,其中每一位代表一个特定的权限,类似于文件系统存储权限的方式。

8、位域(Bitfields)

Redis Bitfields 位域允许设置、递增和获取任意位长度的整数值。可以对从无符号 1 位整数到有符号 63 位整数的任何内容进行操作。

这些值使用二进制编码的 Redis 字符串存储。位域支持原子读、写和递增操作,使它们成为管理计数器和类似数值的不错选择。

9、地理空间索引(Geospatial indexes)

Redis Geospatial indexes地理空间索引让您可以存储坐标并进行搜索。此数据结构可用于查找给定半径或边界框内的附近点。

10、HyperLogLog

HyperLogLog 底层也是 String 实现,与其说 HyperLogLog 是一种单独的数据类型,倒不如说是对 String 数据类型做 API 封装的应用程序。HyperLogLog 是一种估计集合基数的数据结构。作为一种概率数据结构,HyperLogLog 以完美的准确性换取高效的空间利用。

11、Bitmaps、Bitfields、Geospatial、HyperLogLog的底层

高级数据类型底层数据类型
BitmapString
BitfieldsString
GeospatialindexesSorted Set
HyperLogLogString

四、源码中的7种数据类型

源码内容中,define了7种类型:OBJ_ STRING 0、OBJ_ LIST 1、OBJ_ SET 2、OBJ_ ZSET 3、OBJ_ HASH 4、0BJ_ MODULE 5、OBJ_ STREAM 6。

这个0BJ_ MODULEMODULE对象类型是一种特殊的类型,表示对象,由Redis模块直接管理。这其中就包括了 Bitmaps, Hyperloglogs, Geospatial indexes, Bitfields.

所以当回答的时候,建议先说10种,再说7种,并展开官网和源码中的注释进行回答。让面试官看到你的理解和你对基本逻辑的掌握更系统和专业。

总结

本文作为Redis的开篇,简单介绍Redis以及其数据类型、存储、事务、lua、集群等等特性,展开讲解Redis的10中数据类型,并给出源码中的7种数据类型的结构,

所以当回答的时候,建议先说10种,再说7种,并展开官网和源码中的注释进行回答。让面试官看到你的理解和你对基本逻辑的掌握更系统和专业。