L’autore di questo post mette in dubbio la prospettiva presentata in un articolo di MinIO, che suggerisce che POSIX non sia un’adeguata scelta per i depositi di oggetti. Ha condotto test approfonditi che coinvolgono MinIO s3fs-fuse
e JuiceFS. I risultati indicano che MinIO e JuiceFS offrono un’eccellente prestazione, mentre s3fs-fuse
risulta in ritardo. In scenari di sovrascrittura di file piccoli, JuiceFS FUSE-POSIX supera le altre soluzioni.
Recentemente, mi sono imbattuto in un articolo sul blog di MinIO intitolato “Mettere un Filesystem in cima a un Object Store è una cattiva idea. Ecco perché.” L’autore ha usato s3fs-fuse
come esempio per illustrare le sfide delle prestazioni incontrate quando si accede ai dati di MinIO utilizzando metodi POSIX (Portable Operating System Interface), evidenziando che le prestazioni sono significativamente più lente rispetto all’accesso diretto a MinIO. L’autore attribuisce questi problemi di prestazioni a difetti intrinseci di POSIX. Tuttavia, la nostra esperienza differisce in qualche modo da questa conclusione.
POSIX è uno standard utile e ampiamente adottato. Lo sviluppo di software conforme a POSIX garantisce compatibilità e portabilità tra diversi sistemi operativi. La maggior parte delle applicazioni in vari settori rispetta lo standard POSIX. Con l’avanzamento delle tecnologie di cloud computing, big data e AI, nonché l’aumento del volume di dati memorizzati, c’è una crescente richiesta di soluzioni di archiviazione elastica come i negozi di oggetti. Sebbene negozi di oggetti come MinIO forniscano SDK in più lingue, molte applicazioni tradizionali faticano a adattare il loro codice per utilizzare le API di archiviazione di oggetti. Questo ha portato a vari prodotti di archiviazione che implementano interfacce POSIX su negozi di oggetti per soddisfare questa domanda inflessibile.
Molti prodotti nell’industria, come Ceph, JuiceFS e Weka, hanno implementato con successo interfacce POSIX su negozi di oggetti. Queste soluzioni hanno grandi basi di utenti e numerosi successi, e si comportano bene in termini di prestazioni.
Mentre è vero che POSIX ha una notevole complessità, i problemi associati non sono insormontabili. Con rispetto e desiderio di verificare queste affermazioni, ho allestito un ambiente di test, ho impiegato gli stessi dati di esempio e metodi di test descritti nell’articolo di MinIO e ho condotto una verifica.
Prodotti confrontati e obiettivi dei test
Per fornire una valutazione completa, ho introdotto JuiceFS nel confronto.
JuiceFS è un file system distribuito open-source e nativo cloud. Utilizza lo storage di oggetti come livello di archiviazione dei dati e si basa su un database separato per memorizzare i metadati. Offre vari metodi di accesso, tra cui API POSIX, API S3, Driver CSI, API HDFS e WebDAV, oltre a meccanismi unici di suddivisione dei dati, caching e lettura/scrittura simultanea. JuiceFS è un file system, fondamentalmente diverso dalle soluzioni come s3fs-fuse
, che convertono semplicemente dallo storage di oggetti ai protocolli POSIX.
Introducendo JuiceFS nella comparazione, ho inteso valutare oggettivamente i vantaggi e gli svantaggi dell’implementazione di protocolli come POSIX sopra lo storage di oggetti.
I conducted the following two tests on MinIO, JuiceFS, and s3fs-fuse
:
- Scrittura di un file da 10 GB
- Sovrascrittura di piccoli file con Pandas
Tutte e tre le soluzioni hanno utilizzato un’istanza di MinIO distribuita su server separati come archiviazione sottostante. Per i campioni di prova, è stato utilizzato un file da 10 GB, che era lo stesso file CSV menzionato nell’articolo su MinIO.
Tutte le ambienti, software, script e dati di esempio in questo articolo sono accompagnati da codice completo e istruzioni per garantire che tu possa riprodurre l’ambiente e i risultati dei test.
Configurazione dell’ambiente del server e dei test
Due server cloud configurati in modo identico:
- Sistema: Ubuntu 22.04 x64
- CPU: 8 core
- RAM: 16 GB
- SSD: 500 GB
- Rete: VPC
Le informazioni per ogni server:
Server | IP | Purpose |
---|---|---|
Server A | 172.16.254.18 | Deploying the MinIO instance |
Server B | 172.16.254.19 | As the test environment |
Preparazione Server A
1. Ho distribuito MinIO su Server A utilizzando Docker con i seguenti comandi:
# Creare una directory dedicata e navigarvi.
mkdir minio && cd minio
# Creare un file di configurazione.
mkdir config
touch config/minio
2. Ho scritto le seguenti informazioni nel file config/minio
:
MINIO_ROOT_USER=admin
MINIO_ROOT_PASSWORD=abc123abc
MINIO_VOLUMES="/mnt/data"
3. Ho creato il contenitore MinIO:
sudo docker run -d --name minio \
-p 9000:9000 \
-p 9090:9090 \
-v /mnt/minio-data:/mnt/data \
-v ./config/minio:/etc/config.env \
-e "MINIO_CONFIG_ENV_FILE=/etc/config.env" \
--restart unless-stopped \
minio/minio server --console-address ":9090"
4. Sulla Console Web di MinIO, ho pre-creato tre bucket:
Bucket name | Purpose |
---|---|
test-minio | For testing MinIO |
test-juicefs | For testing JuiceFS |
test-s3fs | For testing s3fs-fuse |
Preparazione Server B
1. Ho scaricato il file di esempio di prova da 10 GB.
curl -LO https://data.cityofnewyork.us/api/views/t29m-gskq/rows.csv?accessType=DOWNLOAD
2. Ho installato il client mc
.
mc
è un file manager da riga di comando sviluppato dal progetto MinIO. Consente operazioni di lettura e scrittura sia su archiviazione di oggetti locale che compatibile con S3 nella riga di comando Linux. Il comando mc cp
fornisce aggiornamenti in tempo reale sulla progressione e sulla velocità durante la copia dei dati, facilitando l’osservazione di vari test.
Nota: Per mantenere la parità dei test, tutti e tre i metodi hanno utilizzato
mc
per i test di scrittura dei file.
# Scaricare mc.
wget https://dl.min.io/client/mc/release/linux-amd64/mc
# Controllare la versione di mc.
mc -v
mc version RELEASE.2023-09-20T15-22-31Z (commit-id=38b8665e9e8649f98e6162bdb5163172e6ecc187)
Runtime: go1.21.1 linux/amd64
# Installare mc.
sudo install mc /usr/bin
# Impostare un alias per MinIO.
mc alias set my http://172.16.254.18:9000 admin abc123abc
3. Ho scaricato s3fs-fuse
.
sudo apt install s3fs
# Controllare la versione.
s3fs --version
Amazon Simple Storage Service File System V1.93 (commit:unknown) with OpenSSL
# Impostare la chiave di accesso all'archiviazione di oggetti.
echo admin:abc123abc > ~/.passwd-s3fs
# Modificare i permessi del file chiave.
chmod 600 ~/.passwd-s3fs
# Creare la directory di montaggio.
mkdir mnt-s3fs
# Montare l'archiviazione di oggetti.
s3fs test-s3fs:/ /root/mnt-s3fs -o url=http://172.16.254.18:9000 -o use_path_request_style
4. Ho installato JuiceFS.
I used the official script to install the latest JuiceFS Community Edition.
# Script di installazione in un click
curl -sSL https://d.juicefs.com/install | sh -
# Controllare la versione.
juicefs version
juicefs version 1.1.0+2023-09-04.08c4ae6
5. Ho creato un file system. JuiceFS è un file system che deve essere creato prima dell’uso. Oltre all’archiviazione di oggetti, richiede un database come motore di metadati. Supporta vari database. Qui, ho utilizzato Redis, comunemente usato, come motore di metadati.
Nota: Ho installato Redis su Server A, accessibile tramite
172.16.254.18:6379
senza password. Il processo di installazione è omesso qui. Puoi fare riferimento alla documentazione di Redis per i dettagli.
# Crea il file system.
juicefs format --storage minio \
--bucket http://172.16.254.18:9000/test-juicefs \
--access-key admin \
--secret-key abc123abc \
--trash-days 0 \
redis://172.16.254.18/1 \
myjfs
6. Ho accesso a JuiceFS utilizzando i metodi più comunemente usati POSIX e S3 API e testato le loro prestazioni.
# Crea directory di montaggio.
mkdir ~/mnt-juicefs
# Monta il file system in modalità POSIX.
juicefs mount redis://172.16.254.18/1 /root/mnt-juicefs
# Accedi al file system utilizzando il metodo S3 API.
export MINIO_ROOT_USER=admin
export MINIO_ROOT_PASSWORD=abc123abc
juicefs gateway redis://172.16.254.18/1 0.0.0.0:9000
# Imposta un alias per l'API S3 di JuiceFS in mc.
mc alias set juicefs http://172.16.254.18:9000 admin abc123abc
Nota: Il Gateway JuiceFS può anche essere distribuito su Server A o su qualsiasi altro server accessibile in rete poiché espone un’API S3 basata su rete.
Test e Risultati
Ecco un rapido riassunto dei miei test e risultati:
Test | MinIO | S3FS-FUSE | JuiceFS (FUSE) |
JuiceFS (S3 gateway) |
---|---|---|---|---|
Writing a 10 GB file | 0m27.651s | 3m6.380s | 0m28.107s | 0m28.091s |
Overwriting small files with Pandas | 0.83s | 0.78s | 0.46s | 0.96s |
Test 1: Scrittura di un file da 10 GB
Questo test è stato progettato per valutare le prestazioni nella scrittura di file di grandi dimensioni. Minore è il tempo impiegato, migliori sono le prestazioni. Ho utilizzato il comando time
per misurare la durata delle operazioni di scrittura, fornendo tre metri
real
: Il tempo effettivo dall’inizio alla fine del comando. Include tutti i tempi di attesa, come l’attesa per il completamento delle operazioni di I/O, l’attesa per lo switch di processo e l’attesa per le risorse.user
: Il tempo eseguito in modalità utente, che indica il tempo CPU utilizzato per eseguire il codice utente. Tipicamente rappresenta il carico di lavoro computazionale del comando.sys
: Il tempo eseguito in modalità kernel, che indica il tempo CPU utilizzato per eseguire il codice kernel. Tipicamente rappresenta il carico di lavoro legato alle chiamate di sistema, come I/O su file e gestione dei processi.
MinIO
I ran the following command to perform a copy test:
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv my/test-minio/
Risultati per la scrittura di un file da 10 GB direttamente su MinIO:
real 0m27.651s
user 0m10.767s
sys 0m5.439s
s3fs-fuse
I ran the following command to perform a copy test:
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv /root/mnt-s3fs/
Risultati per la scrittura di un file da 10 GB direttamente su s3fs-fuse
:
real 3m6.380s
user 0m0.012s
sys 0m5.459s
Nota: Sebbene il tempo di scrittura fosse di 3 minuti e 6 secondi per
s3fs-fuse
, non ci sono stati fallimenti di scrittura come descritti nell’articolo di MinIO.
JuiceFS
I tested the performance of JuiceFS for large file writes using both the POSIX and S3 API methods:
# Test di scrittura POSIX
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv /root/mnt-juicefs/
# Test di scrittura API S3
time mc cp ./2018_Yellow_Taxi_Trip_Data.csv juicefs/myjfs/
Risultati per la scrittura POSIX di un file da 10 GB con JuiceFS:
real 0m28.107s
user 0m0.292s
sys 0m6.930s
Risultati per la scrittura API S3 di un file da 10 GB con JuiceFS:
real 0m28.091s
user 0m13.643s
sys 0m4.142s
Riepilogo dei risultati della scrittura di file di grandi dimensioni
La seguente figura mostra i risultati dei test:

I risultati dei test mostrano che sia la scrittura diretta su MinIO che su JuiceFS hanno fornito prestazioni comparabili, completando il compito in circa 30 secondi. Al contrario, s3fs-fuse
ha impiegato oltre 3 minuti per scrivere un file da 10 GB, che è circa sei volte più lento dei primi due.
Quando si scrivono file di grandi dimensioni, mc
utilizza l’API Multipart per caricare file in parti nell’interfaccia S3. Al contrario, s3fs-fuse
può scrivere solo su POSIX in un unico thread. JuiceFS suddivide automaticamente anche i file di grandi dimensioni in parti e le scrive in modo concorrente su MinIO durante le scritture sequenziali, garantendo prestazioni paragonabili a quelle di scritture dirette su MinIO. S3FS, invece, scrive prima su un disco cache in un unico thread e successivamente carica il file in parti su MinIO, risultando in tempi di scrittura più lunghi.
Basandosi sul calcolo che ha impiegato 30 secondi per scrivere un file da 10 GB, la velocità media era di 333 MB/s. Questo era limitato dalla larghezza di banda dei SSD dei server cloud. Questi risultati dei test indicavano che sia MinIO che JuiceFS potevano massimizzare la larghezza di banda dei SSD locali e le loro prestazioni migliorerebbero con miglioramenti dei dischi cloud del server e della larghezza di banda di rete.
Test 2: Sovrascrittura di Piccoli File con Pandas
Questo test valutava le prestazioni dei sistemi di archiviazione di oggetti in scenari di sovrascrittura di piccoli file. I script di test per ogni software differivano leggermente. Puoi trovare tutto il codice dello script qui.
MinIO
I got the test script and ran the test:
# Ottieni lo script di test.
curl -LO https://gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-minio.py
# Esegui il test.
python3 pandas-minio.py
Il risultato è stato il seguente:
Execution time: 0.83 seconds
s3fs-fuse
I got the test script and ran the test:
# Ottieni lo script di test.
curl -LO gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-s3fs.py
# Esegui il test.
python3 pandas-s3fs.py
Il risultato del test è stato il seguente:
Execution time: 0.78 seconds
JuiceFS POSIX
I got the test script and ran the test:
# Ottieni lo script di test.
curl -LO gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-juicefs-posix.py
# Esegui il test.
python3 pandas-juicefs-posix.py
Il risultato del test è stato il seguente:
Execution time: 0.43 seconds
API S3 di JuiceFS
I got the test script and ran the test:
# Ottieni lo script di test.
curl -LO https://gist.githubusercontent.com/yuhr123/7acb7e6bb42fb0ff12f3ba64d2cdd7da/raw/30c748e20b56dec642a58f9cccd7ea6e213dab3c/pandas-juicefs-s3api.py
# Esegui il test.
python3 pandas-juicefs-s3api.py
Il risultato del test è stato il seguente:
Execution time: 0.86 seconds
Riepilogo delle Sovrascritture di File Piccoli di Pandas
La seguente figura mostra i risultati del test:

