扛并发主力军,引入应用层缓存

1.背景

缓存的使用一定是今后开发中100%会用到的技术,尤其是Redis相关的问题,如果面试官不问我我几个缓存相关的问题,那我觉得我可能是去了个假的互联网公司。

这里考虑到有些初学者刚刚出校园或者自学中,准许我多费口舌介绍下关于缓存的基础知识,我们买电脑的时候关心三个比较重要的参数:1.CPU or GPU 型号。2.内存大小。3.硬盘大小。这三个硬件直接决定你电脑性能的好坏。

两个最关键的因素就是 CPU 和 内存,如何衡量一个CPU的好坏?

这是我日常开发用的电脑,我们发现有三个关于内存的参数:

  1. L2 缓存:每个核心 256 KB

  2. L3 缓存:6 M

  3. 内存:16 G

缓存和内存的大小是决定你电脑性能的重要参数,我们都知道内存价格远高于磁盘,高速缓存(L2/L3)价格高于内存。

速度:寄存器 > 高速缓存(SRCM) > 内存(DRAM) > 磁盘(SSD > HDD)

画图工具:VisualParadigm

缓存概念

Cache一词来源于1967年的一篇电子工程期刊论文。其作者将法语词“cache”赋予“safekeeping storage”的涵义,用于计算机工程领域。

当CPU处理数据时,它会先到Cache中去寻找,如果数据因之前的操作已经读取而被暂存其中,就不需要再从随机存取存储器(Random Access Memory)中读取数据——由于CPU的运行速度一般比主内存的读取速度快,主存储器周期(访问主存储器所需要的时间)为数个时钟周期。因此若要访问主内存的话,就必须等待数个CPU周期从而造成浪费。

提供“缓存”的目的是为了让数据访问的速度适应CPU的处理速度,其基于的原理是内存中“程序执行与数据访问的局域性行为”,即一定程序执行时间和空间内,被访问的代码集中于一部分。为了充分发挥缓存的作用,不仅依靠“暂存刚刚访问过的数据”,还要使用硬件实现的指令预测与数据预取技术——尽可能把将要使用的数据预先从内存中取到缓存里。

CPU的缓存曾经是用在超级计算机上的一种高级技术,不过现今计算机上使用的的AMD或Intel微处理器都在芯片内部集成了大小不等的数据缓存和指令缓存,通称为L1缓存(L1 Cache即Level 1 On-die Cache,第一级片上高速缓冲存储器);而比L1更大容量的L2缓存曾经被放在CPU外部(主板或者CPU接口卡上),但是现在已经成为CPU内部的标准组件;更昂贵的CPU会配备比L2缓存还要大的L3缓存(level 3 On-die Cache第三级高速缓冲存储器)。

面试官:你过去的项目中使用了缓存技术吗?哪些业务场景使用了?

分析:不管是C端还是B端业务场景,都会使用缓存,如果系统设计不会使用缓存,那实在是无法说服面试官发offer出来,使用缓存优势就是快,缺点是速度越快价格越昂贵,传统的基于硬盘存储的Mysql已经无法满足现有互联网公司的流量,为了提高系统的性能,应对大流量高并发,cache 在企业里也有也会广泛应用。

我:

项目中我主要在4个地方使用到缓存

  1. CDN:

  2. 代理

  3. 本地缓存

  4. 分布式缓存

CDN 广泛应用于网站与应用加速、游戏加速、音视频点播、文件等场景,通过高性能缓存机制,静态加速,静态资源如各类型图片、css、js小文件等,提高访问效率和资源可用性。

代理在前面的小节讲到 《Nginx下的负载均衡》 ,Nginx 可作为 http 缓存工具。

后面的章节主要围绕“本地缓存”和“分布式缓存”重点介绍应用层缓存的使用,因为作为开发工程师,应用层你接触相对比较多。

缓存分布图

缓存使用场景

使用缓存,通常考虑两种情况:

  1. 短时间内相同数据重复查询多次且数据更新不频繁,这个时候可以选择先从缓存查询,查询不到再从数据库加载并回设到缓存的方式。此种场景较适合用单机缓存。

  2. 高并发查询热点数据,后端数据库不堪重负,可以用缓存来扛。

