# Implementierung von Multi-Tenancy in MyScale

Da LLMs immer bekannter und beliebter werden, erkunden immer mehr Entwickler den CVP (ChatGPT, Vektordatenbank, Prompt)-Stack, um Anwendungen für verschiedene Benutzer oder Benutzergruppen zu erstellen. Es ist entscheidend, die Unterstützung für Multi-Tenancy in Vektordatenbanken zu ermöglichen, um diese Anforderung zu erfüllen. Diese Anleitung hilft Ihnen dabei, Multi-Tenancy in MyScale zu verstehen und umzusetzen.

# Verständnis von Multi-Tenancy

Multi-Tenancy in einer Vektordatenbank (Anwendung) bezieht sich auf die Fähigkeit der Datenbank, mehrere Mandanten oder Benutzer (oder Benutzergruppen) zu bedienen, während ihre Daten logisch voneinander isoliert bleiben. Die Daten jedes Mandanten werden in einer Multi-Tenant-Architektur separat gespeichert und verwaltet, obwohl sie die gleiche physische Infrastruktur und Ressourcen teilen.

Die Implementierung von Multi-Tenancy in Vektordatenbankanwendungen sollte vier Hauptanforderungen erfüllen:

  • Performance-Neutralität: Ein Konzept, das darauf abzielt, eine konsistente und vergleichbare Leistung für alle Multi-Tenant- und Single-User-Workloads, einschließlich aller CRUD (Create, Read, Update, Delete)-Operationen, aufrechtzuerhalten.
  • Datenisolierung: Die Daten jedes Mandanten sollten getrennt gespeichert werden.
  • Skalierbarkeit: Die Anwendung sollte eine große Anzahl von Mandanten unterstützen.
  • Effiziente Ein- und Auslagerung: Das Hinzufügen oder Entfernen eines Mandanten sollte sich nicht auf andere Mandanten auswirken.

# Strategien zur Implementierung von Multi-Tenancy

Die Implementierung von Multi-Tenancy in MyScale erfordert sorgfältige Planung und Berücksichtigung, um Datenisolierung, Sicherheit und Leistung zu gewährleisten.

Hier sind einige Strategien und bewährte Verfahren zur effektiven Implementierung von Multi-Tenancy:

# Tabellenorientierte Multi-Tenancy

In MyScale wird jede Tabelle separat gespeichert, was es einfach macht, mehrere Tabellen innerhalb eines einzigen Clusters zu erstellen. Für jeden Mandanten können Sie eine dedizierte Tabelle erstellen. Zum Beispiel erstellt die folgende SQL-Anweisung eine Tabelle für einen Chatbot-Mandanten:

CREATE TABLE db.message_chatbot1
(
    user_id      FixedString(16),
    message_id   FixedString(16),
    timestamp    DateTime,
    message_embedding  Array(Float32),
    CONSTRAINT check_length CHECK length(message_embedding) = 768
) ENGINE = MergeTree
ORDER BY message_id

Die Vektorsuche für diese Strategie ist ähnlich wie bei einem einzelnen Mandanten. Sie können einen Mandanten löschen, indem Sie seine Tabelle löschen, was sich nicht auf andere Mandanten auswirkt. Diese Strategie kann jedoch zu Ressourcenverschwendung führen und ist für Multi-Tenancy im großen Maßstab ungeeignet. Daher wird empfohlen, bei einem MyScale-Cluster mit Pod-Größe x1 nicht mehr als 100 Tabellen zu haben.

Diese Strategie ermöglicht auch eine rollenbasierte Zugriffskontrolle (Role-Based Access Control, RBAC)), bei der verschiedenen Benutzern und Rollen unterschiedliche Tabellen zugewiesen werden.

# Metadatenfilterorientierte Multi-Tenancy

Die metadatenfilterorientierte Multi-Tenancy ist ein Ansatz zur Implementierung von Multi-Tenancy in einem Datenbanksystem, bei dem Daten für mehrere Mandanten in denselben Tabellen gespeichert werden. Der Zugriff auf die Daten wird anhand von Metadaten oder Attributen, die jedem Datensatz zugeordnet sind, gesteuert und isoliert, was eine effiziente Speicherung ermöglicht und gleichzeitig eine robuste Datenisolierung und Sicherheit gewährleistet.

In der Praxis verwendet die metadatenfilterorientierte Multi-Tenancy das Mandantenfeld als Filter und kann auf drei Arten erreicht werden: partitionsschlüsselbasiert, primärschlüsselbasiert oder eine Kombination aus beidem.

# Partitionsschlüsselbasierte Multi-Tenancy

