paint-brush
Warum Sie ein Dateisystem nicht über einen Objektspeicher legen solltenvon@minio
6,908 Lesungen
6,908 Lesungen

Warum Sie ein Dateisystem nicht über einen Objektspeicher legen sollten

von MinIO7m2023/11/14
Read on Terminal Reader

Zu lang; Lesen

Wenn große Unternehmen für Deep Learning, KI und andere datenintensive Anwendungsfälle Unmengen an Daten speichern und darauf zugreifen müssen, verfügt POSIX nicht über die Fähigkeit oder Skalierbarkeit, diese Anforderungen zu erfüllen.
featured image - Warum Sie ein Dateisystem nicht über einen Objektspeicher legen sollten
MinIO HackerNoon profile picture
0-item
1-item

Beim Kauf von Speicher liegt der Schwerpunkt normalerweise auf den Medien, es kann jedoch noch wichtiger sein, auch Zugriffsmethoden zu berücksichtigen. Bei der Gestaltung und Beschaffung der Infrastruktur müssen Sie Speicherprotokolle berücksichtigen, insbesondere wenn Sie den Legacy-Speicher hinter sich lassen und auf Cloud-nativen Objektspeicher migrieren. Allerdings ist die Objektspeicherung für die Kommunikation auf die S3-API angewiesen, während ältere Workloads auf POSIX basieren, der Schnittstelle für tragbare Betriebssysteme, die eine Reihe von Standards bereitstellt, die in den 1980er Jahren entwickelt wurden, um die Portabilität von Anwendungen zwischen Unix-Betriebssystemen zu ermöglichen. Die Chancen stehen gut, dass die meisten Unternehmen seit Jahrzehnten Anwendungen im Einsatz haben, die für die Ausführung unter POSIX entwickelt wurden. Es besteht auch die Möglichkeit, dass sich die Ingenieure der schlechten Leistung von POSIX bereits bewusst sind.


Wenn Sie allerdings über Legacy-Systeme verfügen, die Daten nur in einem bestimmten Format oder aus einer bestimmten Quelle aufnehmen können, sind Ihre Möglichkeiten möglicherweise begrenzt und Sie haben möglicherweise keine andere Wahl, als ein veraltetes Protokoll zu implementieren oder Ihren Code neu zu schreiben. Wenn Sie beispielsweise nur von einer lokalen Festplatte mit einem Dateisystem und nicht mit RESTful-APIs, auf die über das Netzwerk zugegriffen wird, Daten aufnehmen können, müssen Sie diese Daten zunächst auf der Festplatte verfügbar machen, bevor Ihre Anwendung sie verwenden kann. Die Verwendung eines Objektspeichers als Dateisystem hat jedoch eine Reihe schwerwiegender negativer Auswirkungen auf Leistung, Kompatibilität, Datenintegrität und Sicherheit.


Lassen Sie uns dies anhand einiger realer Tests mit einem kleinen Dienstprogramm namens s3fs-fuse demonstrieren. Mit diesem Dienstprogramm können Sie einen S3-Bucket als lokales Dateisystem bereitstellen. Es steht für S3 (Simple Storage Service) File System – FUSE (Filesystem in Userspace). Es handelt sich um ein Open-Source-Projekt, das die FUSE-Schnittstelle (Filesystem in Userspace) nutzt, um eine dateisystemähnliche Schnittstelle zu S3 bereitzustellen.


Sobald ein S3-Bucket mit s3fs-fuse gemountet ist, können Sie mit dem Bucket interagieren, als wäre es ein lokales Dateisystem. Das bedeutet, dass Sie reguläre Dateivorgänge (wie Lesen, Schreiben, Verschieben usw.) für Dateien in Ihrem Bucket verwenden können. Das klingt erstaunlich praktisch und wir können behaupten, dass es die Anwendungsentwicklung vereinfacht. Aber von Natur aus weisen Objektspeicher und Dateisysteme grundlegende Unterschiede auf, die sich auf den als Dateisystem bereitgestellten S3-Bucket auswirken.


Nehmen wir uns einen Moment Zeit, um vom Dienstprogramm s3fs-fuse Abstand zu nehmen und die wahren Gründe zu diskutieren, warum die Behandlung von Objektspeicher als Dateisystem alles andere als optimal ist. Das Problem ist viel größer als s3fs-fuse und umfasst andere Dienstprogramme wie Rust-basiertes Mountpoint für Amazon S3 , einen Datei-Client, der lokale Dateisystem-API-Aufrufe in S3-Objekt-API-Aufrufe übersetzt. Der erste Grund ist, dass alle diese Dienstprogramme für Dateisystemoperationen auf POSIX angewiesen sind. POSIX ist ineffizient und nie für die Arbeit mit sehr großen Dateien über das Netzwerk gedacht.


