Event sourcing inakutaka uache kufuta na kuandika upya data zako. Katika programu ya kawaida ya CRUD, kuhuisha anwani ya usafirishaji ya mtumiaji inamaanisha kutafuta mstari huo, kubadilisha thamani, na kutupa hali ya awali. Event sourcing inachukua njia tofauti. Inahifadhi kila mabadiliko kama ukweli usiobadilika (immutable fact): mtumiaji alitengeneza akaunti, alihuisha anwani yake, alithibitisha barua pepe yake. Hali ya sasa ya mfumo haihifadhiwi moja kwa moja. Inatengenezwa kwa kurudia matukio haya kwa mpangilio.

Mtindo huu unatatua matatizo ya kweli. Kumbukumbu za ukaguzi (audit trails) zinakuwa matokeo ya ziada bila gharama. Unaweza kuunda upya hali ya oda wakati wowote uliopita. Unaweza kurekebisha makosa (debug) kwa kurudia kile hasa kilichotokea. Changamoto yake ni utata (complexity). Sasa unasimamia mtiririko wa ukweli, mifano ya kusoma (read models), na uwiano wa baadaye (eventual consistency) badala ya mistari rahisi ya data.

PostgreSQL inaweza kutumika kama ghala lako la matukio (event store). Timu nyingi tayari inaitumia. Inatoa miamala ya ACID, JSONB kwa ajili ya payload zinazobadilika, na zana za nakala za akiba (backup) zilizothibitishwa. Huhitaji kuleta Kafka, Cassandra, au hifadhidata maalum ya ghala la matukio siku ya kwanza. Mfano wa kawaida wa Postgres unakupa dhamana za miamala na kumbukumbu za ukaguzi zinazohitajika na event sourcing bila kuongeza mzigo wa miundombinu yako.

Muundo wa Ghala la Matukio la Postgres

Muundo (schema) unaweza kuwa rahisi kiasi cha kushangaza. Kwa kiwango cha chini kabisa, unahitaji jedwali linaloongeza matukio na halifanyi mabadiliko (updates) kwenye matukio yaliyopo. Muundo wa vitendo unaonekana hivi:

  • id kama bigserial au UUID, inayotumika kama mpangilio wa jumla.
  • stream_id kwa ajili ya kuunganisha matukio yanayohusiana, kama vile mabadiliko yote ya mtumiaji mmoja au oda moja.
  • event_type kama maandishi ya kawaida: UserEmailChanged, PaymentReceived, InventoryAdjusted.
  • payload kama JSONB, inayoshikilia data mahususi ya tukio hilo.
  • occurred_at ikiwa na usahihi wa saa (timezone).
  • version kwa kila mtiririko (stream), inayodhibiti ushindani wa matumaini (optimistic concurrency).

Unadhibiti sheria ya kutobadilisha data (immutability) kwenye kodi ya programu au kwa kutumia kizuizi cha hifadhidata (database constraint). Kielezo cha kipekee (unique index) kwenye (stream_id, version) huzuia waandishi wawili kuongeza namba ile ile ya mfuatano. Amri inapokuja, unasoma toleo la sasa la mtiririko huo, unaliongeza, na kuingiza tukio jipya ndani ya muamala (transaction). Ikiwa mchakato mwingine ulikutangulia, kizuizi cha kipekee kitafeli, na utajaribu tena au kukataa amri hiyo.

Chukulia mfano halisi. Unaendesha mfumo wa stoo (inventory system). Badala ya mstari mmoja wa inventory wenye safu ya quantity, unaongeza matukio kwenye jedwali la inventory_events. ItemReceived inaongeza vitengo kumi. ItemReserved inaondoa viwili. ItemShipped inaondoa vitatu. Ili kujua hisa ya sasa kwa SKU-42, unajumlisha payload za matukio husika. Ili kujua hisa ya siku tatu zilizopita, unajumlisha matukio hadi wakati huo tu. Ikiwa hitilafu katika mantiki yako ya usafirishaji ilisababisha kosa Jumanne iliyopita, unarudia matukio kupitia kodi iliyorekebishwa ili kupata hali halisi. Huwezi kufanya hivyo kwa kutumia amri rahisi ya UPDATE.

