JNPF雲平臺之多租戶的探索

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

什麼是租戶

剛開始接觸這個概念時,你確定感受「租戶」這個詞怪怪的。但假設咱們換個詞,我相信你當即就有感受了。這個詞就是「客戶」(這裏的客戶指的就是商業上面的客戶)。數據庫

一個租戶就是一個客戶,比方咱們開發的服務是給 XXX 企業使用的,那該企業就是咱們的一個客戶/租戶;假設這個服務是面向互聯網的,那麼使用該服務的每個互聯網用戶都是一個客戶/租戶。緩存

爲何需要多租戶支持

開發人員辛辛苦苦開發出一個服務。提供給了我的/企業使用,這樣就完事了麼?固然不該該僅僅是這樣。咱們開發出一個服務。最好是能夠同一時候提供給多個我的/企業使用。而且這些客戶最好是共享同一套服務執行時(Runtime),這樣能夠大大減小服務的運維成本:架構

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

另外,這樣也可以減小服務的開發成本:app

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

多租戶場景舉例負載均衡

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

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

比方現在的業務是「公佈文章」。需要將文章數據保存在 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」,即多租戶共享一個應用,相應一套基礎設施。

 一種平臺設計

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

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

總結

  • 租戶和客戶的概念相似
  • 對多租戶的支持咱們通常指的是應用對多租戶的支持
  • 在技術層面支持多租戶需要實現數據/狀態隔離
  • 使用命名空間進行隔離實現抽象
  • 租戶到命名空間的映射可由平臺集成
相關文章
相關標籤/搜索