簡體   English   中英

為什么將服務結構服務的分區策略綁定到分區而不是服務?

[英]Why is the partitioning strategy for a service fabric service tied to the partition instead of to the service?

我剛剛開始為Service Fabric應用程序編寫一些動態端點發現,並正在尋找有關如何解析服務端點的示例。 我在stackoverflow上找到了以下代碼示例:

https://stackoverflow.com/a/38562986/4787510

我對此做了一些小的改動,所以這是我的代碼:

private readonly FabricClient m_fabricClient

public async Task RefreshEndpointList()
{
        var appList = await m_fabricClient.QueryManager.GetApplicationListAsync();
        var app = appList.Single(x => x.ApplicationName.ToString().Contains("<MyFabricDeploymentName>"));

        // Go through all running services
        foreach (var service in await m_fabricClient.QueryManager.GetServiceListAsync(app.ApplicationName))
        {
            var partitions = await m_fabricClient.QueryManager.GetPartitionListAsync(service.ServiceName);

            // Go through all partitions
            foreach (var partition in partitions)
            {
                // Check what kind of service we have - depending on that the resolver figures out the endpoints.
                // E.g. Singleton is easy as it is just one endpoint, otherwise we need some load balancing later on
                ServicePartitionKey key;
                switch (partition.PartitionInformation.Kind)
                {
                    case ServicePartitionKind.Singleton:
                        key = ServicePartitionKey.Singleton;
                        break;
                    case ServicePartitionKind.Int64Range:
                        var longKey = (Int64RangePartitionInformation)partition.PartitionInformation;
                        key = new ServicePartitionKey(longKey.LowKey);
                        break;
                    case ServicePartitionKind.Named:
                        var namedKey = (NamedPartitionInformation)partition.PartitionInformation;
                        key = new ServicePartitionKey(namedKey.Name);
                        break;
                    default:
                        throw new ArgumentOutOfRangeException($"Can't resolve partition kind for partition with id {partition.PartitionInformation.Id}");
                }

                var resolvedServicePartition = await ServicePartitionResolver.GetDefault().ResolveAsync(service.ServiceName, key, CancellationToken.None);

                m_endpointCache.PutItem(service.ServiceTypeName, new ServiceDetail(service.ServiceTypeName, service.ServiceKind, ServicePartitionKind.Int64Range, resolvedServicePartition.Endpoints));
            }
        }
    }
}

我很高興找到了這個片段,但是在研究它的過程中,我發現一件事讓我有些困惑。

因此,在閱讀完SF文檔之后,據我所知,這似乎是它從上到下遵循的體系結構:

服務結構集群->服務結構應用程序(例如myApp_Fabric)->服務(例如,前端服務,個人資料圖片微服務,后端服務)

從服務中,我們可以深入到分區,而分區基本上類似於群集中節點上可以駐留多個實例(副本)的節點上的“容器”,實例是服務的實際部署。

不過,我不確定我是否正確設置了節點/分區/副本之間的差異。

但是,回到我的困惑和實際問題:

為什么有關分區策略的信息(單例,intRange,命名)附加在分區信息上,而不是附加在服務本身上? 據我了解,分區基本上是我將服務配置為分布在服務結構節點之間的產品。

那么,為什么分區策略不直接與服務綁定?

關於Service Fabric中的服務,有兩種類型:有狀態服務和無狀態服務。

無狀態服務不會使用可靠的集合來處理狀態。 如果他們需要維護狀態,則必須依賴外部持久性解決方案,例如數據庫等。由於它們不處理可靠集合提供的狀態,因此會為其分配Singelton分區類型。

有狀態服務具有將狀態存儲在可靠集合中的能力。 為了能夠擴展那些服務,應該將這些集合中的數據划分為多個分區。 每個服務實例都分配有一個特定的分區。 按服務指定分區數量,如以下示例所示:

<Service Name="Processing">
    <StatefulService ServiceTypeName="ProcessingType" TargetReplicaSetSize="3" MinReplicaSetSize="3">
        <UniformInt64Partition PartitionCount="26" LowKey="0" HighKey="25" />
    </StatefulService>
</Service>

因此,鑒於上述示例,我不理解您關於分區策略未直接綁定到服務的最后一句話。

鑒於上述情況,將運行該服務的26個實例,每個分區一個實例,再乘以副本數。

在無狀態服務的情況下,將只有一個分區(單例分區),因此實際實例數為1 * 3(副本數)=3。(3個副本只是一個示例。大多數情況下,實例數為無狀態服務設置為-1,表示集群中每個節點有1個實例。)

另一件事:在您的代碼中,在代碼迭代的分區中有一條注釋行:

//例如,Singleton很容易,因為它只是一個端點,否則稍后我們需要一些負載平衡

此注釋是錯誤的,說明分區與負載平衡有關。 並非如此,這與如何在服務實例上划分數據有關,並且您需要獲取處理特定分區的服務的地址。 假設我有一個包含26個分區的服務,並且我想獲取存儲在第5個分區中的數據。 然后,我需要獲取為該分區提供服務的實例的端點。

您可能已經閱讀了文檔 如果沒有,我建議也閱讀它。

解決您的意見:

我只是想知道,是否不可能在同一分區上運行多個服務?

可靠的集合使用它們與服務耦合,基礎分區也是如此。 因此,同一分區上只能運行一項服務。

但是,服務實例可以。 如果服務的副本大小為3,則將有3個實例為該分區提供服務。 但是主實例只有1個,讀寫復制到輔助實例的數據。

想象您的服務就像披薩一樣,當您請求披薩時,您要求披薩的味道(服務類型),通常不需要指定披薩切成薄片的方式(即:8件),通常比薩店會處理對您而言,根據比薩的大小,有些可能切成4、8或更多的切片。

創建服務實例時,您會以類似的方式看到,您需要一個服務,該服務將保存您的數據,並且您不必關心數據的存儲方式。

作為消費者,當您需要了解服務的分區時,就像打電話給比薩店,並要求他們將比薩餅切成4片而不是8片一樣,您仍然會得到相同的比薩餅,但是現在您需要擔心的是件將被切成薄片。 服務分區的主要問題在於,許多應用程序設計都會將此分區泄漏給客戶端,並且客戶端在使用之前需要知道它有多少個分區或放置在什么位置。

您不必在意將服務分區作為消費者,而應將其作為提供者(比薩店),假設您訂購了一個大比薩餅,而比薩店的包裝盒(節點)用完了再放入比薩餅,他們可以將比薩餅一分為二小盒子。 最終,消費者會收到相同的披薩,但要放在單獨的盒子中,必須處理它才能在其中找到切片。

以此類推,我們可以將比較視為:

  • 風味=服務類型
  • 披薩=服務
  • 大小和切片方式=分區方案
  • 切片=分區
  • Box =節點
  • 披薩數量=復制品

在Service Fabric中,將其解耦的原因是,消費者可以請求服務,而提供者可以決定如何對它進行分區,在大多數情況下,分區是在創建應用程序時靜態定義的,但它可以是動態的,就像在UniformInt64Partition中顯示的那樣,您可以定義特定服務實例所需的分區數量,可以在不更改代碼的情況下,使同一服務的多個實例具有不同的分區或不同的方案。 如何將這些分區公開給客戶端,是實現的詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM