架构师训练营 第五周 学习心得

用户头像
李君
关注
发布于: 2020 年 07 月 08 日
架构师训练营 第五周 学习心得

1. 分布式缓存架构

1.1 缓存

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

1.1.1 作用

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

1.1.2 原理

  • 缓存的本质就Hash表,通过对缓存键进行hashcode后进行取模后,快速的读取内存地址中的数据。

1.2 缓存的关键指标

命中率

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



  • 缓存键集合大小

尽可能的减少缓存键的数量。键的数量越少缓存的效率越高。



  • 缓存可使用内存空间的大小

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



  • 缓存对象的生存时间

对象缓存的时间越长,缓存对象被重用的可能性就越高。

1.3 几种缓存的类型

1.3.2 通读缓存

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

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

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



代理缓存

  • 由一个代理服务器下载的页面存储。 一个代理服务器为多个用户提供一条通道。缓冲的代理允许一个代理服务器减少对同一个网站的同样页面的请求次数。一旦代理服务器的一个用户请求了某页,代理服务器就保存该页以服务于它的其他用户的同样请求。



反向代理缓存

  • 客户端向一个服务器A提交请求后,服务器A偷偷地去服务器B上获取资源,并返回给客户端。客户端天真地以为数据是服务器A给他的。在这过程中,服务器A称为“反向代理服务器”,服务器B称为反向代理服务器的“后端服务器”。



内容分发网络(CDN)

  • CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率

1.3.3 旁路缓存

  • 对象缓存是一种旁路缓存,旁路缓存通常是一个独立的键值对存储。

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



