来源:真没什么逻辑
为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响 。如果你有想要了解的问题,可以在文章下面留言 。数据库管理系统在今天已经是软件的重要组成部分,开源的 MySQL、PostgreSQL 以及商业化的 Oracle 等数据库已经随处可见,几乎所有的服务都需要依赖数据库管理系统存储数据 。
文章插图
database-banner
图 1 - 数据库
数据库不会丢失数据听起来像是理所当然的事情,持久化能力也应该是数据库的最基本保障,但是在这个复杂的世界上想要保证数据不丢失是很困难的 。在今天,我们能找到很多数据库出现问题导致数据丢失的例子:
- MongoDB 在过去很长的一段时间都不能保证持久性,很容易就会丢失数据[^1];
- RocksDB DeleteRange 功能导致的数据丢失问题[^2];
- 腾讯云硬盘故障,导致创业公司线上生产数据完全丢失[^3];
- 人为因素导致的运维和配置错误是数据库丢失数据的首要原因;
- 数据库存储数据使用的磁盘损坏导致数据丢失;
- 数据库的功能和实现复杂,数据没有及时刷入磁盘就有丢失的风险;
第一是正常数据搬迁流程默认开启数据校验,开启之后可以有效发现并规避源端数据异常,保障搬迁数据正确性,但是运维人员为了加速完成搬迁任务,违规关闭了数据校验;减少人为错误的最好方式是将数据的备份和运维等操作标准化,使用自动化的流程处理涉及数据安全的操作,这样才能降低人为干预带来的风险 。
第二是正常数据搬迁完成之后,源仓库数据应保留24小时,用于搬迁异常情况下的数据恢复,但是运维人员为了尽快降低仓库使用率,违规对源仓库进行了数据回收 。
对于软件工程师来说,我们应该敬畏生产环境,谨慎地在生产环境执行一切操作,认识到所有的操作都可能对线上正在运行的服务产生影响,这样才能降低类似问题发生的概率 。
硬件错误
我们在 为什么基础服务不应该高可用 一文中曾经介绍过任何一个线上的服务能够正常运行都是极其偶然的,只要时间拉的足够长,我们就没有办法保证服务 100% 的可用性[^4] 。磁盘等硬件如果使用的时间足够长,很有可能会发生损坏,根据 google 论文中的数据,5 年内硬盘的年平均故障率(Annualized Failure Rates,AFR)为 8.6%[^5] 。
2018 年,腾讯云数据损坏事故的起因就是磁盘静默错误(Silent data corruption)[^6]导致的单副本数据错误 。磁盘静默错误是没有被磁盘固件或者宿主操作系统发现的错误,包括以下情况:电缆松了、电源供给不可靠、外部震动、网络引起的数据丢失等问题 。
正是因为磁盘的数据损坏非常常见,所以我们需要数据冗余的方式保证磁盘在发生不可修复读错误(Unrecoverable Read Error)时能够恢复磁盘数据 。独立冗余磁盘阵列(Redundant Array of Independent Disks,RAID)是一种能够将多个物理磁盘组合成一个逻辑磁盘的数据存储虚拟化技术,它能够增加数据冗余并提高性能[^7] 。
文章插图
raid-strategy
图 2 - RAID 三大策略
RAID 主要使用分割(Striping)、镜像(Mirroring)和奇偶校验(Parity)三大策略管理磁盘中的数据,我们这里举几个简单的例子:
- RAID 0 使用了数据分割技术,但是没有镜像和奇偶校验 。它对磁盘上的数据几乎不进行任何的保护,任意一块磁盘磁盘损坏都意味着其中的数据无法恢复,但是因为不存在冗余,所以它也会提供较好的性能;
- RAID 1 使用了数据镜像的功能,但是没有奇偶校验和数据分割 。所有的数据都会写入两个相同的磁盘,两个磁盘都能对外提供数据读取的服务 。这种方式降低了磁盘的使用率,但是能够提高读取性能并提供备份;
推荐阅读
- Redis为什么是单线程,高并发快由哪些因素决定?
- 黑茶银耳饮会反弹吗,孕妇可以喝菊花茶吗
- 百度截流怎么做?百度截流百度霸屏技术教程,看完本文即可学会百度霸屏技术
- PHP初学者总会遇到非常头疼问题,今天给你们总结一下
- 报销|为什么很多公司面试不报销路费?
- 发动机为什么要大修?家用车做好这3点,开到报废也不用大修
- 地球绕太阳的公转为什么是椭圆轨道?
- C1增加D证需要多久,会很难吗
- 人在单位,面对以下几个规则,你要学会变通
- 聪明的员工,在辞职前都会懂得做这4点