技术解密 | Airbnb 研发的可扩展的中央授权系统 Himeji

93 阅读3分钟

Airbnb最近发布博客介绍了可扩展的中央授权系统 Himeji 的开发过程。Himeji 可以存储权限数据并进行权限检查,作为一个中央真理来源。

它使用分片和复制的内存缓存来提高性能和降低延迟,并在生产中经历了大约一年的检验。它的吞吐量已经从2020年3月的 0 扩展到 2021年3月的 850k实体/秒,同时保持 99.999% 高可用,12毫秒延迟在99百分数

下面的图片描述了Himeji的三层架构。

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f68cdebc33684f36b2d8c508e4ed1140~tplv-k3u1fbpfcp-zoom-1.image

来源。 medium.com/airbnb-engi…

  • 协调层接收客户端请求,负责从缓存中获取数据。

  • 缓存层是分片和复制的,负责在内存中进行过滤,并在缓存错过时从数据库中加载。Airbnb的目标是缓存的命中率达到98%。

  • 最后,数据层使用Amazon Aurora进行持久的数据库存储。Airbnb的SpinalTap检测数据突变,并通过Apache Kafka发送通知以使缓存失效。

Airbnb工程师Alan Yao描述了这种架构设计的原因:

在过去的几年里,Airbnb 的工程从单体的 Ruby on Rails 架构转移到面向服务的架构。在我们的 Rails 架构中,我们每个资源都有一个 API 来访问基础数据。这些 API 有授权检查以保护敏感数据。由于有一个单一的方法来访问资源的数据,管理这些检查很容易。在向 SOA 过渡的过程中,我们转向了一个分层的架构,数据服务包裹着数据库,展示服务从多个数据服务中获取水分。

根据 Yao 的说法,Airbnb 最初把权限检查转移到了展示服务,如下图所示:

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7fb25a8de8e34fef91d30af3cdf4c67f~tplv-k3u1fbpfcp-zoom-1.image

图片来源 medium.com/airbnb-engi…

这个选择导致了几个问题。首先,授权检查现在是重复的,管理起来很困难。其次,每个授权检查都需要向多个服务发出扇形信号以执行所需的逻辑,这严重降低了性能和可靠性。解决方案是将授权检查转移到数据服务,而不是展示服务,并创建 Himeji,允许以一种集中的、可扩展的方式存储权限数据。下图描述了 Himeji 以及它是如何在 Airbnb 系统中使用的。

https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0991a9b875124cd49d547da79d1a691a~tplv-k3u1fbpfcp-zoom-1.image

*图片来源 medium.com/airbnb-engi…

Himeji的检查API允许数据服务执行权限检查。数据服务可以询问Himeji,一个特定的委托人(例如,用户)是否对一个特定的实体有关系(例如,特权或行动)。例如,一个数据服务可以问:"用户123可以写到列表10的描述吗?"。这种结构被称为元组(tuple)。它的灵感来自于Google Zanzibar,这是Google的全球授权系统。

Himeji中的许可规则可以存储在数据库中,也可以从配置中导出。例如,下面的配置规则允许委托人读取一个房源的位置,如果委托人是房源的所有者(所有者是存储在DB中的房源权限)。另外,它允许与房源相关的预订的客人也可以读取位置信息。

列表。
  LOCATION:
    '#READ'。
      联盟。
        - #OWNER
        - LISTING : $id # RESERVATION @
          参考( RESERVATION : $reservationId # GUEST)

因此,如果一个客人试图读取该房源的位置,数据服务将检查该用户的委托人是否有权限。基于上述规则,Himeji会自动查询该委托人是否是房源预订的客人,并会返回相应的结果。

为了缩短整合时间,推动开发者采用,Airbnb创建了一些工具。其中包括用 Apache AirflowApache Spark 移植预先存在的许可数据的工具,以及自动生成Java和Scala代码的脚本。