本文为稀土技能社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!


Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

咱们好,又碰头了。

作为《深化了解缓存原理与实战规划》系列专栏,在前面的文章中,咱们一同领略了Guava Cache、Caffeine、Ehcache等优异的本地JVM级别本地缓存框架的特性、原理与具体的运用方法。除却本地缓存之外,在当时分布式、微服务等架构盛行的年代,本地缓存显着无法满意大型体系中的各种缓存诉求,比方前面文章中反复提及的缓存漂移问题、以及单机缓存无法逾越的内存容量瓶颈。作为应对之法,会集式缓存被广泛的运用在各中分布式体系中,而运用最广泛的莫过于咱们耳熟能详的Redis了。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

提到Redis,咱们应该都不会生疏,至少应该是有听过这个名字。在中大型分布式体系中,Redis似乎成了一种标配,而提到会集缓存,许多人脑海中榜首闪过的也是Redis。Redis是一个依据内存的非联系型数据库(NoSQL),首要是存储key-value类型的键值对数据,而value则支撑多种不同的类型。因为其强悍的功能体现以及完善的可靠性与集群扩展机制,使其俘获了许多开发人员的青睐,成为了高并发体系的制胜法宝。接下来的几篇文章中呢,咱们就一同聊一聊与Redis有关的内容,讨论下Redis在会集式缓存范畴鹤立鸡群的诀窍。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

Redis的各种数据类型

作为缓存组件,Redis的数据结构全体而言便是key-value类型的键值对,可是Redis关于value类型的支撑仍是比较丰富的,提供了5种不同的数据结构,能够满意大部分场景的运用诉求。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

对几种类型的结构特色与运用留意点梳理汇总如下:

类型 阐明 支撑功用
string 一般字符串 字符串的根底增修改查才能,假如是整数或者浮点数,还支撑自增自减才能。
list 链表内容,每个元素都是一个独立的字符串,内容能够相同 根底增修改查才能,从链表两头插入或者弹出元素,依照下标获取指定元素列表等等
set 无序调集,每个元素都是一个独立字符串,元素之间不答应重复 根底增修改查才能,判别元素是否存在,随机获取元素等等
hash 无序的key-value键值对调集 根底增修改查才能,获取一切的键值对
zset 能够了解为一种比较特殊的hash结构,含有member和score两个概念,对应到hash类型上分别是key与value的联系,其区别点在在于score是固定的double类型的value 根底增修改查才能,支撑依据score排序并获取指定的排序个数的元素列表

实践的运用中,也会依据各自类型不同的特色,用来完成不同的业务诉求。

举个比方:

一个体系内的告诉公告检查功用,能够将公告ID作为key,然后这边告诉公告的阅读量作为score,在redis中存储为zset类型,然后每次读取详情操作的都累加更新下对应的score值,这样的话,就能够依据score进行降序排列,拉取到抢手新闻公告的排行榜。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

Redis的百变应用场景

依据Redis提供的根底才能,在项目中不同场景都有被广泛的运用,下面列举几个常见的运用场景。

在分布式体系里边常常会需求用到分布式锁,完成分布式锁的方法有许多种,其间运用的比较广泛的一种战略,便是依据Redis来完成的。之所以选用Redis来作为分布式锁,能够有几方面理由:

  1. redis满足的快
  2. redis提供了setnx + expire的机制,完全契合分布式锁的完成关键
  3. Redisson客户端的流行,使得依据redis的分布式锁愈加简略
  • 数据库扛压层

凭借redis超高的处理功能,常常会被放置在数据库的前面,用于数据扛压场景运用。比方各种秒杀场景,能够将数据库中的库存信息缓存到redis中,然后运用redis来抗住秒杀期间洪水般的大并发量恳求。

  • 登录验证码存储

这个场景也很常见,比方用户发送的短信验证码,一般都会要求5分钟内有效。这种状况下,能够将验证码信息存储在redis中并设定5分钟后主动过期。这样的话就能够完成超时失效的功用,而无需业务层面去维护过期信息。

  • 大局ID生成&大局限流

