Scalare Immich: Come abbiamo riprogettato la geocodifica inversa per biblioteche fotografiche massive

Introduzione: La magia di sapere “Dove”
Per gli appassionati di home lab e i sostenitori della privacy dei dati, Immich è emerso come una soluzione self-hosted di primo livello per la gestione di foto e video. Offre una potente alternativa privata ai servizi basati sul cloud. Una delle sue caratteristiche più convincenti è un pezzo di magia in background: la geocodifica inversa. Questo processo analizza automaticamente le coordinate GPS incorporate nei dati EXIF di una foto e la arricchisce con un contesto di posizione leggibile dall’uomo—la città, lo stato e il paese dove l’immagine è stata catturata.
Come notato nella documentazione ufficiale di Immich, questa potente capacità è guidata dal database geografico completo GeoNames. Questo permette a Immich di trasformare un semplice insieme di coordinate in informazioni significative che puoi usare per cercare e organizzare i tuoi ricordi.
Ma cosa succede quando questa elegante caratteristica autonoma deve funzionare non solo per un singolo utente, ma attraverso una piattaforma multi-tenant massiccia? Questa era la sfida di scalabilità che abbiamo affrontato a PixelUnion, e ci ha spinto a reimmaginare come questa magia viene consegnata.
La sfida: La geocodifica predefinita di Immich su scala
Per progettare una soluzione migliore, abbiamo prima dovuto apprezzare il design strategico dell’architettura predefinita di Immich. L’approccio standard è brillante per il suo pubblico target di utenti individuali, ma le sue scelte di design fondamentali creano colli di bottiglia prevedibili quando vengono distribuite per una grande base di utenti con migliaia di biblioteche fotografiche.
Come funziona la geocodifica standard di Immich
In una configurazione standard, Immich scarica il dataset GeoNames e lo carica direttamente in una tabella del database PostgreSQL locale. Secondo la documentazione, questo processo di importazione viene attivato durante ogni aggiornamento di versione minore, assicurando che i dati di posizione rimangano aggiornati.
Il beneficio principale di questa architettura è chiaro: mantiene tutto l’elaborazione dei dati completamente autonoma sul server dell’utente. Questo migliora la privacy e la semplicità operativa, poiché non ci sono dipendenze esterne per questa caratteristica centrale. Per un tipico self-hoster che gestisce la propria biblioteca personale, una tabella del database di circa 100MB è una soluzione perfettamente ragionevole ed efficiente per le ricerche locali veloci che alimentano sia la visualizzazione della posizione che la funzionalità “Smart Search” di Immich.
Il collo di bottiglia nelle distribuzioni su larga scala
Questo modello autonomo inizia a rompersi in ambienti multi-utente su larga scala come il nostro a PixelUnion. Il problema centrale è il gonfiore del database. Quando quella singola tabella di geodati di ~100MB viene replicata su centinaia o migliaia di istanze di database individuali, l’overhead di archiviazione cumulativo diventa immenso. Questo ha presentato sfide operative significative, aumentando drammaticamente la difficoltà e il costo associati al ridimensionamento della nostra infrastruttura Postgres molto grande.
Un problema secondario era l’overhead ripetitivo del lavoro di importazione stesso. Il processo di download e caricamento del dataset, che viene eseguito dopo ogni aggiornamento di Immich, diventa un compito altamente inefficiente e ad alta intensità di risorse quando moltiplicato su tutta la nostra distribuzione. Avevamo bisogno di un modo per centralizzare questa funzione senza compromettere le sue prestazioni.
La nostra soluzione: Disaccoppiare la geocodifica con un microservizio
Il nostro obiettivo strategico era disaccoppiare la funzione di geocodifica dal database principale di Immich. Questo cambiamento architetturale è stato progettato per fornire maggiore flessibilità, efficienza e scalabilità senza alterare le caratteristiche centrali orientate all’utente di Immich. Miriamo a risolvere il problema di scalabilità a livello di infrastruttura mantenendo il comportamento dell’applicazione coerente.
Il cambiamento architetturale dalla tabella locale all’API centrale
La nostra soluzione è stata sostituire la query diretta del database con una semplice chiamata API a un microservizio dedicato. Invece di ogni istanza Immich che mantiene la propria copia dei dati GeoNames, ora eseguiamo un singolo microservizio di geocodifica centralizzato all’interno del nostro cluster. Questo servizio contiene i dati GeoNames ed espone endpoint API per gestire sia le richieste di geocodifica inversa che le ricerche di nomi di luoghi per tutte le istanze Immich.
Crucialmente, il microservizio è progettato per restituire dati nello stesso formato esatto che Immich si aspetta dalla sua query del database interno. Questo rende il cambiamento architetturale completamente trasparente per la logica dell’applicazione, richiedendo solo una modifica minore per dirigere le richieste alla nuova API invece della tabella locale.
Uno sguardo tecnico al codice
Per implementare questo, abbiamo introdotto una nuova variabile d’ambiente, GEODATA_API_URL, come visto nel nostro commit alla codebase di Immich. Questa variabile funge da feature flag che dice a un’istanza Immich se usare il metodo del database tradizionale o la nostra nuova API esterna per entrambe le funzioni di geocodifica e ricerca.
La logica centrale, visibile nelle modifiche a map.repository.ts e search.repository.ts, segue un semplice controllo condizionale per ogni funzione:
| |
Questo cambiamento elegante è potente per due ragioni. Primo, rende la nuova caratteristica un miglioramento opt-in, preservando la perfetta compatibilità all’indietro per tutti gli utenti Immich esistenti. Secondo, fornisce un percorso pulito e configurabile per distribuzioni scalate come la nostra per scaricare l’intero carico di lavoro dei geodati senza richiedere un fork complesso o invasivo dell’applicazione principale.
L’impatto: Vincite misurabili e un Immich più scalabile
Questi cambiamenti architetturali non erano solo miglioramenti teorici; hanno portato a miglioramenti significativi e misurabili nell’efficienza, convenienza e manutenibilità della nostra piattaforma.
Benefici chiave realizzati
- Dieta drastica del database: La vittoria più immediata è stata una riduzione drammatica nella dimensione di ogni istanza del database Immich. Rimuovendo la tabella di geodati di ~100MB dal database di ogni utente, abbiamo recuperato una quantità massiccia di archiviazione attraverso il nostro cluster.
- Aggiornamenti semplificati: Il nostro cambiamento elimina completamente il lavoro di importazione dei geodati che Immich eseguiva precedentemente dopo ogni aggiornamento. Questo risparmia tempo e risorse di calcolo considerevoli durante i nostri cicli di aggiornamento in tutta la piattaforma. Questo è confermato dalla nuova logica nel codice, che registra esplicitamente che sta “saltando l’importazione locale dei geodati” quando la nostra API esterna è configurata.
- Scalabilità migliorata: Con un’impronta del database più piccola, l’intera distribuzione Immich è più facile da gestire, fare backup e scalare. Inoltre, centralizzare la logica migliora le prestazioni e la coerenza sia dell’arricchimento dei dati di posizione che delle query di ricerca attraverso la piattaforma, permettendoci di supportare più utenti in modo più efficiente e conveniente.
Aperto a tutti
Crediamo nel potere dell’open source e nel restituire alle comunità che costruiscono strumenti incredibili come Immich. Questa soluzione è stata contribuita attraverso il nostro fork open source pubblico. Puoi ispezionare l’implementazione esatta, dalla nuova variabile d’ambiente alle chiamate API condizionali, nel commit collegato di seguito.
Visualizza il commit completo su GitHub
Riflessioni finali
Il nostro viaggio dall’identificare un collo di bottiglia di scalabilità critico all’implementare una soluzione di microservizio robusta e disaccoppiata evidenzia una sfida comune nell’ingegneria del software: una caratteristica che è perfetta per una scala può diventare un ostacolo in un’altra. Analizzando attentamente il problema e implementando una soluzione flessibile e compatibile all’indietro, siamo stati in grado di migliorare l’architettura di Immich per le nostre esigenze mentre contribuiamo un’opzione preziosa alla comunità più ampia. A PixelUnion, rimaniamo impegnati nell’open source e incoraggiamo tutti nelle comunità di home lab e self-hosting a esplorare, adattare e costruire su questi tipi di soluzioni.