学习笔记: 架构师训练营 - 第五周

用户头像
四夕晖
关注
发布于: 2020 年 10 月 25 日

1、缓存与缓冲

缓存:存储在计算机上的原始数据的复制集,以便于访问。介于数据访问者和数据源之间的一种高速存储,当数据需要多次读取的时候,用于加快读取的速度

缓冲:在向硬盘写入数据时,先把数据放入缓冲区,然后再一起向硬盘写入,把分散的写操作集中进行,减少磁盘碎片和硬盘的反复寻道,从而提高系统性能

缓存(cache)是用来加速数据从硬盘中"读取",而缓冲(buffer)是用来加速数据"写入"硬盘

2、缓存数据存储(Hash表)

一般缓存数据使用key-value的数据结构存储数据,通过计算key的hashCode对应的hash表索引来存取数据。

3、缓存的关键指标-缓存命中率

缓存是否有效依赖于能多少次重用同一个缓存响应业务请求,这个度量指标被称作缓存命中率,例如查询一个缓存,十次查询九次能够得到正确结果,那么它的命中率是90%。

3.1、影响缓存命中率的主要指标

  • 缓存键集合大小:缓存中的每个对象使用缓存键进行识别,定位一个对象的唯一方式就是对缓存键执行精确匹配。一定要想办法减少可能的缓存键数量。键数量越少,缓存的效率越高。

  • 缓存可使用内存空间:缓存可使用内存空间直接决定了缓存对象的平均大小和缓存对象数量。因为缓存通常存储在内存中,缓存对象可用空间受到严格限制且相对昂贵。如果想缓存更多的对象,就需要先删除老的对象,再添加新的对象。替换(清除)对象会降低缓存命中率,因为缓存对象被删除后,将来的请求就无法命中了。物理上能缓存的对象越多,缓存命中率就越高

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

4、常见的缓存

代理缓存:将远程数据中心数据缓存至公司网络代理服务器

反向代理缓存:

反向代理:反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源。同时,用户不需要知道目标服务器的地址,也无须在用户端作任何设定。反向代理服务器通常可用来作为Web加速,即使用反向代理作为Web服务器的前置机来降低网络和服务器的负载,提高访问效率。



反向代理缓存是指在反向代理服务器中添加缓存,将数据或者页面缓存至反向代理服务中,当用户请求到达反向代理服务器时,由反向代理服务器将请求结果返回,使得真正的请求不用到达web服务器,减少web服务器请求,提高服务器吞吐率

多层反向代理缓存:是指在在服务与服务之间,服务与前端web服务器之间,添加多个反向代理服务器和负载均衡,并且配置缓存

内容分发网络(CDN):部署在距离终端用户最近的网络服务商,用户的网络请求总是先到达他的网络服务商那里,在这里缓存网站的一些静态资源(较少变化的数据),可以就近以最快速度返回给用户,如视频网站和门户网站会将用户访问量大的热点内容缓存在CDN。

CDN同时配置静态文件和动态内容:CloudFront CDN拦截所有的请求,根据请求判断是否为静态内容请求,静态内容请求直接访问云服务器中的静态内容,动态内容的请求访问web应用服务器

通读缓存(read-through):

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

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

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

旁路缓存(cache-aside):

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

  • 应用代码通常会询问对象缓存需要的对象是否存在,如果存在,它会获取并使用缓存

浏览器对象缓存:

即浏览器中缓存对象,常用的LocalStorage,SessionStorage

// 在WebStorage中缓存对象的JavaScript代码
var preferences = {/* data object to be stored */};
localStorage.setItem('preferences', JSON.stringify(preferences));
// 访问缓存对象的JavaScript代码
var cachedData = localStorage.getItem('preferences'); var preferences = JSON.parse(cachedData);



本地对象构建分布式缓存:

  • 对象直接缓存在应用程序内存中 。

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

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

本地对象缓存:

现在一般都不会采用本地对象构建分布式缓存,在同步更新缓存时会占用系统资源。

远程分布式对象缓存:

一般使用memcached 和 redis 部署远程分布式对象缓存

Memcached 分布式对象缓存

其访问模型如下:

多台Memcached服务器构成缓存集群,应用程序通过memcached api访问,在其内部使用路由算法算出某个对象具体的服务器地址,再通过通讯模块到相应的服务器去获取对象。其中路由算法的实现是关键。



1、hash值取模

用服务器数目除缓存数据KEY的 Hash 值,余数为服务器列表下标编号。hash(key)%N。使用 Hash 算法能够使缓存数据在整个分布式缓存集群中比较均衡地分布。对 Hash 路由算法稍加改进,就可以实现和负载均衡算法中加权负载均衡一样的加权路由。

