---
title: 服务器虚拟化
taxonomy:
    category: docs
---

服务器虚拟化是第一代基础设施并发技术：既然由于软件架构的限制导致单机性能有上限，那我们就把一台多核服务器拆成多台来使用。

服务器虚拟化技术可以在一台物理机上同时运行多台虚拟机，而每一台虚拟机都拥有完整的操作系统和硬件资源，包括 CPU、内存、磁盘、网卡等，虚拟机之间是完全隔离的，它们不知道邻居是谁，而在绝大多数情况下也不需要知道，因为硬件绑定技术已经十分成熟了：邻居哪怕在挖矿，也不会影响你的性能，因为它们的硬件资源已经在底层物理硬件层面被隔离开了。

你是否曾经思考过，在一台裸金属服务器的操作系统内直接运行 Apache、MySQL、Redis、Elasticsearch，与开四台虚拟机分别运行它们之间有什么区别呢？系统设计哲学不是“如无必要勿增实体”吗？虚拟机技术到底有什么价值来让我们新增四个实体呢？

### 资源隔离

首先，就要说到我们第一章中提过的运维哲学了：

> 运维的核心价值不在于资源的扩充，而在于资源的隔离。

在后端技术领域中，有许多成熟的开源软件可供选择，每个都有独特的发展路径，百花齐放、百家争鸣。如果将所有服务都部署在裸金属服务器上，理论上使用内存管道通信的效率会比虚拟机之间通过虚拟以太网通信更高。然而，在这种情况下实现资源隔离却是一项挑战。

目前，拥有自我资源限制能力的软件并不多见。大部分软件都是“有多少资源就占用多少资源”，即根据请求压力任意获取计算资源，这容易导致其他软件的生存空间被挤占，形成木桶效应，进而导致系统整体性能下降。

虚拟化技术通过将虚拟机与物理核心进行强绑定，可以无限接近将一台 64 核服务器拆分为 32 台 2 核服务器的目标。此外，内存也可以进行完全预分配，从而最大程度地减少虚拟机之间的相互干扰。如图 2-2 所示就是虚拟化技术的示意图。

![1529514558](/media/1529514558.png)
<center>图 2-2 虚拟化技术示意图</center>

### 提高运维效率

在传统的物理服务器时代，操作系统需要运维人员使用光盘安装，软件的安装也需要手动一台一台地操作。当出现软件或硬件故障时，运维人员需要逐一判断和解决，效率非常低下。然而，随着虚拟化技术的发展，物理服务器只需要安装一次操作系统，除非遇到安全性问题，否则几乎不需要更新。而作为业务承载者的虚拟机却可以随着时间的推进不断更新版本，跟上时代的步伐。

虚拟机技术显著降低了对每个重要服务进行资源监测的复杂度，极大地提升了运维效率。目前市场上成熟的监控软件都是读取操作系统指标进行监控的，如果想要对一台机器上的多个进程分别进行监控，技术难度要大很多。

此外，虚拟机技术还具备部分可编程的特性，这就催生了第一代“自动运维”技术的出现。随着时间的推移，自动运维技术逐渐发展壮大，如今已经创造了一个巨大的市场——以亚马逊云计算为首的云计算市场。

众多中小企业通过购买这些价格低廉的云服务，得以使用过去只有大公司庞大的平台架构部门才能构建起的高级基础服务。这不仅帮助中小企业缩减了成本，还为业务的发展提供了更多的可能性。

### 强大的兼容性和可调试能力

虚拟化技术，如同一条标准化的生产线，为我们提供了一套逻辑上的“不可变基础设施”。这就像是一个魔法，使得当我们的系统规模增大，或者我们采购了新的物理服务器之后，我们仍然可以非常方便地直接运行旧的虚拟机镜像。这种灵活性让我们避免了“新硬件只能安装新版操作系统而无法支持旧版本软件”的尴尬局面。

想象一下，如果有一台虚拟机运行的时间非常久，那它大可以随时迁移到最新的硬件平台之上，不必再费尽心思、小心翼翼地维护一台开机了十年的老旧服务器。这样，我们就避免了因为老旧硬件故障而造成业务的重大损失。

此外，虚拟化技术还赋予了我们无比强大的资源管理能力。我们可以在任何时间对虚拟机系统的关键资源做出任何调整，可以设计各种高级网络架构，可以随时重启虚拟机，不用担心“物理服务器重启之后开机失败”这种处理起来非常麻烦的问题。如果我们对操作系统做出了修改但启动不了，只需要恢复上一版镜像就可以了。

最后，虚拟化技术对操作系统开发的贡献也很大，大幅提升了操作系统开发中涉及到硬件的调试效率。这使得我们发现问题、获取 Dump 信息、测试问题是否已解决的速度都提升了一大截。

### 高可用架构

在裸金属时代，如果我们需要搭建一个高可用集群，我们至少需要 2 台路由器、2 台后端服务器，2 台数据库服务器，架构如图 2-3 所示。

![](/media/16889171932855.jpg)
<center>图 2-3 基础高可用集群架构</center>

而使用最新的超融合技术，只需要 2 台物理机便可以把这件事情全干了：因为路由器、后端服务器、数据库服务器全部都可以虚拟化，它们三个完全可以运行在同一台物理服务器之上。两台超融合物理服务器搭建的高可用集群架构如图 2-4 所示。

![](/media/1697193293.png)
<center>图 2-4 两台物理服务器高可用集群架构</center>

时至今日，VMWare 在服务器超融合领域仍然占据着统治地位。通过将 vSphere 软件安装在三台物理服务器上，形成一个小集群，就能够提供高可用架构的全套基础设施。下面我们将简要介绍一些主要的高可用基础设施。

1. 统一应用网关：就是图 2-4 中的路由器实现的功能，对流量进行转发，单台服务器宕机不影响对外服务。
2. 共享存储：在小集群之内形成一个统一的磁盘存储，单台服务器宕机不影响磁盘的正常使用和数据安全。
3. 虚拟机热漂移：虚拟机无需关机地在物理服务器之间迁移，实现真正的“无缝迁移”，该技术通过共享存储和内存实时拷贝来实现。
4. 自动故障转移：基于上述三个主要的组件和功能，在某一台物理机宕机之后，整个集群的对外服务完全不受影响，从网络到计算到数据库都可以在几秒内恢复对外服务。

如果只用一台物理服务器直接安装 Linux，然后把所有应用软件都安装在物理机上，很显然上述这些高可用特性都做不到：一旦这台物理机的某个部件发生了故障导致宕机的话，全部服务都会挂掉。

### 利用集群架构提升总体性能

由于许多软件都具有类似 Apache 的“单机性能极限”，因此采用虚拟化技术将单个机器拆分成多个机器，可以直接实现性能的提升。假设我们将 Apache、Redis、MySQL 和 Elasticsearch 都安装在裸金属操作系统上，它们可能会异口同声地表示：即使有这么多核心，我也用不上啊。

在后续的第 4 章中，我们将对 Apache 进行非常详细的讨论。现在，让我们先来探讨其他几种技术的“单机性能极限”以及相应的虚拟机集群方案。

#### Redis 的单机性能极限

Redis 作为单线程内存数据库（仅限 2020 年 6.0 版本之前），即使只拥有两个处理器核心，其每秒查询数（QPS）也能达到十万次。即便你给它分配了 32 核心处理器，最大性能还是只有十万次查询/秒，只会浪费资源。

在前几天 Redis 回应新兴内存数据库 Dragonfly 挑战的文章中，Redis 维护团队[建议大家搭建“单机集群”](https://redis.com/blog/redis-architecture-13-years-later/) 来实现对机器上所有 CPU 的完全利用，Redis 团队的内心 OS 一定是：宝宝心里苦但宝宝不说。

如果你具备控制物理机的权限，那么基于虚拟化技术搭建多虚拟机上的 Redis 集群是一种比单机集群更加稳定和高性能的解决方案。这是因为虚拟化平台对虚拟环境中操作系统的管理能力要远远高于 Systemd 对进程的控制能力。

#### MySQL 的单机性能极限

在当今 NVMe PCIe 5.0 的时代，单个闪存磁盘的读写速度已经达到了惊人的 12.8GB/S。MySQL 的单机 CPU 使用强度也得到了大幅提升。然而，如果使用最新的 AMD EPYC™ 9654 192 核 CPU 搭建的双路服务器（包含两颗 CPU）来运行单机 MySQL，情况会如何呢？显然，单节点 MySQL 无论如何也无法充分利用 384 个物理核心和 768 个线程，其性能极限也会停留在几万 QPS。

实际上，开源标准版 MySQL 的性能瓶颈在于内存容量和磁盘速度，对 CPU 资源的需求并不是很高。在两台虚拟机拥有独立固态硬盘的情况下，将 16 核虚拟机拆分成两台 8 核虚拟机并构建成一个半同步一主一从的 MySQL 集群，可以轻松地将数据库的读性能提升一倍，只需稍微牺牲一点点的写性能。

关于 Web 系统的瓶颈在数据库、数据库的瓶颈在存储的话题，我们将在后面的第四部分专门展开讨论，并使用多章内容进行深入探讨。

#### Elasticsearch 的单机性能极限

Elasticsearch 作为一个 Java 应用，显然拥有着明确的单机性能极限：线程切换需要读写内存，性能上限就在那里。所以 Elasticsearch 采用了自选举集群架构来实现水平扩展：官方建议单节点不要超过 32GB 内存。

如果你的物理服务器上面 CPU 和内存资源很多，就应该基于虚拟机技术做多节点 Elasticsearch 集群，Elasticsearch 集群的扩展能力是非常不错的，基本上可以实现线性的集群性能提升。作为一个搜索引擎，大家竟然都拿他当数据库用，从这里就足以看出它优秀的水平扩展能力了。

在后面第 11 章中我们讨论到缓存与队列时，我们还会重点学习一下 Elasticsearch 优秀的内存缓存设计。
