1662 words
8 minutes

特斯拉级系统设计面试题(十六):PB 级自动驾驶数据备份系统 — 增量备份、异地容灾与快速恢复

2023 年特斯拉自动驾驶数据存储系统出过一起事故:某区域数据中心磁盘故障导致 3 天内 100PB 数据无法访问,自动驾驶训练 pipeline 全部停摆。后端复盘发现,该区域原本应该有 3 副本,但运维误操作导致副本数降到 1。恢复耗时 72 小时(业内顶配),期间自动驾驶研发完全停滞。

数据备份系统的”四大挑战”:

  • 数据量巨大:累计 PB 级、日增 30PB
  • 备份窗口短:24 小时不间断,不能停机备份
  • RPO / RTO 严格:RPO < 1 小时,RTO < 4 小时
  • 成本控制:全量备份成本高

它不是”做个 rsync”那么简单,而是**“PB 级数据 + 跨区域容灾 + 自动化 + 成本优化”**的工业级数据基础设施。


核心考察点#

  • 数据分层:热/温/冷
  • 增量备份:差分、块级、文件级
  • 跨区域复制:同步、异步
  • RPO / RTO:指标定义和实现
  • 灾难恢复演练:周期性演练

面试误区:很多候选人只答”rsync + 异地存储”,没有考虑PB 级增量、跨区域、自动化、成本优化这些工业级要素。


题目重述#

题目:设计特斯拉自动驾驶数据备份系统,支持:

  1. PB 级数据:累计 50PB+、日增 30PB
  2. 增量备份:差分、块级
  3. 跨区域容灾:3 副本、跨大洲
  4. 快速恢复:RPO < 1 小时,RTO < 4 小时
  5. 成本优化:分层存储、生命周期管理
  6. 自动化:无需人工干预
  7. 灾难演练:季度演练

请给出整体架构、核心数据模型、关键流程、典型问题处理。


标准回答(架构设计)#

1. 整体架构:四层存储#

┌─────────────────────────────────────────────────────────────┐
│ 生产存储 (Production) │
│ - 高速 NVMe - 实时写入 - 多副本 │
└────────────────────────┬────────────────────────────────────┘
┌────────────────────────▼────────────────────────────────────┐
│ 备份层 (Backup) │
│ - 增量备份 - 块级去重 - 压缩 │
└────────────────────────┬────────────────────────────────────┘
┌────────────────────────▼────────────────────────────────────┐
│ 跨区域复制 (Replication) │
│ - 同城双活 - 异地灾备 │
└────────────────────────┬────────────────────────────────────┘
┌────────────────────────▼────────────────────────────────────┐
│ 冷存储 (Cold Archive) │
│ - S3 Glacier - 长期保存 │
└──────────────────────────────────────────────────────────────┘

2. 数据分层策略#

/**
* 数据生命周期管理
*/
@Service
class DataLifecycleService {
/**
* 数据分层规则
*/
fun tierRules() = listOf(
// 0-30 天:热存储(高频访问)
TierRule(age = 0..30, storage = "HOT",
pricePerGB = 0.023, // 美元
accessLatency = "ms"),
// 30-180 天:温存储(中等访问)
TierRule(age = 30..180, storage = "WARM",
pricePerGB = 0.0125,
accessLatency = "s"),
// 180 天-3 年:冷存储(低频访问)
TierRule(age = 180..1095, storage = "COLD",
pricePerGB = 0.004,
accessLatency = "min"),
// 3 年+:归档存储(几乎不访问)
TierRule(age = 1095..Int.MAX_VALUE, storage = "ARCHIVE",
pricePerGB = 0.00099,
accessLatency = "hour")
)
/**
* 自动迁移
*/
@Scheduled(cron = "0 0 2 * * *") // 每天 2 点
fun migrateData() {
for (rule in tierRules()) {
val candidates = dataRepo.findByAgeAndTier(
ageMin = rule.age.first,
ageMax = rule.age.last,
currentTier = rule.storage.downgrade()
)
for (data in candidates) {
storageService.moveTo(data, rule.storage)
}
}
}
}

3. 增量备份#

/**
* 块级增量备份
*/
@Service
class IncrementalBackupService(
private val chunkService: ChunkService,
private val deduplicationService: DeduplicationService
) {
/**
* 块级差分备份
*/
fun incrementalBackup(dataId: String, newData: ByteArray): BackupResult {
// 1. 块级切分(4MB 一个块)
val newChunks = chunkService.split(newData, chunkSize = 4 * 1024 * 1024)
// 2. 去重(Content-Defined Chunking)
val uniqueChunks = deduplicationService.deduplicate(dataId, newChunks)
// 3. 计算差分(只备份新增的块)
val existingChunks = metadataRepo.getChunks(dataId).toSet()
val toBackup = newChunks.filter { it.hash !in existingChunks }
// 4. 上传到备份存储
for (chunk in toBackup) {
backupStorage.put(chunk.hash, chunk.data)
}
// 5. 更新元数据
metadataRepo.updateChunks(dataId, newChunks.map { it.hash })
return BackupResult(
originalSize = newData.size,
backupSize = toBackup.sumOf { it.data.size },
dedupRatio = 1.0 - toBackup.size.toDouble() / newChunks.size
)
}
}

4. 跨区域复制#

/**
* 跨区域异步复制
*/
@Service
class CrossRegionReplicationService(
private val primaryStorage: ObjectStorage,
private val secondaryStorage: ObjectStorage
) {
/**
* 异步复制(异地灾备)
*/
@Scheduled(fixedRate = 60000) // 1 分钟
fun replicate() {
// 1. 找出主区域待复制的数据
val pending = primaryStorage.listPendingReplication()
// 2. 批量复制到异地
for (batch in pending.chunked(1000)) {
val tasks = batch.map { dataId ->
async {
val data = primaryStorage.get(dataId)
secondaryStorage.put(dataId, data)
replicationLog.recordReplicated(dataId)
}
}
tasks.awaitAll()
}
}
}

5. 灾难恢复#

/**
* 灾难恢复服务
*/
@Service
class DisasterRecoveryService(
private val backupStorage: BackupStorage,
private val primaryStorage: ObjectStorage
) {
companion object {
// RPO = 1 小时(数据丢失容忍 1 小时)
// RTO = 4 小时(恢复时间不超过 4 小时)
private const val RPO_HOURS = 1
private const val RTO_HOURS = 4
}
/**
* 灾难恢复(主区域故障)
*/
fun failoverToSecondary(): FailoverResult {
log.warn("Initiating failover to secondary region")
// 1. 提升灾备为主
val startTime = Instant.now()
primaryStorage.promoteSecondary()
// 2. 切换流量
trafficService.redirectToSecondary()
// 3. 校验数据完整性
val integrityCheck = backupStorage.verifyIntegrity()
if (!integrityCheck.passed) {
log.error("Integrity check failed: {}", integrityCheck.errors)
}
val rto = Duration.between(startTime, Instant.now())
log.info("Failover completed in {} (RTO target: {} hours)", rto, RTO_HOURS)
return FailoverResult(rto = rto)
}
/**
* 季度灾难恢复演练
*/
@Scheduled(cron = "0 0 3 1 1,4,7,10 *") // 季度首月
fun quarterlyDrill() {
log.info("Starting quarterly DR drill")
// 1. 在隔离环境模拟恢复
val drillResult = simulateRecovery()
// 2. 报告 RTO / RPO
val report = DrillReport(
rto = drillResult.actualRto,
rpo = drillResult.actualRpo,
targetRto = Duration.ofHours(RTO_HOURS.toLong()),
targetRpo = Duration.ofHours(RPO_HOURS.toLong()),
passed = drillResult.passed
)
// 3. 通知结果
reportService.publish(report)
}
}

追问深度#

Q1:增量备份的一致性怎么保证?#

快照 + WAL(Write-Ahead Log)

// 备份时先做快照
val snapshot = storageService.createSnapshot(dataId)
// 然后基于快照做增量
incrementalBackupService.backupFromSnapshot(snapshot.id)

Q2:PB 级数据如何快速恢复?#

并行恢复 + 优先级

// 优先级:核心训练数据 > 普通数据
fun restore(priority: Priority) {
when (priority) {
Priority.CRITICAL -> parallelRestore(concurrency = 100)
Priority.HIGH -> parallelRestore(concurrency = 50)
Priority.NORMAL -> parallelRestore(concurrency = 10)
}
}

Q3:备份数据如何验证完整性?#

定期校验 + 抽样恢复

// 每周校验一次
@Scheduled(cron = "0 0 3 * * SUN")
fun verifyIntegrity() {
val samples = backupStorage.randomSample(0.01) // 1% 抽样
for (sample in samples) {
val original = primaryStorage.get(sample.id)
val restored = backupStorage.get(sample.id)
if (original.hash != restored.hash) {
alertService.send("BACKUP_CORRUPTED", sample.id)
}
}
}

Q4:如何优化备份成本?#

去重 + 压缩 + 冷热分层

Q5:跨区域复制延迟怎么办?#

异步复制 + 业务层容忍


常见坑#

1. 备份窗口太长:全量备份 24 小时不够,要增量。 2. 没有跨区域副本:单数据中心故障就丢数据。 3. 备份不验证:以为备份了实际没备份。 4. RPO / RTO 不达标:实际 RTO 24 小时。 5. 没做灾难演练:真出故障时慌乱。


可执行 Checklist#

  • 块级增量备份
  • 跨区域副本(至少 3 副本、跨大洲)
  • 数据分层(热/温/冷)
  • 自动生命周期管理
  • 完整性校验
  • 季度灾难演练
  • 备份监控告警
  • 成本核算
  • RPO / RTO 指标监控

写在最后#

PB 级数据备份系统是**“数据安全 + 成本控制 + 自动化”的三角平衡。它的核心是副本策略 + 增量备份 + 自动化**。

三大底线

  • 3-2-1 原则:3 副本、2 种介质、1 份异地
  • 自动化:人工备份必出错
  • 演练:不演练等于没备份

下篇预告:第 17 篇 — 特斯拉车载语音控制后端系统(端云协同、< 100ms 延迟、离线兜底)

特斯拉级系统设计面试题(十六):PB 级自动驾驶数据备份系统 — 增量备份、异地容灾与快速恢复
https://cyber.cc.cd/posts/blogs/tesla-system-design-16-data-backup/
Author
Lance
Published at
2026-06-17
License
CC BY-NC-SA 4.0