具体应用场景:

  • 排行榜相关的问题,如新浪微博热门话题榜,百度当前热搜榜,一定是在缓存了。

  • 热门商品列表

  • 计数问题的功能,比如记录网站访问次数或用户访问ip个数。

4.常用缓存框架

在应用服务器本地缓存着热点数据,应用程序可以在本机内存中直接访问数据,而无需访问数据库。在Java里,本地缓存就是缓存在JVM所在主机的内存中,常规设计中,本地缓存处于分布式缓存上一层,客户端请求优先查询本地缓存,如果本地缓存未命中,再去查找 Redis,如果 Redis 依旧没命中,最后查找数据库。也可以直接设计分布式缓存+数据库两层架构。

本地缓存流行框架

  1. Guavn Cache :Google开源的Java重用工具集库Guava里的一款缓存工具。

  2. Ehcache:非常流行的纯Java开源缓存框架,使用简单,高速,实现线程安全的缓存管理类库。

  3. 编程语言自带数据结构:如 Java 的 HashMap,CurrentHashMap 等。

  4. Spring 缓存:Spring 全家桶无所不能,如果你的项目组人少事儿多,Spring Cache 或许是不错的选择。

分布式缓存流行框架

  1. Reids:一个远程非关系型内存数据库

  2. Memcached:应用较广的开源分布式缓存产品之一

  3. 阿里Tair:阿里开源产品

Redis 是当前最流行的分布式缓存框架,企业广泛使用,也是面试中要求较高的,每个程序员都必须了解掌握,后面会针对 Redis 详细介绍。

为什么要使用缓存

在高并发请求时,为何我们频繁提到缓存技术?最直接的原因是,磁盘IO及网络开销是直接请求内存IO千百上千倍,做个简单计算,如果我们需要某个数据,该数据从数据库磁盘读出来需要0.0045S,经过网络请求传输需要0.0005S,那么每个请求完成最少需要0.005S,该数据服务器每秒最多只能响应200个请求,而如果该数据存于本机内存里,读出来只需要100us,那么每秒能够响应10000个请求。通过将数据存储到离CPU更近的位置,减少数据传输时间,提高处理效率,这就是缓存的意义。

下图是小编工作中负责过的一个风控系统在日常24H中 Redis集群 QPS 曲线图,从业务低峰期几千或晚高峰最高30W,一个 Redis 集群都可轻松应对,30W QPS 在大型系统中流量并不算高,且不是核心系统,如果在多几倍几十倍多流量,一个结构优良的 Redis 集群都可轻松应对,这充分说明了我们为什么要使用缓存,缓存可以把系统系统响应能力提高N个数量级,远高于传统基于硬盘的关系型数据库。所以学会在系统中设计使用缓存也是企业招聘时要求工程师必会的技能。

image-20190812203402366

5.关于缓存的一些算法

常用缓存数据淘汰策略

缓存是非常宝贵的资源,不能把所有数据都放入缓存,只能把最重要的或者要求查询速度最快的数据缓存起来,比如微博热门话题排行榜功能,通常使用缓存查询,而不是数据库。

  1. FIFO(First In First Out): 先进先出算法,即先放入缓存的先被移除。

  2. LRU(Least Recently Used): 最近最少使用算法,使用时间距离现在最久的那个被移除。

  3. LFU(Least Frequently Used): 最不常用算法,一定时间段内使用次数(频率)最少的那个被移除。

缓存数据更新策略

  1. 定时任务从数据库直接更新缓存:适用于对时间不敏感的数据。

  2. 查询时写缓存,即查询优先查询缓存,若缓存未命中,查询数据库,将返回结果写入缓存,数据更新时先 delete 缓存,再更新缓存。

  3. MQ 消息异步更新缓存,后文中会针对MQ的应用做单独讲解。

6.总结

思考:关于缓存淘汰策略和更新策略,各自有什么优点?有什么缺点?读者可以作为延伸学习。

为什么要了解每种策略的优缺点,工作中业务场景千差万别,只有知道不同策略的优缺点才能知道哪种策略最适合当前的业务场景。

高并发网站后台一定离不开缓存的使用,所以面试中要求工程师必须掌握。