缺点:分布式缓存集群需要扩容的时候,更改服务器列表,仍旧使用Hash路由算法,会出现缓存未命中率比较高, 例如缓存服务器由 3 台扩容至 4 台很容易计算出缓存未命中的概率达到了 75%,这个概率会随着服务器节点数量增加变得越来越大

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

  • 构造一个长度为2^32的整数环(长度可以自定义,这个环被称作一致性Hash环)

  • 根据节点名称(可以是服务器的IP地址,也可是服务器编号的下标)的Hash值(分布范围在[0 ,(2^32)-1]),将缓存服务器节点放置在这个Hash环上

  • 根据需要缓存的数据的KEY值计算得到其Hash值(其分布范围也在[0 ,(2^32)-1]),然后在Hash环上顺时针查找距离这个KEY的Hash值最近的缓存服务器节点,最近遇到的这个服务器节点就是其应该定位到的服务器节点

一致性Hash算法在增加或者删除缓存服务器节点时只会影响到哈希环中相邻的节点

缺点:这样实现的一致性hash算法会造成数据分布不均,有些节点数据存储较多,有些节点数据存储稀少问题

一致性哈希算法引入了虚拟节点机制,即对每一个服务节点计算多个哈希,每个计算结果位置都放置一个此服务节点,称为虚拟节点

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

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

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

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

4.2合理使用缓存

使用缓存对提高系统性能有很多好处,但是不合理的使用缓存可能非但不能提高系统的 性能,还会成为系统的累赘,甚至风险。实践中,缓存滥用的情景屡见不鲜——过分依赖缓存、不合适的数据访问特性等

  • 频繁修改的数据:这种数据如果缓存起来,由于频繁修改,应用还来不及读取就已失效 或更新,徒增系统负担。一般说来,数据的读写比在2:1以上,缓存才有意义。

  • 没有热点的访问:缓存使用内存作为存储,内存资源宝贵而有限,不能将所有数据都缓存起来,如果应用系统访问数据没有热点,不遵循二八定律,即大部分数据访问不是集中在小部分数据上,那么缓存就没有意义,因为大部分数据还没有被再次访问就已经被挤出缓存了。

  • 数据不一致与脏读:一般会对缓存的数据设置失效时间,一旦超过失效时间,就要从数据库中重新加载。因此应用要容忍一定时间的数据不一致,如卖家已经编辑了商品属性, 但是需要过一段时间才能被买家看到。在互联网应用中,这种延迟通常是可以接受的, 但是具体应用仍需慎重对待。还有一种策略是数据更新时立即更新缓存,不过也会带来更多系统开销和事务一致性的问题。因此数据更新时通知缓存失效,删除该缓存数据, 是一种更加稳妥的做法。

  • 缓存雪崩:缓存是为了提高数据读取性能的,缓存数据丢失或者缓存不可用不会影响到 应用程序的处——它可以从数据库直接获取数据。但是随着业务的发展,缓存会承担大 部分的数据访问压力,数据库已经习惯了有缓存的日子,所以当缓存服务崩溃的时候, 数据库会因为完全不能承受如此大的压力而宕机,进而导致整个网站不可用。这种情况, 被称作缓存雪崩,发生这种故障,甚至不能简单的重启缓存服务器和数据库服务器来恢 复网站访问。

  • 缓存预热:缓存中存放的是热点数据,热点数据又是缓存系统利用 LRU(最近最久未用) 算法对不断访问的数据筛选淘汰出来的,这个过程需要花费较长的时间,在这段时间, 系统的性能和数据库负载都不太好,那么最好在缓存系统启动的时候就把热点数据加载 好,这个缓存预加载手段叫做缓存预热(warm up)。对于一些元数据如城市地名列表、 类目信息,可以启动时加载数据库中全部数据到缓存进行预热。

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

4.3 Redis VS Memcached

  • Redis 支持复杂的数据结构

  • Redis 支持多路复用异步 I/O

  • 高性能 Redis 支持主从复制高可用

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

4.4 Redis 集群

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

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

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

  • 所有的 Redis 节点彼此互联。

5、消息队列与异步架构

5.1同步调用 VS 异步调用

  • 同步调用:是一种阻塞式调用,一段代码调用另一端代码时,必须等待这段代码执行结束并返回结果后,代码才能继续执行下去。 例如考试时,有的同学是一道题一道题的往下做,当有一道题没做出来时,绝对不会继续做下去,这就是同步调用的过程,一段逻辑没有执行完成时,代码会一直等待,直到代码执行结束,才执行下面的逻辑。

  • 异步调用:是一种非阻塞式调用,一段异步代码还未执行完,可以继续执行下一段代码逻辑,当代码执行完以后,通过回调函数返回继续执行相应的逻辑,而不耽误其他代码的执行。

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

  • 消息生产者:负责生产消息,

  • 消息队列:用来保存消息生产者产生的消息

  • 消息消费者:消费消息队列中消息生产者生产的消息

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

  • 点对点

  • 发布订阅模型

