写点什么

技术选型 - 学习总结笔记

用户头像
Xuenqlve
关注
发布于: 2020 年 11 月 22 日

缓存

什么是缓存

缓存:存储在计算机上的一个原始数据复制集,以便于访问

缓存是介于数据访问和数据源之间的一种高速存储,当数据需要多长读取到的时候,用于加快读取速度

缓存(cache)和缓冲(Buffer)的区别?

Buffer 是用来在读写数据时,在应用程序和低速的设备之间用来缓冲数据的一个中间存储

Cache 是用来在多次读取数据的时候将数据放入到 cache 中,然后每一次要对的时候从 cache 中读取就可以了

缓存使用场景

CPU 缓存;   操作系统缓存;    数据库缓存;    JVM 缓存;

CDN 缓存;    代理与反向代理缓存;    前端缓存;    应用程序缓存;    分布式对象缓存

各种介质数访问延迟

缓存数据存储(Hash 表)

hash 表的时间复杂度为 O1

缓存的关键指标

缓存命中率
  • 缓存是否有效依赖于能多少次重用同一个缓存相应业务请求,这个度量指标被称为缓存命中率

  • 如果查询一个缓存,十次查询九次能够得到正确结果,那么它的命中率是 90% 

影响缓存命中的主要指标
  • 缓存键集合大小:缓存建空间是应用能够生成的所有键的数量,从统计数字上看,应用生的唯一键越多,重用的机会越小。

  • 缓存可使用内存空间:可使用的内存空间直接决定了缓存对象的平均大小和缓存对象数量,当可用空间受到限制时,想要缓存更多的对象,就需要先删除老的对象,在添加新的对象。替换(删除)对象会降低缓存命中率

  • 缓存对象生存时间: 被称为 TTL(Time To Live) ,对象缓存的时间越长,缓存对象被重用的可能性就越高

缓存使用建议

一定要想办法减少可能缓存键的数量,键数量越小,缓存的效率越高

物理上能缓存对象越少,缓存的命中率就越高

长期有效的数据更加适合缓存,快速失效的数据不适合使用缓存

代理缓存

代理用户上网的代理

反向代理缓存 代理数据中心的缓存

内容分发网络(CDN)

CDN 同时配置静态文件和动态内容

通读缓存
  • 代理缓存,反向代理缓存,CDN 缓存都是通读缓存

  • 通读缓存给客户端返回缓存资源,并在请求未命中缓存是获取实际数据

  • 客户端连接的是通读缓存而不是生成响应的原始服务器

旁路缓存
  • 对象缓存是一种旁路缓存,旁路缓存通常是一个独立部署的键值对(key-value) 存储。

  • 应用代理通常会询问对象缓存需要的对象是否存在,如果存在,他会获取并使用缓存的对象,如果不存在或已过期,应用会连接主数据源来组装对象,并将其保存会对象缓存中以便将来使用

最大的区别是客户端连接是否需要连接最终数据源

通读缓存是不连接代理数据源的,代理数据源的访问

旁路缓存是不代理,是由客户端获取到应用数据后,自己将数据写入导旁路缓存中


浏览器对象缓存
本地对象缓存 
  • 对象直接缓存在应用程序内存中

  • 对象缓存在共享内存,同一台机器的多个进程可以访问它们

  • 缓存服务器作为独立应用和应用程序部署在同一个服务器上

本地对象缓存构建分布式集群

这种方法在互联网时代很快就被抛弃了

虽然每台服务器都使用了 cahe  但是每台服务器缓存的数据都是一样的,当要缓存大量数据时,有限的内存却缓存了大量的数据,这样对资源是一种浪费

当一台缓存服务上的缓存需要更新时,它需要通知其他服务器上的缓存,同样进行数据更新,浪费了宝贵的带宽资源

远程分布式对象缓存

缓存数据不需要占据业务服务器的资源,有利于提高业务服务器自身的性能和扩展性

缓存部署在专用的服务器上面,可以构建一个集群,当缓存资源不足的时候,可以通过线性伸缩的方式添加服务器,实现扩容。

Memcached 分布式缓存访问模型

架构师一定要搞清楚我们可以使用的技术,他背后的架构原理是什么样子的,不要盲目的说缓存就是提升性能的,加机器就是提升能力的,但是可能是使用的算法不正确,加了机器不但没有提升性能,还会导致系统崩溃。

 遇到问题不要生搬硬套,导致悲剧性的结局

路由算法

余数 hash 算法

当集群添加节点时会导致大部分的 key 缓存不命中。

分布式对象缓存的一致性 hash 算法

顺时针查找距离它最近的 node 节点

当业务访问到 node3 到 node2 之间的 key 时,顺时针查找会将请求发到 node3 上,由于 node3 是新添加的节点上没有数据,业务会直接访问数据源,因为是旁路缓存,会将访问到的数据写到 node3 上

