2017-05-11 36 views
1

我們有一個B2B模型,我們在Azure爲我們的小企業客戶的員工,合作伙伴和客戶託管一個門戶。目前,我們在node.js網絡應用程序中運行良好,但我們希望轉移到大規模的Azure功能,這使我們重新思考最初的設計。在DocumentDB中分隔租戶和主機名的最佳方式是什麼?

目前,該進來的web應用程序的每個XHR請求經過這樣的邏輯:

  1. 得到對應的主機名
  2. 的siteconfig文件從siteconfig文檔檢索的organization_ID
  3. 插入organization_id納入查詢的WHERE子句

我們使用node-cache將siteconfig文檔存儲在內存中,因此檢索ti mes仍然非常快,只有在第一次請求主機名時,我們會連續運行兩個查詢。

由於Azure函數不會在請求之間存儲狀態或緩存,所以我們將無法緩存主機名/組織ID關係。同樣,如果我們爲每個請求在一個Function中運行兩個DocumentDB查詢,那麼我們的數據庫成本將幾乎翻倍。

所以我的問題是這樣的 - 是否有一個很好的方法來檢索這個信息在一個單一的查詢,可以加載到Azure功能?在舊世界的RDBMS我只是用一個連接或者甚至一個子查詢是這樣的:

SELECT c.name, c.price 
FROM c 
WHERE c.type = "product" 
AND c.organization_id = 
    (SELECT d.organization_id FROM d WHERE d.hostname = @hostname) 

這裏有以下一些樣本文檔。具體而言,當一個請求進入到我們要返回小部件和Widget b。使用一個單一的查詢,但不作爲的小工具屬於不同的公司portal.xyz.com/api/products。

{ 
    id: "17500961", 
    type: "organization", 
    name: "XYZ inc." 
} 

{ 
    id: "34903332", 
    type: "siteconfig", 
    hostname: "portal.xyz.com", 
    organizationid: "17500961" 
} 

{ 
    id: "86785057", 
    type: "product", 
    name: "Widget A", 
    price: "9.99", 
    organizationid: "17500961" 
} 

{ 
    id: "17979681", 
    type: "product", 
    name: "Widget B", 
    price: "14.99", 
    organizationid: "17500961" 
} 

{ 
    id: "24669887", 
    type: "product", 
    name: "Gadget", 
    price: "899", 
    organizationid: "31514620" 
} 

我們不想依賴於來自客戶端的數據請求中的organizationid,這提供了內部安全明知X公司不能檢索任何組織數據,但他們自己的,因爲在確定服務器通過傳入的請求頭。

一個解決方案已經在我腦海中消失是將主機名添加到每個文件,但是,似乎是多餘/複製數據的極端金額。

請問DocumentDB專家謹慎權衡這個並提供一些指導?

+0

我第一次給你的建議是在兩次往返的情況下實現它,然後只有在你驗證這不是高性能或太昂貴後才優化到本地高速緩存。 –

+0

你是說在DocumentDB中的單個查詢中確實沒有辦法做到這一點? – Graham

+0

您可以使用您建議的方法,緩存或Fabios其他建議。但是,這些增加了複雜性。我所說的只是嘗試直接前進兩次往返的方法,然後再訴諸於複雜性。 –

回答

1

有人可能能夠提供額外的選項,當涉及到宇宙DB/DocumentDB,但這裏有一些你從Azure的功能角度有選擇:

1.使用認證信息導出組織ID

你還沒有描述你是如何驗證你的用戶的,但是一種非常常見的方法是確保像你的租戶ID(在你的情況下是組織ID)在簽名中作爲索賠出現令牌可以在服務器上驗證。這完全消除了令牌發佈後緩存或額外查找的需要。

2。使用外部緩存

Azure Redis Cache外部緩存將讓你保持你需要你的函數環境之外的狀態,因爲它擴展將是從功能應用實例訪問。這在一個偉大的價值提供了極大的性能(你需要的費用比較你會根據你的負載來支付憑證DB請求)

3.局部靜態映射

使用此選項僅作爲後備,因爲它不可預測,並可能隨時間而改變。推薦其他2個選項

您可以在Function App環境中維護本地緩存以減少查找次數。該緩存將確保這些查找不會發生在每個請求上,而是針對每個運行時實例,因此,當您的函數應用擴展時,新實例將不會填充該緩存,但是一旦信息被緩存,後續請求將觸發相同的主機需要獲取組織信息。 你需要保持密切關注該應用程序的行爲,如果您選擇使用此解決方案,因爲,正如上面提到的,它可能會有所不同,不會像預測的

我希望這有助於。

+0

你能否詳細說明#1?特別是,你如何在令牌中嵌入一些東西?和,你如何驗證它? –

+0

Fabio答案#3的註釋:1)D:\ HOME(環境變量%HOME%)在所有實例中共享。 D:\ local \ Temp(%TMP%)和D:\ local \ AppData(%APPDATA%)不在實例之間共享。這些大小取決於。 2)爲了獲得Azure函數的本地緩存,我使用了%TMP%和node-localstorage的JSONStorage類。 3)#2增加了複雜性。我對#3的建議也是如此,但更少。我的理念是做最簡單的工作,到目前爲止,我不必訴諸於外部Redis Cache之類的東西,所以我相信它實際上超過了#2恕我直言。 –

+0

謝謝,這有很多很棒的信息。身份驗證令牌可以工作,但我必須小心,因爲一個最終用戶可以訪問我們多個客戶的門戶。 Redis Cache看起來很棒,而且非常划算。 – Graham

相關問題