关于缓存常见面试题举例:

  1. 为什么使用缓存,有什么优点?

  2. Redis 与 Memcached 区别。

  3. 缓存更新策略 & 淘汰策略。

  4. 关于 Redis 的知识点,如 Redis 常用数据结构,持久化策略,线程模型等。

参考资料

  1. 维基百科:https://zh.wikipedia.org/wiki/缓存

  2. 美团点评技术博客:https://tech.meituan.com/

联系我

VX搜索【转行程序员】回复”加群“,我会拉你进技术群。讲真的,在这个群,哪怕您不说话,光看聊天记录也是一种成长。阿里/腾讯/百度资深工程师、Google技术大神、IBM工程师、还有我王炸、各路大牛都在,有任何不明白的都进群提问。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310792.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c语言筛法求一个范围内的素数,运用埃拉托色尼筛法求解一定范围内的素数.docx...

#includetypedef struct Node{int data;struct Node *link;}LinkList;void buildList(int max,LinkList *&head){//构建链表函数LinkList *l,*p;int i;head(LinkList*)malloc(sizeof(LinkList));head->linkNULL;lhead;for(i2;i<max;i){p(LinkList*)malloc(sizeof(Lin…

LeetCode 783二叉搜索树节点最小距离-简单

给你一个二叉搜索树的根节点 root &#xff0c;返回 树中任意两不同节点值之间的最小差值 。 示例 1&#xff1a; 输入&#xff1a;root [4,2,6,1,3] 输出&#xff1a;1 示例 2&#xff1a; 输入&#xff1a;root [1,0,48,null,null,12,49] 输出&#xff1a;1 提示&…

二级c语言作答文件不存在,全国计算机等级考试二级C语言上机考试题库及答案...

希望对有需要的人有帮助第1套 一、填空给定函数的功能是调用fun函数建立班级通讯录。通讯录记录每位学生的编号&#xff0c;姓名和电话号码。班级的人数和学生的信息从键盘读入&#xff0c;每个人的信息作为一个数据块写到名为答案yfile5.dat的二进制文件中。答案:1. STYPE 2. …

使用 VMware + win10 + vs2019 从零搭建双机内核调试环境

我在前面的文章——《使用 VMware win10 VirtualKD windbg 从零搭建双机内核调试环境》分享了使用 windbg 进行双机内核调试的环境搭建的步骤。有小伙伴儿留言说&#xff1a;在使用 vs 进行双机内核调试的时候&#xff0c;总是连不上。希望能发一篇使用 vs 进行双机内核调试…

LeetCode 617合并二叉树-简单

给定两个二叉树&#xff0c;想象当你将它们中的一个覆盖到另一个上时&#xff0c;两个二叉树的一些节点便会重叠。 你需要将他们合并为一个新的二叉树。合并的规则是如果两个节点重叠&#xff0c;那么将他们的值相加作为节点合并后的新值&#xff0c;否则不为 NULL 的节点将直…

配合理lcd的c语言小游戏,C语言源程序LCD.doc

C语言源程序LCDC语言源程序//******** 小波电子工作室 All rights reserved******//******** 个人主页&#xff1a;/niejinbo **//******** 文 件 名&#xff1a; lcd_0712.c **************//******** 功能概要&#xff1a; LCD液晶显示字符 ***********//******** MCU: STC89…

C#中的9个“黑魔法”与“骚操作”

C#中的9个“黑魔法”与“骚操作”我们知道 C#是非常先进的语言&#xff0c;因为是它很有远见的“语法糖”。这些“语法糖”有时过于好用&#xff0c;导致有人觉得它是 C#编译器写死的东西&#xff0c;没有道理可讲的——有点像“黑魔法”。那么我们可以看看 C#这些高级语言功能…

LeetCode 872叶子相似的树-简单

请考虑一棵二叉树上所有的叶子&#xff0c;这些叶子的值按从左到右的顺序排列形成一个 叶值序列 。 举个例子&#xff0c;如上图所示&#xff0c;给定一棵叶值序列为 (6, 7, 4, 9, 8) 的树。 如果有两棵二叉树的叶值序列是相同&#xff0c;那么我们就认为它们是 叶相似 的。 …

android圆形变方形动画,CSS3 简单的圆形/方形变形动画

