高级架构师_Redis_第1章_ 缓存原理与设计

文章目录

  • 高级架构师_Redis_第1章_ 缓存原理与设计
    • 第一节 缓存原理与设计
      • 1.1 缓存基本思想
        • 1.11 缓存的使用场景
        • 1.12 什么是缓存?
        • 1.13 大型网站中缓存的使用
      • 1.2 常见缓存的分类
        • 1.21 客户端缓存
        • 1.22 网络端缓存
        • 1.23 服务端缓存
      • 1.3 缓存的优势与代价
        • 1.31 使用缓存的优势
        • 1.32 使用缓存的代价
      • 1.4 缓存的读写模式
        • 1.41 Cache Aside Pattern(常用)
        • 1.42 Read/Write Through Pattern
        • 1.43 Write Behind Caching Pattern
      • 1.5 缓存架构的设计思路
      • 1.6 案例:设计拉勾首页缓存职位列表、热门职位

第一节 缓存原理与设计

1.1 缓存基本思想

1.11 缓存的使用场景

DB 缓存,减轻 DB 服务器压力

一般情况下数据存在数据库中,应用程序直接操作数据库。

当访问量上万,数据库压力增大,可以采取的方案有: 读写分离,分库分表
当访问量达到 10 万、百万,需要引入缓存。 将已经访问过的内容或数据存储起来,当再次访问时先找缓存,缓存命中返回数据。 不命中再找数据库,并回填缓存。

提高系统响应

数据库的数据是存在文件里,也就是硬盘,与内存做交换(swap) 在大量瞬间访问时(高并发)MySQL 单机会因为频繁 IO 而造成无法响应。

MySQL 的 InnoDB 是有行锁 将数据缓存在 Redis 中,也就是存在了内存中。 内存天然支持高并发访问。可以瞬间处理大量请求。 qps 到达 11 万/S 读请求 8 万写/S

做 Session 分离

传统的 session 是由 tomcat 自己进行维护和管理。

集群或分布式环境,不同的 tomcat 管理各自的 session。 只能在各个 tomcat 之间,通过网络和 Io 进行 session 的复制,极大的影响了系统的性能。

1、各个 Tomcat 间复制 session,性能损耗

2、不能保证各个 Tomcat 的 Session 数据同步

将登录成功后的 Session 信息,存放在 Redis 中,这样多个服务器(Tomcat)可以共享 Session 信息。

Redis 的作用是数据的临时存储

做分布式锁(Redis)

一般讲锁是多线程的锁,是在一个进程中的 多个进程(JVM)在并发时也会产生问题,也要控制时序性 可以采用分布式锁。使用 Redis 实现 setNX

做乐观锁(Redis)

同步锁和数据库中的行锁、表锁都是悲观锁

悲观锁的性能是比较低的,响应性比较差

高性能、高响应(秒杀)采用乐观锁

Redis 可以实现乐观锁 watch + incr

1.12 什么是缓存?

缓存原指 CPU 上的一种高速存储器,它先于内存与 CPU 交换数据,速度很快 现在泛指存储在计算机上的原始数据的复制集,便于快速访问。 在互联网技术中,缓存是系统快速响应的关键技术之一 以空间换时间的一种技术(艺术)

1.13 大型网站中缓存的使用

单机架构 LAMP(Linux+apache+MySQL+PHP)、JavaEE(SSM)

访问量越大,响应力越差,用户体验越差

引入缓存、示意图如下:

在大型网站中从浏览器到网络,再到应用服务器,再到数据库,通过在各个层面应用缓存技术,大大提 升了系统性能和用户体验。

1.2 常见缓存的分类

1.21 客户端缓存

传统互联网:页面缓存和浏览器缓存

移动互联网:APP 缓存

页面缓存

页面缓存:页面自身对某些元素或全部元素进行存储,并保存成文件。

html5:Cookie、WebStorage(SessionStorage 和 LocalStorage)、WebSql、indexDB、Application Cache 等

开启步骤:

1、设置 manifest 描述文件

CACHE MANIFEST
#comment
js/index.js
img/bg.png

2、html 关联 manifest 属性

<html lang="en" manifest="demo.appcache">

使用 LocalStorage 进行本地的数据存储,示例代码:

localStorage.setItem("Name","张飞")
localStorage.getItem("Name")
localStorage.removeItem("Name")
localStorage.clear()

浏览器缓存

当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器有“要请求资源”的副本,就可以直接 从浏览器缓存中提取而不是从原始服务器中提取这个资源。

浏览器缓存可分为强制缓存和协商缓存。

强制缓存:直接使用浏览器的缓存数据