在分布式体系中,Redis作为一个能够被一切节点拜访的会集节点,加上其具有的incrby原子指令,使得在多个场景下发挥价值:

  1. 将其用作大局仅有ID的生成,以确保各个节点之间生成的仅有ID不会冲突。

  2. incrby能够完成大局恳求量的计算计数,结合expire一同能够完成守时重置计数器,从而完成限流才能

  • bitmap方法存储每日报到数据

其实,Redis还支撑位图Bitmap)格式进行数据存储。前面咱们说Redis支撑五种数据结构里边并没有看到Bitmap类型的身影,其实Redis的bitmap数据最终存储的是string类型,可是Redis为Bitmap操作提供了配套的操作接口,比方setbit指令。

位图的存在便是为了服务于海量数据的存储场景的,比方体系里边有10亿用户,现在需求记载每个人每天的报到状况,每天10亿数据量,假如用一般String类型存储,每天10亿条数据量,时刻一久任何的Redis也扛不住。而依据bitmap的方法存储,则能够极大的降低全体数据量。关于redis的bitmap操作与运用,后面文章会打开论述。

  • 抢手榜单生成

依据Redis的zset数据结构,能够将抢手值作为score进行存储,这样能够依据需求,依照score进行排序并拉取榜单数据。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

后端面试中的常客

这篇文章中,咱们改变下以往的文章行文叙事风格。咱们先不直接切入到Redis的具体特性或功用点的完成原理与运用层面,而是先从面试场景作为切入口,经过几个面试问题,来感触下Redis全体的“魅力”、引出Redis所具有的核心特性与常见运用留意事项。

因为Redis在项目中的广泛运用,也让其成为了后端面试中的抢手嘉宾。许多小伙伴应该在面试中都被问过与Redis有关的问题吧?当然有许多的八股文背诵一下就能够应付许多简略的面试场景,但笔者作为面试官一般不太会直接去问八股文问题,常常会将问题稍作包装之后再去问。

下面举几个比方。

Q1. 许多人都说Redis处理快是因为它是单线程的,Redis进程中真的只要一个线程吗?为什么惯例项目中为了提高并发量都会选用线程池等方法来多线程处理,而Redis却反其道而行之呢?

许多的面试八股文中都会提到说Redis是单线程的,这个说法其实不够谨慎,因为Redis中并非是只要一个线程,整个进程中还有一些额定的线程担任做一些辅助的其他业务,比方管理与客户端的连接,比方行列中音讯的维护等等。

Redis全体依据一种多路复用的机制来完成恳求的接纳与分配处理。全体简化后的处理逻辑如下图所示。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

所以说,其实Redis只是是选用单线程来担任履行指令恳求处理,而非整个Redis便是一个单线程的。回到开始的问题,为什么Redis挑选选用单线程的方法来履行指令。在多线程编程的时分面临问题首要有:

  • 并发线程安全问题, 需求确保操作的先后顺序,需求确保同一时刻只能有1个线程对某个对象进行写操作 —— 需求构建完备的同步维护机制,会对全体功能形成影响。
  • 多线程维护的体系额定开销 —— CPU需求不停的在多个线程之间进行切换,由此会带来一系列的额定开销。

而因为Redis是一种key-value模型的数据结构模式,比方许多查询操作都是O(1)的时刻复杂度,其操作履行速度非常快,所以这种状况下,结合I/O多路复用模型一同,运用单线程的方法履行指令,反而能够达到比多线程愈加优异的体现。

问题能够进一步引申,能够持续聊一些其他问题。比方:

  • 已然Redis是单线程的,那运用的时分有什么需求留意的事项吗? 不能履行耗时操作,会阻塞其他恳求指令的履行。

  • I/O多路复用是个什么概念?它和BIONIO之间有什么异同? 诸如此类的问题,都能够进一步的去打开调查。

  • 当时计算机一般都是多核CPU,用单线程去履行的话,相当于其它几个核就浪费了,那有什么方法能够将其他的几个核也运用起来么? 答案其实也不难,在一台机器上一同去部署多个Redis进程,组成个集群,就能够啦。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

Q2. 假如我想要查询一下出产环境的Redis中有多少以“User_”最初的记载数量,能够怎么做?

