Serviceaffiniteit configureren en gebruiken in Service Fabric

Affiniteit is een besturingselement dat voornamelijk wordt geboden om de overgang van grotere monolithische toepassingen naar de cloud en microserviceswereld te vergemakkelijken. Het wordt ook gebruikt als optimalisatie voor het verbeteren van de prestaties van services, hoewel dit bijwerkingen kan hebben.

Stel dat u een grotere app, of een app die niet is ontworpen met microservices in gedachten, meeneemt naar Service Fabric (of een gedistribueerde omgeving). Dit type overgang is gebruikelijk. U begint door de hele app in de omgeving te tillen, in te pakken en ervoor te zorgen dat deze probleemloos werkt. Vervolgens begint u het op te delen in verschillende kleinere services die allemaal met elkaar communiceren.

Uiteindelijk zult u merken dat de toepassing een aantal problemen ondervindt. De problemen vallen meestal in een van deze categorieën:

  1. Sommige onderdelen X in de monolithische app hadden een niet-gedocumenteerde afhankelijkheid van onderdeel Y en u hebt deze onderdelen zojuist omgezet in afzonderlijke services. Omdat deze services nu worden uitgevoerd op verschillende knooppunten in het cluster, zijn ze verbroken.
  2. Deze onderdelen communiceren via (lokale named pipes | gedeeld geheugen | bestanden op schijf) en ze moeten nu om prestatieredenen echt naar een gedeelde lokale resource kunnen schrijven. Die harde afhankelijkheid wordt later misschien verwijderd.
  3. Alles is in orde, maar het blijkt dat deze twee onderdelen eigenlijk chatty/prestatiegevoelig zijn. Toen ze deze naar afzonderlijke services verplaatsten, namen de algehele prestaties van toepassingen toe of namen de latentie toe. Als gevolg hiervan voldoet de algehele toepassing niet aan de verwachtingen.

In deze gevallen willen we ons herstructureringswerk niet kwijtraken en willen we niet teruggaan naar de monoliet. De laatste voorwaarde kan zelfs wenselijk zijn als een eenvoudige optimalisatie. Totdat we de onderdelen opnieuw kunnen ontwerpen om op een natuurlijke manier te werken als services (of totdat we de prestatieverwachtingen op een andere manier kunnen oplossen), hebben we een gevoel van lokaliteit nodig.

Wat u moet doen? Nou, je kunt proberen affiniteit in te schakelen.

Affiniteit configureren

Als u affiniteit wilt instellen, definieert u een affiniteitsrelatie tussen twee verschillende services. U kunt affiniteit zien als het 'wijzen' van de ene service naar een andere service en het zeggen: 'Deze service kan alleen worden uitgevoerd waar die service wordt uitgevoerd'. Soms verwijzen we naar affiniteit als een bovenliggende/onderliggende relatie (waarbij u het kind naar de bovenliggende relatie wijst). Affiniteit zorgt ervoor dat de replica's of exemplaren van de ene service op dezelfde knooppunten worden geplaatst als die van een andere service.

ServiceCorrelationDescription affinityDescription = new ServiceCorrelationDescription();
affinityDescription.Scheme = ServiceCorrelationScheme.Affinity;
affinityDescription.ServiceName = new Uri("fabric:/otherApplication/parentService");
serviceDescription.Correlations.Add(affinityDescription);
await fabricClient.ServiceManager.CreateServiceAsync(serviceDescription);

Notitie

Een onderliggende service kan slechts deelnemen aan één affiniteitsrelatie. Als u wilt dat het kind wordt gekoppeld aan twee bovenliggende services tegelijk, hebt u een aantal opties:

  • De relaties omkeren (parentService1 en parentService2 hebben een punt naar de huidige onderliggende service), of
  • Wijs een van de bovenliggende items standaard aan als hub en zorg ervoor dat alle services naar die service verwijzen.

Het resulterende plaatsingsgedrag in het cluster moet hetzelfde zijn.

Verschillende affiniteitsopties

Affiniteit wordt weergegeven via een van de verschillende correlatieschema's en heeft twee verschillende modi. De meest voorkomende affiniteitsmodus is wat we NonAlignedAffinity noemen. In NonAlignedAffinity worden de replica's of exemplaren van de verschillende services op dezelfde knooppunten geplaatst. De andere modus is AlignedAffinity. Uitgelijnde affiniteit is alleen nuttig met stateful services. Als u twee stateful services configureert voor een op elkaar afgestemde affiniteit, zorgt u ervoor dat de primaire functies van deze services op dezelfde knooppunten als elkaar worden geplaatst. Het zorgt er ook voor dat elk paar secundaire bestanden voor deze services op dezelfde knooppunten wordt geplaatst. Het is ook mogelijk (maar minder gebruikelijk) om NonAlignedAffinity te configureren voor stateful services. Voor NonAlignedAffinity worden de verschillende replica's van de twee stateful services uitgevoerd op dezelfde knooppunten, maar hun primaire versies kunnen op verschillende knooppunten terechtkomen.

