尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

system-design-notes第22章:设计酒店预订系统完整指南

system-design-notes第22章:设计酒店预订系统完整指南 system-design-notes第22章设计酒店预订系统完整指南【免费下载链接】system-design-notesNotes of the book System Desgin Interview - An Insiders Guide项目地址: https://gitcode.com/GitHub_Trending/sy/system-design-notes本文是 system-design-notes 第 22 章的完整指南带你用系统设计的标准流程——需求分析、容量估算、数据建模、并发控制、分片扩展与数据一致性——一步步设计一个酒店预订系统。酒店预订系统是面试高频题同一套思路也适用于 Airbnb、机票预订、电影售票等场景。读完本文你将掌握避免重复预订、数据库分片和微服务一致性的实用方案。 第1步先弄清需求明确酒店预订系统的边界在动手设计前先和面试官确认范围。第22章给出的核心设定一个拥有5000 家酒店、100 万间客房的酒店集团网站用户在预订时全额付款仅通过网站/App 下单支持取消预订允许10% 的超售overbooking——酒店会多卖房间赌有人会取消房价每天变化价格与当日入住率相关非功能性需求高峰期大量用户可能同时订同一家酒店系统要支持高并发预订延迟中等即可几秒内完成可以接受。 面试技巧先问清楚预订的是具体房间还是房型这会直接影响数据模型设计。用纸面估算算清系统规模假设 70% 客房被占用、平均住 3 天则每日约100万 × 0.7 / 3 ≈ 24 万笔预订折算平均TPS 只有 3 左右——写压力很小。但页面浏览量按漏斗反推![酒店预订系统的QPS估算漏斗图从预订到房型详情页的访问量推算](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/qps-estimation.png?utm_sourcegitcode_repo_files)若 3 笔预订、每页 10% 转化率则预订详情页约 30 次/秒、房型页约 300 次/秒。读多写少这个特征决定了后面的数据库选型。️ 第2步高层设计——API、数据模型与微服务架构酒店预订系统的 RESTful API 设计核心接口分三组详见 22. Hotel Reservation System/README.md分组关键接口酒店GET /v1/hotels/{id}、POST /v1/hotels仅运营房间GET /v1/hotels/{id}/rooms/{id}预订POST /v1/reservations、DELETE /v1/reservations/{id}注意预订请求中带有一个reservationID字段它是幂等键后文解决重复预订时要用到。为什么选关系型数据库读多写少关系型数据库如 MySQL正合适预订涉及金钱必须靠ACID 事务防止重复扣款、负数库存酒店-房型-预订的结构非常清晰关系模型好表达初始表结构包含 hotel、room、reservation 三张表其中status字段描述房间状态机![酒店预订系统schema设计hotel、room、reservation三张核心表](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/schema-design.png?utm_sourcegitcode_repo_files)但这个初版模型有个缺陷用户预订的是房型而非具体房间号房间号应在下单时才分配。后面第3步会修正它。微服务架构图六个服务的职责划分![酒店预订系统微服务架构酒店服务、价格服务、预订服务、支付服务与公共API网关](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/high-level-design.png?utm_sourcegitcode_repo_files)公共 API 网关负责限流、认证限流方案可参考 04. Rate Limiter/Readme.md酒店服务 / 价格服务酒店和房型数据变化慢可激进缓存价格服务按未来日期提供房费预订服务接收预订并管理房间库存支付服务处理付款成功后更新预订状态服务间通信用 gRPC 这类 RPC 框架 第3步改进数据模型——按房型预订才是关键修正后的 API 不再传roomID而是传roomTypeID 数量roomCount。更新后的表结构如下![改进后的酒店预订系统schema新增room_type_rate与room_type_inventory库存表](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/updated-schema.png?utm_sourcegitcode_repo_files)新增的room_type_inventory表是精髓每行记录(酒店, 房型, 单一日期)的库存total_inventory该房型总房间数扣除临时下架的total_reserved该日期已预订数判断是否有房total_reserved 要订数 ≤ 110% × total_inventory支持 10% 超售行由每日 CRON 任务预生成。按 5000 家酒店 × 20 种房型 × 2 年 × 365 天估算仅7300 万行单台数据库服务器就能扛住加读写副本即可保证高可用。若预订表膨胀可按hash(hotel_id)分库分表所有查询都带 hotel_id分片键天然合适历史数据可归档到冷存储。⚔️ 第4步并发难题——防止重复预订的3种实战方案这是本章最核心的考点。要解决两个问题同一用户连点两次预订多个用户同时抢同一房型。问题一同一用户双击预订前端禁用按钮只是权宜之计可靠做法是幂等 API![酒店预订系统幂等设计reservation_id重复提交被后端识别为重复订单](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/idempotency.png?utm_sourcegitcode_repo_files)流程用户填信息时先生成一个全局唯一的reservation_id无论点击几次完成预订提交的都是同一个 id数据库对该列建唯一约束重复记录直接写入失败![数据库唯一约束拦截重复预订第二条相同reservation_id的记录被拒绝](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/unique-constraint-violation.png?utm_sourcegitcode_repo_files)问题二多用户同时抢订在低隔离级别下两个事务可能都看到还有房双双写入成功造成超售![酒店预订系统重复预订场景用户1和用户2同时下单导致库存检查竞态](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/double-booking-multiple-users.png?utm_sourcegitcode_repo_files)三种解法对比方案1悲观锁Pessimistic Locking用SELECT ... FOR UPDATE在更新前锁住行。![悲观锁原理图解SELECT FOR UPDATE锁定库存行直到事务提交](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/pessimistic-locking.png?utm_sourcegitcode_repo_files)✅ 实现简单串行化更新适合高争用场景❌ 长事务会阻塞其他所有事务可能死锁扩展性差方案2乐观锁Optimistic Locking⭐ 本章推荐给表加version列更新时校验版本号并 1失败则重试。![乐观锁原理图解版本号校验防止基于旧数据的更新](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/optimistic-locking.png?utm_sourcegitcode_repo_files)✅ 不加数据库锁性能好避免基于过期数据修改❌ 高争用下大量回滚性能下降酒店预订 TPS 只有个位数争用低乐观锁是最佳选择建议用版本号而非时间戳服务器时钟可能不准方案3数据库约束直接用 CHECK 约束兜底total_inventory - total_reserved 0。![数据库约束防止库存为负check_room_count约束拦截非法UPDATE](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/database-constraint.png?utm_sourcegitcode_repo_files)✅ 最简单小争用场景表现好❌ 部分数据库不支持约束难以像代码一样版本管理 面试加分点说明乐观锁 唯一约束组合拳——幂等键防单人重复版本/约束防多人竞态数据库约束做最后防线。 第5步可扩展性——数据库分片 Redis 缓存若系统被 booking.com 级别的流量采用QPS 放大 1000 倍瓶颈在哪所有服务都是无状态直接横向复制即可原理见 01. Scaling/Readme.md。真正难扩展的是有状态的数据库解法是分片![酒店预订系统数据库分片按hotel_id将数据分布到多个分片集群](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/database-sharding.png?utm_sourcegitcode_repo_files)假设 QPS 达 30,000拆成 16 个分片后每片仅 1875 QPS在单 MySQL 集群能力之内。再叠加Redis 库存缓存库存 key 按hotelID_roomTypeID_{date}存储![Redis库存缓存架构CDC异步同步数据库变更到Redis缓存层](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/inventory-cache.png?utm_sourcegitcode_repo_files)缓存与数据库通过CDC 流式机制如 Debezium异步同步短暂不一致没关系最终写入时数据库约束会拦截非法预订最坏情况只是用户刷新页面看到没房了为已过期日期设置 TTL 自动清理缓存的代价是一致性难维护需评估其对用户体验的影响——这是经典的缓存与一致性权衡可延伸阅读 06. Key-Value Store/Readme.md。 第6步微服务间的数据一致性权衡单体应用可以用同一个关系型数据库的事务保证原子性而拆成微服务后跨服务操作不再原子![微服务非原子操作预订服务与支付服务分离后无法用单库事务保证一致性](https://raw.gitcode.com/GitHub_Trending/sy/system-design-notes/raw/9d8388721e7231442763ad37398b8d82224aa68f/22. Hotel Reservation System/images/microservice-non-atomic-operation.png?utm_sourcegitcode_repo_files)本章的务实选择是混合架构预订和库存 API 放在同一个服务内继续享受 ACID 事务的红利避免不必要的复杂度。若坚持纯微服务每服务独立数据库则要用两阶段提交2PC跨节点原子提交但一个节点卡顿会阻塞所有节点性能差Saga一系列本地事务 失败时的补偿事务属于最终一致方案⚖️ 核心思想跨服务一致性会显著抬高系统复杂度先问值不值得能用单库事务解决的别上分布式协议。✅ 本章核心要点速记步骤关键决策需求与估算TPS≈3 读多写少支持 10% 超售技术选型MySQLACID 微服务 gRPC数据模型按房型日期库存表CRON 预生成并发控制幂等键 乐观锁 唯一约束扩展hotel_id 分片 Redis 库存缓存 CDC 同步一致性混合架构优先必要时 Saga / 2PC延伸阅读容量估算方法见 02. Back Of the Envelope Estimation/Readme.md本章完整源码笔记见 22. Hotel Reservation System/README.md。把这套估算 → 建模 → 防竞态 → 分片 → 一致性的流程记熟机票、门票、演出订票类面试题都能直接复用。【免费下载链接】system-design-notesNotes of the book System Desgin Interview - An Insiders Guide项目地址: https://gitcode.com/GitHub_Trending/sy/system-design-notes创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表