SQLite su Litestream: realtime replikacija

Kas yra Litestream ir kodėl jis svarbus

Kai kalbame apie SQLite, dažnai išgirstame, kad tai puiki duomenų bazė mažiems projektams, prototipams ar mobilioms aplikacijoms. Bet produkcinėje aplinkoje? Daugelis kelia antakius. Problema visada buvo ta pati – kaip užtikrinti duomenų saugumą ir atsarginių kopijų kūrimą, kai dirbi su vienu failu?

Čia ir ateina į pagalbą Litestream. Tai atviro kodo įrankis, kuris keičia žaidimo taisykles SQLite naudotojams. Jis veikia kaip nuolatinis replikacijos sluoksnis, kuris stebi jūsų SQLite duomenų bazę ir automatiškai siunčia visus pakeitimus į išorinę saugyklą – S3, Azure Blob Storage, Google Cloud Storage ar net į kitą serverį per SFTP.

Kas įdomiausia – Litestream nedaro jokių pakeitimų pačioje SQLite duomenų bazėje. Jis tiesiog skaito WAL (Write-Ahead Log) failą ir replikuoja pakeitimus beveik realiuoju laiku. Tai reiškia, kad jūsų aplikacija net nežino, kad kas nors stebi ir kopijuoja duomenis fone.

Kaip veikia replikacijos mechanizmas

SQLite naudoja WAL režimą, kuris leidžia rašyti pakeitimus į atskirą žurnalo failą prieš juos įrašant į pagrindinę duomenų bazę. Litestream išnaudoja šį mechanizmą genialiai paprastai – jis stebi WAL failą ir kopijuoja naujus įrašus į nurodytą saugyklą.

Procesas vyksta maždaug taip: kai jūsų aplikacija atlieka INSERT, UPDATE ar DELETE operaciją, SQLite įrašo pakeitimus į WAL failą. Litestream pastebi šiuos pakeitimus ir per kelias sekundes (dažniausiai 1-10 sekundžių) nusiunčia juos į debesų saugyklą kaip mažus snapshot’us.

Svarbu suprasti, kad tai nėra tradicinė master-slave replikacija, kurią matome PostgreSQL ar MySQL. Čia kalbame apie nuolatinį atsarginių kopijų kūrimą su galimybe atkurti duomenų bazę bet kuriuo momentu. Jei serveris sugenda, galite paleisti naują instanciją, ir Litestream automatiškai atsisiųs naujausią duomenų bazės versiją iš saugyklos.

Praktinis įdiegimas žingsnis po žingsnio

Pradėkime nuo paprasčiausio scenarijaus – turite Linux serverį su SQLite duomenų baze ir norite replikuoti ją į AWS S3. Pirmas žingsnis – įdiegti Litestream. Jei naudojate Ubuntu ar Debian:

wget https://github.com/benbjohnson/litestream/releases/download/v0.3.13/litestream-v0.3.13-linux-amd64.deb
sudo dpkg -i litestream-v0.3.13-linux-amd64.deb

Dabar sukurkite konfigūracijos failą /etc/litestream.yml. Štai minimalistinė konfigūracija, kuri veikia:

dbs:
- path: /var/lib/myapp/database.db
replicas:
- url: s3://mybucket.s3.amazonaws.com/db

Tai viskas, kas reikalinga baziniam veikimui. Žinoma, reikės sukonfigūruoti AWS kredencialus per aplinkos kintamuosius arba IAM roles, jei naudojate EC2. Bet pati Litestream konfigūracija – tiesiog kelios eilutės.

Paleiskite Litestream kaip systemd servisą:

sudo systemctl enable litestream
sudo systemctl start litestream

Ir štai taip – jūsų duomenų bazė dabar replikuojama į S3. Galite patikrinti statusą su litestream databases komanda, kuri parodys visas stebimas duomenų bazes ir jų replikacijas.

Atkūrimo procesas kai viskas griūva

Teorija teorija, bet kas nutinka, kai serveris tikrai sugenda? Čia Litestream parodo savo tikrąją vertę. Atkūrimo procesas yra stulbinamai paprastas.

Tarkime, jūsų serveris sudegė (tikėkimės, kad tik metaforiškai). Paleidžiate naują instanciją, įdiegiate Litestream su ta pačia konfigūracija ir vykdote:

litestream restore -o /var/lib/myapp/database.db s3://mybucket.s3.amazonaws.com/db

Litestream atsisiųs bazinį snapshot’ą ir pritaikys visus WAL segmentus, kad atkurtų duomenų bazę iki paskutinio įmanomo momento. Priklausomai nuo duomenų bazės dydžio ir replikacijos dažnumo, galite prarasti maksimaliai kelias sekundes duomenų.

Praktikoje, jei naudojate container’ius (Docker, Kubernetes), galite sukonfigūruoti init container’į, kuris automatiškai atkuria duomenų bazę prieš paleidžiant pagrindinę aplikaciją. Tai atrodo maždaug taip:

initContainers:
- name: restore-db
image: litestream/litestream:latest
command: ["litestream", "restore", "-if-db-not-exists", "/data/db.sqlite"]

Našumo aspektai ir realūs skaičiai

Vienas dažniausių klausimų – ar Litestream nesuletina duomenų bazės? Trumpas atsakymas: ne, jei jūsų serveris nėra iš 2005 metų.

Litestream veikia atskirame procese ir naudoja labai mažai resursų. Vidutiniškai jis sunaudoja apie 10-20 MB RAM ir minimalų CPU kiekį. Kadangi jis tik skaito WAL failą, o ne kišasi į rašymo operacijas, jūsų aplikacija dirba normaliu greičiu.

