写点什么

架构师训练营第 1 期第 5 周学习总结

用户头像
du tiezheng
关注
发布于: 2020 年 10 月 25 日

一、缓存


优化系统读性能。

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

缓存与缓冲的区别:

缓冲是介于高速与低速设备之间的临时存储,缓冲不涉及多次读取。

缓存无处不在。

内存访问速度时 SSD 的 1000 倍,SSD 是磁盘访问速度 100 倍。

缓存的数据存储结构:哈希表 O(1)

数据 key->hashcode->哈希表索引

1.1 关键指标

缓存命中率


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

  1. 缓存键集合大小

缓存键空间是应用能够生成的所有键的数量。要想办法减少可能的缓存键数量。键数量越少,缓存的效率越高。

  1. 缓存可使用内存空间

缓存可使用内存空间直接决定了缓存对象的大小和数量。物理上能缓存的对象越多,缓存命中率就越高。

  1. 缓存对象生存时间

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


分类

1 通读缓存

客户端连接的是通读缓存而不是原始服务器。通读缓存给客户端返回缓存资源,并在请求未命中缓存时获取实际数据。

通读缓存包括:

代理缓存、反向代理缓存、CDN


2 旁路缓存

旁路缓存通常是一个独立存储。客户端先询问缓存需要的对象是否存在,如果存在,直接获取使用,如果不存在或已过期,客户端会连接主数据源获取对象,并将其保存回缓存以便将来使用。

旁路缓存包括:

浏览器缓存、本地缓存、远程分布式缓存


1.2 一致性哈希

作业

1.3 缓存的优势

缓存部署的越接近客户端,对系统的资源节省效果越明显。


缓存如何提高性能:

1.内存访问速度高于磁盘。

2.缓存保存最终结果,不需要中间计算和 CPU 消耗。

3.缓存降低数据库、磁盘、网络压力,使这些 I 设备有好的响应特性。


缓存是系统性能提升的大杀器:

技术简单、性能提升显著、应用场景多


1.4 合理使用缓存

1 频繁修改的数据

频繁修改导致应用还来不及读取就已失效。数据的读写比在 2:1 以上,缓存才有意义。


2 非热点数据

内存有限,不能将所有数据都缓存。如果数据没有热点,大部分还没有被再次访问就已经被挤出缓存了(LRU),那么缓存就没有意义。缓存热点数据应遵循二八定律。


3 脏读

一般会对缓存数据设置失效时间。应用要容忍一定时间的数据不一致。数据更新时,立即更新缓存会带来更多系统开销和事务一致性的问题。更新时简单通知缓存失效,是一种更稳妥的做法。


4 缓存雪崩

随着业务的发展,缓存会承担大部分的数据访问压力,当缓存服务崩溃时,数据库会因为完全不能承受剧大的访问压力而宕机,进而导致整个系统不可用。


5 缓存预热

缓存中存放的热点数据,是缓存系统利用 LRU 算法不断筛选淘汰出来的,过程较长,在这段时间,系统的性能和数据库负载都不好,那么最好在缓存系统启动的时候就把热点数据加载好。一些元数据,可以启动时加载数据库中全部数据到缓存进行预热。


6 缓存穿透

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


1.5 分布式缓存产品

Redis 的优势:

支持复杂的数据结构。

支持多路复用异步 I/ 高性能。

支持主从复制高可用。

支持原生集群与 share nothing 集群模式


Redis 集群的实现:

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

Redis-cluster 把所有的物理节点映射到[0-16383]slot 上(类似与一致性哈希),cluster 负责维护 slot 与服务器的映射关系。

所有的 Redis 节点彼此互联。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。


二、消息队列

优化系统写性能

2.1 同步调用 VS 异步调用

同步调用:调用线程阻塞等待调用结果返回,再通知调用端。

异步调用:调用线程将请求消息发到消息队列,就返回通知调用端。后续收到调用响应,由其他线程执行当前调用模块的回调函数。

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

架构角色:生产者、消息队列、消费者

消息的生产者、消费者都是异步执行的,他们通过消息队列解耦、解阻塞。


