tomoya06 / web-developer-guidance

Actually it's just a notebook for keeping down some working experience.
4 stars 0 forks source link

Backend - 工程化 #22

Open tomoya06 opened 3 years ago

tomoya06 commented 3 years ago

负载均衡

定义:负载平衡(Load balancing)是一种计算机技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载。主要作用是将大量作业合理地分摊到多个操作单元上进行执行,用于解决互联网架构中的高并发和高可用的问题。

杂技

四层负载均衡vs七层负载均衡

参考知乎博客

四层负载均衡具体实现方式为:通过报文中的IP地址和端口,再加上负载均衡设备所采用的负载均衡算法(参考nginx可用的负载均衡算法,有随机、最少连接数、哈希、一致性哈希等),最终确定选择后端哪台下游服务器。以TCP为例,客户端向负载均衡发送SYN请求建立第一次连接,通过配置的负载均衡算法选择一台后端服务器,并且将报文中的IP地址信息修改为后台服务器的IP地址信息,因此TCP三次握手连接是与后端服务器直接建立起来的。

七层服务均衡在应用层选择服务器,只能先与负载均衡设备进行TCP连接,然后负载均衡设备再与后端服务器建立另外一条TCP连接通道。因此,七层设备在网络性能损耗会更多一些。

比较:四层负载均衡很容易将垃圾流量转发至后台服务器,而七层设备则可以过滤这些恶意并清洗这些流量,但要求设备本身具备很强的抗DDOS流量的能力。

如何确定实际处理的机器?

简述思路:在response header中添加标记值即可,例如读取系统host参数注入到header中,当然请求方和服务方也要在日志中记录对应标记值。

tomoya06 commented 3 years ago

消息队列

定义:消息队列(英语:Message queue)是一种进程间通信或同一进程的不同线程间的通信方式。本身是异步的,它允许接收者在消息发送很长时间后再取回消息。

使用场景

参考CS-Notes 消息队列

  1. 异步处理
  2. 流量削峰
  3. 应用解耦

可靠性

发送端完成操作后一定能将消息成功发送到消息队列中;接收端能够从消息队列成功消费一次消息。

实际应用

kafka消息队列

image

基本概念:

  1. broker:kafka集群的一台或多台服务器
  2. topic:消息类别
  3. producer:消息生产者,往kafka发消息
  4. consumer:消费者,往kafka拉取消息
  5. partition:topic物理上的分组,每个partition是一个有序的队列,partition中的每条消息会分配一个id aka. offset
tomoya06 commented 3 years ago

缓存

本节继续参考CS-Notes 缓存 这里的缓存更多指的是接口缓存,面向数据库请求;前端的http缓存面向文件传输,有些微妙の不同。

缓存特征

  1. 命中率:当某个请求能够通过访问缓存而得到响应时,称为缓存命中。缓存命中率越高,缓存的利用率也就越高。
  2. 最大空间:缓存通常位于内存中,因此缓存的最大空间不可能非常大。当缓存存放的数据量超过最大空间时,就需要淘汰部分数据来存放新到达的数据。淘汰策略参考操作系统-内存管理-页面置换算法,主要有FIFO/LRU/LFU等

缓存位置

以浏览器网页请求为例,请求文件或数据有可能缓存的位置包括:

  1. 浏览器:通过http请求cache-control控制,部分数据可缓存在浏览器
  2. ISP、反向代理服务器、CDN
  3. 分布式缓存:如Redis、Memcache
  4. 数据库缓存:如MySQL有自己的查询缓存机制来提高查询效率

缓存问题

缓存穿透

解决方案:

  1. 缓存空值。但如果对大量空数据请求都缓存的话反而增加了存储压力
  2. 过滤不存在的请求,例如使用布隆过滤器

缓存击穿

解决方案:

  1. 在数据库上,对热门数据加互斥锁,第一个拿到锁的请求读完数据之后,写好新的缓存,其他请求可以继续读缓存

缓存雪崩

解决方案:

  1. 调整缓存过期时间
  2. 分布式缓存,每个节点只缓存部分数据
  3. 限流,控制能同时打到数据库的请求数量,剩余请求被限流等待

缓存一致性

解决方法:

  1. 数据更新时立刻更新或删除缓存
  2. 原始数据和缓存数据都加版本号

缓存无底洞现象