浏览器缓存

  • 浏览器缓存(Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就可以从本地磁盘显示文档,这样就可以加速页面的阅览。



本地对象缓存

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

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

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



远程分布式对象缓存

  • 在网络中由多台服务器组成的集群为其他应用提供统一的缓存的服务。

  • 高可用,可伸缩,高性能。



1.4 缓存提升性能的几个特点

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

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

  • 缓存可以降低磁盘,网络的负载压力,是这些I/O设备可以获得更好的响应特性。



1.5 使用缓存几个常见问题

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

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

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

  • 缓存雪崩: 缓存是为了提高数据的读取性能的,当缓存突然失效时会导致数据库不能承受巨大的压力而宕机,从而使整个系统不能提供服务。这种情况被称为缓存雪崩。

  • 缓存预热: 缓存中是存放热点数据的,热点数据有事缓存利用LRU(最近最久未用)算法对不断访问的数据筛选出来的。因为这个过程会比较花时间,从而这段时间的系统的性能和负载都会不太好。所以最好在缓存系统启动的时候就把热点数据加载进去,这个过程就叫缓存预热。

  • 缓存穿透: 如果因为不恰当的业务或者恶意攻击持续高并发的请求某个不存在的数据,应为没有缓存保护这个数据,从而导致数据库的访问量增加导致系统崩溃。一个简单的策略就是缓存这个不存在的值,设置一个较短的失效时间。

1.6 Redis VS Memcached

1.6.1 Memcached

一个免费开源的、高性能的、具有分布式内存对象的缓存系统



特点

  • 数据仅存在于内存中,宕机或重启数据将全部失效。

  • 内容数据达到启动时设定内存指定值后、基于LRU算法删除缓存,LAZY模式、可指定最大内存用量。

  • 实际瓶颈在于网络连接、占应较少的CPU资源。

  • 服务器端无分布式功能、取决于客户端的实现、可布署多台服务器,访问时做个均衡策略如根据IP分配连接负载。

  • 存储的节点数据键名250字节、键值限制在1MB、只适合普通字符串、作为小规模的数据分布式平台是十分有效果。

  • 32位机器单进程使用最大内存2G、可分多个端口开启多进程支持、64位机器可认为无上限。

1.6.2 Redis

Redis是一个开源,内存数据结构存储,用作数据库,缓存和消息代理。



特点

  • 内存数据库,速度快,也支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。

  • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。

  • Redis支持数据的备份,即master-slave模式的数据备份。

  • 支持事务。

1.6.3 对比



性能(网络IO模型)

Memcached是多线程,非阻塞IO复用的网络模型。Memcache可以利用多核优势,单实例吞吐量极高,可以达到几十万QPS,适用于最大程度扛量。

Redis使用单线程的IO复用模型。由于Redis只使用单核,而Memcached可以使用多核,所以在比较上,平均每一个核上Redis在存储小数据时比Memcached性能更高。而在100k以上的数据中,Memcached性能要高于Redis,虽然Redis最近也在存储大数据的性能上进行优化,但是比起Memcached,还是稍有逊色。



内存使用

Memcached使用预分配的内存池的方式,使用slab和大小不同的chunk来管理内存,Item根据大小选择合适的chunk存储,内存池的方式可以省去申请/释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除。

Redis使用现场申请内存的方式来存储数据,并且很少使用free-list等方式来优化内存分配,会在一定程度上存在内存碎片,Redis跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致swap也不会剔除任何非临时数据(但会尝试剔除部分临时数据),这点上Redis更适合作为存储而不是cache。



数据一致性

Memcached提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。CAS(Check and Set)是一个确保并发一致性的机制,属于“乐观锁”范畴;原理很简单:拿版本号,操作,对比版本号,如果一致就操作,不一致就放弃任何操作。

redis使用的是单线程模型,提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断,保证了数据按顺序提交。



可靠性

memecache 把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。

redis有部份存在硬盘上,这样能保证数据的持久性,支持数据的持久化。



分布式存储

redis支持master-slave复制模式

memcache可以使用一致性hash做分布式



数据支持类型

Memcached基本只支持简单的key-value存储,不过memcache还可用于缓存其他东西,例如图片、视频等等。

Redis除key/value之外,还支持list,set,sorted set,hash等众多数据结构。也可以在服务器端直接对数据进行丰富的操作,这样可以减少网络IO次数和数据体积。

2. 消息队列和异步架构

消息队列是一种异步的服务间通信方式,是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构

2.1 同步调用 VS 异步调用

  • 同步调用:提交完任务后,就在原地等待任务执行完毕,拿到运行结果/返回值后再执行下一步,同步调用下任务是串行执行。

  • 异步调用:提交完任务后,不会再原地等待任务执行完毕,直接执行下一行代码,异步调用时并发执行。

2.2 消息队列异步调用架构

2.2.1 点对点模型

  • 消费者和生产者只需要知道消息队列的名字,生产者发送消息到消息队列中,而消息队列的另一端是多个消费者竞争消费消息,每个到达消息队列的消息只会被路由到一个消费者中去,所以消费者看到的是全部消息的一个子集。我们看这张图,消息的生产者有多个,消息的消费者也有多个,多个生产者将消息发送到消息队列中,而有多个消费者去消息队列中对消息进行竞争性的消费。每个消息只会被一个消费者消费,每个消费者只会消费消息队列中的一部分消息。

2.2.2 发布订阅模型

  • 在发布订阅模型中,消息可能被发送到不止一个消费者,生产者发送消息到一个主题,而不是队列中。消息被发布到主题后,就会被克隆给每一个订阅它的消费者,每个消费者接收一份消息复制到自己的私有队列。消费者可以独立于其他消费者使用自己订阅的消息,消费者之间不会竞争消息。常用的分布式消息队列都支持发布订阅模型,也就是说消息的发布订阅模型是分布式消息队列的一个功能特性。

2.3 消息队列的作用

2.3.1 提升处理性能

  • 对一些比较耗时的操作,可以把处理过程通过消息队列进行异步处理。这样做可以推迟耗时操作的处理,使耗时操作异步化,而不必阻塞客户端的程序,客户端的程序在得到处理结果之前就可以继续执行,从而提高客户端程序的处理性能。

2.3.2 更好的伸缩性

  • 耗时的任务可以通过分布式消息队列,向多台消费者服务器并行发送消息,然后在很多台消费者服务器上并行处理消息,也就是说可以在多台物理服务器上运行消费者。那么当负载上升的时候,可以很容易地添加更多的机器成为消费者。

2.3.3 削峰填谷

  • 在访问高峰,用户的并发访问数可能超过了系统的处理能力,所以在高峰期就可能会导致系统负载过大,响应速度变慢,更严重的可能会导致系统崩溃。这种情况下,通过消息队列将用户请求的消息纳入到消息队列中,通过消息队列缓冲消费者处理消息的速度。消息的生产者它有高峰有低谷,但是到了消费者这里,只会按照自己的最佳处理能力去消费消息。高峰期它会把消息缓冲在消息队列中,而在低谷期它也还是使用自己最大的处理能力去获取消息,将前面缓冲起来、来不及及时处理的消息处理掉。那么,通过这种手段可以实现系统负载消峰填谷,也就是说将访问的高峰消掉,而将访问的低谷填平,使系统处在一个最佳的处理状态之下,不会对系统的负载产生太大的冲击。

2.3.4 失败隔离和自我修复

  • 因为发布者不直接依赖消费者,所以分布式消息队列可以将消费者系统产生的错误异常与生产者系统隔离开来,生产者不受消费者失败的影响。 当在消息消费过程中出现处理逻辑失败的时候,这个错误只会影响到消费者自身,而不会传递给消息的生产者,也就是应用程序可以按照原来的处理逻辑继续执行。

  • 所以,这也就意味着在任何时候都可以对后端的服务器执行维护和发布操作。可以重启、添加或删除服务器,而不影响生产者的可用性,这样简化了部署和服务器管理的难度。



2.3.5 解耦

  • 也就是说可以多个生产者发布消息,多个消费者处理消息,共同完成完整的业务处理逻辑,但是它们的不需要直接的交互调用,没有代码的依赖耦合。在传统的同步调用中,调用者代码必须要依赖被调用者的代码,也就是生产者代码必须要依赖消费者的处理逻辑代码,代码需要直接的耦合,而使用消息队列,这两部分的代码不需要进行任何的耦合。耦合程度越低的代码越容易维护,也越容易进行扩展。

3. 负载均衡架构

3.1 几种负载均衡的方式

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。

3.1.1 HTTP重定向

  • HTTP重定向服务器是一台普通的应用服务器,其唯一个功能就是根据用户的HTTP请求计算出一台真实的服务器地址,并将该服务器地址写入HTTP重定向响应中(重定向响应状态码为302)返回给用户浏览器。用户浏览器在获取到响应之后,根据返回的信息,重新发送一个请求到真实的服务器上。

缺点 

浏览器需要两次请求服务器才能完成一次访问,性能较差;同时,重定向服务器本身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限。

3.1.2 DNS负载均衡

  • DNS服务器每次域名解析请求都会根据对应的负载均衡算法计算出一个不同的IP地址并返回,这样A记录中配置多个服务器就可以构成一个集群,并可以实现负载均衡。

优点

  • 将负载均衡的工作交给DNS,省去了网站管理维护负载均衡服务器的麻烦。

  • 技术实现比较灵活、方便,简单易行,成本低,使用于大多数TCP/IP应用。

  • 对于部署在服务器上的应用来说不需要进行任何的代码修改即可实现不同机器上的应用访问。

  • 服务器可以位于互联网的任意位置。

  • 同时许多DNS还支持基于地理位置的域名解析,即会将域名解析成距离用户地理最近的一个服务器地址,这样就可以加速用户访问,改善性能。

缺点

  • 目前的DNS是多级解析的,每一级DNS都可能缓存A记录,当某台服务器下线之后,即使修改了A记录,要使其生效也需要较长的时间,这段时间,DNS任然会将域名解析到已下线的服务器上,最终导致用户访问失败。

  • 不能够按服务器的处理能力来分配负载。DNS负载均衡采用的是简单的轮询算法,不能区分服务器之间的差异,不能反映服务器当前运行状态,所以其的负载均衡效果并不是太好。

  • 可能会造成额外的网络问题。为了使本DNS服务器和其他DNS服务器及时交互,保证DNS数据及时更新,使地址能随机分配,一般都要将DNS的刷新时间设置的较小,但太小将会使DNS流量大增造成额外的网络问题。

3.1.3 反向代理负载均衡

定义

  • 使用代理服务器可以将请求转发给内部的Web服务器,使用这种加速模式显然可以提升静态网页的访问速度。因此也可以考虑使用这种技术,让代理服务器将请求 均匀转发给多台内部Web服务器之一上,从而达到负载均衡的目的。

缺点

  • 因此对于连接请求数量非常大的时候,代理服务器的负载也就非常之大了,在最后反向代理服务器会成为服务的瓶颈。

3.1.4 IP负载均衡

定义

  • 它工作在传输层,它可以修改发送来的IP数据包,将数据包的目标地址修改为实际服务器地址。

缺点

  • 负载均衡的网络带宽会成为瓶颈。

3.1.5 数据链路负载均衡

定义

  • 它是工作在数据链路层(第二层),通过修改数据包的目标MAC地址(没有修改目标IP),将数据包转发到实际服务器上,不同的是,实际服务器的响应数据包将直接发送给客户羰,而不经过调度器。

优点

  • 这种方式适合搭建可扩展的负载均衡系统,不论是Web服务器还是文件服务器,以及视频服务器,它都拥有出色的性能。

3.2 负载均衡几种算法

3.2.1 轮询

  • 将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。

3.2.2 随机

  • 通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。

3.2.3 加权

  • 给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,并将请求顺序且按照权重分配到后端。

3.2.4 最小连接数法

  • 最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。

3.2.5 源地址哈希法

  • 源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

3.3 Session管理的几种方式

1. Session复制

Session复制是早期企业应用系统使用比较多的一种服务器集群Session管理机制。应用服务器开启Web容器的的Session复制功能,在集群中的几台服务器之间同步Session对象,是的每台服务器上都保存所有用户的Session信息,这样任何一台机器宕机都不会导致Session数据的丢失,而服务器使用Session时候,也只需要在本机获取即可。



缺点

  • 只能使用在集群规模比较小的情况下(企业应用系统,使用人数少,相对比较常见这种模式),当集群规模比较大的时候,集群服务器之间需要大量的通信进行Session的复制,占用服务器和网络的大量资源,系统负担较大。而且由于用户的session信息在每台服务器上都有备份,在大量用户访问下,可能会出现服务器内存都还不够session使用的情况。

2. Session绑定

会话保持是利用负载均衡的原地址Hash算法实现,负载均衡服务器总是将来源于同一IP的请求分发到同一台服务器上,,也可以根据cookie信息将同一个用户的请求每次都分发到同一台服务器上,不过这时的负载均衡服务器必须工作在HTTP协议层上。这种会话保持也叫黏滞会话



缺点

  • 一旦某台服务器发生宕机,则该服务器上的所有session信息就会不存在,用户请求就会切换到其他服务器,而其他服务器因为没有其对应的session信息导致无法完成相关业务。所以这种方法基本上不会被采纳。

3. 利用Cookie记录Session

就是将session记录在客户端,每次请求服务器的时候将session放在请求中发送给服务器,服务器处理过请求后再将修改过的session返回给客户端。网站虽然没有客户端,但是可以利用浏览器支持的cookie记录session。



缺点

  • 比如cookie的大小存在限制能记录的信息不能超过限制;比如每次请求都要传输cookie影响性能;比如cookie可被修改或者存在破解的可能,导致cookie不能存重要信息,安全系数不够。但是由于cookie简单易用,支持服务器的线性伸缩,而且大部分的session信息相对较小,所以其实很多网站或多或少的都会使用cookie来记录部分不重要的session信息。

4. Session共享服务器



目前最理想的服务器集群的session管理应该是session服务器,集成了高可用、伸缩性好、对保存信息大小没有限制、性能也相对很好。这种统一管理session的方式将应用服务器分离,分为无状态的应用服务器和有状态的session服务器。

4. 分布式数据库

4.1 MySql 复制

4.1.1 概述



简单来说就是保证主服务器(Master)和从服务器(Slave)的数据是一致性的,向Master插入数据后,Slave会自动从Master把修改的数据同步过来(有一定的延迟),通过这种方式来保证数据的一致性,就是Mysql复制。

4.1.2 解决什么问题

  • 高可用

  • 负载分摊

  • 数据备份

  • 业务模块化

4.1.3 如何工作

  • Master将数据改变记录到二进制日志(binary log)中,也就是配置文件log-bin指定的文件,这些记录叫做二进制日志事件(binary log events)。

  • Slave通过I/O线程读取Master中的binary log events并写入到它的中继日志(relay log)。

  • Slave重做中继日志中的事件,把中继日志中的事件信息一条一条的在本地执行一次,完成数据在本地的存储,从而实现将改变反映到它自己的数据(数据重放)。

4.1.4 几种复制的方式

  • 主从复制

  • 主多从复制

  • 主主复制

4. 注意事项

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

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

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



发布于: 2020 年 07 月 08 日 阅读数: 31
用户头像

李君

关注

结硬寨,打呆仗。 2018.09.11 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营 第五周 学习心得