雲平臺之多租戶

雲平臺之多租戶

在雲領域我們經常會聽到一個詞:多租戶。這個詞在不同的語境中有着不同的含義,本文將介紹雲平臺中的多租戶的概念以及實現多租戶支持的思路。

什麼是租戶

剛開始接觸這個概念時,你肯定感覺“租戶”這個詞怪怪的,但如果我們換個詞,我相信你馬上就有感覺了,這個詞就是“客戶”(這裏的客戶指的就是商業上面的客戶)。一個租戶就是一個客戶,比如我們開發的服務是給 XXX 企業使用的,那該企業就是我們的一個客戶/租戶;如果這個服務是面向互聯網的,那麼使用該服務的每個互聯網用戶都是一個客戶/租戶。

爲什麼需要多租戶支持

開發者辛辛苦苦開發出一個服務,提供給了個人/企業使用,這樣就完事了麼?當然不應該只是這樣,我們開發出一個服務,最好是能夠同時提供給多個個人/企業使用,而且這些客戶最好是共享同一套服務運行時(Runtime),這樣可以大大降低服務的運維成本:

  • 服務運行時如果分開,則運維的成本與客戶數成正比(比如更新部署大量客戶的場景)
  • 節省資源(將服務所需資源利用最大化:運維團隊統一、硬件使用)

另外,這樣也可以降低服務的開發成本:

  • 我們只需要考慮如何實現單用戶的服務邏輯:業務邏輯對應其所有客戶都是相同的,無論什麼客戶來使用,程序提供的服務都是一樣的。進一步說,在業務層面我們開發這個服務時理論上不需要考慮多客戶支持,我們只用關注該服務的業務邏輯如何實現
  • 多客戶的管理功能可以進行統一:開發者應該不用考慮客戶管理功能,這部分應該是由雲平臺統一提供的

多租戶場景舉例

假設我們要開發的服務是一個博客平臺,這個服務是面向互聯網用戶的,每個互聯網用戶都是我們的客戶(一個用戶就是一個租戶)。

在不支持多租戶的環境中,爲了隔離每個用戶的數據,至少我們在設計數據庫表時會考慮大多數表都存在一個 user_id 字段,用於 CRUD 數據時使用該字段進行用戶隔離

比如現在的業務是“發佈文章”,需要將文章數據保存在 article 表中,在實現時實際上我們關注了兩件事情:

  1. CRUD:這是業務邏輯實現的一部分
  2. 用戶隔離:需要加入 user_id,做業務關聯

1 是“純”業務邏輯部分的實現,這是必須實現的;2 則是爲了多用戶博客平臺而需要考慮的,這並不是博客平臺本身的業務邏輯。這裏如果能得到平臺的多租戶支持,就不用考慮第 2 點了,這樣可以將注意力集中於第 1 點業務邏輯實現上,這是非常典型的一個多租戶場景。

多租戶支持

我們可以這樣理解多租戶支持:

  • 從服務提供的角度看,我們開發的一個服務運行時可以同時提供給多個客戶使用,並且客戶之間的數據/狀態是保持隔離的
  • 從服務使用的角度看,我和你可以作爲不同的客戶同時使用同一個運行的服務,此時我們使用該服務完成的業務是相互不影響的,就好像我們在使用自己獨享的服務一樣

那麼這個服務就是支持多“客戶”的,即該服務支持多租戶。這裏的“服務”可以是應用,可以是 SaaS 平臺,也可以是 PaaS 平臺。不過按目前我們熟悉的雲平臺看,應用的多租戶支持應該是最常規的,這是因爲應用面向的是用戶,這個羣體是很龐大的。

多租戶支持從實現的角度看,“是一種軟件架構技術”,之所以強調它是屬於架構層面是因爲要實現它必須在做技術架構時就要將其考慮在內。

一種租戶模型

本文一開始我們提到使用“客戶”來置換“租戶”來理解租戶的含義,再從“商業”這個方面來看的話,我們不難發現租戶其實就是其雲環境中的商業模式實現的一部分。商業模式是多樣的,這意味着租戶的劃分也是多樣的,這裏我們描述其中一種可能的租戶棧:

  • 應用程序是提供給用戶使用的,對於應用來說,用戶就是它的租戶(這一點業界比較統一)
  • SaaS 提供的服務是給應用開發商使用的,對於 SaaS 來說,應用開發商就是它的租戶
  • PaaS 提供的服務是給應用系統使用的,對於 PaaS 來說,相關應用的組合就是它的租戶