CSS语言&#xff1a;CSSSCSS确定html,body {width: 100%;height: 100%;background-color: #221e40;}*,*:after,*::before {box-sizing: border-box;}.centered {width: 100%;height: 100px;position: absolute;top: 50%;margin-top: -50px;}.morph {width: 100%;height: 100px;…

.NET Core开发实战(第35课:MediatR:让领域事件处理更加优雅)--学习笔记

35 | MediatR&#xff1a;让领域事件处理更加优雅核心对象IMediatorINotificationINotificationHandler这两个与之前的 Request 的行为是不一样的&#xff0c;接下来看一下代码internal class MyEvent : INotification {public string EventName { get; set; } }internal class…

LeetCode 559N叉树的最大深度-简单

给定一个 N 叉树&#xff0c;找到其最大深度。 最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。 N 叉树输入按层序遍历序列化表示&#xff0c;每组子节点由空值分隔&#xff08;请参见示例&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [1,null,3,…

android 5.0状态栏下载地址,Android沉浸式状态栏(5.0以上系统)

Android沉浸式状态栏(5.0以上系统)沉浸式状态栏可以分为两种:1.直接给状态栏设置颜色 (如下图:)这里写图片描述java代码形式:if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {Window window activity.getWindow();window.addFlags(WindowManager.LayoutParams…

解析“60k”大佬的19道C#面试题(下)

解析“60k”大佬的19道C#面试题&#xff08;下&#xff09;在上篇中&#xff0c;我解析了前 10 道题目&#xff0c;本篇我将尝试解析后面剩下的所有题目。解析“60k”大佬的19道C#面试题&#xff08;上&#xff09;这些题目确实不怎么经常使用&#xff0c;因此在后文中&#xf…

LeetCode 543二叉树的直径-简单

给定一棵二叉树&#xff0c;你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路径长度中的最大值。这条路径可能穿过也可能不穿过根结点。 示例 : 给定二叉树 1/ \2 3/ \ 4 5 返回 3, 它的长度是路径 [4,2,1,3] 或者 [5,2,1,3]。 代码如下: /*** Def…

android 卡顿代码定位,Android 性能优化实例:通过 TraceView 定位卡顿问题

8种机械键盘轴体对比本人程序员&#xff0c;要买一个写代码的键盘&#xff0c;请问红轴和茶轴怎么选&#xff1f;背景项目中使用了鸿洋大神的TreeView树状结构控件&#xff0c; 但是由于在主线程中使用了注解/反射来定位节点&#xff0c; 内容一多就有点卡顿。因此通过android …

DotNetCore三大Redis客户端对比和使用心得

前言稍微复杂一点的互联网项目&#xff0c;技术选型都会涉及Redis&#xff0c;.NetCore的生态越发完善&#xff0c;支持.NetCore的Redis客户端越来越多&#xff0c;下面三款常见的Redis客户端&#xff0c;相信大家平时或多或少用到一些&#xff0c;结合三款客户端的使用经历&am…

LeetCode 226翻转二叉树-简单

翻转一棵二叉树。 示例&#xff1a; 输入&#xff1a; 4/ \2 7/ \ / \ 1 3 6 9输出&#xff1a; 4/ \7 2/ \ / \ 9 6 3 1代码如下: /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode…

android elevation 白色,Android Elevation

简介&#xff1a;在Android API21&#xff0c;新添加了一个属性&#xff1a;android:elevation&#xff0c;用以在xml定义View的深度(高度)&#xff0c;也即z方向的值。除了elevation之外&#xff0c;类似于已有的translationX、translationY&#xff0c;也相对应地新增了一个t…

(译)创建.NET Core多租户应用程序-租户解析

介绍本系列博客文章探讨了如何在ASP.NET Core Web应用程序中实现多租户。这里有很多代码段&#xff0c;因此您可以按照自己的示例应用程序进行操作。在此过程的最后&#xff0c;没有对应的NuGet程序包&#xff0c;但这是一个很好的学习和练习。它涉及到框架的一些“核心”部分。…

LeetCode 404左叶子之和-简单

计算给定二叉树的所有左叶子之和。 示例&#xff1a; 3/ \9 20/ \15 7在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&#xff0c;所以返回 24 代码如下: /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode…