欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > Airbnb/Booking 系统设计(high level architecture)

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

2025/1/3 19:14:11 来源:https://blog.csdn.net/DachuiLi/article/details/144688214  浏览:    关键词: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了 😂

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com