Airbnb/Booking 系统设计(high level architecture)

原文地址 CodeKarle: Airbnb System Design | Booking.com System Design

B站搜 “Airbnb System Design” 有视频版本

需求:

功能性需求

系统用户包括商家和客人。

Hotel - 商家(拥有hotel的人)

        onboarding - 商家可以入住系统。

        update - 商家可以修改hotel相关内容,如增加 room,修改 pricing,增加新的 images等。

        booking -  查看预定,收入等。

User - 客人(预定hotel的人)

        search -  搜索指定地点,符合搜索条件的 hotel (价格区间、星级等级、 海景房等)。

        book - 进行预定

        check booking  -  查看预定。

Analytics -  一些系统分析。

非功能性需求

Low latency

High Availability

High Consistency - (一旦用户预定了hotel,应立刻看到结果)

Scale (Google 搜索得知 )

        500k Hotels (全世界大概有 50万 家 hotel)

        10M Rooms (大概共有 1000万房间)

        1000 Rooms / Hotel (Max: 7500)   (所以假设每个hotel 大概有 1000个 room,有些有 7500个room, 估的高点,是为了更好的处理一些 edge cases)

 总体设计和数据流向

Hotel Service提供给商家入驻和修改等功能,上传的图片保存在 CDN服务器,数据库保存图片链接。MySQL采用一个Master,多个Slave集群。流量高峰时动态增加Slave缓解读取压力。Hotel Service亦可动态水平扩展。

商家新增一个 room,数据将会写入 kafka,然后 search consumer将会拉取这些数据,存储到search数据库。

Search这里使用的是 Elasticsearch,同类型的可以使用 Solr,这里使用 ES,主要是想支持模糊查询(fuzzy search)。假设用户搜索马尔代夫(Maldives)的hotel,用户可能输入错误的名字。这种情况最好也会有搜索结果。

ES 集群 之上是 Search Service,提供给用户 搜索功能。

若此时系统流量激增,我们可以进行水平扩展,增加Kafka集群的node数量、增加 search consumers数量、增加 ES 集群的node数量。

Booking Service 坐落于 一个MySQL集群之上,当预定发生时,预定数据保存在此MySQL集群中。同时调用 Payment Service,成功之后,预定状态为“已确认”。

此时,当预定发生时,应当通知Search Service这个房间已被预定,不应再次出现在搜索结果中。所以此预定数据流入Kafka集群,被Search Consumers读取,修改相关数据。

对于live data (也就是处于中间状态的预定记录)存放于MySQL数据库,一旦预定到达最终状态(如 已完成,或取消)则进入 Archival Service,然后到达 Cassandra 集群。

这里使用 Cassandra 是因为 Cassandra能够轻松处理大量读写操作。

Notification Service 从 Kafka 读取需要通知的事件,比如 预定成功通知商家,预定被取消要通知用户,通知用户费用清单等。

Booking Mgmt Service 负责商家查看预定,用户查看预定历史等。连接两个数据源,从MySQL获取所有 active bookings,从 Cassandra获取已经发生了的预定信息。

这里在MySQL前面加了个 Redis,用来缓存查询的用户拥有的Bookings的结果。这里缓存策略是 write-through,即当有新的booking进入时,先写Redis,然后同步更新MySQL。

对于系统数据分析部分,往往一开始并不能预知所有需要分析的需求。所以这里使用 Hadoop 集群,针对系统所有的事件(比如商家所有hotel的基本信息,商家所有的预定,所有的交易信息等)都写入 Kafka。所以需要Spark Streaming Consumer来从Kafka读取这些事件,放入到Hadoop集群,然后通过Hive queries或任何其他类型的queries来构建一些reporting。

Hotel Service

部分APIs

部分 DB deisgn,红色部分是 主键或外健。

hotel 表中的 original_images 指的是商户上传的图片链接, display_images是压缩过后的图片链接。

rooms 表中 price_min, price_max, 这里通过Hadoop集群,运行machine learning model做一些供需分析得出一个 optimal price。也就是说供应少,需求多,那么价格就上涨。所以这里的 price_min, price_max就是 hotel提供的价格区间, 价格根据需求再次范围浮动。

facilities 是 hotel和room所配备的设备。

hotel_facilities 和 room_facilities 是两张 mapping 表。多对多的关系。

此处我们并没有使用Redis进行缓存,因为 hotel service并不会有流量激增的情况,而是在 search service。

Booking Service

部分DB design, 红色为主键或外健。

available_rooms 中 room_id, date, initial_quantity 字段来自于 hotel_service。 available_quantity意思是特定room_id, 特定的date,剩余的房间数量。表上有约束(constraint)限制不能为负值。

booking 表中 status字段有四个值可选(reserved, booked, cancelled, completed)。

部分API设计:

一个预定API 以post的形式,包括5个参数,其中并不包括price参数,后面从数据库中获取。