条件:Cache-Control 的 max-age 没有过期或者 Expires 的缓存时间没有过期

<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="Expires" content="Mon, 20 Aug 2010 23:00:00 GMT" />

协商缓存:服务器资源未修改,使用浏览器的缓存(304);反之,使用服务器资源(200)。

<meta http-equiv="cache-control" content="no-cache">

APP 缓存

原生 APP 中把数据缓存在内存、文件或本地数据库(SQLite)中。比如图片文件。

1.22 网络端缓存

通过代理的方式响应客户端请求,对重复的请求返回缓存中的数据资源。

Web 代理缓存

可以缓存原生服务器的静态资源,比如样式、图片等。

常见的反向代理服务器比如大名鼎鼎的 Nginx。

边缘缓存

边缘缓存中典型的商业化服务就是 CDN 了。

CDN 的全称是 Content Delivery Network,即内容分发网络。

CDN 通过部署在各地的边缘服务器,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度 和命中率。

CDN 的关键技术主要有内容存储和分发技术。现在一般的公有云服务商都提供 CDN 服务。

1.23 服务端缓存

服务器端缓存是整个缓存体系的核心。包括数据库级缓存、平台级缓存和应用级缓存。

数据库级缓存

数据库是用来存储和管理数据的。

MySQL 在 Server 层使用查询缓存机制。将查询后的数据缓存起来。

K-V 结构,Key:select 语句的 hash 值,Value:查询结果

InnoDB 存储引擎中的 buffer-pool 用于缓存 InnoDB 索引及数据块

平台级缓存

平台级缓存指的是带有缓存特性的应用框架。 比如:GuavaCache 、EhCache(二级缓存,硬盘)、OSCache(页面缓存)等。 部署在应用服务器上,也称为服务器本地缓存

应用级缓存(重点)

具有缓存功能的中间件:Redis、Memcached、EVCache(AWS)、Tair(阿里 、美团)等。 采用 K-V 形式存储。 利用集群支持高可用、高性能、高并发、高扩展。 分布式缓存

1.3 缓存的优势与代价

1.31 使用缓存的优势

提升用户体验

用户体验(User Experience):用户在使用产品过程中建立起来的一种纯主观感受。

缓存的使用可以提升系统的响应能力,大大提升了用户体验。

减轻服务器压力

客户端缓存、网络端缓存减轻应用服务器压力。

服务端缓存减轻数据库服务器的压力。

提升系统性能

系统性能指标:响应时间、延迟时间、吞吐量、并发用户数和资源利用率等。

缓存技术可以:

  • 缩短系统的响应时间
  • 减少网络传输时间和应用延迟时间
  • 提高系统的吞吐量
  • 增加系统的并发用户数
  • 提高了数据库资源的利用率
1.32 使用缓存的代价

额外的硬件支出

缓存是一种软件系统中以空间换时间的技术

需要额外的磁盘空间和内存空间来存储数据

搭建缓存服务器集群需要额外的服务器

采用云服务器的缓存服务就不用额外的服务器了

阿里云(Tair、Redis),百度云(Redis),提供缓存服务

AWS 亚马逊云服务:EVCache

高并发缓存失效

在高并发场景下会出现缓存失效(缓存穿透、缓存雪崩、缓存击穿)

造成瞬间数据库访问量增大,甚至崩溃

缓存与数据库数据同步

缓存与数据库无法做到数据的实时同步

Redis 无法做到主从时时数据同步

缓存并发竞争

多个 redis 的客户端同时对一个 key 进行 set 值得时候由于执行顺序引起的并发问题

1.4 缓存的读写模式

缓存有三种读写模式

1.41 Cache Aside Pattern(常用)

Cache Aside Pattern(旁路缓存),是最经典的缓存 + 数据库读写模式。

读的时候,先读缓存,缓存没有的话,就读数据库,然后取出数据后放入缓存,同时返回响应。

更新的时候,先更新数据库,然后再删除缓存。

为什么是删除缓存,而不是更新缓存呢?

1、缓存的值是一个结构:hash、list,更新数据需要遍历 先遍历(耗时)后修改

2、懒加载,使用的时候才更新缓存,使用的时候才从 DB 中加载

也可以采用异步的方式填充缓存 开启一个线程 定时将 DB 的数据刷到缓存中

高并发脏读的三种情况

1、先更新数据库,再更新缓存

update 与 commit 之间,更新缓存,commit 失败 则 DB 与缓存数据不一致

2、先删除缓存,再更新数据库

update 与 commit 之间,有新的读,缓存空,读 DB 数据到缓存

数据是旧的数据 commit 后 DB 为新数据 则 DB 与缓存数据不一致

