作者记录的笔记一部分来自于【全方位搞定Redis,Redis基础+Docker+Redis集群+MySQL集群+调用Lua脚本+整合SpringBoot】https://www.bilibili.com/video/BV1md4y1o7DY?vd_source=3026e1149e1e36cc45042854c30dd20c
已购买知识星球,希望老师能允许作者发布笔记。对作者自身,未来就业方向与数据库、大数据开发相关,目前有Mysql、Docker、Springboot基础(其实Redis也有基础),现正式学习Redis相关知识,希望能够坚持下去!
Redis简要介绍
Mysql、Sqlserver最终还是存储在硬盘上的。
自动过期:Redis经常用作缓存的中间件,缓存一定是有有效期的。
非关系型的大优势在于读写性能很高!
以数据类型作为分类依据,可将Nosql进一步划分。作者略有了解过,目前的感受就是:图数据库有很大的发展潜力和进步。而HBase作为列族数据库,曾经也支持着第二代大数据平台的发展。了解上述概念很重要,也是作者的目标之一!
Redis安装
大致步骤就是:搜索官网下载稳定版本,打开虚拟机,传输并解压。但是注意,官网下载的版本还是源码,不能直接使用需要进行编译。需要安装gcc编译器对源码进行编译。最后默认会被安装在usr/local/bin目录下。
作者在修改redis.conf后XShell突然不好用了,随后就再也打不开了,报了50003的错误后又来一个。作者直接卸了重新装,发现好了……
作者又出现问题了:
别烦,这个问题好解决,看后面照着做就行了。但是它基本上告诉内核:“不管怎样,总是允许内存分配,即使用尽了所有的物理内存和交换空间。”这是具有一定风险的。
CLI
命令行客户端redis-cli,作者兄弟学前端的,以为这是脚手架,我其实也不明白这个cli出现的如此广泛,到底有没有统一的意思?
"CLI" 这个词是 "Command Line Interface" 的缩写,意为“命令行界面”。这是一种用户和计算机程序交互的界面,与我们熟知的图形用户界面(Graphical User Interface,即 GUI)相对。CLI 是在纯文本模式下,通过键入命令来与计算机或应用程序交互的方法。
在历史上,计算机最初是通过命令行界面进行操作的,因为那时的计算机硬件资源有限,没有足够的计算能力来运行复杂的图形界面。随着技术的进步,GUI 成为了主流,但 CLI 仍然广泛存在,特别是在开发者和系统管理员的工作中,因为它提供了一种更直接、灵活且高效的交互方式。
关于您提到的 `redis-cli`,这是 Redis 数据库的官方命令行客户端,用于与 Redis 服务器进行交互。您可以使用 `redis-cli` 执行各种 Redis 命令,如设置和获取键值、查看统计信息等。
至于 "脚手架" 这个词,它在前端开发中通常指的是帮助开发者快速设置新项目的工具,为开发者提供了一个基础的项目结构和配置,从而避免了从零开始设置项目的麻烦。这与 CLI 是两个不同的概念,但有些脚手架工具确实是通过 CLI 来使用的,例如 `create-react-app`。
总的来说,CLI 是一个广泛使用的概念,并不仅仅局限于某个具体的应用或技术领域。
基本数据类型String
Redis缓存
热点数据缓存到redis中!作为缓存中间件!
缓存通常来说,需要每隔一段时间进行清除,为了避免内存溢出。这样就可以设置生存时间/有效期。
Redis数据类型
值的数据类型、值的数据类型!
String类型
SDS:相当于使用了C的结构体实现了String类型。通过两个整型变量控制整个空间。
下面简要对使用SDS的原因进行解释:
Redis 不使用 C 语言标准库提供的字符串(String),而选择使用简单动态字符串(SDS,Simple Dynamic String)作为其默认的字符串表示,是出于以下几个重要原因:
-
防止缓冲区溢出:与传统的 C 字符串不同,SDS 保存了字符串的长度。因此,在执行操作时,Redis 可以确保不会超出字符串分配的内存范围,这在很大程度上防止了缓冲区溢出的可能性。
-
减少修改字符串时的重复分配:传统的 C 字符串如果需要增长或缩短,通常需要多次内存分配和数据复制。而 SDS 设计时会预分配额外的未使用空间(free space),这样在字符串后追加内容时,如果未使用空间足够,就不需要重新分配内存。
-
常数时间复杂度获取字符串长度:因为 SDS 存储了字符串的长度,所以获取字符串的长度是常数时间复杂度的操作,与字符串的实际长度无关。而传统的 C 字符串获取长度需要遍历整个字符串直到 null 终止符,其复杂度是 O(n)。
-
二进制安全:C 字符串是以 null 字节('\0')来结束的,这意味着它不能完整存储包含 null 字节的数据,如某些二进制数据。而 SDS 可以存储任何二进制数据,包括 null 字节,因为它的长度是显式存储的,而不是依赖 null 终止符。
-
兼容部分 C 字符串函数:尽管 SDS 提供了自己的一套 API,但其内部结构允许它在必要时与标准的 C 字符串函数兼容。
从数据结构的角度看,SDS(Redis 中的简单动态字符串)和 Java 的 ArrayList
有相似之处。以下是它们之间的一些相似点:
-
动态扩展:当数据增加并超出当前分配的容量时,两者都会动态地重新分配内存来扩展其存储空间。
-
预分配策略:为了减少连续的内存分配操作,
ArrayList
和 SDS 都采用了预分配策略。当它们增长时,它们不仅仅分配当前所需的空间,还会分配额外的空间,以期待未来的增长。这样,在未来的一些操作中,就可以避免重新分配内存。 -
存储实际大小:
ArrayList
和 SDS 都存储了它们实际的大小信息。ArrayList
有一个size
成员来表示实际元素的数量,而 SDS 有一个长度字段来表示字符串的长度。 -
附加的元信息:与 C 字符串或 Java 的数组不同,这两种结构都存储了额外的元信息(例如长度或容量),这为它们提供了更高的效率和灵活性。
-
避免某些操作的高代价:由于它们的动态性和附加的元信息,这两个数据结构都避免了某些操作的高代价。例如,获取 SDS 的长度是一个常数时间操作,而在
ArrayList
中添加元素(如果不需要重新分配)也是一个常数时间操作。
当然,SDS 和 ArrayList
也有其本质上的差异,如 SDS 专为字符串设计,而 ArrayList
是一个泛型的动态数组实现。但从数据结构设计的角度看,它们都展示了如何通过附加信息和智能策略来优化常见操作的效率。
上图黄色+蓝色的空间就是SDS中的buf[]字符数组的空间,这就是为什么有len和free了。原来是预先留了一些空间,这样后续若需要继续分配内存,则不必再申请空间,提高字符串存储效率。
如果字符串剩余空间不足时,会自动扩充。小空间Redis是成倍扩充的,大空间是1MB扩充的。
如果重复设置key值,则默认情况下新的值会将旧值覆盖。但是如果加上NX,就不会存在覆盖的情况。在设置EX/PX时不能使用表达式,只能是整数值!
-
Redis中重复set有什么用?
在 Redis 中,使用
SET
命令可以为一个键设置一个值。如果这个键已经存在,则它的值会被新值替换。这意味着你可以重复使用SET
命令来更新某个键的值。 -
参数EX/PX应用场景是什么?
EX
和PX
是SET
命令的选项,它们分别代表“秒”和“毫秒”。当你为键设置值的时候,可以使用这些选项来设定这个键的过期时间。EX
:设置键的过期时间,单位为秒。例如:SET key value EX 10
会在10秒后使这个键过期。PX
:设置键的过期时间,单位为毫秒。
这些选项在很多场景中都很有用,比如缓存数据时。你可能不希望缓存中的数据永远存在,因为数据可能会变得陈旧。通过设置一个合适的过期时间,你可以确保数据在一段时间后会自动被删除,从而保持数据的新鲜度。可以set key value NX,也可以调用setNX key value
-
KEEPTTL有什么意义?
KEEPTTL
是 Redis 6.0 中新增的一个选项。当你使用SET
命令更新一个已经存在的键的值时,如果这个键有一个过期时间,使用KEEPTTL
可以保持这个过期时间不变。这意味着,即使你更新了键的值,它的过期时间还是和原来一样。如果不使用
KEEPTTL
,并且没有为这个键设置新的过期时间(使用EX
或PX
),那么这个键将变为永久的,不会过期。 -
和他们有什么关系?
这些选项都是
SET
命令的一部分,用于控制键的过期行为。在某些应用场景中,你可能只想更新键的值,而保持它原来的过期时间,那么KEEPTTL
就很有用。而在其他场景中,你可能想在设置值的时候指定一个新的过期时间,那么EX
和PX
就会派上用场。
注意批量设置字符串的时候mset和mget都不能含有参数。比如执行如下指令:
乍一看没问题,然后刷新数据库后发现:
好吧,它已经没有参数选项了,所以只能把我的EX定义为key,其值为100。使用ttl(注意该指令只能一次查看一个键值对的有效期)查一下该键值对的有效期:
-1代表有效期永久。对于其他参数比如NX/XX,它们后面没有任何数值,所以直接报错处理!
这个值,虽然是在字符串中,但是必须是数值类型才能进行加减。
如果incr/decr key的key不存在,则会先set这样的key,然后将其值设为默认值0,再进行加减操作。incrby/decrby能够在key后面设置加减法的步长!
本质上就是set指令增加get的功能,在某些情况下能够合理地提示旧值。