Rationalisierung der Autorisierung
Stellen Sie sich vor, Sie besuchen in den USA eine Bar (zur Erinnerung: Alkoholausschank erst ab 21 Jahren!). Beim Betreten der Bar kontrolliert man Ihren Ausweis und jedes Mal, wenn Sie einen Drink bestellen, wird Ihr Ausweis erneut kontrolliert. Genau so lief es mit der Autorisierung bis zur Version 7.16 ab: Jeder Knoten (Eingangstür) verlangte eine Autorisierung und jede Shard (Drinkbestellung) ebenfalls. Wie wäre es aber, wenn eine einmalige Ausweisprüfung an der Eingangstür ausreichen würde? Lassen Sie uns dieses Gleichnis auf eine Autorisierung in Elasticsearch anwenden!
Bei Elasticsearch können Nutzer eine rollen-/attributbasierte Zugriffssteuerung einrichten, um granulare Berechtigungen auf Feld-, Dokument- oder Indexebene zu gewähren. Vorher gab es in vielen Phasen einer Suchabfrage
Autorisierungsschritte, um sicherzustellen, dass niemand Unbefugtes auf Daten zugreifen kann. Die Sicherheit, die die Autorisierungsfunktion ermöglicht, hat aber ihren Preis und einige der dabei verwendeten Logiken lassen sich nicht horizontal skalieren, wenn der Cluster größer wird. So kann zum Beispiel das Abrufen von Feldfunktionen für alle Felder in allen Indizes in einem großen Cluster viele Sekunden oder sogar Minuten dauern, wobei fast die gesamte Ausführungszeit mit autorisierungsbezogenen Arbeiten verbracht wird.
7.16 nimmt sich dieser Probleme von zwei Seiten aus an:
- Algorithmische Verbesserungen sorgen für schnellere individuelle Anforderungsautorisierungen, sowohl was REST-Anforderungen als auch was Autorisierungen während der Kommunikation in der Transportschicht (also die gesamte interne Netzwerkkommunikation zwischen den Knoten in einem Elasticsearch-Cluster) betrifft.
- Die Autorisierung interner Anforderungen wird entweder von vorherigen Prüfungen übernommen oder in vielen Fällen deutlich kostengünstiger gemacht. Bis zur Version 7.16 hat Elasticsearch beim Autorisieren interner Transportanforderungen innerhalb des Clusters dieselbe Autorisierungslogik eingesetzt, die auch schon die erste externe Anforderung hat durchlaufen müssen. Auf diese Weise wurde die Einführung einer Angriffsoberfläche in der internen Knoten-zu-Knoten-Kommunikation verhindert, die es einem Angreifer ermöglicht hätte, mithilfe gefälschter interner Anfragen die Autorisierungslogik zu umgehen. Durch das Überspringen der Platzhalter-Erweiterung bei Unteranfragen, das Überspringen der Autorisierung für knotenlokale Anfragen (im selben Knoten) und die Reduzierung der Gesamtzahl von Anforderungen, die für Aktionen wie die Suche erforderlich sind, ist dies jetzt mit deutlich weniger Kosten verbunden.
Reduzierung von Shard-Anfragen in der Vorabfilterphase
In 7.16 wurde eine neue Suchstrategie für die mit pre_filter_shard_size
eingerichtete Vorabfilterphase implementiert, mit der die Zahl der Anfragen pro gefundenen Knoten auf eine reduziert wird. Bis zur Version 7.16 erforderte die erste Phase einer Suche, in der versucht wird, alle Shards aus der Abfrage herauszufiltern, von denen bekannt ist, dass sie keine relevanten Daten enthalten, seitens des koordinierenden Knotens für jede Shard eine eigene Anfrage an einen Datenknoten. Wenn Tausende von Shards gleichzeitig abgefragt werden, bedeutete dies, dass Tausende von Anfragen pro Suchanfrage vom koordinierenden Knoten gesendet, Tausende von Antworten auf dem koordinierenden Knoten verwaltet und alle diese Anfragen auf den Datenknoten bearbeitet werden mussten. Das Skalieren des Clusters durch Hinzufügen zusätzlicher Datenknoten hilft zwar, die Performance der Verarbeitung dieser Menge von Anfragen auf den Datenknoten zu verbessern, bringt aber nichts für die Performance dieser Operation auf dem koordinierenden Knoten.
In Version 7.16 wurde die Strategie zur Ausführung der Vorabfilterphase
so geändert, dass pro Knoten nur noch eine Anfrage gesendet wird, die dann für alle Shards auf dem Knoten gilt. Dies wird in Abbildung 1 dargestellt. Für ein Cluster mit Tausenden von Shards, die über drei Datenknoten verteilt sind, bedeutet dies, dass sich die Zahl der Netzwerkanfragen in der anfänglichen Suchphase von Tausenden auf drei oder weniger reduziert, und dies ganz unabhängig von der Zahl der Shards in der Suche. Da die Anfragen pro Shard in den Versionen vor 7.16 im Wesentlichen alle dieselben Daten enthielten – nämlich die Suchabfrage –, führt das Senden nur einer Anfrage pro Knoten dazu, dass diese Informationen nicht mehr über mehrere Anfragen dupliziert werden. Das Ergebnis ist eine sehr deutliche Reduzierung der Zahl der Bytes, die durch das Netzwerk geschickt werden.