天天看點

JNPF雲平台之多租戶的探索

JNPF雲平台之多租戶的探索

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

什麼是租戶

剛開始接觸這個概念時,你肯定感覺“租戶”這個詞怪怪的。但假設我們換個詞,我相信你立即就有感覺了。這個詞就是“客戶”(這裡的客戶指的就是商業上面的客戶)。

一個租戶就是一個客戶,比方我們開發的服務是給 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 點比較easy實作。這是一個業務模型方面的問題,能夠依據業務域來抽象租戶模型,比方企業應用通常是依照“組織機構”來區分租戶的;

第 2 點是一個純技術的需求。須要在平台技術實作上支援按“租戶”的執行時隔離,我們強調的是隔離,由于在實作時我們要達到的目标就是隔離,僅僅隻是這裡是按租戶(租戶僅僅是一個商業概念,技術層面我們最好能夠将其進行抽象。盡量減小商業模式多樣化對技術架構的沖擊)。我們能夠将租戶映射到一個抽象概念上,這個抽象概念能夠實作我們的隔離需求。

命名空間

前面我們讨論多租戶支援都是自上而下的:從應用多租戶需求到資料隔離實作;如今我們再換種視角,自下而上:先通過命名空間隔離資料,再将命名空間提供給應用多租戶的實作使用。自下而上的目的主要是在平台内部,我們可以通過“命名空間”來進行資料/狀态隔離的抽象。終于的理想情況是命名空間不僅可以支援應用多租戶實作,還可以可選擇性地暴露命名空間 APIs。讓應用可以進行某些資料的隔離(比方緩存)。友善業務實作。

隔離的實作

租戶請求從開始到結束平台都須要知曉這個請求映射的命名空間。從請求處理棧我們能夠這樣大緻劃分一下:

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

在這個棧中每一層平台都是須要知道這個請求相應的命名空間的。平台能夠提供一個統一登入的服務,将租戶資訊映射為命名空間并儲存到使用者會話中,這樣每次該使用者的請求:

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

這裡我們使用的隔離實作基本思路是“Shared application”,即多租戶共享一個應用,相應一套基礎設施。

 一種平台設計

 前面談了這麼多,如今我們能夠腦補出一種支援應用多租戶的雲平台:

JNPF雲平台之多租戶的探索

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

總結

  • 租戶和客戶的概念類似
  • 對多租戶的支援我們一般指的是應用對多租戶的支援
  • 在技術層面支援多租戶須要實作資料/狀态隔離
  • 使用命名空間進行隔離實作抽象
  • 租戶到命名空間的映射可由平台內建

繼續閱讀