Kanuni Zinazokuepusha na Matatizo

Kujenga juu ya Postgres hakupunguzi hitaji la nidhamu. Kanuni zifuatazo zinahusika moja kwa moja na mifumo ya event-sourced.

Iweke iwe rahisi. Utata huua uaminifu. Zuia hamu ya kujenga mfumo wa jumla wa matukio (generic event framework) kabla ya kuendesha mtiririko mmoja unaofanya kazi. Jedwali moja, kazi ya ghala (repository function) ya kuongeza matukio, na mfanyakazi wa upitishaji (projection worker) wa kujenga mifano ya kusoma (read models) zinatosha kuthibitisha thamani. Ongeza zana tu wakati tatizo halisi linapotokea.

Anza kidogo. Usiandike upya mfumo wako mzima (monolith). Chagua muktadha mmoja uliowekwa (bounded context) ambapo kumbukumbu za ukaguzi zinahalalisha gharama za ziada. Daftari la malipo, injini ya mtiririko wa kazi, au mfumo wa uhifadhi wa stoo ni chaguo nzuri. Jenga mtiririko huo mmoja kuanzia mwanzo hadi mwisho. Uruhusu uendeshe kwenye uzalishaji (production). Kisha amua ikiwa unapaswa kuupanua.

Fafanua mafanikio kwanza. Event sourcing si usanifu wa lazima; ni suluhisho la mahitaji mahususi. Ikiwa hitaji lako ni kufuatilia hali ya mwisho tu, CRUD ni haraka na rahisi zaidi. Ikiwa unahitaji maswali ya kihistoria (temporal queries), ukaguzi mkali, au uwezo wa kujenga upya mifano ya kusoma (read models) wakati wowote, basi matukio (events) yanafaa. Jua tatizo unalotatua kabla ya kuamua.

Pima kabla ya kuboresha. PostgreSQL ya kisasa kwenye vifaa vya kawaida inaweza kupokea maelfu ya matukio kwa sekunde kwa kutumia jedwali rahisi la kuongeza tu (append-only table). Usigawanye (shard) ghala lako la matukio au ulete mifumo migumu ya kugawa data (partitioning) mpaka ufuatiliaji wako uthibitishe kuwa umemaliza kutumia njia rahisi zaidi. Weka kielelezo (index) kwenye safu unazouliza. Rekebisha autovacuum kwa ajili ya kazi za kuongeza tu (append-only workloads). Kisha pima tena.

Jaribu kila kitu. Fanya unit test kwenye event handlers zako. Fanya integration test kwenye njia ya kuongeza data (append path). Muhimu zaidi, jaribu hali za hitilafu (failure scenarios). Nini kinatokea wakati node mbili zinapojaribu kuongeza data kwenye stream moja kwa wakati mmoja? Nini kinatokea wakati projection worker anapozima katikati ya batch? Andika majaribio yanayothibitisha optimistic concurrency na ahadi zako za at-least-once delivery.

Fuatilia kwenye uzalishaji (production). Jedwali la matukio (events table) litakua. Tofauti na normalized schema ambapo maboresho huweka idadi ya mistari vilevile, event sourcing imekusudiwa kuwa ya kuongeza tu (additive). Fuatilia ukubwa wa jedwali, disk I/O, na ucheleweshaji (lag) kati ya write model yako na projections za read model yako. Weka tahadhari (alerts) kwenye ucheleweshaji wa projection kabla watumiaji wako hawajagundua data iliyopitwa na wakati.

Weka kazi za mwongozo katika mfumo wa kiotomatiki. Mabadiliko ya mwongozo ya schema, ujenzi upya wa projection kwa mkono, na kurudia matukio (event replay) kwa mkono ni mabomu yanayolipuka muda wowote. Andika script ya mkakati wako wa uhamiaji (migration strategy). Ikiwa unabadilisha schema ya tukio, weka upcasting au mabadiliko (transformation) katika mfumo wa kiotomatiki ili matukio ya zamani yaweze kurudiwa kupitia mantiki mpya bila kuingiliwa na binadamu usiku wa manane.