这个问题其实是有一点小陷阱的。查找以指定前缀最初的记载,首先许多同学想到的便是keys指令,但问题中有个约束是在出产环境中履行。所以这个问题看似简略,其实需求结合如下几点来综合考虑:

  1. 通常状况下,出产环境中的数据量是非常大的、且恳求并发量会比较高;
  2. Redis的keys指令是一个耗时操作,复杂度O(n),数据量越大履行速度越慢;
  3. Redis的指令履行是单线程履行的。

依据上述几点要素,假如在数据量较大的出产环境去履行keys指令将会导致履行耗时特别长,而因为Redis是单线程履行指令,就会导致其他恳求指令被阻塞无法履行,这样在一个高并发集群内,很简单形成集群内恳求的大面积阻塞,影响体系的全体稳定性。

那么keys指令不能够用,有什么替代方案呢?能够运用scan指令。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

Q3. 假如有一批机器,内存都比较小(单机内存小于全体待缓存数据量),用来建立个Redis做热门数据缓存扛压以降低数据库的恳求压力。假如你来做的话,会有哪些应对思路呢?

这个问题就比较敞开,并且答案也不仅有,考核的点也比较综合。

首先来分析下标题,从题干描绘中能够捕捉到几个信息,以及对应的相关知识点:

  1. 单机内存小于全体数据量,所以想要将一切数据全量加载到单机内存里边是不可行的;
  2. 运用Redis的用途是扛压来降低数据库拜访压力的,也便是答应部分恳求穿透Redis打到数据库上的,所以能够考虑将有限内存用来存放热门数据,扛住大部分的流量;
  3. 标题说有一批机器,便是说机器的数量不止一台,所以能够考虑构建集群的方法,扩展Redis集群总内存大小,这样以集群的力量来缓存悉数的数据量。

所以说这个标题里边其实触及到了两个考点:

  1. 热门数据的概念、也即Redis的数据筛选战略。
  2. Redis集群扩展的相关概念。

更进一步,又能够引申出许多其它细节问题,比方:

  • Redis中的数据筛选战略有哪些? no-enviction、volatile-lru、volatile-ttl、volatile-random、allkeys-lru、allkeys-random

  • Redis的数据筛选战略与数据过期有啥区别? 数据过期是达到了设定的过期时刻之后使数据不可用,而数据筛选战略首要是在容量满之后采取的被迫应对战略。

  • Redis集群中是怎么决议一个记载应该保存在哪个节点上的? 关于一致性Hash相关的内容,以及怎么处理数据歪斜问题、节点扩容对缓存命中状况的影响等等。

回头看下,是不是其间蕴含的内容仍是蛮多的?

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

这里咱们以面试场景中会被问及的几个问题作为切入点,大约聊了下与Redis有关的一系列内容。当然这里介绍的都比较浅显,乃至只是列了下相关的知识点,首要是先让咱们先感触下Redis所包括与触及的相关知识点。在后续的文章中,咱们将逐渐逐一地去分析与介绍。

小结回顾

好啦,作为redis部分的榜首篇内容,咱们只是简略的聊了下Redis的根底概念以及首要的特性介绍,一同经过几个实践的面试题演示了下Redis全体内容的“博学多才”。而关于Redis的更多细化方向的打开论述,咱们将会在后续文章中逐渐介绍。那么你对Redis怎么看呢?欢迎谈论区一同交流下,等待和各位小伙伴们一同商讨、共同生长。

弥补阐明1

本文归于《深化了解缓存原理与实战规划》系列专栏的内容之一。该专栏环绕缓存这个宏大命题进行打开论述,全方位、体系性地深度分析各种缓存完成战略与原理、以及缓存的各种用法、各种问题应对战略,并一同讨论下缓存规划的哲学。

假如有兴趣,也欢迎关注此专栏。

弥补阐明2

  • 关于本文中触及的演示代码的完好示例,我现已收拾并提交到github中,假如您有需求,能够自取:github.com/veezean/Jav…

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点

我是悟道,聊技能、又不只是聊技能~

假如觉得有用,请点赞 + 关注让我感触到您的支撑。也能够关注下我的公众号【架构悟道】,获取更及时的更新。

等待与你一同讨论,一同生长为更好的自己。

Redis缓存何以一枝独秀?——从百变应用场景与热门面试题中感受下Redis的核心特性与使用注意点