消息生产者将生产的消息按照topic发布在不同的消息队列中,再由订阅不同topic的消息消费者进行消费

5.4 消息队列的好处

  • 实现异步处理,提升处理性能:耗时的操作通过消息队列进行异步处理,使得请求也能及时返回给用户

  • 更好的伸缩性:

  • 削峰填谷:

  • 失败隔离和自我修复:因为发布者不直接依赖消费者,所以消息系统可以将消费者系统错误与生产者系统组件隔离。生产者和消费者互相不受对方失败影响。这意味着任意时刻,我们都可以对后端服务器执行维护和发布操作。我们可以重启、添 加或删除服务 器而不影响生产者可用性,这样简化了部署和服务器管理的难度。



  • 解耦



5.5事件驱动架构 EDA

以用户注册举例,当新用户注册时,通过发布新用户注册事件,而后监听新用户注册事件的消费者在收到新用户注册的事件后,做出相应的处理,将耗时的请求拆分成多个,一个出错后可以通过容错机制补偿不影响其他流程。

5.6主要 MQ 产品比较

• RabbitMQ 的主要特点是性能好,社区活跃,但是 RabbitMQ 用 Erlang 开发,对不熟 悉 Erlang 的同学而言不便于二次开发和维护。(49M)

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

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

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

6 负载均衡架构



负载均衡是使用指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务;一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。

负载均衡的作用(解决的问题):

1.解决并发压力,提高应用处理性能(增加吞吐量,加强网络处理能力);

2.提供故障转移,实现高可用;

3.通过添加或减少服务器数量,提供网站伸缩性(扩展性);

4.安全防护;(负载均衡设备上做一些过滤,黑白名单等处理)

6.1 HTTP 重定向负载均衡

HTTP重定向服务器是一台普通的应用服务器,其唯一个功能就是根据用户的HTTP请求计算出一台真实的服务器地址,并将该服务器地址写入HTTP重定向响应中(重定向响应状态码为302)返回给用户浏览器。用户浏览器在获取到响应之后,根据返回的信息,重新发送一个请求到真实的服务器上。如上图所示,用户访问114.100.80.10,重定向服务器计根据某种负载均衡算法算出真实的服务器地址为112.100.80.3并返回给用户浏览器,用户浏览器得到返回后重新对112.100.80.3发起了请求,最后完成访问。

这种负载均衡方案的有点是比较简单,缺点是浏览器需要两次请求服务器才能完成一次访问,性能较差;同时,重定向服务器本身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限;使用HTTP返回码302重定向,有可能使搜索引擎判断为SEO作弊,降低搜索排名。因此实践中很少使用这种负载均衡方案来部署

6.2 DNS 负载均衡

DNS(Domain Name Server,域名服务器)是进行域名(domain name)和与之相对应的IP地址 (IP address)转换的服务器。DNS中保存了一张域名(domain name)和与之相对应的IP地址 (IP address)的表,以解析消息的域名;



当用户向域名www.mysite.com发起请求时,向DNS服务器请求解析域名对应的IP地址,DNS返回给用户服务的ip地址,用户终端取到ip地址后,再向服务器请求。

优点

  1. 使用简单:负载均衡工作,交给DNS服务器处理,省掉了负载均衡服务器维护的麻烦

  2. 提高性能:可以支持基于地址的域名解析,解析成距离用户最近的服务器地址,可以加快访问速度,改善性能;

缺点

  1. 可用性差:DNS解析是多级解析,新增/修改DNS后,解析时间较长;解析过程中,用户访问网站将失败;

  2. 扩展性低:DNS负载均衡的控制权在域名商那里,无法对其做更多的改善和扩展;

  3. 维护性差:也不能反映服务器的当前运行状态;支持的算法少;不能区分服务器的差异(不能根据系统与服务的状态来判断负载)

将DNS作为第一级负载均衡,记录对应着内部负载均衡的IP地址,通过内部负载均衡将请求分发到真实的Web服务器上。一般用于互联网公司,复杂的业务系统不合适使用。

6.3 反向代理负载均衡

使用反向代理服务器构建反向代理负载均衡,在反向代理服务器中配置多个应用服务器集群,通过负载均衡算法将用户发送的请求,内部转发到相应的业务服务器中,当业务服务器处理完后,将结果返回给反向代理服务器,再由反向代理服务器将结果返回。



用反向代理的好处是,可以将负载均衡和代理服务器的高速缓存技术结合在一起,提供有益的性能,具备额外的安全性,外部客户不能直接访问真实的服务器。并 且实现起来可以实现较好的负载均衡策略,将负载可以非常均衡的分给内部服务器,不会出现负载集中到某个服务器的偶然现象



