MongoDB hanggang Postgres
PAUNAWA: Ang blog post na ito ay isang pagsasanib ng aking MongoDB hanggang Postgres (2024-03-06) at Sequelize vs. Prisma (2023-05-25). Ang orihinal na mga blog ay inalis, at ang blog na ito ang pumalit sa kanila dahil parehong naglalaman ng halos magkaparehong nilalaman/impormasyon. Ang paglipat ay nagsimula noong unang bahagi ng Marso 2023, ang pagpapalit ay nangyari noong kalagitnaan ng Nobyembre 2023, at ang lahat ng mga instance ng lumang sistema ng MongoDB ay ganap na isinara noong unang bahagi ng Enero 2024.
Panimula
Sa panahon ko sa eBay, hinarap ko ang naging pinaka-materyal na mahirap na suliraning teknikal sa aking karera: ang paglipat ng Storage Management System (STMS) mula MongoDB patungong Postgres. Hindi lang ito simpleng pagpapalit ng database; isa itong ganap na pagbabago sa arkitektura ng isang kritikal na sistema na tumatanggap ng mahigit 1.5 milyong metrics kada minuto sa iba’t ibang data center ng eBay, na may kinakailangang zero downtime at pagpapanatili ng halos lahat ng kasalukuyang functionality.
Ano ang STMS?
Ang Storage Management System (STMS) ay nagsisilbing isang kritikal na internal na kasangkapan para sa Service & Storage Infrastructure (SSI) team ng eBay. Sinusubaybayan at pinamamahalaan nito ang mga device sa iba’t ibang data center ng eBay, na nagbibigay-daan sa mga engineer na:
- Subaybayan ang mga metrics mula sa dose-dosenang array, switch, host, disk group, at cluster
- Pangasiwaan ang alerting para sa mga switch at array
- Tapusin ang mga advanced na gawain tulad ng host allocations
- Ma-access ang real-time na data para sa iba pang internal na serbisyo ng eBay
Ang STMS ay sumasaklaw sa mahigit 70 array, 60 switch, 1100 host, 900 disk group, at 200 cluster sa 3 data center ng eBay. Dahil sa mahalagang papel nito sa imprastraktura ng eBay, ang anumang downtime o pagkawala ng functionality ay direktang makaaapekto sa mga pangunahing serbisyo at operasyon ng negosyo ng kumpanya.
Ang Hamon
Bakit Kinakailangan ang Paglipat
Ang desisyon na lumipat mula MongoDB patungong Postgres ay hindi basta-basta ginawa. Bagama’t nagsilbi nang maayos ang MongoDB sa STMS noong una, ang lumalaking kumplikasyon ng aming mga ugnayan ng data at ang pangangailangan para sa mas sopistikadong kakayahan sa pag-query ay nagpaunawa na ang Postgres ay mas magandang pangmatagalang solusyon para sa aming use case.
Ano ang Nagpahirap sa Problema na Ito
Ang kumplikasyon ng paglipat na ito ay nagmula sa ilang pangunahing hamon:
1. Pangunahing Pagkakaiba ng Database
Ang MongoDB at Postgres ay mga batayang magkaibang database. Ang MongoDB ay isang dokumentong nakabatay na database (NoSQL), na ang ibig sabihin ay ang data ay nakaimbak bilang JSON sa mga collection, gaya ng mga dokumento sa isang filing cabinet. Ang Postgres ay isang relational na database (SQL), na ang ibig sabihin ay ang data ay nakaimbak bilang mga row sa mga table, gaya sa isang spreadsheet.
2. Arkitektura ng Codebase
Ang buong backend ng STMS ay itinayo upang magproseso at mamahala ng data bilang mga JSON, gamit ang mga package na eksklusibong tugma sa MongoDB para sa mga operasyon sa database. Ibig sabihin nito ay hindi lang pagpapalit ng database ang kailangang gawin, kundi pati ang pagbubuo muli kung paano hinahawakan ng aming buong application ang data.
3. Kinakailangang Zero Downtime
Dahil sa kahalagahan ng STMS bilang isang internal na kasangkapan, hindi puwedeng magkaroon ng downtime sa panahon ng paglipat. Kailangang magpatuloy ang sistema sa pagseserbisyo ng 1.5+ milyong metrics kada minuto sa buong proseso.
4. Masikip na Timeline at Limitadong Karanasan
Kailangang matapos ang paglipat sa loob ng ilang buwan, at sa simula ay walang malinaw na planong pagpapatupad. Wala ni ako ni ang mga katrabaho ko na may karanasan sa paglipat ng isang malaking legacy codebase mula NoSQL patungong SQL databases, at limitado rin ang dati kong karanasan sa Postgres.
5. Sukat at Kumplikasyon
Kasama sa paglipat ang pag-convert ng 36 MongoDB collection tungo sa 74 Postgres table, na nangangailangan ng maingat na pagsasaalang-alang sa mga ugnayan, indexing, at query optimization.
Pagpili ng Tamang ORM: Sequelize vs Prisma
Isa sa mga unang pangunahing desisyon ay ang pagpili ng isang ORM (Object-Relational Mapping) na kasangkapan. Dahil ang aming codebase ay idinisenyo na para gumamit ng Mongoose para sa MongoDB, ang paggamit ng ORM ay magbibigay ng pinakamadulas na landas ng paglipat.
Pagsusuri ng mga Pangangailangan
Pagkatapos ng masusing pagsusuri sa mga pangangailangan ng proyekto, itinatag ko ang mahahalagang pamantayan para sa anumang solusyon ng ORM:
- Dapat ay isang JavaScript package (ang karamihan sa aming code ay isinulat sa JavaScript)
- Dapat sumuporta sa Postgres at sa karamihan ng mga tampok nito
- Dapat ay hindi bababa sa kapantay o mas mahusay ang performance kaysa Mongoose
- Dapat ay open source at pinananatili
Ang mga Kalahok
Matapos ang malawak na pananaliksik, binawasan ko ito sa dalawang pangunahing kalaban: Sequelize at Prisma. Gumawa ako ng komprehensibong mga testing environment gamit ang Docker para sa Postgres at in-convert ang aming pinakamalaki at pinaka-komplikadong dataset mula sa istruktura ng dokumento patungo sa istruktura ng table.
Pamamaraan ng Pagsubok
Para sa bawat ORM, sinukat ko ang performance sa mga kritikal na operasyon:
- Oras para lumikha ng isang entry
- Oras para mag-update ng isang entry
- Oras para mag-update ng nested na mga entry (mga ugnayan at JSON key-value)
- Oras para mag-delete ng isang entry
- Oras para mag-query/makakuha ng isang entry
Ang Desisyon: Sequelize
Bandang Mayo 15, 2023, nagpasya ako na ang Sequelize ang mas mahusay na ORM para sa aming use case. Narito kung bakit:
Mga Kalamangan ng Sequelize:
- Tunay na open-source at hindi pinananatili ng isang startup na may pondo
- Sinusuportahan ang karamihan sa mga tampok ng Postgres
- Mas mahusay ang performance, lalo na kumpara sa Prisma
- Mature na ecosystem na may mahigit 10 taon ng pag-unlad
- Flexible na representasyon ng model/schema gamit ang mga JavaScript class
- Suporta para sa kumplikadong joins at mga opsyon sa pag-filter kabilang ang Regex
Mga Resulta ng Performance:
Sa aking mga pagsubok, malaki ang lamang ng Sequelize sa Prisma. Para sa aming malalaking dataset na mga entry:
- Sequelize: ~2.26 segundo bawat entry
- Prisma: ~11.21 segundo bawat entry
Ang Prisma ay humigit-kumulang 5x na mas mabagal kaysa Sequelize para sa aming use case. Bukod pa rito, ang pag-delete ng isang entry mula sa aming pinakamalaking dataset ay inabot ng Prisma nang halos 4 na minuto, na hindi katanggap-tanggap para sa aming mga kinakailangan.
Mga Hamon ng Sequelize:
- Mas kumplikado at mas bloated na mga representasyon ng model (564 linya vs 262 linya para sa Mongoose)
- Nakalilitong syntax sa ilang kaso
- Kumplikasyon sa pag-migrate ng database
- Mas hindi komprehensibo ang dokumentasyon kumpara sa Prisma
Paghahambing ng Mga Kalamangan at Kahinaan ng Sequelize at Prisma
Upang mabigyan ng mas buong larawan kung bakit ko pinili ang Sequelize, nais kong ibahagi ang detalyadong mga kalamangan at kahinaan na naipon ko para sa parehong mga ORM noong aking pagsusuri. Tiningnan ko rin kung paano sila nagkakatapat pagdating sa representasyon ng schema at suporta ng komunidad noong Mayo 15, 2023. Ang mas malalim na pagbusisi na ito ay nakatulong upang pagtibayin ang aking pagpili, at umaasa akong maaaring maging kapaki-pakinabang ito sa sinumang nahaharap sa katulad na desisyon.
Mga Kalamangan ng Sequelize:
- May function na sync() na awtomatikong lumilikha at humahawak ng mga table para sa iyo, na nakakatipid ng maraming manu-manong pagsisikap.
- Kayang humawak ng kumplikadong joins para sa nested data, na kritikal para sa istruktura ng STMS.
- Sumusuporta sa malawak na hanay ng mga opsyon sa pag-filter, kabilang ang Regex, na nagbibigay ng kakayahang umangkop sa mga query.
- Ang representasyon ng model/schema ay ginagawa sa raw JavaScript gamit ang mga class, na lubos na nako-customize upang umangkop sa mga partikular na pangangailangan.
- Walang putol na hinahawakan ang mga koneksyon sa database, kabilang ang suporta para sa maraming read-connections.
- Sumusuporta sa raw SQL queries kapag kailangan mong silipin ang nasa ilalim ng hood.
- Mga estadistika ng komunidad noong Mayo 15, 2023: Sa NPM, huling in-update 14 na araw ang nakalipas na may 1,505,835 lingguhang downloads; sa GitHub, huling in-update kahapon na may 4.2k Forks at 27.9k Stars. Open source ito na may MIT license sa loob ng mahigit 10 taon, kaya tiwala akong mananatili itong ganoon.
Mga Kahinaan ng Sequelize:
- Maaaring maging napakakumplikado at bloated ng representasyon ng model/schema. Halimbawa, habang ang representasyon ng Mongoose ng aming malaking dataset ay humigit-kumulang 262 linya (kabilang ang mga espasyo), ang parehong dataset sa Sequelize ay lumobo sa 564 na linya.
- Maaaring nakalilito at komplikado ang syntax sa ilang sitwasyon, na kung minsan ay nagpabagal sa akin.
- Ang pagma-migrate o pag-e-edit ng database ay nakapapagod. Kahit na ang sequelize-cli ay gumagawa ng migration scripts, nananatili itong matrabaho, bagama’t napansin kong ito ay karaniwang suliranin sa karamihan ng mga ORM.
- Hindi ganoon kaganda ang dokumentasyon, bagama’t gumaganda ito. Sa kabutihang-palad, ang mga kasangkapan tulad ng ChatGPT ay may matibay na pagkaunawa sa Sequelize dahil sa mahabang kasaysayan nito, na tumulong punan ang mga puwang.
- Hindi kasing-sensitibo sa type tulad ng Prisma, na maaaring magdulot ng mga isyu sa ilang proyekto.
- Limitado ang suporta sa TypeScript, bagama’t hindi ito alalahanin para sa STMS, maaari itong maging deal breaker para sa iba.
Mga Kalamangan ng Prisma:
- Gumagamit ng sarili nitong wika ng schema, na ginagawang mas malinis at mas maigsi ang paglikha ng model. Para sa paghahambing, habang ang Mongoose ay gumamit ng 262 linya para sa aming malaking dataset, nagawa ito ng Prisma sa 221 linya lamang.
- May kasamang CLI tool na nagpapadali sa paglikha at pag-migrate ng database, na siyang pinakamahusay na nakita ko mula sa isang ORM hanggang ngayon, kahit na hindi ito perpekto.
- Sumusuporta sa raw SQL queries, na nagbibigay ng kakayahang umangkop kapag kinakailangan.
- Malinis at mas madaling maintindihan ang syntax ng code kumpara sa Sequelize, kaya mas madaling matutuhan.
- Awtomatikong bumubuo ng query builders para sa Node.js at TypeScript sa pamamagitan ng client nito, na isang magandang dagdag.
- May mahusay at malinis na dokumentasyon. Hindi kasing-up-to-date ang ChatGPT sa Prisma, ngunit kadalasan ay nababawi ito ng opisyal na docs.
- Mga estadistika ng komunidad noong Mayo 15, 2023: Sa NPM, huling in-update 6 na araw ang nakalipas na may 1,344,705 lingguhang downloads; sa GitHub, huling in-update 3 oras ang nakalipas na may 1.1k Forks at 31.3k Stars.
Mga Kahinaan ng Prisma:
- Hindi sumusuporta sa Regex filtering para sa Postgres, bagama’t may inaalok itong mga alternatibo tulad ng “contains,” “includes,” at “startsWith.”
- Malaking problema ang performance sa aking mga pagsubok. Ang paglikha ng mga entry para sa aming malaking dataset ay inabot ng Prisma ng humigit-kumulang 11.21 segundo bawat entry kumpara sa 2.26 segundo ng Sequelize, na halos 5x na mas mabagal.
- Ang pag-delete ng isang entry mula sa malaking dataset ay tumagal ng halos 4 na minuto, na isang deal breaker para sa aming mga pangangailangan.
- Kahit sa patas na paghahambing sa isang kumplikadong dataset ng relasyon na may tatlong patong na lalim, mas mabilis nang malaki ang Sequelize sa mga deletion.
- Ang Prisma ay sinusuportahan ng isang startup na may $56.5 milyon na pondo. Bagama’t open source ang pangunahing ORM code nito sa ilalim ng Apache-2.0, nag-aalangan ako sa posibleng mga pagbabago sa lisensiya sa hinaharap, katulad ng nangyari sa MongoDB.
Ang mga detalyadong paghahambing na ito ay nagpaalinaw na ang Sequelize ay mas akma sa mga pangangailangan ng STMS, lalo na sa performance at pangmatagalang pagiging maaasahan. Ngunit naisip kong ang mas detalyadong pagbubuo nito sa ganitong paraan ay maaaring makatulong sa iba na nakikipagbuno rin sa kaparehong pagpili para sa kanilang mga proyekto.
Ang Proseso ng Migrasyon
Pagbabago ng Estruktura ng Datos
Ang paglipat mula sa istruktura ng dokumento ng MongoDB patungo sa relasyunal na istruktura ng Postgres ay nangangailangan ng maingat na pagpaplano. Kailangan kong:
- Suriin ang mga Ugnayan: Tukuyin kung paano magkakaugnay ang mga dokumento ng MongoDB sa isa’t isa at magdisenyo ng angkop na mga ugnayan ng foreign key
- I-normalize ang Datos: Hatiin ang mga nakapaloob na dokumento sa magkakahiwalay na mga talahanayan kung naaangkop
- Panatilihin ang mga Tampok ng JSON: Gumamit ng mga column ng JSONB para sa tunay na hindi nakaayos na datos na kailangang manatiling nababaluktot
- Magdisenyo ng mga Index: Lumikha ng angkop na mga index para sa pagganap ng query
Mga Pasadyang Solusyon
Ang migrasyon ay nangangailangan ng pagbuo ng ilang pasadyang solusyon:
1. Mga Script sa Migrasyon ng Datos Gumawa ako ng komprehensibong mga script upang:
- I-extract ang datos mula sa mga koleksyon ng MongoDB
- I-transform ang mga istruktura ng dokumento tungo sa anyong relasyunal
- I-import ang datos sa mga talahanayan ng Postgres na may wastong mga ugnayan
2. Layer ng Pagkakatugma ng API Upang mapanatili ang zero downtime, bumuo ako ng isang layer ng pagkakatugma na maaaring:
- I-ruta ang mga kahilingan sa alinman sa MongoDB o Postgres depende sa estado ng migrasyon
- Tiyakin ang pagkakapare-pareho ng datos sa panahon ng paglipat
- Magbigay ng mga mekanismong pang-backup
3. Pasadyang Middleware Bumuo ng middleware upang pangasiwaan ang mga pagkakaiba sa paraan ng paghawak ng MongoDB at Postgres sa ilang partikular na operasyon, na tinitiyak na ang mga umiiral na endpoint ng API ay patuloy na gumagana nang walang pagbabago.
Paglampas sa mga Teknikal na Hamon
Paghawak ng mga Komplikadong Ugnayan
Isa sa pinakamalalaking hamon ay ang pag-convert ng mga nakapaloob na dokumento ng MongoDB sa mga ugnayan ng Postgres. Halimbawa, maaaring maglaman ang isang dokumento ng MongoDB ng:
- Mga pangunahing katangian
- Mga nakapaloob na bagay na kumakatawan sa mga kaugnay na entidad
- Mga array ng mga nakapaloob na dokumento
Kailangang maingat itong hati-hatiin sa:
- Mga pangunahing talahanayan para sa mga pangunahing entidad
- Mga junction table para sa mga many-to-many na ugnayan
- Mga ugnayang foreign key para sa one-to-many na mga asosasyon
Pag-optimize ng Query
Ang mga pattern ng query ng MongoDB ay hindi direktang maisasalin sa SQL. Kailangan kong:
- Isulat muli ang mga komplikadong aggregation pipeline bilang mga SQL join
- I-optimize ang mga index para sa mga bagong pattern ng query
- Tiyakin na ang pagganap ng query ay umabot o lumampas sa pagganap ng MongoDB
Integridad ng Datos
Ang pagtiyak ng integridad ng datos sa panahon ng migrasyon ay nangangailangan ng:
- Komprehensibong mga script ng beripikasyon
- Mga pamamaraan ng rollback
- Real-time na pagsi-synchronize ng datos sa panahon ng mga yugto ng paglipat
Mga Resulta at Epekto
Matagumpay na natapos ang migrasyon ng STMS mula MongoDB patungong Postgres nang walang downtime habang pinananatili ang halos lahat ng tampok at functionality. Lumampas ang mga resulta sa inaasahan:
Mga Pagpapahusay sa Pagganap:
- Bumuti ang pagganap ng query para sa mga komplikadong relasyunal na query
- Mas mahusay na pagkakapare-pareho at integridad ng datos
- Mas episyenteng paggamit ng storage
Mga Benepisyong Operasyonal:
- Pinalakas na mga kakayahan sa pagmamanman at pag-debug
- Mas mahusay na integrasyon sa mga umiiral na SQL-based na tool ng eBay
- Pinahusay na mga pamamaraan ng backup at recovery
Epekto sa Koponan:
- Pinalawak na kaalaman ng koponan sa mga relasyunal na database
- Naitatag na mga pattern para sa mga susunod na migrasyon ng database
- Nalikha na mga muling magagamit na tool at proseso
Mga Teknikal na Kasanayang Nakuha
Malaki ang pinalawak ng proyektong ito sa aking teknikal na kadalubhasaan:
Mga Teknolohiya ng Database:
- Malalim na pag-unawa sa mga tampok at pag-optimize ng Postgres
- SQL query optimization at performance tuning
- Mga pattern ng disenyo ng database at normalisasyon
- Mga konfigurasyon ng primary-standby database
Mga Kasangkapan sa Pagbuo:
- Sequelize ORM at pagbuo ng query
- Mga estratehiya sa migrasyon ng database
- Mga metodolohiya ng performance testing
- Pagsusuri ng datos at integridad
Mga Pattern ng Arkitektura:
- Mga estratehiya ng migrasyon na zero-downtime
- Mga layer ng pagkakatugma ng API
- Mga pattern ng abstraksiyon ng database
- Mga sistema ng pagmamanman at pag-aalerto
Personal at Propesyonal na Paglago
Ang proyektong migrasyon na ito ay nagbago nang malaki sa aking pag-unlad sa karera. Inilagay ako nito sa hindi pa natatahak na teritoryo, na nangangailangan ng:
Mga Kasanayan sa Pamumuno:
- Pamumuno sa isang komplikadong teknikal na proyekto nang walang dating karanasan
- Paggawa ng mahahalagang desisyong pang-arkitektura sa ilalim ng presyon
- Koordinasyon sa maraming koponan at mga stakeholder
Mga Kakayahan sa Paglutas ng Problema:
- Paghahati-hati ng komplikadong mga problema sa mga mapapamahalaang bahagi
- Pagbuo ng malikhaing mga solusyon sa walang kapantay na mga hamon
- Pagbabalanse ng maraming nagtatagisan na mga kinakailangan at limitasyon
Komunikasyon at Pagtutulungan:
- Pagpapaliwanag ng mga teknikal na konsepto sa mga hindi teknikal na stakeholder
- Pagtatala ng mga proseso at desisyon para sa hinaharap na sanggunian
- Pagtuturo sa mga miyembro ng koponan sa mga bagong teknolohiya at pattern
Mga Natutuhang Aral
Mga Teknikal na Aral
- Mahalaga ang Pagpili ng Database: Ang pagpili sa pagitan ng NoSQL at SQL ay dapat batay sa mga partikular na gamit at pangmatagalang mga kinakailangan
- Kritikal ang Pagsubok sa Pagganap: Ang mga teoretikal na bentahe ay hindi laging nagsasalin sa totoong-buhay na mga pakinabang sa pagganap
- Pagpaplano ng Migrasyon: Ang komprehensibong pagpaplano at pagsubok ay mahalaga para sa mga komplikadong migrasyon
- Pamumuhunan sa mga Tool: Ang pagbuo ng wastong mga tool nang maaga ay nakakatipid ng malaking oras at nagpapababa ng mga pagkakamali
Mga Aral sa Pamamahala ng Proyekto
- Komunikasyon sa mga Stakeholder: Ang regular na mga update at malinaw na komunikasyon ay pumipigil sa mga hindi pagkakaunawaan
- Pamamahala sa Panganib: Mahalaga ang pagkakaroon ng mga fallback plan at mga pamamaraan ng rollback
- Pamamahala ng Timeline: Maglaan ng buffer time para sa mga hindi inaasahang hamon at learning curve
- Dokumentasyon: Ang masusing dokumentasyon ay nagbibigay-daan sa paglilipat ng kaalaman at hinaharap na maintenance
Konklusyon
Ang migrasyon ng STMS mula MongoDB patungong Postgres ay tumatayong pinakamahirap at pinakakapanipaniwalang teknikal na problemang nalutas ko sa aking karera. Nangailangan ito hindi lamang ng teknikal na kadalubhasaan, kundi pati ng pamumuno, pagpaplano, at kakayahang umangkop. Ipinakita ng tagumpay ng proyekto na sa wastong pagpaplano, masusing pagsubok, at dedikasyon sa kahusayan, maging ang pinakamakabuluhang mga teknikal na hamon ay maaaring mapagtagumpayan.
Ang karanasang ito ay lubusang nagbago sa aking paglapit sa software engineering, na binibigyang-diin ang kahalagahan ng:
- Pag-unawa sa buong konteksto at mga kinakailangan bago gumawa ng mga desisyong teknikal
- Paglalaan ng oras sa wastong mga tool at pagsubok
- Pagpapanatili ng malinaw na komunikasyon sa buong mga komplikadong proyekto
- Pagiging handang matuto ng mga bagong teknolohiya at pamamaraan kapag kinakailangan
Ang tagumpay ng migrasyon ay hindi lamang nagpabuti sa mga kakayahan ng STMS kundi nagtatag din ng mga pattern at prosesong patuloy na nakikinabang sa mga proyekto ng imprastruktura ng eBay. Pinagtibay nito ang aking paniniwala na ang pagyakap sa mga hindi kilalang hamon at ang pagtagumpay sa pamamagitan ng mga ito ay susi sa parehong personal at propesyonal na pag-unlad.
Sa pagbabalik-tanaw, ang proyektong ito ay kumakatawan sa isang punto ng pagbabago sa aking karera, na binago ako mula sa isang developer na nagpapatupad ng mga solusyon tungo sa isang engineer na kayang mag-arkitekto at mamuno sa mga komplikadong teknikal na inisyatiba. Ang kumpiyansa at mga kasanayang nakuha mula sa karanasang ito ay patuloy na gumagabay sa aking paglapit sa mga bagong hamon at oportunidad sa software engineering.