一致性 hash 缓 的问题:

  • 访问请求不均衡:对 node hash 产生的结果是随机的,可能会出现,有点节点距离过近,有的节点距离过远。

  • 增加一个节点时:只能对其中一个节点分摊压力,其他节点的负载压力变。没有启动很好的扩展效果。

基于虚拟节点的一致性 Hash 算法

每个物理服务器对于相同的虚机节点放到环上,key 查找的时候,就可以近似均匀的访问到所有的物理节点。

技术栈各个层次的缓存 提升的性能:

缓存为什么能显著提升性能:

  • 缓存数据通常来着内存,比磁盘上的数据更快的访问速度

  • 缓存存储数据的最终结果形态,不需要中间计算,减少 CPU 资源的消耗

  • 缓存降低数据库,磁盘,网络的负载压力,使这些 I/O 设备获得更好的相应性能

缓存是系统优化的大杀器

  • 技术简单

  • 性能提升显著

  • 应用场景多

缓存主要的是优化读性能,对与写数据要是要写入到最终的数据源,通常是数据库。因为缓存是不可靠的存储。

缓存使用注意事项:

  • 频繁修改的数据,不适合使用的缓存。

  • 没有热点的访问,缓存的二八定律:百分之八十的访问集中在百分之 20 的数据上。LRU 算法:最近最久访问算法。

  • 数据的不一致与脏的。对缓存设置失效时间,一旦超过失效时间,就要重新加载数据。

  • 缓存雪崩:缓存失效,导致所有请求都到达数据库,数据库承受不了压力而宕机,导致网站不可用。

  • 缓存预热:热点数据是缓存系统利用 LRU 算法不断访问的数据筛选淘汰出来的,这个过程需要花费较长时间,在这段时间大量请求会落到数据库上,可能会导致数据库承受不了压力,所以需要将缓存进行预加载处理,这种手段叫做缓存预热。

  • 缓存穿透:不恰当的业务或者恶意攻击持续高并发的请求某个不存在的数据,因为缓存没有该数据,所有请求都会落到数据库上,对数据库造成很大的压力。一个简单的对策是将不存在的数据也缓存起来(value 值设置为 null) ,并设置一个较短的过期时间。

Redis Vs Memcached

  • Redis 支持复杂的数据结构

  • Redis 支持多路复用的异步 I/O 高性能

  • Redis 支持主从复制高可用

  • Redis 原生集群与 share nothing 集群模式

Redis 集群:

  • redis 集群预分好了 16384 个桶,当需要在 redis 集群中放置一个 key-value 是,根据 CRC16(key) mod 16384 的值,决定将会一个 key 放到那个桶中。

  •  Redis-cluster 把所有的物理节点映射到[0-16383]slot 上(不一定是平均分配),cluster 负责维护 slot 与服务器的映射关系

  • 客户端与 Redis 节点直连,客户端不需要连接所有节点,连接集群中任何一个可用节点即可

  • 所有的 redis 节点彼此互联

消息队列

同步调用 VS 异步调用

同步调用:

异步调用:

有回调的异步调用

消息队列构建异步调用框架

点对点模型:生产者生产的消息只会被消费一次。

发布订阅模型: 生产者产生消息,可以被多个消费者消费。

消息队列好处:

  • 实现异步处理,提升处理新能

  • 更好的伸缩性

  • 削峰填谷

  • 失败隔离和自我修复 

  • 解耦

事件驱动架构 EDA

耦合表面积:


主要 MQ 产品比较:

  • RabbitMQ 的主要特性是性能好,社区活跃,但是 RabbitMQ 用 Erlang 开发,对不熟悉 Erlang 的同学不便做二次开发。

  • ActiveMQ 影响比较广泛,可以跨平台,使用 Java 开发,对 Java 比较友好

  • RocketMQ 是阿里推出的一个开源产品,也是使用 Java 开发的,新能比较好,可靠性高

  • Kafka ,LinkedIn 出品的,Scala 开发,专门针对分布式场景进行了优化,因此分布式的伸缩性会比较好 (更加热门)

负载均衡架构

http 重定向负载均衡:

DNS 负载均衡:

反向代理负载均衡:

IP 负载均衡:

链路层负载均衡:

负载均衡算法:

  •  轮询:所有请求被依次分发到每个应用服务器上,适合于所有服务器硬件都是相同的

  • 加权轮询:根据应用服务器硬件性能的情况,在轮询的基础上,按照配置的权重将请求分发到每个服务器,高性能的服务分配更多请求

  • 随机:请求被随机分配到各个应用服务器

  • 加权随机:带有权重的随机算法

  • 最少连接:记录每个应用服务器正在处理的连接数(请求数),将新到的请求分发到最少连接的服务器上,应该说是最符合负载均衡定义的算法

  • 源地址散列:根据请求来源 IP 地址进行 hash 计算,得到应用服务器,保证同一个来源的请求总在同一个服务器上处理,实现会话粘滞。

分布式关系数据库

MySQL 复制