Weka kumbukumbu za chaguzi zako. Andika kwa nini stream fulani zipo, kila aina ya tukio inamaanisha nini, na ni lini timu inapaswa kuchagua CRUD badala ya matukio. Event sourcing huleta mzigo wa kiakili (cognitive load). Kumbukumbu nzuri humzuia mhandisi mpya kukisia vibaya na kuongeza matukio yaliyoharibika kwenye stream muhimu.

Mitego Inayopoteza Miezi Mingi

Event sourcing ina namna ya kusikika vizuri kwenye mchoro lakini inakuwa yenye maumivu kwenye uzalishaji. Tahadhari na mitego hii.

Kudharau ugumu. Kurudia matukio ili kujenga upya hali (state) ni rahisi kifikra. Kusimamia idempotency, snapshotting kwa ajili ya utendaji, na miamala ya fidia (compensating transactions) kwenye aggregates si rahisi. Gawanya mfumo wako katika vipande vidogo. Tatua stream moja baada ya nyingine.

Uhandisi uliopitiliza (Over-engineering). Usitengeneze cluster ya Kafka yenye node nyingi kwa sababu unadhani kiasi chako cha matukio kitahitaji hivyo siku moja. Postgres inaweza kukusaidia kwa mbali sana. Ingiza miundombinu mipya tu unapokuwa na kizuizi (bottleneck) kilichopimwa ambacho huwezi kukirekebisha ndani ya mipangilio yako ya sasa.

Kupuuza deni la kiufundi (technical debt). Schema za zamani za matukio hudumu milele. Ikiwa unabadilisha payload ya OrderCreated, bado una matukio milioni kumi ya kihistoria katika umbo la zamani. Fuatilia deni hili. Panga wasomaji wanaokubaliana na matoleo ya zamani (backward-compatible readers) au script za uhamiaji. Usiruhusu mzigo wa matukio ya zamani (legacy events) kupunguza kasi ya kila kipengele kipya.

Kuchagua zana ambazo timu haiwezi kuzitumia. Usanifu bora hufeli ikiwa mtu mmoja tu ndiye anayeuelewa. Ikiwa timu yako inajua Postgres na SQL, anza hapo. Ikiwa unaanzisha event store maalum, hakikisha una utaalamu wa kiutendaji wa kuirekebisha (debug) saa nane usiku.

Hatua ya Kuanzia ya Kiutendaji

Ikiwa mbinu hii inafaa tatizo lako, usisubiri marekebisho ya robo tano zijazo. Anza wiki hii.

Kagua mifumo yako ya sasa. Tafuta sehemu ambapo rekodi ya ukaguzi (audit trail) ingetatua maumivu halisi. Labda ni mashine ya hali ya oda (order state machine) ambayo kwa sasa inahifadhi safu moja ya status. Labda ni leja ya kifedha ambapo marekebisho ya salio yanahitaji marekebisho ya database kwa mkono. Chagua pengo moja ambapo kuandika upya hali (overwriting state) imekuumiza.

Kisha chagua uboreshaji mmoja mdogo unaoweza kufanya leo. Tengeneza jedwali moja la matukio. Unda stream moja. Andika projection moja inayojenga read model kutoka kwa matukio hayo. Iweke (deploy) nyuma ya feature flag. Iangalie ikishughulikia trafiki halisi.

Event sourcing kwa kutumia PostgreSQL si uchawi. Ni zana ya kiutendaji kwa timu zinazohitaji kujua si tu mahali vitu vilipo, bali jinsi vilivyofika hapo. Jenga polepole, pima kwa uaminifu, na acha mahitaji yako halisi yaongoze usanifu.

Chanzo: https://dev.to/therizwansaleem/event-sourcing-with-postgresql-using-the-database-as-an-event-store-2kd4