Die Geschwindigkeit von POSIX-basierten Systemen nimmt ab, wenn die Nachfrage, insbesondere die gleichzeitige Nachfrage, an ihnen steigt. Wenn große Unternehmen für Deep Learning, KI und andere datenintensive Anwendungsfälle Unmengen an Daten speichern und darauf zugreifen müssen, verfügt POSIX nicht über die Fähigkeit oder Skalierbarkeit, diese Anforderungen zu erfüllen. Während All-Flash-Arrays POSIX im Spiel gehalten haben, sind Skalierbarkeit und RESTful-APIs (die Markenzeichen der Cloud) wie Kryptonit.


Aus diesem Grund ist die Ausführung von POSIX auf einem Objektspeicher nicht optimal. Werfen wir einen Blick auf einige der Gründe dafür:


  1. Leistung: Die POSIX FS-Schnittstelle ist von Natur aus IOPS-zentriert. Sie sind gesprächig, teuer und schwer zu skalieren. Die RESTful S3 API behebt dieses Problem, indem sie IOPS in ein Durchsatzproblem umwandelt. Der Durchsatz ist einfacher und kostengünstiger zu skalieren. Aus diesem Grund ist Objektspeicher in großem Umfang hochleistungsfähig. Die Schichtung von POSIX über S3 lässt sich nicht skalieren, da POSIX zu gesprächig ist, um über eine HTTP-RESTful-Schnittstelle ausgeführt zu werden.


  2. Semantik: Da Objektoperationen atomar und unveränderlich sind, gibt es keine Möglichkeit, die Konsistenzkorrektheit zu garantieren. Dies bedeutet, dass Sie im Falle eines Absturzes die nicht festgeschriebenen Daten verlieren können oder bei gemeinsam genutzten Bereitstellungen auf Korruptionsprobleme stoßen können.


  3. Datenintegrität : Schreibvorgänge oder Änderungen an einer Datei werden erst im Namespace angezeigt, wenn sie festgeschrieben wird. Dies bedeutet, dass beim gleichzeitigen Zugriff über gemeinsam genutzte Mounts hinweg die Änderungen nicht sichtbar sind. Für den gemeinsamen Zugriff ist es nicht sinnvoll.


  4. Zugriffskontrolle: POSIX-Berechtigungen und ACLs sind primitiv und nicht mit der Art und Weise kompatibel, wie die S3-API mit Identitäts- und Zugriffsverwaltungsrichtlinien umgeht. Es ist nicht möglich, die POSIX-Zugriffsverwaltung sicher auf Top-S3-APIs zu implementieren.


POSIX fehlen auch die meisten Funktionen, die Entwickler an S3 lieben, wie z. B. Verschlüsselung auf Objektebene, Versionierung, Unveränderlichkeit – diese haben in der POSIX-Welt einfach kein Äquivalent und nichts ist in der Lage, sie zu übersetzen.

POSIX-Schmerzpunkte

Diese Beispiele veranschaulichen das Problem und seine Auswirkungen. Zu Beginn verwenden wir diese CSV-Datei, die etwa 10 GB groß ist und 112 Zeilen enthält.


Hinweis: Wir gehen davon aus, dass die s3fs-fuse bereits installiert ist und Sie einen der Buckets aus dem Objektspeicher in Ihr Dateisystem gemountet haben. Wenn nicht, befolgen Sie die Anweisungen hier .


In diesen Beispielen gehen wir davon aus, dass der Bucket-Name test-bucket und der Dateiname taxi-data.csv im Verzeichnis /home/user/ lautet und s3fs-fuse bucket unter /home/user/test-bucket/ gemountet ist.

Kopiervorgang

Wir versuchen zunächst etwas Einfaches und versuchen, die CSV-Datei mithilfe von MC-Befehlen in unseren Test-Bucket zu kopieren und die benötigte Zeit aufzuzeichnen

time mc cp /home/user/taxi-data.csv minio/test-bucket/taxi-data.csv


Dies sollte nicht viel Zeit in Anspruch nehmen und die Datei sollte in unseren Bucket kopiert werden. Versuchen wir nun, dasselbe mit s3fs-fuse zu tun

time cp /home/user/taxi-data.csv /home/user/test-bucket/taxi-data.csv


Zeit, die während des Tests benötigt wurde


 real 1m36.056s user 0m14.507s sys 0m31.891s


In meinem Fall konnte ich die Datei nur teilweise in den Bucket kopieren und der Vorgang schlug mit der folgenden Fehlermeldung fehl


 cp: error writing '/home/user/test-bucket/taxi-data.csv': Input/output error cp: failed to close '/home/user/test-bucket/taxi-data.csv': Input/output error


Nach mehreren Versuchen gelang es


 real 5m3.661s user 0m0.053s sys 2m35.234s


Wie Sie sehen, wird das Dienstprogramm aufgrund der Menge an API-Aufrufen, die das Dienstprogramm durchführen muss, und des allgemeinen Overheads der Vorgänge instabil und die meisten Vorgänge werden nicht einmal abgeschlossen.