这里不从 booking API中获取 price是因为 request 可能被篡改,而且从request获取price并不是一个很好的设计。

当一个 booking 请求到达时,先检查available_rooms表中的 available_quantity 是否有足够的room,进一步则进行锁定,进行支付。

这里插入booking表和 修改 available_room表中的 available_quantity是在同一个transaction中完成的。如果available_quantity 只有一个,且同时有多人争抢,则通过数据库的约束 available_quantity 不能为负值来保证只有一条记录能修改数量成功,也就是只有一条记录插入booking,也就是只有一个人会跳转到支付流程。

这里进行锁定5分钟,我们借助于 Redis的TTL(Time To Live)功能,key过期会有个callback。

当支付成功,标记status为 Booked,Payment Service返回的 invoice_id 保存到 booking表中。相对应的 events 写入kafka,以便其它消费者使用。

当支付失败,标记 status为 Cancelled, 恢复 available_quantity。

当Redis中key过期,收到通知 callback,同时 用户也被跳转至 payment 流程,且支付成功。这里分两种情况:

1,如果先收到payment success,那么 booking 状态被改成 Booked,此时再收到key 过期,修改booking status时需要判断是不是 reserved 状态,只有 reserved 才能被 cancel。

2,如果先收到 key 过期通知,那么booking 状态被改成了 cancelled,然后再收到 payment success 。要么 revert payment;要么判断是否 还有 available_quantity,修改 booking 状态成 booked。

这里还有个问题是 Redis这种key 过期的方式,并非能保证你能在精准的时间点收到 callback,多少都会有延迟,具体情况就要看对实时性的需求了。也可以每隔一秒去主动查询 Redis,不过CPU等的消耗也是一个问题。

其实无论payment 成功与否,在收到payment 结果时,就直接可以从redis中删除这个肯定会过期的key。

技术栈的替换

mysql -> 可以用其它任何支持ACID的数据库,如 Postgres。

Redis -> Memcache 等。

Cassandra->    这里打算继续使用 Cassandra,技术上可以用 HBase代替,但更费操作。

Kafka -> ActiveMQ, Rabbit MQ, Amazon queue等。但Kafka更易于扩展。

系统监控使用 Grafana

跨地域传播

数据中心的相互备份等。。。.... 看不下去了,接触到再说吧。

也太high level了 😂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/65532.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【QT开发自制小工具】PDF/图片转excel---调用百度OCR API接口

前言 前几年WPS还可以免费处理5页以内的PDF转excel,现在必须付费了,而且其他在线的PDF转excel都是要收费的,刚好前几年调研过百度OCR的高精度含位置接口,依然是每天可以免费调用50次,本篇是基于此接口,开发…

Vscode左大括号不另起一行、注释自动换行

参考大佬的博客VSCode 格式化 cpp 文件时配置左大括号不换行_vscode大括号不换行-CSDN博客 Clang_format_style {BasedOnStyle: Chromium, IndentWidth: 4}

原神新角色玛薇卡配队攻略 原神玛薇卡技能机制

原神在2025年1月1日即将迎来一次版本更新,玛薇卡、茜特菈莉、蓝砚三名角色即将上线,今天就给大家抢先介绍一下玛薇卡的机制和配队。 技能机制 战技挂火:战技不用充能就可以输出,但是挂火频率和范围比香菱低一些,适合搭…

8086汇编(16位汇编)学习笔记10.寄存器总结

8086汇编(16位汇编)学习笔记10.寄存器总结-C/C基础-断点社区-专业的老牌游戏安全技术交流社区 - BpSend.net 寄存器 8086CPU有14个寄存器 它们的名称为: AX、BX、CX、DX、SI、DI、SP、BP、 IP**、CS、DS、ES、**SS、PSW。 8086CPU所有的寄存器都是16位的&#…

llamafactory报错:双卡4090GPU,训练qwen2.5:7B、14B时报错GPU显存不足(out of memory),轻松搞定~~~

实际问题场景: 使用llamafactory进行微调qwen2.5 7B和14B的大模型时,会出现out of memory的报错。尝试使用降低batch_size(原本是2,现在降到1)的方式,可以让qwen2.5:7B跑起来,但时不时会不稳定…

Java设计模式 —— 【结构型模式】享元模式(Flyweight Pattern) 详解

文章目录 概述结构案例实现优缺点及使用场景 概述 享元模式也叫蝇量模式:运用共享技术有效地支持大量细粒度的对象; 常用于系统底层开发,解决系统的性能问题。像数据库连接池,里面都是创建好的连接对象,在这些连接对象…

【maven】什么是坐标(依赖)继承与模块、web项目启动访问

目录 2. Maven 基础 2.1 坐标 2.1.0 什么是坐标(依赖) 2.1.1 获得坐标 2.1.2 使用坐标 2.1.3 依赖范围 2.1.4 依赖传递 2.1.5 依赖冲突&调节原则 2.1.6 依赖排除 2.1.7 使用第三方jar包 2.2 继承与模块 2.2.1 概述 2.2.2 分析 2.2.3 实…

操作系统论文导读(八):Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个

Schedulability analysis of sporadic tasks with multiple criticality specifications——具有多个关键性规范的零星任务的可调度性分析 目录 一、论文核心思想 二、基本定义 2.1 关键性指标 2.2 任务及相关参数定义 2.3 几个基础定义 三、可调度性分析 3.1 调度算法分…

【LeetCode】2506、统计相似字符串对的数目

【LeetCode】2506、统计相似字符串对的数目 文章目录 一、哈希表位运算1.1 哈希表位运算 二、多语言解法 一、哈希表位运算 1.1 哈希表位运算 每个字符串, 可用一个 int 表示. (每个字符 是 int 的一个位) 哈希表记录各 字符组合 出现的次数 步骤: 遇到一个字符串, 得到 ma…

uniapp使用ucharts组件

1.ucharts准备 有两种使用方式:一种是在uni的插件市场下载(组件化开发)。一种是手动引入ucharts包。官方都封装好组件了,我们不用岂不是浪费。 直接去dcloud插件市场(DCloud 插件市场)找,第一…

YOLOv11模型改进-模块-引入多尺度大核注意力Multi-scale Large Kernel Attention

MLKA 的提出源于图像超分辨率任务的挑战性,该任务需重建低质量图像缺失的高频信息,但因 LR 与 HR 图像对应关系复杂,寻找像素相关性困难。此前模型扩展容量的方法增加了训练负担和数据收集成本,而采用的注意力机制无法同时获取局部…

《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失如何修复?

《战神:诸神黄昏》游戏运行时提示找不到emp.dll怎么办?emp.dll丢失的修复方法 在畅游《战神:诸神黄昏》这款史诗级游戏的过程中,如果突然遭遇“找不到emp.dll”的错误提示,无疑会打断你的冒险之旅。作为一名深耕软件开…

RabbitMQ基础篇之快速入门

文章目录 一、目标需求二、RabbitMQ 控制台操作步骤1.创建队列2.交换机概述3.向交换机发送消息4.结果分析5.消息丢失原因 三、绑定交换机与队列四、测试消息发送五、消息查看六、结论 一、目标需求 新建队列:创建 hello.queue1 和 hello.queue2 两个队列。消息发送…

非数学专业小白第一次学习Mathematica心得和体会

文章目录 1.软件界面说明2.我为什么要学习Mathematica软件3.如何进行学习4.一些具体使用4.1正余弦函数4.2一个图里面两个函数4.3 3D图形的绘制4.4密度图4.5三维向量图4.6坐标轴说明4.7图像说明4.8绘图的图例4.9指定范围4.10指定绘图样式4.11极限方程求和4.12基本图4.13邻接矩阵…

C#实现图像骨架化(ZhangSuen细化算法)

原始图像: 骨架化后图像: 需要安装一个NuGet包:System.Drawing.Common 代码如下: using System.Drawing; using System.Drawing.Imaging;public class Image {public int Width { get; }public int Height { get; }private bool[,] pixels;// 构造函数,初始化图像的宽度…

【论文阅读笔记】IC-Light

SCALING IN-THE-WILD TRAINING FOR DIFFUSION-BASED ILLUMINATION HARMONIZATION AND EDITING BY IMPOSING CONSISTENT LIGHT TRANSPORT 通过施加一致的光线传输来扩展基于扩散模型的真实场景光照协调与编辑训练 前言摘要引言相关工作基于学习的基于扩散模型的外观和光照操纵光…

论文阅读 - 《Large Language Models Are Zero-Shot Time Series Forecasters》

Abstract 通过将时间序列编码为数字组成的字符串,我们可以将时间序列预测当做文本中下一个 token预测的框架。通过开发这种方法,我们发现像GPT-3和LLaMA-2这样的大语言模型在下游任务上可以有零样本时间序列外推能力上持平或者超过专门设计的时间序列训…

《机器学习》——线性回归模型

文章目录 线性回归模型简介一元线性回归模型多元线性回归模型误差项分析一元线性模型实例完整代码 多元线性模型实例完整代码 线性回归模型简介 线性回归是利用数理统计中回归分析,来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法。 相关关系&…

redis cluster集群

华子目录 什么是redis集群redis cluster的体系架构什么是数据sharding?什么是hash tag集群中删除或新增节点,数据如何迁移?redis集群如何使用gossip通信?定义meet信息ping消息pong消息fail消息(不是用gossip协议实现的&#xff0…

Excel批量设置行高,Excel表格设置自动换行后打印显示不全,Excel表格设置最合适的行高后打印显示不全,完美解决方案!!!

文章目录 说个问题(很严重!!!)写个方案会Python看这里Python环境搭建不存在多行合并存在多行合并 不会Python看这里 说个问题(很严重!!!) 平时处理Excel表格…