Testavau Litestream su vidutinio dydžio aplikacija (apie 2GB duomenų bazė, ~100 rašymo operacijų per sekundę), ir replikacijos vėlavimas buvo 2-5 sekundės į S3. Tai reiškia, kad blogiausiu atveju galite prarasti 5 sekundžių duomenis, jei serveris staiga išsijungia.

Tinklo sąnaudos taip pat yra priimtinos. Litestream siunčia tik pakeitimus, ne visą duomenų bazę. Tai reiškia, kad jei atlikote 1000 INSERT operacijų, kurios pridėjo 1MB duomenų, į S3 bus išsiųsta tik ~1MB, ne visa 2GB duomenų bazė.

Alternatyvūs scenarijai ir konfigūracijos

Nors S3 yra populiariausias pasirinkimas, Litestream palaiko įvairias saugyklas. Jei naudojate Azure, konfigūracija atrodo taip:

replicas:
- url: abs://mycontainer.blob.core.windows.net/db
azure-account-name: myaccount
azure-account-key: ${AZURE_ACCOUNT_KEY}

Google Cloud Storage naudotojams:

replicas:
- url: gcs://mybucket/db

Bet štai įdomesnis variantas – galite replikuoti į kelis destination’us vienu metu. Pavyzdžiui, į S3 ir į kitą serverį per SFTP:

replicas:
- url: s3://mybucket.s3.amazonaws.com/db
- url: sftp://[email protected]:22/path/to/db

Tai suteikia papildomą saugumo lygį – jei viena saugykla nepasiekiama, turite atsarginę.

Dar viena naudinga funkcija – retention politikos. Galite nurodyti, kiek laiko saugoti senus snapshot’us:

replicas:
- url: s3://mybucket.s3.amazonaws.com/db
retention: 24h
snapshot-interval: 1h

Tai reiškia, kad Litestream sukurs pilną snapshot’ą kas valandą ir saugos juos 24 valandas. Senesni snapshot’ai bus automatiškai ištrinami.

Kai SQLite tampa rimta alternatyva

Su Litestream SQLite tampa visai kitokiu žvėriu. Staiga turite lengvą, greitą duomenų bazę su enterprise-level atsarginių kopijų sistema. Tai keičia skaičiavimus daugeliui projektų.

Pavyzdžiui, jei kuriate SaaS aplikaciją su multi-tenant architektūra, galite duoti kiekvienam tenant’ui atskirą SQLite duomenų bazę. Litestream gali stebėti šimtus ar net tūkstančius duomenų bazių vienu metu. Konfigūracija su wildcard’ais atrodo taip:

dbs:
- path: /var/lib/tenants/*.db
replicas:
- url: s3://mybucket.s3.amazonaws.com/${LITESTREAM_DB_NAME}

Kiekviena tenant duomenų bazė bus replikuojama į savo S3 „folderį”. Tai suteikia puikią izoliaciją ir supaprastina GDPR compliance – norite ištrinti tenant’o duomenis? Tiesiog ištrinkite vieną failą ir jo replikas.

Ką daryti kai reikia daugiau nei vieno serverio

Litestream nėra skirtas horizontaliam scale’inimui su keliais rašančiais serveriais. Tai svarbu suprasti – jei jums reikia kelių aplikacijos instancijų, kurios visos rašo į tą pačią duomenų bazę, SQLite su Litestream nėra tinkamas sprendimas.

Bet yra būdų apeiti šį apribojimą. Vienas populiarus pattern’as – naudoti read replicas. Pagrindinis serveris rašo į SQLite su Litestream, o kiti serveriai periodiškai atsisiunčia naujausią versiją ir naudoja ją tik skaitymui. Tai veikia stebėtinai gerai aplikacijoms, kur skaitymo operacijų yra daug daugiau nei rašymo.

Kitas variantas – sharding. Jei turite didelį duomenų kiekį, galite jį padalinti į kelias SQLite duomenų bazes pagal kokį nors raktą (pvz., user_id). Kiekviena duomenų bazė gyvena atskirame serveryje su savo Litestream replikacija.

Arba galite naudoti Litestream kaip atsarginių kopijų sprendimą, o pagrindiniam darbui pasirinkti kažką kitą. Pavyzdžiui, naudoti PostgreSQL kasdieniniam darbui, bet eksportuoti duomenis į SQLite ir replikuoti su Litestream kaip papildomą saugumo sluoksnį.

Kai technologija tampa įrankiu, o ne kliūtimi

Po kelių mėnesių naudojant Litestream produkcijoje, galiu pasakyti, kad tai vienas iš tų įrankių, kurie tiesiog veikia. Nereikia stebėti dashboard’ų, konfigūruoti sudėtingų cluster’ių ar samdyti DBA.

Žinoma, SQLite su Litestream nėra silver bullet. Jei kuriate kitą Facebook ar turite milijonus rašymo operacijų per sekundę, jums reikės kažko galingesnio. Bet jei kuriate normalią web aplikaciją, API, content management sistemą ar bet ką panašaus – šis derinys gali būti idealus.

Svarbiausias patarimas: pradėkite paprastai. Įdiekite Litestream su bazine konfigūracija, paleiskite ir pamiršite. Jei vėliau prireiks daugiau funkcionalumo – pridėkite retention politikas, papildomus destination’us, monitoring’ą. Bet bazinis setup’as veikia iš karto ir reikalauja minimalios priežiūros.

Ir dar vienas dalykas – testuokite atkūrimo procesą. Ne teorijoje, o praktiškai. Sukurkite test serverį, „sudaužykite” jį ir atkurkite duomenis. Padarykite tai kelis kartus, kol procesas taps automatinis. Nes kai tikrai prireiks atkurti duomenis, nenorite mokytis kaip tai daryti skubos metu.

Daugiau

Mintlify: dokumentacijos platforma