Affiniteitsmodi en hun effecten

Gewenste status van de beste inspanning

Een affiniteitsrelatie is best effort. Het biedt niet dezelfde garanties van collocatie of betrouwbaarheid die in hetzelfde uitvoerbare proces worden uitgevoerd. De services in een affiniteitsrelatie zijn fundamenteel verschillende entiteiten die kunnen mislukken en onafhankelijk kunnen worden verplaatst. Een affiniteitsrelatie kan ook worden verbroken, hoewel deze onderbrekingen tijdelijk zijn. Capaciteitsbeperkingen kunnen bijvoorbeeld betekenen dat slechts enkele serviceobjecten in de affiniteitsrelatie op een bepaald knooppunt passen. In deze gevallen, zelfs als er een affiniteitsrelatie aanwezig is, kan deze niet worden afgedwongen vanwege de andere beperkingen. Als dit mogelijk is, wordt de schending later automatisch gecorrigeerd.

Ketens versus sterren

De cluster-Resource Manager kan momenteel geen ketens van affiniteitsrelaties modelleren. Dit betekent dat een service die een onderliggend element is in de ene affiniteitsrelatie, geen bovenliggende service in een andere affiniteitsrelatie kan zijn. Als u dit type relatie wilt modelleren, moet u deze als een ster modelleren in plaats van een keten. Als u van een keten naar een ster wilt gaan, wordt het onderste onderliggende kind in plaats daarvan bovenliggend op het bovenliggende element van het eerste kind. Afhankelijk van de rangschikking van uw services, moet u dit mogelijk meerdere keren doen. Als er geen natuurlijke bovenliggende service is, moet u mogelijk een service maken die als tijdelijke aanduiding fungeert. Afhankelijk van uw vereisten wilt u mogelijk ook kijken naar toepassingsgroepen.

Ketens versus sterren in de context van affiniteitsrelaties

Een ander ding om op te merken over affiniteitsrelaties is dat ze standaard directioneel zijn. Dit betekent dat de affiniteitsregel alleen afdwingt dat het onderliggende item met het bovenliggende item is geplaatst. Het zorgt er niet voor dat het bovenliggende item zich bij het kind bevindt. Als er een affiniteitsschending is en om de schending om de een of andere reden te corrigeren, is het daarom niet haalbaar om het kind naar het knooppunt van het bovenliggende item te verplaatsen, zelfs als het verplaatsen van het bovenliggende item naar het knooppunt van het kind de schending zou hebben gecorrigeerd. Als u de configuratie MoveParentToFixAffinityViolation instelt op true, wordt de directionaliteit verwijderd. Het is ook belangrijk om te weten dat de affiniteitsrelatie niet perfect of direct kan worden afgedwongen, omdat verschillende services verschillende levenscyclussen hebben en kunnen mislukken en onafhankelijk van elkaar kunnen worden verplaatst. Stel dat het bovenliggende knooppunt plotseling een failover uitvoert naar een ander knooppunt omdat het is vastgelopen. De failover wordt eerst afgehandeld door de cluster-Resource Manager en failoverbeheer, omdat het de prioriteit is om de services up-, consistent en beschikbaar te houden. Zodra de failover is voltooid, wordt de affiniteitsrelatie verbroken, maar de cluster-Resource Manager denkt dat alles in orde is totdat wordt opgemerkt dat het onderliggende element zich niet bij het bovenliggende item bevindt. Dit soort controles worden periodiek uitgevoerd. Meer informatie over hoe de Cluster-Resource Manager beperkingen evalueert, is beschikbaar in dit artikel. In dit artikel wordt meer uitgelegd over het configureren van het ritme waarop deze beperkingen worden geëvalueerd.

Ondersteuning voor partitionering

Het laatste wat u opvalt over affiniteit, is dat affiniteitsrelaties niet worden ondersteund wanneer het bovenliggende element is gepartitioneerd. Gepartitioneerde bovenliggende services kunnen uiteindelijk worden ondersteund, maar momenteel is dit niet toegestaan.

Volgende stappen