分页与过滤:Redis中的渐进式数据处理妙招
本文的主要内容就先有一篇小故事来引出吧。
一个问题引发的「血案」曾经发生过这样一件事,我们的 Redis 服务器存储了海量的数据,其中登录用户信息是以 user_token_id 的形式存储的。运营人员想要当前所有的用户登录信息,然后悲剧就发生了:因为我们的工程师使用了 keys user_token_* 来查询对应的用户,结果导致 Redis 假死不可用,以至于影响到线上的其他业务接连发生问题,然后就收到了一堆的系统预警短信。并且这个假死的时间是和存储的数据成正比的,数据量越大假死的时间就越长,导致的故障时间也越长。
那如何避免这个问题呢?
问题的解决方法在 Redis 2.8 之前,我们只能使用 keys 命令来查询我们想要的数据,但这个命令存在两个缺点:
此命令没有分页功能,我们只能一次性查询出所有符合条件的 key 值,如果查询结果非常巨大,那么得到的输出信息也会非常多;
keys 命令是遍历查询,因此它的查询时间复杂度是 o(n),所以数据量越大查询时间就越长。
然而,比较幸运的是在 Redis 2.8 时推出了 Scan,解决了我们这些问题,下面来看 Scan 的具体使 ...
深入解析管道(Pipelining):提升性能的利器
管道技术 (Pipeline) 是客户端提供的一种批处理技术,用于一次处理多个 Redis 命令,从而提高整个交互的性能。
通常情况下 Redis 都是单行执行的,客户端先向服务期发送请求,服务端接收并处理请求后再把结果返回给客户端,这种处理模式在非频繁请求时不会有任何问题。但是当出现大批量请求时,因为每个请求都要经历先请求再响应的过程,这就会造成网络资源浪费,此时就需要管道技术来把所有的命令整合一次发给服务端,再一次响应给客户端,这样就能大大的提升了 Redis 的响应速度。
普通命令模式,如下图所示:
管道模式,如下图所示:
小贴士:管道中命令越多,管道技术的作用就更大,相比于普通模式来说执行效率就越高。
管道解决了什么问题?管道技术解决了多个命令集中请求时造成网络资源浪费的问题,加快了 Redis 的响应速度,让 Redis 拥有更高的运行速度。但要注意的一点是,管道技术本质上是客户端提供的功能,而非 Redis 服务器端的功能。
如何使用?这里介绍使用采用Java语言。
首先先获取 Pipeline 对象,再为 Pipeline 对象设置需要执行的命令,最后再使用 sy ...
Redis为何快得飞起?解密闪电侠的内存魔法
Redis 为什么这么快,这是我在了解 Redis 之前最大的疑问,即使你只是刚刚听说 Redis,对 Redis 的查询速度想必也是有所耳闻。
在没有深入学习之前,我只会回答因为 Redis 是依赖于内存实现的,所以速度快的飞起。但是,仅仅依靠内存,是不是就把设计人员费的心思给浪费了呢。
在了解为什么之前,我们先来看一下到底有多快。
官方使用基准测试的结果是,单线程的 Redis 吞吐量可以达到 10W/每秒,如下图所示:
内存存储:速度的基础
Redis 是一个内存数据库,它的数据存储在内存中,而计算机访问内存比起磁盘读写要快出数个数量级。因此,相较其他需要从磁盘读取数据的传统数据库而言,Redis 的速度要快得多。内存存储使Redis天生就具备了高速基因,这只是它快速的基础。
此外,由于数据直接从内存进行读写,而不必过多考虑如何将它们高效地保存到磁盘上(只有将数据以 RDB 的方式持久化时才会面对这个问题),这也使得 Redis 可以直接使用高效的底层数据结构。
单线程模型:化繁为简的极致Redis 是单线程,主要是指 Redis 的网络IO和键值对读写是由一个线程来完成的, ...
Redis的键值过期和内存淘汰机制:内存的游戏
Redis 是一个 k-v 型数据库,我们所有的数据都是存放在内存中的,但是内存是有大小限制的,不可能无限制的增量。想要把不需要的数据清理掉,一种办法是直接删除,这个咱们前面章节有详细说过;另外一种就是设置过期时间,缓存过期后,由Redis系统自行删除。这边需要注意的是,缓存过期之后,并不是马上删除的,那Redis是怎么删除过期数据的呢?主要通过两个方式
惰性删除
通过定时任务,定期选取部分数据删除
但是无论是惰性删除还是定期删除,都可能存在删除不尽的情况,无法删除完全,还有就是 Redis 中的使用过程中,随着写数据的增加,Redis 中的内存不够用了,这时候就需要 Redis 的内存淘汰策略了。
Redis 的「内存淘汰策略」和「过期删除策略」,很容易混淆,这两个机制虽然都是做删除的操作,但是触发的条件和使用的策略都是不同的。
Redis 过期策略指的是 Redis 使用那种策略,来删除已经过期的键值对;
Redis 内存淘汰机制指的是,当 Redis 运行内存已经超过 Redis 设置的最大内存之后,将采用什么策略来删除符合条件的键值对,以此来保障 Redis 高效的运行。 ...
Redis事务的深潜之旅:像个老司机一样操作数据!
在学习关系型数据库时,有一个非常重要的概念——事务,它扮演着关键的角色。它确保了数据操作的完整性、一致性、隔离性和持久性。
那么你有没有想过,非关系型数据库 Redis 是如何处理并使用事务的呢?是否与关系型数据库一一致?又是否能保证 ACID?
为了解开这些疑问,也为了能更加熟练地掌握 Redis,成为一个老司机。今天,我们就来学习 Redis 事务相关的内容。
什么是Redis事务?Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令,一个事务中所有命令都会被序列化。在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求不会插入到事务执行命令序列中。
总结说:Redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令。
事务的基本使用事务在其他语言中,一般分为以下三个阶段:
开启事务——Begin Transaction
执行业务代码,提交事务——Commit Transaction
业务处理中出现异常,回滚事务——Rollback Transaction
以 Java 中的事务执行为例:
12345678910// 开启事务begin ...
Redis数据结构五兄弟:数据江湖的武林盟主
今天继续学习 Redis 相关的知识,Redis 的五种基础数据结构。虽然在之前的博客中也有提到过这五种数据结构,当时赶着背东西,基本上就是从别人的八股文里抄的,所以还是重新学一下,重新记录加深记忆,正文开始。
在数据的江湖里,Redis无疑是那位神秘莫测、武功高强的武林盟主。今天,我们要介绍的就是Redis的五个顶级弟子(Redis 到现在已经有 9 种数据结构了),他们各怀绝技,行走江湖无往不利。话不多说,让我们一睹这五兄弟的风采!
前言我知道现在你已经迫不及待的想要了解这五个大侠了,但是在正式学习这些之前,我们先来了解一下 Redis 武林中的一些“潜规则”。
Redis的两层数据结构简介Redis 为什么会有如此高的性能?这也是一个老生常谈的问题了,其中之一的原因就是它的每种数据结构都是经过专门设计的,并都有一种或多种数据结构来支持,依赖这些灵活的数据结构,来提升读取和写入的性能。
想要了解Redis的数据结构,可以从两个不同的层面来讨论它:
第一个层面,是从使用者的角度,这一层面也是Redis暴露给外部的调用接口,比如:
string
list
hash
set
sorte ...
Redis持久化:让你的数据不再“无疾而终”
Redis的出现,大大提高了我们的查询速度,因其将数据存在内存中,我们的查询速度得到了质的提升。也正是因为在内存中,如果服务器突然断电关机,再次开机后我们的数据也就荡然无存了,这会让我们很崩溃。如何解决?那就是 Redis 的持久化。
今天我要聊的就是 Redis 持久化。没错,就是那个让你的数据在服务器重启后依然坚挺的功能。不知道你有没有这种感觉:当你以为自己写的代码“永垂不朽”时,服务器重启却让一切化为乌有?别担心,Redis 持久化来拯救你!
什么是持久化Redis是一个超级快的内存数据库,但问题来了,内存的特点是断电即失,所以Redis默认情况下,你的数据就像美梦一样——一觉醒来全没了。因此,Redis提供了持久化的功能,帮你把数据存储到硬盘上,这样就算是大风吹断电缆,你的数据也不会“风中凌乱”。
Redis 持久化拥有以下三种方式:
快照方式(RDB, Redis DataBase)将某一个时刻的内存数据,以二进制的方式写入磁盘;
文件追加方式(AOF, Append Only File),记录所有的操作命令,并以文本的形式追加到文件中;
混合持久化方式,Redis 4.0 ...
Redis执行流程大揭秘:从命令到结果的奇幻之旅
随着内卷这一情况的不断深化,在数据库方面只学习 MySQL 显然是不够的。那么效率极高的 Redis 就成为了学习首选,以至于现在熟练掌握 Redis 已经成为应届生的必备技能了。
笔者也是在一个多月前第一次接触到 Redis,期间断断续续地学了一点内容,但并不是深入系统的学习,只是去看了一下几个常见问题的八股文,太浮躁了。既然要直接准备秋招,那就还有大把的时间,所以今天开始系统地学习一下 Redis 相关的内容。
安装、运行这些最开始的东西就不多赘述了,毕竟操作 Redis 的代码也已经写了不少了。那除了这些以外,还有什么适合当作学习的第一步呢?
今天的文章将会深入 Redis 到底是如何执行我们输入的命令的。
Redis 是怎么执行命令的?面对这个问题,大部分朋友心中的答案是:客户端发送命令给到服务端,服务端收到执行之后再处理将命令执行结果返回给客户端,简单来说如下图:
显然这样的答案不能帮我们了解 Redis 的工作原理,还是看看更细节的过程吧。
命令执行流程一条命令的执行过程有很多细节,但大体可分为:客户端先将用户输入的命令,转化为 Redis 相关的通讯协议,再用 sock ...
细说空结构体:Go语言中的奇妙用途
在 Go 语言中,正常的 struct 就是一个普通的内存块,必定是要占用一块内存的,并且结构体的大小是要经过边界,长度是对其的。
当你需要一个结构体,但是却丝毫不关系里面的内容,声明一个最小的结构体,也需要占用 1 字节,这是就要用到今天的主角——空结构体了。
“空结构体”是不占内存的,size 为 0;运行下面的代码可以得出,空结构体是不占用内存的。
12345678910package mainimport ( "fmt" "unsafe")func main() { fmt.Println(unsafe.Sizeof(struct{}{}))}
本质上来讲,使用空结构体的初衷只有一个:节省内存,但是更多的情况,节省的内存其实很有限,这种情况使用空结构体的考量其实是:根本不关心结构体变量的值。
什么原理特殊变量:zerobase空结构体时没有内存大小的结构体。这句话是没有错,但是更准确的来说,其实是有一个特殊起点的,那就是 zerobase 变量,这是一个 uintptr 全局变 ...
了解MongoDB——你想知道的都在这
数据库的学习总算是走出 MySQL 了,开源项目涉及的知识确实非常广,还有几个关系型数据库还在学习,今天就先来学习一下另外一个被广泛应用的 NoSQL——MongoDB。
本文仅作为笔者在了解 MongoDB 时学到的一些东西,并不会包含很深入的原理解析,当个科普文就可以了。
什么是 NoSQL?在学习 MongoDB 之前,先来了解一下什么是 NoSQL。之前在面试时被面试官问道,除了 MySQL 以外,还了解什么数据库。我回答,不知道。结束后,我机智的舍友问我为什么不回答 NoSQL,我以为这是不知道其他数据库的英文表达(离谱)。
NoSQL 也被称为 “not only SQL” 或 “non-SQL”,它是一种数据库设计方法,可以在关系数据库中的传统结构之外存储和查询数据。
虽然 NoSQL 仍然可以存储关系数据库管理系统 (RDBMS) 中的数据,但与 RDBMS 相比,数据存储方式有所不同。决定使用关系数据库还是非关系数据库在很大程度上取决于上下文,并且因用例而异。
NoSQL 数据库并非采用关系数据库的典型表结构,而是将数据存储在一个数据结构中,例如 JSON 文档。由于 ...