解决方法:

  1. 优化批量数据操作命令;
  2. 减少网络通信次数;
  3. 降低接入成本,使用长连接 / 连接池,NIO 等。
tomoya06 commented 3 years ago

MySQL优化

索引优化

MySQL索引

索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现。

B+树索引

InnoDB引擎的索引实现方式。下图是B+的存储结构

image

InnoDB 的索引分为主索引和辅助索引。主索引的叶子节点 data 域记录着完整的数据记录,这种索引方式被称为聚簇索引。因为无法把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。辅助索引的叶子节点的 data 域记录着主键的值,因此在使用辅助索引进行查找时,需要先查找到主键值,然后再到主索引中进行查找。

其他索引

此外还有哈希索引、全文索引、空间数据索引等。详见CS-Notes MySQL索引

优化策略

更多优化策略参考小册。关键原理在于利用B+树索引的特性,查询条件优先选择索引中靠左的列

  1. 独立的列:在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引
  2. 多列索引:在需要使用多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好
  3. 索引列的顺序:让选择性最强的索引列放在前面。选择性是指不重复的索引值和记录总数的比值
  4. 前缀索引:对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符
  5. 覆盖索引:索引包含所有需要查询的字段的值,可以不用再去查聚簇索引(InnoDB)

数据访问优化

优化策略

  1. 只返回必要的列:避免select *
  2. 只返回必要的行:使用LIMIT OFFSET分页
  3. 缓存重复查询的数据
  4. 使用索引来覆盖查询

切分

水平切分

aka. Sharding。它是将同一个表中的记录拆分到多个结构相同的表中。当一个表的数据不断增多时,Sharding 是必然的选择,它可以将数据分布到集群的不同节点上,从而缓存单个数据库的压力。

image

切分策略

  1. 哈希取模:hash(key) % N
  2. 范围:可以是 ID 范围也可以是时间范围;
  3. 映射表:使用单独的一个数据库来存储映射关系。

存在问题及解决方法

  1. 事务问题:可以使用分布式事务来解决
  2. 连接:分解成多个单表查询,然后在用户程序中进行连接
  3. ID唯一性:全局唯一ID(UUID);分片指定ID范围等

垂直切分

垂直切分是将一张表按列切分成多个表,通常是按照列的关系密集程度进行切分,也可以利用垂直切分将经常被使用的列和不经常被使用的列切分到不同的表中。

image

复制

主从复制

主要涉及三个线程:binlog 线程、I/O 线程和 SQL 线程。

image

读写分离

问题分析

读多写少。主服务器处理写操作以及实时性要求比较高的读操作,而从服务器处理读操作,多台从服务器可以分担读取压力。

提升性能原因

读写分离常用代理方式来实现,代理服务器接收应用层传来的读写请求,然后决定转发到哪个服务器。

tomoya06 commented 3 years ago

接口性能

接口性能指标

QPS,每秒查询

QPS:Queries Per Second意思是“每秒查询率”,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。

TPS,每秒事务

TPS:是Transactions Per Second的缩写,也就是事务数/秒。它是软件测试结果的测量单位。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数。

QPS vs TPS:QPS基本类似于TPS,但是不同的是,对于一个页面的一次访问,形成一个TPS;但一次页面请求,可能产生多次对服务器的请求,服务器对这些请求,就可计入“QPS”之中。如,访问一个页面会请求服务器2次,一次访问,产生一个“T”,产生2个“Q”。

RT,响应时间

响应时间:执行一个请求从开始到最后收到响应数据所花费的总体时间,即从客户端发起请求到收到服务器响应结果的时间。

并发数

并发数是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。

一般地,存在如下关系:并发数 = QPS * 平均响应时间

吞吐量

系统的吞吐量(承压能力)与request对CPU的消耗、外部接口、IO等等紧密关联。单个request 对CPU消耗越高,外部系统接口、IO速度越慢,系统吞吐能力越低,反之越高。

TP指标

TP,即Top percentile,前百分位数。

百分位数,统计学术语,如果将一组数据从小到大排序,并计算相应的累计百分位,则某一百分位所对应数据的值就称为这一百分位的百分位数,以Pk表示第k百分位数。

以TP90为例,表示收集一个时间段内的多个请求时间,按从小到大排序,其中第90%位即为TP90。类似地,还可以用TP99、TP999等作为性能指标。

其他指标

参考博客-接口性能指标