高性能系统架构要点(一)

高性能系统的设计,要解决的问题可以归结到3个方面:

  • 计算
  • 存储
  • 网络

存储和网络,本质上都是IO问题,也可以简化合并为一类。

所有系统都可以抽象为一个函数:输入+计算=输出,也就是计算+IO。

1. 计算

计算要解决的问题包括:

  • 计算效率
  • 计算规模

用最短的时间最小的计算完成对于一个问题的处理,就是计算效率

例如:一项计算能用加法或乘法,那是加法还是乘法?一条指令能完成的事情,就不要用两条。耗时的计算要避免重复。

计算规模要考虑的则是怎样将大量的计算并行化,这样就能通过增加硬件来解决问题。

例如:天气预报的计算,要通过算法设计尽量将其大规模的计算过程,拆成能够并行化的多个子计算过程,类似map-reduce。高并发的请求,要尽量避免资源的排队使用,若无法避免,则通过拆锁、预分配等方式,拆成多个队列,增加队列的数量减少队列的长度,提高并行度。

所有的计算,最终都要落到CPU上执行上。那么如何衡量CPU的使用效率呢?

CPU Usage vs Load

CPU的使用效率,可以从两个方面衡量:Usage 和 Load。

  • Usage 衡量的是CPU忙碌的时间,也就是单位时间内,CPU在干活的时间占比。例如,复杂的数学计算,会很耗Usage。

  • Load 则是衡量CPU的负载压力,在一个时间点上,使用或排队等待CPU资源的进程/线程数量(OS调度的最小单位)。

例如:同样是Usage90%,A机器CPU的Load是0.1,B机器CPU的Load是10,说明B机器的CPU过载严重。

CPU的处理能力取决于两个方面:

  • 核数:决定了能够并行执行的任务的数量。
  • 速度:决定了每个核处理计算指令的速度,也就是每秒能处理指令的数量。

从系统架构层面考虑计算问题,需要掌握各阶段的计算效率、并行程度,从而判断出该系统是个什么样的系统,是计算密集型还是负载密集型,从而设计合理的部署方案,提高CPU的使用效率和系统的处理效率。同时,应该将具有不同计算特性的服务,部署在不同的物理机上,避免CPU处理效率的不稳定。

例如:用于大数据计算的服务,和用于提供rpc的服务,应该避免部署在一台机器上。计算密集型任务长时间占用CPU,会导致负载型任务等待CPU调度的时间出现波动,从而使得其响应时间出现波动甚至产生超时。

2. 存储

现今主要的存储介质包括:

  • CPU L1/L2 Cache
  • RAM 随机存取内存
  • solid state drives (SSDs) 固态硬盘
  • hard disk drives (HDDs) 硬盘

存储的访问,可以细分为寻址+数据传输,就像CPU一样,存储能否并行访问,取决于硬件的设计。

受芯片结构限制,无论是什么存储介质,都不可能无限数量的并行,就像CPU核数限制了能够并行执行的任务一样。所以,对存储的访问,最终都会出现顺序排队处理的情况。

对于内存和SSD,其支持随机存取,因此性能好,一般只需观测他们的使用率即可。为了提高他们的并行性能,可采用支持多插槽主板的方式,来接入多个设备。

对于硬盘,其内部是机械结构,读写数据时需要移动磁头进行寻址,这个过程比读取数据会更耗时,因此硬盘的随机存取性能较差。

对于小文件,存储在SSD上可以提升读写效率。硬盘更适合存取较大文件。

存储的使用效率,有两个关键指标:

  • IO处理速率:每秒处理的IO操作数量。
    • IOPS (Input/Output Operations Per Second, pronounced i-ops)
  • 数据传输速率:每秒读写的数据量大小。例如: 5mb/s

IOPS相关,有以下几个可观测的指标:

  • 负载情况:单位时间内系统提交的IO操作请求数量
  • 堆积情况:时间点上,排队等待处理的IO操作请求数量。同时衍生出队列长度、等待时间指标。
  • 处理性能:单位时间内处理完成的IO操作数量、数据量大小。

关于IOPS,Linux系统下,使用命令iostat -x可以获得以下几个指标:

  • rrqm/s The number of read requests merged per second that were queued to the device.
  • wrqm/s The number of write requests merged per second that were queued to the device.
  • r/s The number (after merges) of read requests completed per second for the device.
  • w/s The number (after merges) of write requests completed per second for the device.
  • rsec/s (rkB/s, rMB/s) The number of sectors (kilobytes, megabytes) read from the device per second.
  • wsec/s (wkB/s, wMB/s) The number of sectors (kilobytes, megabytes) written to the device per second.
  • avgrq-sz The average size (in sectors) of the requests that were issued to the device.
  • avgqu-sz The average queue length of the requests that were issued to the device.
  • awaitThe average time (in milliseconds) for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.
  • r_awaitThe average time (in milliseconds) for read requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.
  • w_awaitThe average time (in milliseconds) for write requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.

通过观察存储设备的IO处理速率和数据传输速率,可以估算出平均存取文件大小,分析出随机存储的负载情况,从而去优化程序的文件存储设计。数据传输速率太高,可以去优化程序减少传输的数据量,或者增加硬件提升带宽。

3. 网络

TODO

x.REF