3、先更新数据库,再删除缓存(推荐)

update 与 commit 之间,有新的读,缓存空,读 DB 数据到缓存

数据是旧的数据 commit 后 DB 为新数据 则 DB 与缓存数据不一致

采用延时双删策略

1.42 Read/Write Through Pattern

应用程序只操作缓存,缓存操作数据库。

Read-Through(穿透读模式/直读模式):应用程序读缓存,缓存没有,由缓存回源到数据库,并写入 缓存。(guavacache)

Write-Through(穿透写模式/直写模式):应用程序写缓存,缓存写数据库。 该种模式需要提供数据库的 handler,开发较为复杂。

1.43 Write Behind Caching Pattern

应用程序只更新缓存。 缓存通过异步的方式将数据批量或合并后更新到 DB 中 不能时时同步,甚至会丢数据

1.5 缓存架构的设计思路

缓存的整体设计思路包括:

1、多层次

分布式缓存宕机,本地缓存还可以使用

2、数据类型

  • 简单数据类型

  • Value 是字符串或整数或二进制

  • Value 的值比较大(大于 100K)

  • 只进行 setter 和 getter 可采用

  • Memcached Memcached 纯内存缓存,多线程 K-V

  • 复杂数据类型

  • Value 是 hash、set、list、zset 需要存储关系,聚合,计算 可采用 Redis

3、要做集群

  • 分布式缓存集群方案(Redis)

  • codis 哨兵 + 主从

  • RedisCluster

4、缓存的数据结构设计

  • 1、与数据库表一致

数据库表和缓存是一一对应的

缓存的字段会比数据库表少一些

缓存的数据是经常访问的 用户表,商品表

  • 2、与数据库表不一致

需要存储关系,聚合,计算等 比如某个用户的帖子、用户的评论。 以用户评论为例,DB 结构如下

ID UID PostTime Content
1 1000 1547342000 xxxxxxxxxx
2 1000 1547342000 xxxxxxxxxx
3 1001 1547341030 xxxxxxxxxx

如果要取出 UID 为 1000 的用户的评论,原始的表的数据结构显然是不行的。

我们应做如下设计:

  • key:UID+ 时间戳(精确到天) 评论一般以天为计算单位

  • value:Redis 的 Hash 类型。field 为 id 和 content (id+content)

  • expire:设置为一天

1.6 案例:设计拉勾首页缓存职位列表、热门职位

拉勾网(www.lagou.com),是国内的招聘门户网站,亿万级 PV,单机响应性能 QPS 万级。

首页分析: 职位时时变化,不能使用静态 html 采用模板技术,数据在服务端拿出,不能为空

数据不一定时时 架构图如下:

  • 1、静态文件

在 nginx 中,放置静态文件,比如 css,js, 图片等