Die Datenisolierung wird durch Zuweisen einer eindeutigen Partition an jeden Mandanten erreicht. Die folgende SQL-Anweisung beschreibt die Erstellung einer nach Benutzer-ID partitionierten Tabelle, wobei jeder Benutzer einem Mandanten (Partition) entspricht:

CREATE TABLE db.message_app
(
    user_id      FixedString(16),
    message_id   FixedString(16),
    timestamp    DateTime,
    message_embedding  Array(Float32),
    CONSTRAINT check_length CHECK length(message_embedding) = 768
) ENGINE = MergeTree
ORDER BY message_id
PARTITION BY user_id

Bei der Ausführung einer Vektorsuche verwenden Sie das Mandantenfeld als Filter, um die entsprechende Partition zu finden, wie in der folgenden SQL-Anweisung:

SELECT message_id, distance(data, [...]) AS dist
FROM db.message_app 
WHERE user_id = 'xxxxxxxxxxxxxxxx'
ORDER BY dist LIMIT 10

Darüber hinaus können Sie eine Partition (Mandanten) leicht mit diesem Befehl löschen:

ALTER TABLE db.message_app DROP PARTITION 'xxxxxxxxxxxxxxxx'

TIP

Für optimale INSERT- und Abfrageleistung wird empfohlen, die Gesamtzahl der Partitionen in einer Tabelle in einem MyScale-Cluster mit Pod-Größe x1 unter 100 zu halten.

# Primärschlüsselbasierte Multi-Tenancy

Das Mandantenfeld ist in dieser Strategie der Primärschlüssel, was die Abrufgeschwindigkeit von Mandantendaten erhöht.

Diese Strategie beschränkt nicht die Anzahl der Mandanten. Daten von allen verschiedenen Mandanten werden in einer Partition gespeichert. Zum Beispiel beschreibt die folgende SQL-Anweisung, wie eine Tabelle erstellt wird, bei der jeder Benutzer als Mandant behandelt wird:

CREATE TABLE db.message_app
(
    user_id      FixedString(16),
    timestamp    DateTime,
    message_id   FixedString(16),
    message_embedding  Array(Float32),
    CONSTRAINT check_length CHECK length(message_embedding) = 768
) ENGINE = MergeTree
ORDER BY (user_id, message_id)

Eine Vektorsuche in dieser Strategie ist ähnlich wie bei der partitionsschlüsselbasierten Strategie.

Jedoch ist das Löschen eines Mandanten langsamer und erfordert eine DELETE FROM-Anweisung, wie die folgende SQL-Anweisung zeigt:

DELETE FROM TABLE db.message_app WHERE user_id = 'xxxxxxxxxxxxxxxx' 

# Partition + Primärschlüsselbasierte Multi-Tenancy

Sie können Ressourcenisolierung und Mandantenskalierbarkeit durch Kombination der partitionsschlüssel- und primärschlüsselbasierten Multi-Tenancy-Strategien ausbalancieren. Diese Methode speichert Daten von mehreren Mandanten in derselben Partition und unterstützt Multi-Tenancy im großen Maßstab bei gleichzeitig moderater Isolierung.

Zum Beispiel zeigt die folgende SQL-Anweisung, wie eine Tabelle erstellt wird, die Mandantendaten auf zehn Partitionen verteilt:

CREATE TABLE db.message_app
(
    user_id      FixedString(16),
    timestamp    DateTime,
    message_id   FixedString(16),
    message_embedding  Array(Float32),
    CONSTRAINT check_length CHECK length(message_embedding) = 768
) ENGINE = MergeTree
ORDER BY (user_id, message_id)
PARTITION BY sipHash64(user_id) % 10

Die Ausführung von Vektorsuchen und das Löschen von Mandanten erfolgt wie bei der primärschlüsselbasierten Strategie. Die INSERT-Leistung kann jedoch langsamer sein, insbesondere beim Umgang mit mehreren Partitionen innerhalb eines einzelnen Einfügebereichs. Daher ist das Einfügen von Daten mit derselben Partition in einem einzelnen Block bewährte Praxis für diese Strategie.

# Zusammenfassung

Hier ist eine Zusammenfassung der von uns empfohlenen Multi-Tenancy-Strategien und ihrer Eigenschaften:

Multi-Tenancy-Modell Performance-Overhead Isolationsniveau Mandantenskalierung Einfache Ein- und Auslagerung
Tabellenorientiert Hoch Stark Mittel Hoch
Partitionsschlüsselbasiert Hoch Mittel Mittel Hoch
Primärschlüsselbasiert Niedrig Schwach Groß Mittel
Partition + Primärschlüsselbasiert Mittel Schwach Groß Mittel
Last Updated: Sat Apr 13 2024 10:45:55 GMT+0000