Pandas-Beispiel

Wir haben Ihnen ein einfaches cp Beispiel gezeigt, das vielleicht überzeugend war oder auch nicht, denn seien wir ehrlich, Sie denken vielleicht, time cp sei ziemlich rudimentär.


Für diejenigen, die mehr empirische Beweise benötigen, schreiben wir also einen Python-Snippet, um dies zu testen. Wir machen ein einfaches Pandas-Beispiel mit s3fs-fuse und dem python s3fs Paket und sehen uns die Auswirkungen auf die Leistung an


 import timeit import os import fsspec import s3fs import pandas as pd # Write a dummy CSV file to test-bucket df = pd.DataFrame({"column1": ["new_value1"], "column2": ["new_value2"]}) df.to_csv("s3://test-bucket/data/test-data.csv", index=False) def process_s3(): # add fsspec for pandas to use `s3://` path style and access S3 buckets directly fsspec.config.conf = { "s3": { "key": os.getenv("AWS_ACCESS_KEY_ID", "minioadmin"), "secret": os.getenv("AWS_SECRET_ACCESS_KEY", "minioadmin"), "client_kwargs": { "endpoint_url": os.getenv("S3_ENDPOINT", "https://play.min.io") } } } s3 = s3fs.S3FileSystem() for i in range(100): # Read the existing data print(i) df = pd.read_csv('s3://test-bucket/data/test-data.csv') # Append a new row new_df = pd.concat([df, pd.DataFrame([{"column1": f"value{i}", "column2": f"value{i}"}])], ignore_index=True) # Write the data back to the file new_df.to_csv('s3://test-bucket/data/test-data.csv', index=False) execution_time = timeit.timeit(process_s3, number=1) print(f"Execution time: {execution_time:.2f} seconds")


Während des Tests benötigte Zeit

 Execution time: 8.54 seconds


Versuchen wir nun dasselbe für s3fs-fuse


 import timeit import pandas as pd # Write a dummy CSV file to test-bucket df = pd.DataFrame({"column1": ["new_value1"], "column2": ["new_value2"]}) df.to_csv("s3://test-bucket/data/test-data.csv", index=False) def process_s3fs(): for i in range(100): # Read the existing data print(i) df = pd.read_csv('/home/user/test-bucket/data/test-data.csv') # Append a new row new_df = pd.concat([df, pd.DataFrame([{"column1": f"value{i}", "column2": f"value{i}"}])], ignore_index=True) # Write the data back to the file new_df.to_csv('/home/user/test-bucket/data/test-data.csv', index=False) execution_time = timeit.timeit(process_s3fs, number=1) print(f"Execution time: {execution_time:.2f} seconds")



Während des Tests benötigte Zeit

 Execution time: 9.59 seconds


Diese Beispiele veranschaulichen ständige Lese- und Schreibvorgänge in S3-Dateien. Stellen Sie sich vor, dass dies von mehreren Clients gleichzeitig ausgeführt wird – die Latenz nimmt dramatisch zu.

Entfernen Sie den Overhead!

Wie Sie sehen, ist der Unterschied zwischen der Verwendung der POSIX-Übersetzung zur Behandlung von Objekten als Dateien und der Verwendung der direkten API zur Arbeit mit Objekten Tag und Nacht. Es gibt einfach keinen Vergleich, wenn es um Sicherheit, Leistung, Datenintegrität und Kompatibilität geht. MinIO verfügt über SDKs zur Integration in fast jede gängige Programmiersprache und kann auf fast jeder Plattform wie Kubernetes, Bare-Metal-Linux, Docker-Containern und vielem mehr ausgeführt werden.


MinIO sichert Objekte mit Verschlüsselung im Ruhezustand und während der Übertragung, kombiniert mit PBAC zur Regulierung des Zugriffs und Löschcodierung zum Schutz der Datenintegrität. Sie erzielen die bestmögliche Leistung, unabhängig davon, wo Sie MinIO ausführen, da es die zugrunde liegende Hardware nutzt (siehe Auswählen der besten Hardware für Ihre MinIO-Bereitstellung ), um die größtmögliche Leistung zu liefern. Wir haben MinIO mit 325 GiB/s (349 GB/s) auf GETs und 165 GiB/s (177 GB/s) auf PUTs mit nur 32 Knoten handelsüblicher NVMe-SSDs getestet .


Es ist einfach kein Dateisystem-Dienstprogramm zwischen MinIO und Ihrer Anwendung erforderlich! Jeder Vorteil, den ältere Apps möglicherweise erhalten, wird durch die Nachteile von POSIX zunichte gemacht.


Wenn Sie Fragen zur Verwendung der POSIX-Übersetzung für Ihre Anwendung haben, wenden Sie sich unbedingt an uns auf Slack !


Auch hier veröffentlicht.