server {listen       80 default_server;server_name localhost;root /mnt/blog/;location / {}#要缓存文件的后缀,可以在以下设置。location ~ .*\.(gif|jpg|png|css|js)(.*) {proxy_pass http://ip地址:90;proxy_redirect off;proxy_set_header Host $host;proxy_cache cache_one;proxy_cache_valid 200 302 24h;proxy_cache_valid 301 30d;proxy_cache_valid any 5m;expires 90d;add_header wall "hello lagou.";}}
  • 2、职位列表

数据特点: 固定数据,一次性读取

方案: 在服务器开启时一次性初始化(从 xml)到服务器本地缓存 采用 Guava Cache,Guava Cache 用于存储频繁使用的少量数据,支持高并发访问 也可以使用 JDK 的 CurrentHashMap,需要自行实现

  • 3、热门职位

数据特点: 频繁变化,不必时时同步 但一定要有数据,不能为空

方案: 数据从服务层读取(dubbo),然后放到本地缓存中(Guava),如果出现超时或读取为空,则返回原 来本地缓存的数据。

注意:不同的客户端看到的数据有可能不一样。

  • 4、数据回填

从 Dubbo 中读取数据时,先读取 Redis 集群的缓存,如果缓存命中则直接返回。 如果缓存不命中则返回本地缓存,不能直接读取数据库。 采用异步的形式从数据库刷入到缓存中。

  • 5、热点策略

对于热点数据我们采用本地缓存策略,而不采用服务熔断策略,因为首页数据可以不准确,但不能不响 应。

高级架构师_Redis_第1章_缓存原理与设计相关推荐

  1. 高级架构师_Redis_第3章_Redis持久化

    高级架构师_Redis_第3章_Redis持久化 文章目录 高级架构师_Redis_第3章_Redis持久化 Redis 持久化 1.1 为什么要持久化 1.2 RDB 介绍 1.3 RDB 执行流程 ...

  2. 高级架构师_Docker_第2章_ Docker核心原理_ 第1节_Docker相关的虚拟化技术

    高级架构师_Docker_第2章_ Docker核心原理_ 第1节_Docker相关的虚拟化技术 文章目录 高级架构师_Docker_第2章_ Docker核心原理_ 第1节_Docker相关的虚拟化 ...

  3. 高级架构师_Docker_第2章_ Docker核心原理_ 第2节_Docker网络

    高级架构师_Docker_第2章_ Docker核心原理_ 第2节_Docker网络 文章目录 高级架构师_Docker_第2章_ Docker核心原理_ 第2节_Docker网络 Docker网络 ...

  4. 高级架构师_Docker_第2章_ Docker核心原理_ 第7节IDEA集成Docker

    高级架构师_Docker_第2章_ Docker核心原理_ 第7节IDEA集成Docker 文章目录 高级架构师_Docker_第2章_ Docker核心原理_ 第7节IDEA集成Docker IDE ...

  5. 高级架构师_Docker_第2章_ Docker核心原理_ 第5节 Dockerfile简介

    高级架构师_Docker_第2章_ Docker核心原理_ 第5节 Dockerfile简介 文章目录 高级架构师_Docker_第2章_ Docker核心原理_ 第5节 Dockerfile简介 D ...

  6. java里面如何加入高级的东西_如何成为一名Java高级架构师

    近些年来互联网快速发展,现阶段的数据量和高并发的诉求,引起了不少传统的技术人员的力不从心,企业愈发关注到了系统架构的重要性,既需要掌控整体又需要洞悉局部瓶颈并依据具体的业务场景给出解决方案的领导型人物 ...

  7. 阿里java架构师+职级_阿里 P8 高级架构师年入100W+,到底什么水平?

    原标题:阿里 P8 高级架构师年入100W+,到底什么水平? 大家都知道,阿里P8高级技术专家,基本上是一线技术人能达到的最高职级,也是很多程序员追求的目标.达到年入百万的P8 Java高级架构师级别 ...

  8. 成为Java高级架构师必看的15本书

    成为Java高级架构师必看的15本书 作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐 ...

  9. 1 张图,拆解阿里 P8高级架构师必会技术栈!

    大家都知道,阿里P8高级技术专家,基本上是一线技术人能达到的最高职级,也是很多程序员追求的目标.达到年入百万的P8 Java高级架构师级别,不仅要具备优秀的编程能力和系统设计能力,在技术视野和业务洞察 ...

最新文章

  1. 用SVN进行团队开发协作生命周期详解
  2. 【Win10 应用开发】语音命令与App Service集成
  3. html制作虚拟人物,一种虚拟人物角色直播系统的制作方法
  4. Mybatis学习之配置优化
  5. C++读取txt中数据的两种方法
  6. UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
  7. 蔡砚刚:uAVS3对标x265 veryslow将节省30%码率
  8. 全网段ip扫描工具安卓_我是如何打造个人专属网络扫描利器
  9. 学习《SQL Server 2005管理员大全》时遇到的困难
  10. SQL SERVER存储过程的几种示例
  11. java开源知识库项目_18个java cms开源项目
  12. MongoDB 数据库简介、安装及使用
  13. 2019西安交通大学计算机复试,西安交通大学2019考研复试分数线多少分 各科基本分数线一览...
  14. 爱尔兰咖啡(作者:痞子蔡)
  15. outlook邮箱显示一直启动中_outlook邮箱打不开一直在加载
  16. 查询student表中姓童的学生情况
  17. 百度token怎么获取_【专栏精选】实战:百度语音识别
  18. 使用Docker Compose构建ZigBee基础架构
  19. Windows目录结构、移动、复制、搜索文件及文件夹等
  20. 禁果效应在游戏剧情中会有什么样的作用

热门文章

  1. 微信插件第一讲之自动回复机器人(护妻宝)
  2. 1.统计所输入字符串中单词的个数。2.删除一个list里面重复元素。3.将列表中的偶数变成它的平方,奇数保持不变。4.输入字符串,将其每个字符的ASCII码形成列表并输出.5.猜单词游戏
  3. pandas 利用 正则表达式 从文本中提取数字
  4. 按键精灵免字库本地识别OCR
  5. SU草图大师错误合集
  6. 【IEEE出版】工业自动化,机器人与控制工程国际会议(IARCE 2022)
  7. Python爬虫是什么?怎么分辨善意爬虫跟恶意爬虫?
  8. 无线热点(AP)不稳定之信道的配置优化实践-分析周围信道修改本地使用信道
  9. 427. 建立四叉树
  10. docker-compose基本命令使用