Skalning av Immich: Hur vi omkonstruerade reverse geocoding för enorma fotobibliotek

Introduktion: Magin med att veta “Var”
För hem labb-entusiaster och dataintegritetsförespråkare har Immich framträtt som en premier självhostad lösning för foto- och videohantering. Det erbjuder ett kraftfullt, privat alternativ till molnbaserade tjänster. En av dess mest övertygande funktioner är en bit bakgrundsmagi: reverse geocoding. Denna process analyserar automatiskt GPS-koordinaterna inbäddade i en fotos EXIF-data och berikar den med mänskligt läsbar platskontext—staden, staten och landet där bilden togs.
Som noterat i den officiella Immich-dokumentationen drivs denna kraftfulla kapacitet av den omfattande GeoNames geografiska databasen. Detta låter Immich förvandla en enkel uppsättning koordinater till meningsfull information som du kan använda för att söka och organisera dina minnen.
Men vad händer när denna eleganta, självständiga funktion behöver fungera inte bara för en enda användare, utan över en enorm, multi-tenant plattform? Detta var skalningsutmaningen vi stötte på på PixelUnion, och det tvingade oss att tänka om hur denna magi levereras.
Utmaningen: Immichs standard geocoding i skala
För att konstruera en bättre lösning måste vi först uppskatta det strategiska designet av Immichs standardarkitektur. Standardmetoden är briljant för sin avsedda publik av individuella användare, men dess kärndesignval skapar förutsägbara flaskhalsar när den distribueras för en stor användarbas med tusentals fotobibliotek.
Hur standard Immich geocoding fungerar
I en standardinställning laddar Immich ner GeoNames-datasamlingen och laddar den direkt i en lokal PostgreSQL-databastabell. Enligt dokumentationen utlöses denna importprocess under varje mindre versionsuppgradering, vilket säkerställer att platsdata förblir uppdaterade.
Den primära fördelen med denna arkitektur är tydlig: den håller all databehandling helt självständig på användarens server. Detta förbättrar integritet och operativ enkelhet, eftersom det inte finns några externa beroenden för denna kärnfunktion. För en typisk självhostare som hanterar sitt personliga bibliotek är en databastabell på cirka 100 MB en perfekt rimlig och effektiv lösning för de snabba, lokala uppslagningar som driver både platsvisning och Immichs “Smart Search”-funktionalitet.
Flaskhalsen i stora distributioner
Denna självständiga modell börjar bryta ner i storskaliga, multi-user-miljöer som vår på PixelUnion. Kärnproblemet är databas-bloat. När den enda ~100 MB geodata-tabellen replikeras över hundratals eller tusentals individuella databasinstanser blir den kumulativa lagringsöverheaden enorm. Detta presenterade betydande operativa utmaningar, vilket dramatiskt ökade svårigheten och kostnaden associerad med att skala ut vår mycket stora Postgres-infrastruktur.
Ett sekundärt problem var den repetitiva overheaden av importjobbet självt. Processen att ladda ner och ladda datasamlingen, som körs efter varje Immich-uppdatering, blir en mycket ineffektiv och resursintensiv uppgift när den multipliceras över hela vår distribution. Vi behövde ett sätt att centralisera denna funktion utan att kompromissa med dess prestanda.
Vår lösning: Koppla bort geocoding med en microservice
Vårt strategiska mål var att koppla bort geocoding-funktionen från den primära Immich-databasen. Denna arkitekturförändring var designad för att leverera större flexibilitet, effektivitet och skalbarhet utan att ändra Immichs kärnanvändarfunktioner. Vi syftade till att lösa skalningsproblemet på infrastrukturnivå medan applikationens beteende förblir konsekvent.
Arkitekturförändringen från lokal tabell till central API
Vår lösning var att ersätta den direkta databasfrågan med ett enkelt API-anrop till en dedikerad microservice. Istället för att varje Immich-instans underhåller sin egen kopia av GeoNames-data kör vi nu en enda, centraliserad geocoding-microservice inom vårt kluster. Denna tjänst håller GeoNames-data och exponerar API-endpoints för att hantera både reverse geocoding-förfrågningar och platsnamnssökningar för alla Immich-instanser.
Kritiskt är att microservicen är designad för att returnera data i exakt samma format som Immich förväntar sig från sin interna databasfråga. Detta gör arkitekturförändringen helt transparent för applikationslogiken, vilket endast kräver en mindre modifiering för att dirigera förfrågningar till det nya API:et istället för den lokala tabellen.
En teknisk titt på koden
För att implementera detta introducerade vi en ny miljövariabel, GEODATA_API_URL, som syns i vår commit till Immich-kodbasen. Denna variabel fungerar som en feature flag som säger till en Immich-instans om den ska använda den traditionella databasmetoden eller vårt nya externa API för både geocoding- och sökfunktioner.
Kärnlogiken, synlig i ändringarna till map.repository.ts och search.repository.ts, följer en enkel villkorskontroll för varje funktion:
| |
Denna eleganta förändring är kraftfull av två skäl. Först gör den den nya funktionen en opt-in-förbättring, vilket bevarar perfekt bakåtkompatibilitet för alla befintliga Immich-användare. För det andra ger den en ren, konfigurerbar väg för skalade distributioner som vår att avlasta hela geodata-arbetsbelastningen utan att kräva en komplex eller invasiv fork av huvudapplikationen.
Påverkan: Mätbara vinster och en mer skalbar Immich
Dessa arkitekturförändringar var inte bara teoretiska förbättringar; de resulterade i betydande, mätbara förbättringar av vår plattforms effektivitet, kostnadseffektivitet och underhållbarhet.
Viktiga fördelar realiserade
- Drastisk databasdiät: Den mest omedelbara segern var en dramatisk minskning av storleken på varje Immich-databasinstans. Genom att ta bort ~100 MB geodata-tabellen från varje användares databas återvann vi en enorm mängd lagring över vårt kluster.
- Förenklade uppdateringar: Vår förändring eliminerar helt geodata-importjobbet som Immich tidigare körde efter varje uppdatering. Detta sparar betydande tid och beräkningsresurser under våra plattformomfattande uppdateringscykler. Detta bekräftas av den nya logiken i koden, som explicit loggar att den “hoppar över lokal geodata-import” när vårt externa API är konfigurerat.
- Förbättrad skalbarhet: Med en mindre databas-fotavtryck är hela Immich-distributionen enklare att hantera, säkerhetskopiera och skala. Dessutom förbättrar centraliseringen av logiken prestandan och konsistensen av både platsdataberikning och sökfrågor över plattformen, vilket låter oss stödja fler användare mer effektivt och kostnadseffektivt.
Öppet för alla
Vi tror på kraften i öppen källkod och att ge tillbaka till gemenskaperna som bygger otroliga verktyg som Immich. Denna lösning har bidragits tillbaka via vår publika, öppen källkod fork. Du kan inspektera den exakta implementeringen, från den nya miljövariabeln till de villkorliga API-anropen, i commiten länkad nedan.
Slutliga tankar
Vår resa från att identifiera en kritisk skalningsflaskhals till att implementera en robust, kopplad microservice-lösning framhäver en vanlig utmaning i mjukvaruutveckling: en funktion som är perfekt för en skala kan bli ett hinder på en annan. Genom att noggrant analysera problemet och implementera en flexibel, bakåtkompatibel lösning kunde vi förbättra Immichs arkitektur för våra behov samtidigt som vi bidrog med ett värdefullt alternativ tillbaka till den bredare gemenskapen. På PixelUnion förblir vi engagerade i öppen källkod och uppmuntrar alla i hem labb- och självhosting-gemenskaperna att utforska, anpassa och bygga vidare på dessa typer av lösningar.