在Azure中管理多租户存储的最有效方法?

时间:2015-03-22 03:49:24

标签: azure azure-storage multi-tenant

我们正在创建一个必须在租户之间隔离数据的多租户应用程序。每个租户将保存各种文档,每个文档可以分为几个不同的文档类别。我们计划对这些文档使用Azure blob存储。但是,考虑到我们的用户群以及每个文档的文档数量和大小,我们不确定如何使用当前的Azure订阅来最好地管理存储帐户。

以下是一些需要考虑的数字。拥有5,000名用户,每位用户每年27,000个8Mb文档,即每年1080TB。每个存储帐户的存储容器最大为500TB。

所以我的问题是存储这些数据并保持在Azure限制内的最有效和最具成本效益的方法是什么?

以下是我们考虑过的一些事项:

  1. 为每个客户创建一个存储帐户。这不起作用,因为每个订阅只能有100个存储帐户(这可能是最理想的解决方案)。

  2. 为每个客户端创建一个blob容器。存储帐户最多可以有500TB,因此除非最终我们必须拆分为其他存储帐户,否则这可能会有效。如果用户最终在两个帐户中拥有数据,我不确定这将如何起作用。可能会变得混乱。

  3. 也许我们在这里遗漏了一些根本简单的东西。

    更新 目前我们的想法是使用Azure表存储,每个文档类型都有一个表。在每个表中,分区键是租户的ID,行键是文档ID。每行还包含文档的元数据类型信息,以及链接到blob本身的URI(或其他内容)。

2 个答案:

答案 0 :(得分:8)

不是一个真正的答案,而是将其视为"思考的食物" :)。基本上,您的架构应该基于每个存储帐户都有scalability targets的事实,并且您的设计应该不超过那些以保持应用程序的高可用性存储。

一些建议:

  • 首先创建多个存储帐户(比如10开头)。我们称他们为Pods
  • 每个租户都会获得一个吊舱。您可以随机选择一个pod存储帐户或使用一些预定义的逻辑。有关pod的信息存储在旁边的租户信息中。
  • 从描述中看来,目前您只需将文件信息存储在一个表中。这会给一个表/存储帐户带来很大的压力,这不是一个可扩展的设计恕我直言。而是在创建租户时,将一个窗格分配给租户,然后为每个租户创建一个表,该表将文件信息存储在该表中。这将带来以下好处:1)您已经很好地隔离了每个租户数据,2)读取请求现在是负载平衡的,因此允许您保持在可伸缩性目标内; 3)由于每个租户数据位于单独的表中,因此{{ 1}}变得自由,如果需要,你可以分配一些其他值。

现在开始存储文件:

  • 您可以再次使用PartitionKey概念,其中每个租户的文件都位于该租户的Pod存储帐户中。
  • 如果您发现此方法存在问题,可以随机选择pod存储帐户并将文件放在那里,并将blob网址存储在pod表中。
  • 你可以只使用一个blob容器(比如Files)或为每个租户分别使用blob容器。
  • 只有一个Blob容器适用于所有租户,管理开销较小,因为您只需在调试新tenant-files时创建此容器。然而,缺点是您无法按租户逻辑分隔文件,因此如果您想提供对文件的直接访问(使用共享访问签名),则会出现问题。
  • 每个租户使用单独的blob容器,管理开销更多,但是您可以获得良好的逻辑隔离。在这种情况下,当租户加入时,您必须在每个pod存储帐户中为该租户创建容器。同样,在调试新pod时,您必须确保为系统中的每个租户创建blob容器。

希望这能让您了解如何构建解决方案。我们在我们的解决方案中使用了其中一些概念(明确使用Azure存储作为数据存储)。看看你提出的架构真的很有趣。

答案 1 :(得分:3)

我只想把我的想法放在这个主题上,它确实有一些多余的信息给Gaurav Mantri的回答。这是基于我在目前的工作中做了非常相似的事情后想出的设计。

Azure Blob存储

  1. 创建租户时,从pod随机选择pod pool,并将其名称空间与租户信息一起存储。

  2. 提供api,用于创建容器名称由租户ID Guid::ToString("N") + <resourcename>组合而成的容器。你不需要把你的用户作为容器出售,我可以是文件夹,工作集或文件箱,你找到一个名字。

  3. 提供api以维护这些容器中的文档。

  4. 这意味着,如果获得更多租户,您只需增加pod pool即可删除那些已填满的pods

    这样做的好处是您不需要使用表存储和blob存储为您的数据保留两个系统。 Blob存储已经有一种方法可以将数据显示为目录/文件层次结构。

    扩展点

    Blob存储Api Broker

    除了上述设计之外,我制作了一个Owin中间件,它包含在客户端和blob存储之间,基本上只是将请求从客户端转发到blob存储。 此步骤不需要,因为您可以委派正常的sas令牌并直接与客户端的blob存储通信。但它可以很容易地在文件上执行操作时挂钩。每个租户都将获得自己的端点files/teantid/<resourcename>/

    使用这样的API还可以使您挂钩到您可能已经使用的任何令牌身份验证系统,以验证身份验证并授权传入的请求,然后在此API中签署请求。

    Blob存储元数据

    使用上面的api代理扩展,结合元数据,实际上可以更进一步,修改传入请求以始终包含元数据,并在将xml返回到blob存储之前添加过滤器,然后再将其发送给客户端以过滤容器或斑点。一个示例是当用户删除blob时,然后设置x-ms-meta-status:deleted并在返回blob /容器时将其过滤掉。这样,您可以添加不同的过程来删除幕后数据。

    这里应该小心,因为你不想在这里加入太多的逻辑,因为它会对所有请求增加一个惩罚,但是聪明地做这个可以使这个工作非常好。

    此扩展还允许您允许用户在容器内创建“空”子文件夹,但放置一个状态为:hidden的零字节文件也将被过滤掉。 (请记住,如果存在虚拟文件夹,blob存储只能显示虚拟文件夹)。这也可以使用表存储来实现。

    Azure搜索

    另一个很好的扩展点是,对于每个blob,您可以将其保存在Azure搜索中以便能够查找内容,这很可能是我最喜欢的。我没有看到任何好的解决方案,只使用blob存储或表存储,可以为您提供良好的搜索功能或甚至一些良好的过滤体验。使用Azure搜索,这将为用户提供真正丰富的再次查找内容的体验。

    快照

    另一个扩展是每次自动修改文件时都可以创建快照。使用代理api会变得更加容易,否则监视日志是一种选择。

    这些想法来自我刚开始分享的一个项目,但由于我在接下来的几个月里忙着上班,所以我不认为自己在暑假前发布我的项目给我时间。该项目的动机是提供一个nuget包,使其他开发人员能够快速设置我上面提到的这个代理api并配置多租户blob存储解决方案。

    如果你读到这篇文章并且相信这样的项目可以节省你在当前开发过程中的时间,我恳请你投票给这个答案。通过这种方式,我可以看到我是否可以在项目上使用更多时间。

    我认为gaurav Mantris的答案更适合上述问题,但只是想分享我对这个主题的想法。