但是负载均衡中要求特别高的效率,这样实现起来就不是十分简单的了。每针对一次代理,代理服务器就 必须打开两个连接,一个为对外的连接,一个为对内的连接,因此对于连接请求数量非常大的时候,代理服务器的负载也就非常之大了,在最后反向代理服务器会成 为服务的瓶颈。例如,使用Apache的mod_rproxy模块来实现负载均衡功能时,提供的并发连接数量受Apache本身的并发连接数量的限制。一般来讲,可以使用它来对连接数量不是特别大,但每次连接都需要消耗大量处理资源的站点进行负载均衡,例如搜寻。

6.4 IP 负载均衡

在网络层通过修改请求目标地址进行负载均衡。用户请求数据包,到达负载均衡服务器后,负载均衡服务器在操作系统内核进程获取网络数据包,根据负载均衡算法得到一台真实服务器地址,然后将请求目的地址修改为,获得的真实ip地址,不需要经过用户进程处理。真实服务器处理完成后,响应数据包回到负载均衡服务器,负载均衡服务器,再将数据包源地址修改为自身的ip地址,发送给用户浏览器。



IP负载均衡,真实物理服务器返回给负载均衡服务器,存在两种方式:

(1)负载均衡服务器在修改目的ip地址的同时修改源地址。将数据包源地址设为自身盘,即源地址转换(snat)。

(2)将负载均衡服务器同时作为真实物理服务器集群的网关服务器。

优点:

(1)在内核进程完成数据分发,比在应用层分发性能更好;

缺点:

(1)所有请求响应都需要经过负载均衡服务器,集群最大吞吐量受限于负载均衡服务器网卡带宽;

6.5 数据链路层负载均衡

在通信协议的数据链路层修改mac地址,进行负载均衡。数据分发时,不修改ip地址,指修改目标mac地址,配置真实物理服务器集群所有机器虚拟ip和负载均衡服务器ip地址一致,达到不修改数据包的源地址和目标地址,进行数据分发的目的。实际处理服务器ip和数据请求目的ip一致,不需要经过负载均衡服务器进行地址转换,可将响应数据包直接返回给用户浏览器,避免负载均衡服务器网卡带宽成为瓶颈。也称为直接路由模式(DR模式)

优点:性能好;

缺点:配置复杂;

实践建议:DR模式是目前使用最广泛的一种负载均衡方式。

6.7混合型负载均衡

由于多个服务器群内硬件设备、各自的规模、提供的服务等的差异,可以考虑给每个服务器群采用最合适的负载均衡方式,然后又在这多个服务器群间再一次负载均衡或群集起来以一个整体向外界提供服务(即把这多个服务器群当做一个新的服务器群),从而达到最佳的性能。将这种方式称之为混合型负载均衡。

此种方式有时也用于单台均衡设备的性能不能满足大量连接请求的情况下。是目前大型互联网公司,普遍使用的方式



6.8 负载均衡算法

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

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

  • 随机:请求被随机分配到各个应用服务器,在许多场合下,这种方案都很简单实用, 因为好的随机数本身就很均衡。如果应用服务器硬件配置不同,也可以很容易的使用 加权随机算法。

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

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

6.9应用服务器集群的 Session 管理

应用服务器的高可用架构设计主要基于服务无状态这一特性,但是事实上,业务总是有 状态的,在交易类的电子商务网站,需要有购物车记录用户的购买信息,用户每次购买 请求都是向购物车中增加商品;在社交类的网站中,需要记录用户的当前登录状态、最 新发布的消息等以便及时将这些信息通知给他的好友。Web 应用中将这些状态信息称作 会话(Session),单机情况下,Session 可交给 Web 容器管理,在使用负载均衡的集 群环境中,Session 管理主要有以下几种手段。

6.9.1Session 复制

session复制即在每个应用服务器之间都保存session,使用同步机制将不同服务器之间的session进行同步,现基本不考虑此种实现方式。

6.9.2Session 绑定

将用户终端的ip和应用服务器进行绑定,实现当用户访问时,仅能访问某个已绑定的应用服务器,此方案当用户ip变更时,登录session会失效

6.9.3利用 Cookie 记录 Session

利用客户端cookie来保存用户状态,达到与session相同的效果。本方案也存在缺点:cookie存储数据有限,且在某些环境下不支持cookie时此方案无效;但大多数环境可以使用,在此种方案中需要考虑无法使用cookie时的补偿方案

6.9.4Session 服务器

利用单一session服务器来存储用户session



发布于: 2020 年 10 月 25 日 阅读数: 9
用户头像

四夕晖

关注

还未添加个人签名 2018.01.16 加入

还未添加个人简介

评论

发布
暂无评论
学习笔记:架构师训练营-第五周