SaaS 和 PaaS 面向的是開發商、系統等非端用戶角色,這一部分一般是由雲平臺開發者決定的(捆綁商業模式),特別是私有/企業雲平臺一般不會考慮形如“在 PaaS 平臺上支持運行多個 SaaS 平臺”這樣的場景。所以下面我們更多的是圍繞“應用對多租戶支持”進行討論。

應用多租戶

應用多租戶的使用場景前面已經介紹過了,現在假設我們是一個雲平臺開發者,爲了滿足支持應用支持多租戶的需求,在雲平臺中我們需要提供下面幾個支持:

  • 租戶管理:CRUD,統計
  • 租戶隔離/共享的服務:隊列、緩存、數據庫等
  • 租戶隔離的統計:日誌、配額

這些支持可以分爲兩類:

  1. 租戶的管理:不會直接面嚮應用的端用戶,面向的是應用的運維,平臺應該提供具體實現
  2. 租戶數據/狀態的隔離:從請求開始就應該可以區分這個請求是來自於哪個租戶,請求處理時在調用鏈路上也需要帶上租戶上下文,數據的存取是按照租戶隔離的,調用平臺提供的服務時也是租戶隔離的

第 1 點比較容易實現,這是一個業務模型方面的問題,可以根據業務域來抽象租戶模型,比如企業應用一般是按照“組織機構”來區分租戶的;

第 2 點是一個純技術的需求,需要在平臺技術實現上支持按“租戶”的運行時隔離,我們強調的是隔離,因爲在實現時我們要達到的目標就是隔離,只不過這裏是按租戶(租戶只是一個商業概念,技術層面我們最好能夠將其進行抽象,儘量減小商業模式多樣化對技術架構的衝擊),我們可以將租戶映射到一個抽象概念上,這個抽象概念可以實現我們的隔離需求。

命名空間

前面我們討論多租戶支持都是自上而下的:從應用多租戶需求到數據隔離實現;現在我們再換種視角,自下而上:先通過命名空間隔離數據,再將命名空間提供給應用多租戶的實現使用。自下而上的目的主要是在平臺內部,我們可以通過“命名空間”來進行數據/狀態隔離的抽象,最終的理想情況是命名空間不僅能夠支持應用多租戶實現,還能夠可選擇性地暴露命名空間 APIs,讓應用可以進行某些數據的隔離(比如緩存),方便業務實現。

隔離的實現

租戶請求從開始到結束平臺都需要知曉這個請求映射的命名空間,從請求處理棧我們可以這樣大致劃分一下:

  • 負載均衡器(LB)
  • 應用容器(APP)
  • 平臺服務接口(RPC)
  • 平臺服務實現(DB/Cache/MQ....)

在這個棧中每一層平臺都是需要知道這個請求對應的命名空間的。平臺可以提供一個統一登錄的服務,將租戶信息映射爲命名空間並保存到用戶會話中,這樣每次該用戶的請求:

  • 過 LB 時就可以區分出命名空間來
  • 在 APP 容器中可以通過會話
  • RPC 時傳遞命名空間
  • 根據服務的不同進行命名空間實現(例如 DB 根據命名空間使用不同的 Schema,MQ 根據命名空間使用不同的隊列)

這裏我們使用的隔離實現基本思路是“Shared application”,即多租戶共享一個應用,對應一套基礎設施(請參考:將單租戶應用程序轉換爲多租戶應用程序)。

 一種平臺設計

 前面談了這麼多,現在我們可以腦補出一種支持應用多租戶的雲平臺:

多租戶雲平臺設計

(這裏的設計思路也包含了有的租戶要求獨享資源的場景)

總結

  • 租戶和客戶的概念類似
  • 對多租戶的支持我們一般指的是應用對多租戶的支持
  • 在技術層面支持多租戶需要實現數據/狀態隔離
  • 使用命名空間進行隔離實現抽象
  • 租戶到命名空間的映射可由平臺集成
發佈了249 篇原創文章 · 獲贊 92 · 訪問量 190萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章