美文网首页找个工作
大并发服务器架构介绍

大并发服务器架构介绍

作者: 吃掉夏天的怪物 | 来源:发表于2021-04-11 13:55 被阅读0次

    B站教程的笔记
    https://www.bilibili.com/video/BV1Zt411K7Gg?p=1

    • 基础
      《Linux系统编程》
      《Linux网络编程》
      《跟我一起学C++》
    • 服务器设计目标
      高性能 (对于大量的并发请求能够及时快速的做出响应
      高可用 (不间断服务、故障转移)
      伸缩性 (TCP能跨机器的通信)
    • 分布式
      负载均衡
      分布式存储
      分布式计算

    任何网络系统都可以抽象为C/S结构

    一个典型的服务器结构

    一个典型的服务器结构.png
    网络I/O + 服务器高性能编程 + 数据库

    网络I/O epoll
    数据库往往是瓶颈发生的地方

    • 超出数据库连接数
      数据库并发连接数10个,应用服务器这边有1000个并发请求,将会有990个请求失败
    • 超出时间限制
      数据库并发连接数10个,数据库1秒钟之内最多能处理1000个请求,应用服务器这边有10000个并发请求,会出现0-10秒的等待。

    1. 超出连接数

    如果前端有大量的请求过来都需要访问数据库,数据库连接资源有限,就可能导致请求失败,这时候可以增加一个中间层(数据访问层DAL),让这些请求过来时排队。
    DAL既可以跟APP部署在同一台机器上面,也可以作为一台单独的机器来部署。


    DAL层.png

    DAL 队列服务 + 连接池 DAL与数据库连接可以生成一些连接放到连接池,下一次请求的时候就不需要重新创建与数据库连接,只需要从连接池中取出一个连接进行处理,这样就可以提高响应速度。

    2. 超出时限

    减轻数据库压力

    • 将业务逻辑挪到应用服务器这边,数据库上仅做一些辅助处理(仅可能简单)。因为数据库上进行计算会占用CPU。
    • 缓存,下次请求就直接从缓存里取降低数据库的压力

    使用缓存会出现问题:
    缓存的更新(缓存同步) 缓存time out

    1. 如果缓存失效,重新去数据库里面查询,再更新缓存,使得缓存与数据库中的数据同步。这种方法实时性比较差。

    2. 一旦数据库中数据更新,立即通知前端的缓存更新,实时性比较高。

    某个业务请求,要改写数据库中的数据,缓冲更新。这里的缓存将查询到的数据存至缓存,将热点数据存至缓存。
    如果要改变数据库中的数据,可能直接对数据库进行update操作,DAL再让cache相应数据进行更新。

    如果缓存了很大的数据,就可能内存不足。就可能将缓存中不活跃的数据换出内存缓存换页。 换出的算法:FIFO、LRU(最近最少使用)、LFU(最近最不频繁使用)。
    实际上缓存的同步,缓存的换页都有开源的产品,比如一些流行的nosql都具有这些功能
    nosql,存放非关系数据,一致性要求不那么高。可以把nosql当作缓存来使用
    比如redis、memcached都可以当分布式缓存来用。

    cache既可以和App(应用服务器)部署在同一台机器上面,也可以部署在不同。 如果部署在同一台机器上面,这个缓存就不是全局的缓存只是局部的缓存。
    如果分布式缓存(缓存是全局的各个应用服务器都可以访问):


    分布式缓存.png

    如果APP足够多,要处理大量的并发。数据库仍然可能会有瓶颈。

    比如,对数据库的写操作把数据库就锁住了,使得其它读请求也被阻塞了。
    可以将数据库读写分离(一般读操作数量>写操作),主从模式

    数据库进行负载均衡,现在主流的数据 库都有replication机制

    负载均衡+读写分离.png

    如果数据容量太大
    数据分区:对数据库进行分库分表

    • 分库: 数据库可以按照一定的逻辑,把表分散到不同的数据库。(垂直分区)

    用户表、业务表、基础相关的表,分为三个这样的主从库。从而每个数据库的容量减小,并发能力增大。
    缺点:DAL层会受到影响

    • 水平分区

    水平分区:每个数据库都有这些表,只不过将表里的数据进行切分
    DAL需要到哪个数据库去找数据也需要一定算法
    很容易横向扩展数据库

    应用服务器的负载均衡
    一个应用服务器可能有多种业务,可以将业务进行分割

    添加一个任务服务器,实现负载均衡


    任务服务器

    ①应用服务器被动接收任务
    任务服务器能够监视,应用服务器的状态(负载,CPU高、IO高、并发高、内存换页高)。实现应用服务器的时候最好暴露一个接口如HTTP。
    查询到这些信息后,选取负载最低(可能有一些算法来确定负载最低)的服务器
    分配任务。

    ②应用服务器主动去任务服务器接收任务进行处理
    好处:一个服务器处理完任务后,说明自己是空闲的。然后取任务。这样其实是最科学的。(任务可能有一些特征,任务服务器分配任务不一定公平)
    缺点:如果应用服务器只能处理某些应用,就会增加任务 服务器的复杂度。如果所有应用服务器都处理相同任务,就应该让应用服务器主动去领任务。

    任务服务器应该能够故障转移(任务服务器应该有两台甚至多台),两个服务器之间通过心跳连接。从而保证服务器的高可用(HA机制)。

    哪个层面出现瓶颈就在哪一个层次增加服务器。

    服务器的高性能编程:

    服务器性能的四大杀手:

    • 数据拷贝(服务器内部应该有缓存机制)
    • 环境切换理性创建线程针对线程切换,该不该用多线程,单线程好还是多线程好,单核服务器多线程未必能够提高性能,采用状态机编程反而效率最高。多核服务器,多线程能够充分发挥服务器的性能(但是也应该尽可能的避免线程之间的环境切换)。
    • 内存分配 内存池(减少对内存的分配,减少向操作系统申请内存)
    • 锁竞争 (有时候应该通过逻辑减低锁的使用,降低锁的竞争)

    单核服务器不能并行处理任务,大量任务提交到服务器。不能并行处理,又使用了多线程,就会增加线程之间的切换。
    状态机使用单线程切换状态

    相关文章

      网友评论

        本文标题:大并发服务器架构介绍

        本文链接:https://www.haomeiwen.com/subject/ngfgkltx.html