# 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 |