In questo test, JuiceFS FUSE-POSIX ha dimostrato la velocità più rapida, quasi il doppio rispetto alle altre soluzioni. MinIO, s3fs-fuse
, e JuiceFS S3 Gateway mostrano prestazioni simili. Dal punto di vista delle sovrascritture di file piccoli, l’interfaccia POSIX si è dimostrata più efficiente, offrendo prestazioni migliori rispetto alle interfacce di storage di oggetti.
Problemi e Analisi
Problema 1: Perché S3FS Era Così Lento?
Analisi: Dai dati del test, è evidente che quando si scrive lo stesso file di 10 GB, S3FS ha impiegato 3 minuti, mentre MinIO e JuiceFS hanno completato il compito in circa 30 secondi. Questa differenza di prestazioni significativa è principalmente dovuta a diverse implementazioni tecniche. Quando s3fs-fuse
scrive un file, prima scrive il file in un file temporaneo locale e poi lo carica nello storage di oggetti a pezzi. Se non c’è spazio sufficiente sul disco locale, carica in modo sincrono. Deve copiare i dati tra il disco locale e lo storage S3. Pertanto, file di grandi dimensioni o un numero significativo di file causano una degradazione delle prestazioni.
Inoltre, S3FS dipende dalle capacità di gestione dei metadati dell’archiviazione oggetto sottostante. Quando si tratta di un grande numero di file, l’interazione frequente con l’archiviazione oggetto per recuperare i metadati ha un impatto significativo sulla performance. In termini semplici, maggiore è la dimensione del file e la quantità totale di file scritti in S3FS, maggiore è l’overhead di prestazioni in proporzione.
Problema 2: Perché JuiceFS Era Più Veloce?
Analisi: Nel test, sia JuiceFS che S3FS hanno utilizzato FUSE per la lettura e la scrittura. JuiceFS ha sfruttato appieno la larghezza di banda del disco come MinIO, ma non ha incontrato problemi di prestazioni come S3FS.
La risposta risiede nelle loro architetture tecniche rispettive. Mentre i dati vengono elaborati attraverso il livello FUSE durante la scrittura dei file, JuiceFS utilizza tecniche di alta concorrenza, caching e suddivisione dei dati per ridurre l’overhead di comunicazione tra il livello FUSE e l’archiviazione oggetto sottostante. Ciò permette a JuiceFS di gestire più richieste di lettura e scrittura di file contemporaneamente, riducendo i tempi di attesa e la latenza di trasmissione.
Inoltre, JuiceFS utilizza un database dedicato (in questo caso, Redis) per gestire i metadati. Quando si tratta di un numero particolarmente elevato di file, un motore di metadati indipendente può alleviare efficacemente il carico di lavoro, consentendo una localizzazione dei file più rapida.
Conclusione
I testi di cui sopra dimostrano che l’utilizzo dello storage di oggetti come base e l’implementazione di un’interfaccia POSIX al di sopra di esso non necessariamente causa una perdita di prestazioni. Sia che si scrivano file grandi o piccoli, JuiceFS mostra prestazioni paragonabili a scritture dirette di MinIO senza alcuna degradazione delle prestazioni dello storage di oggetti sottostante a causa dell’accesso POSIX. Inoltre, in termini di sovrascritture di tabelle Pandas, le prestazioni di JuiceFS FUSE-POSIX rimangono costanti e superano addirittura MinIO quasi di due volte.
I risultati dei test indicano che alcuni software, come s3fs-fuse
, possono subire una degradazione delle prestazioni nella conversione tra interfacce S3 API e POSIX. Mentre può essere uno strumento conveniente per l’accesso temporaneo a S3, per un uso a lungo termine stabile e ad alte prestazioni, è necessario condurre ricerche e validazioni accurate per selezionare soluzioni più adatte.
Per semplici archivi di file non strutturati, l’uso diretto di MinIO o di storage di oggetti cloud è una buona scelta. Tuttavia, per scenari che coinvolgono l’archiviazione e il trattamento di grandi quantità di dati, come l’allenamento di modelli di AI, l’analisi di big data, la persistenza dei dati di Kubernetes e altre operazioni di lettura e scrittura frequenti, JuiceFS offre prestazioni superiori grazie alla gestione indipendente dei metadati, alle capacità di lettura e scrittura simultanee e ai meccanismi di caching. Si tratta di una soluzione di sistema di file ad alte prestazioni che vale la pena considerare.
Source:
https://dzone.com/articles/is-posix-really-unsuitable-for-object-stores-a-dat