Databaseservere og indlejrede databaser: en sammenligning af arkitektur og I/O-egenskaber

Databaseserver
En databaseserver refererer til en database, der kører som en uafhængig serverproces og behandler applikationers anmodninger via netværket. De fleste RDBMS'er, som vi kender godt, såsom MySQL, PostgreSQL og Oracle DB, følger denne model. Databaseservere har følgende fordele.
- Central styring: Data administreres samlet ét sted, hvilket gør konsistens, sikkerhed, backup og gendannelse lettere at håndtere.
- Ressourceuafhængighed: Serveren tildeles sin egen CPU, hukommelse og lagerplads, hvilket sikrer stabil ydeevne uanset applikationens tilstand.
- Høj samtidighed og skalerbarhed: Serveren er optimeret til mange brugeres samtidige adgang, og horisontal skalering gennem clustering eller replikation er relativt ukompliceret.
På grund af disse egenskaber har databaseservere i de seneste årtier etableret sig som standard for softwareinfrastruktur. Som følge af teknologiske fremskridt og ændringer i omgivelserne er ulemperne ved databaseservere dog begyndt at træde frem i nogle miljøer, og embedded databaser får på ny opmærksomhed som et alternativ.
Ny tendens: Embedded databaser
En embedded database er en databasemotor, der ikke kræver en separat serverproces, men i stedet inkluderes i applikationen som et bibliotek og kører i samme proces. SQLite, LevelDB og RocksDB er typiske eksempler på embedded databaser. Baggrunden for, at embedded databaser er fremstået som et stærkt alternativ i det moderne teknologiske miljø, er følgende.
Fremkomsten af SSD'er
I tidligere systemmiljøer med HDD'er som det dominerende lagermedie var ydeevnen ved tilfældig adgang betydeligt lavere end ved sekventiel læsning og skrivning. Derfor var det centralt for ydeevneoptimering at minimere disk-I/O og maksimere hukommelsescaching. Databaseservere har tilpasset sig dette ved at drive store caches og behandle skriveoperationer samlet, og på den måde har de overvundet HDD'ens fysiske begrænsninger.
Fremkomsten af SSD'er har dog fuldstændigt ændret denne forudsætning. En SSD er tusindvis af gange hurtigere til tilfældig I/O end en HDD, og dens latenstid er markant kortere. Som følge heraf er den tidligere opfattelse, at "disk-I/O er den største flaskehals", forsvundet, og i stedet er forsinkelsen ved adgang til en fjernbetjent databaseserver via netværket begyndt at træde frem som den nye flaskehals.
MSA og datauafhængighed
Tidligere var det almindeligt, at en stor monolitisk applikation var afhængig af én centraliseret database. Selvom denne metode er enkel, bliver det med voksende serviceomfang vanskeligere at ændre dataskemaet, og da alle services deler samme database, bliver koblingen mellem dem for stærk.
I moderne mikroservicearkitekturer lægges der vægt på princippet "Database per Service" for at løse dette problem. Når hver service ejer og indkapsler sit eget dedikerede datalager, sikres uafhængighed mellem services, og fejlisolering og skalering bliver lettere. I denne sammenhæng bliver embedded databaser et ideelt valg som datalager på service-niveau. De er letvægts og hurtige og kan implementeres sammen med servicekoden, hvilket passer meget godt til MSA-miljøer.
Et typisk eksempel er i Kubernetes-miljøer, hvor man ofte anvender sidecar-mønsteret til at placere en embedded database ved siden af applikationscontaineren for at optimere den lokale databehandling. Dette reducerer netværksflaskehalse og minimerer forsinkelsen ved dataadgang.
Forenkling af driftsmiljøet
Databaseservere kræver komplekse driftsprocedurer såsom installation, patching, backup, gendannelse efter fejl, replikation og overvågning af ydeevne, og dette kræver dedikerede DBA'er og specialiseret driftspersonale. Især i store miljøer er denne administrative byrde meget stor.
Embedded databaser lindrer disse problemer betydeligt. Når databasen integreres i applikationen, udføres enhedstest, build, versionsstyring og deployment samlet, og der er derfor ikke behov for separat serverdrift. Desuden skaleres den embedded database med, når applikationen skaleres horisontalt, og automatiseret styring gennem DevOps-kultur og CI/CD-pipelines bliver mulig. Især i startups, små services og miljøer til prototypeudvikling reducerer embedded databaser driftskompleksiteten markant og øger udviklings- og deployment-hastigheden betydeligt.
Højtydende systemsprog og udvikling af økosystemet
Tidligere var det almindeligt, at databaser og applikationer blev skrevet på forskellige sprog. For eksempel blev databasemotorer, der krævede høj ydeevne, primært skrevet i C eller C++, mens applikationer blev udviklet i sprog som Java, Python og PHP. Denne fremgangsmåde var effektiv til ydeevneoptimering, men den havde begrænsninger i form af hukommelsessikkerhedsproblemer, kompleks samtidighedshåndtering, latenstid samt vanskeligheder med integration af biblioteker og deployment.
Med fremkomsten af moderne systemprogrammeringssprog såsom Go og Rust er disse begrænsninger dog blevet betydeligt mindre. Især Go er velegnet både til højtydende applikationer og til udvikling af lavniveauprogrammer såsom databasemotorer, og det gør det muligt at håndtere både database og applikation inden for ét sprogøkosystem.
Faktisk anvendes højtydende embedded databaser som BadgerDB og PebbleDB aktivt i Golang. Dette betyder, at embedded databaser ikke blot er et letvægtsalternativ til databaseservere, men har fået en egen konkurrencemæssig styrke og er blevet et vigtigt valg.
Konklusion
Når der er behov for central styring af store datamængder, komplekse transaktioner og høj samtidighed, er databaseserveren fortsat den stærkeste løsning. Men for individuelle services i MSA-miljøer, IoT-edge-enheder, hurtig prototyping og projekter, hvor driftseffektivitet er vigtig, kan embedded databaser være et mere effektivt og fornuftigt valg. Det afgørende er i sidste ende at vælge det værktøj, der bedst passer til den givne situation og de konkrete krav, og udviklingen af embedded databaser giver os flere og mere varierede valgmuligheder.