假设你的业务处于起步阶段,体量非常小,那你的架构是这样的:
这个架构模型非常简单,客户端请求进来,业务应用读写数据库,返回结果,非常好理解。
但需要注意的是,这里的数据库是「单机」部署的,所以它有一个致命的缺点:一旦遭遇意外,例如磁盘损坏、操作系统异常、误删数据,那这意味着所有数据就全部「丢失」了,这个损失是巨大的。
如何避免这个问题呢?我们很容易想到一个方案:备份。
你可以对数据做备份,把数据库文件「定期」cp 到另一台机器上,这样,即使原机器丢失数据,你依旧可以通过备份把数据「恢复」回来,以此保证数据安全。
这个方案实施起来虽然比较简单,但存在 2 个问题:
- 恢复需要时间:业务需先停机,再恢复数据,停机时间取决于恢复的速度,恢复期间服务「不可用」
- 数据不完整:因为是定期备份,数据肯定不是「最新」的,数据完整程度取决于备份的周期
很明显,你的数据库越大,意味故障恢复时间越久。那按照前面我们提到的「高可用」标准,这个方案可能连 1 个 9 都达不到,远远无法满足我们对可用性的要求。
那有什么更好的方案,既可以快速恢复业务?还能尽可能保证数据完整性呢?
这时你可以采用这个方案:主从副本。
03 主从副本
你可以在另一台机器上,再部署一个数据库实例,让这个新实例成为原实例的「副本」,让两者保持「实时同步」,就像这样:
我们一般把原实例叫作主库(master),新实例叫作从库(slave)。这个方案的优点在于:
- 数据完整性高:主从副本实时同步,数据「差异」很小
- 抗故障能力提升:主库有任何异常,从库可随时「切换」为主库,继续提供服务
- 读性能提升:业务应用可直接读从库,分担主库「压力」读压力
这个方案不错,不仅大大提高了数据库的可用性,还提升了系统的读性能。
同样的思路,你的「业务应用」也可以在其它机器部署一份,避免单点。因为业务应用通常是「无状态」的(不像数据库那样存储数据),所以直接部署即可,非常简单。
因为业务应用部署了多个,所以你现在还需要部署一个「接入层」,来做请求的「负载均衡」(一般会使用 nginx 或 LVS),这样当一台机器宕机后,另一台机器也可以「接管」所有流量,持续提供服务。
从这个方案你可以看出,提升可用性的关键思路就是:冗余。
没错,担心一个实例故障,那就部署多个实例,担心一个机器宕机,那就部署多台机器。
到这里,你的架构基本已演变成主流方案了,之后开发新的业务应用,都可以按照这种模式去部署。