消费模型

1 点对点模型

有多个消息的生产者和消费者,但每条消息只会被消费一次。

2 发布订阅模型

生产者发布一个消息,该消息可以通过主题被多个消费者订阅,每条消息可以被多个订阅消费者同时消费。


2.3 消息队列的好处

1 实现异步处理,提升性能。

主要是写性能。


2 更好的伸缩性。

调用方、被调用方解耦后,消费者可按需对算力、存储空间有针对性伸缩。


3 削峰填谷。

避免消费者被流量压垮,也避免按业务高峰部署系统造成资源浪费。


4 失败隔离与自我修复。

生产者不直接依赖消费者,可对消费者灵活的执行运维发布操作。


5 解耦。

隔离和简化开发流程。

2.4 事件驱动架构 EDA

基于发布订阅模型。

系统更加解耦。


个人理解 EDA 更适合低实时需求的系统。而电信系统通常使用点对点消息模型。

2.5 MQ 产品

RabbitMQ

ActiveMQ

RcketMQ

Kafka


产品选型时,尽量选社区活跃,资料多,出问题容易查到解决方案的产品。

一个简单比较的方式是:将产品关键字在搜索引擎中的搜索结果数做排序。


三、负载均衡

3.1 分类


1 HTTP 重定向负载均衡

实现方法简单。多一次网络请求,效率比较低。应用服务器对外暴露 IP,安全性差。现实中应用的不多。


2 DNS 负载均衡

域名服务商提供 DNS,配置简单。此方案在现实中大型互联网应用比较多,虽然对外暴露了 IP,但大型互联网往往有两级负载均衡,暴露的只是内部某一个负载均衡服务器的 IP。


3 反向代理负载均衡

配置简单,在小规模系统上应用较广。所有流量都通过反向代理服务器做应用层协议转换,效率较低,只能承担小规模集群负载均衡。


4 IP 负载均衡

只进行 IP 层的包转发(NAT),性能更高,可处理更大规模的集群。响应数据包通常比较大,所有响应流量都通过负载均衡服务器,给服务器网卡带宽带来压力。


5 数据链路层负载均衡

负载均衡服务器跟所有应用服务器使用相同 IP 地址,负载均衡服务器修改目的 Mac 地址的包转发,应用服务器直接将响应返回给客户端,大大降低了负载均衡服务器的反向带宽压力。


3.2 算法

轮询

加权轮询

随机

最少连接

源地址散列 实现会话粘滞

3.3 Session 管理

1 Session 复制

服务期间复制 session 比较消耗资源,很难提升性能和大规模伸缩,实际中很少使用


2 Session 绑定

基于源地址散列,由于没考虑服务器高可用问题导致 session 失效,实际中很少使用。


3 利用 Cookie 记录 Session

实现比较简单,不依赖于后台服务器。Cookie 大小有限,不适合记录比较大的 session。有些浏览器会禁用 cookie。在实践中较常用。


4 Session 服务器

应用服务器之间 share nothing,无状态伸缩,是最高效的分布式实现方式。


四、后续扩展学习

1 缓存的几种读方式:cache through, cache aside

2 缓存使用的坑:热点、预热、雪崩、穿透、脏读

3 Redis 集群配置和使用(go java 相关 api 中间件),相关配置参数,性能

4 Redis 作为数据库 cache 的最佳实践,用什么结构、如何跟 db 同步数据

5 Redis 作为 nosql,其数据结构在各种业务场景的最佳实践

6 缓存、Redis 在数据结构上的实现:LRU、Zset 跳表、一致性哈希算法

7 多线程编程模型:同步/异步 阻塞/非阻塞。结合项目。

8 了解一个 EDA 架构(微服务中的 SATA?)

9 RabbitMQ、kafka 的配置、集群和使用(go java 相关 api 中间件),相关配置参数,性能

10 反向代理服务器的内部功能,与负载均衡服务器,API Gateway 的区别。


用户头像

du tiezheng

关注

还未添加个人签名 2018.08.16 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第 1 期第 5 周学习总结