MySQL 主从复制

MySQL 一主多从

一主多从复制的优点

  • 分摊负载

  • 专机专用

  • 便于冷备

  • 高可用

MySQL 主主复制: 提升写操作高可用

MySQL 主主失效恢复:

MySQL 主主失效的维护过程:

MySQL 复制注意事项:

  • 主主复制的两个数据库不能并发写入。

  • 复制只是增加了数据的读并发处理能力,没有增加写并发能力和存储能力。

  • 更新表结构会导致巨大的同步延迟。

数据分片

硬编码实现数据分片

映射表外部存储:

数据分片的挑战:

  • 需要大量的额外代码,处理逻辑因此变得更加复杂。

  • 无法执行多分片的联合查询。

  • 无法使用数据库的事务。

  • 随着数据的增长,如何增长更多的服务器。

分布式数据库中间件:

Cobar 系统组件模型

分区内受性:因为网络原因,部分服务器节点之间消息丢失或者延迟,系统依然是可以操作的

CAP 原理:

当网络分区失效发生的时候,我们要么取消操作,这样数据就是一致的,但是系统却不可用,要么我们继续写入数据,但是数据的一致性就得不到保证

对于一个分布式系统而言,网络失效一定会发生,也就是说,分区耐受性是必须保证的,那么可用性和一致性上就必须二选一

当网络分区失效,网络不可用,如果选择了一致性,系统就可能返回一个错误码或者干脆超时,即系统不可用。如果选择了可用性,那么系统总是可以返回一个数据,但是并不保证这个数据是最新的。

在分布式系统必须要满足分区耐受性的前题下,可用性和一致性无法同时满足。


最终一致性:在一段时间内数据可能是不一致的,当网络恢复延迟后且完成数据同步后,最终数据是一致的。

最终一致性写冲突

最简单处理策略:根据时间戳,最后写入覆盖。

客户端冲突解决:客户端自建实现数据冲突解决

投票解决冲突: 写大多数表示成功,读大多数相同的数据

ACID 与 BASE

ACID 

  • 原子性:事务要么全部完成,要么全部取消,如果事务崩溃,状态回到事务之前(事务回滚)

  • 隔离性:隔离性主要依靠锁实现 

  • 持久性:一旦事务提交,不管发生什么(崩溃或者出错)数据要保存在数据中

  • 一致性:只有合法的数据才能写入数据库

BASE

  • 基本可用系统出现不可预知故障时,允许损失部分可用性,如响应时间上的损失或功能上的损失。

  • 弱状态,允许系统中数据存在中间状态,并认为该中间状态不会影响系统整体可用性

  • 最终一致性 数据副本在经过一段时间同步后,最终能够达到一个一致的状态

分布式一致性

分布式系统脑裂:不同服务器获得了互相冲突的数据信息或者执行指令,导致整个集群陷入混乱,数据损坏,被称作分布式系统脑裂

分布式一致性算法 Paxos

三个角色:

  • Proposer 提案者

  • Acceptor  接受者

  • Learner 学习者 最终决策的所有结果 学习者都知道的 

多个服务向 Proposer 提出选主的修改方案,Proposer 会向 Acceptor 提出投票是否同意这次修改,最后根据投票多设置为主服务,然后所有的 Learner 就都任务得票多的是主服务器   

第一阶段:prepare 阶段。   Proposer 向 Acceptors 发出 Prepare 请求,Acceptors 针对收到的 Prepare 进行 Promise 承诺。

第二阶段:Accept 阶段。Proposer 收到多个 Acceptors 承诺的 Promise 后,向 Acceptors 发出 Propose 请求,Acceptors 针对收到的 Propose 请求信息 Accept 处理

第三阶段:Learn 阶段。Proposer 在收到多数 Acceptors 的 Accept 之后,标志这本次 Accept 成功,决议形成,将形成的决议发送个所有的 Learners

Proposer 生成全局唯一且递增的 Proposal ID(可使用时间戳加 Server ID),向所有 Acceptors 发送 Prepare 请求,这里无需携带提案内容,只携带 Proposal ID 即可。

Acceptors 收到 prepare 请求和 Propose 请求后

  1. 不在接受 Proposal ID 小于等于当前请求的 Prepare 请求

  2. 不在接受 Proposal ID 小于等于当前请求的 Propose 请求

Zab 协议


搜索引擎的基本架构

互联网搜索引擎整体架构

Lucene 架构

Lucene 引入了段的概念,将一个索引文件拆分为多个子文件,每个子文件叫做段,每个段是一个单独的可被搜索的数据集,索引的修改针对段进行操作。

ElasticSearch

  • 索引分片,实现分布式

  • 索引备份,实现搞可用性

  • API 更简单,更高级

ES 分片预分配。


用户头像

Xuenqlve

关注

还未添加个人签名 2018.05.03 加入

还未添加个人简介

评论

发布
暂无评论
技术选型 - 学习总结笔记