Ako sa trápime s MongoDB replikáciou - Bart Digital Products Ako sa trápime s MongoDB replikáciou - Bart Digital Products

Ako sa trápime s MongoDB replikáciou…

…takto. Vlastne sa netrápime. Trápi sa MongoDB. Ale to je jeho práca. Nás trošku vytrápilo na začiatku a o tom bude tento článok.

Na projekte SportNet využívame zatial 3 servery. Spočiatku každý slúžil na svoj účel a svoje projekty, ale čím viac sa projekty rozširovali, tým viac sa na seba začali servery podobať. Dnes sú vlastne, dá sa povedať, identické. Majú rovnaký OS, rovnakú softvérovú výbavu, podobné množstvo CPU a RAM.

Na každom bola vlastná inštancia MongoDB, ktorú bolo treba zálohovať, aktualizovať, udržiavať.

V priebehu leta 2020 sme s väčšinou projektov prešli do ich kontainerizácie, teda sú spustiteľné prakticky kdekoľvek, na akomkoľvek serveri cez docker alebo podman. A keďže servery využívame toho času 3, tak sme logicky chceli rozkladať záťaž a presúvať projekty medzi sebou.

A tu nastal prvý problém. Spustiť kontainer je jednoduché, ale prečo by sa mal pripájať cez pol serverovne, alebo cez pol mesta do databázy? Presunieme aj databázu. Ale to je zdĺhavé a nevhodné. Nedá sa to za behu, musíte spraviť výpadok služby. Zle, zle, zle.

Riešením bola replikácia MongoDB v rámci týchto troch serverov.

Pred samotnou replikáciou je vhodné nastaviť mongo tak, aby ukladalo dáta do samostatného adresáru a zdá sa mi vhodné aj nastavenie, aby každá databáza mala vlastný podadresár. To je jednoduché v konfigurácii takto:

# Where and how to store data.
storage:
  dbPath: /var/lib/mongo/data
  directoryPerDB: true

Následne sme skonsolidovali všetky databázy všetkých služieb na jeden server. Na ostatných dvoch sme mongo prečistili, prekonfigurovali rovnakým spôsobom a štartli už do nastavenej replikácie. Works like a charm!

MongoDB je teraz replica-set s tromi nodami, jeden je vždy Primary, do ktorého sa zapisuje, ďalšie sú secondary, ktoré replikujú dáta a sú vždy pripravené prevziať na seba zodpovednosť Primary servera.

Mysleli sme, že sme za vodou. Z omylu nás, jedno nedeľné ráno, vyviedol nečakaný pád MongoDB na primary servri. Najhoršie je sa naučiť na vlastných chybách… Pípla mi SMS, MongoDB je down. No a? Stihnem ešte kávu, však máme replikáciu…

Ani náhodou! Nenastavili sme správne pripojenia v aplikačných environmentoch! Takže služby boli dolu spolu s mongom. Našťastie mám pohotového kolegu, ktorý to vytušil tiež a stihol environmenty na serveroch prepísať. A tak nezabudnite aj vy:

# Mongo DB URI ENV
MONGO_URI=mongodb://meno:heslo@jeden.server:27017,druhy.server:27017,treti.server:27017/db?replicaSet=nazov_replicasetu

Toto je kľúč k úspechu. Toto vám zaručí ${rs.status().members.length}-násobne vyššiu dostupnosť služieb závislých nad MongoDB.

Čo sme tým získali?

Lepšie a jednoduchšie zálohovanie. Stačí vypnúť MongoDB na jednom zo serverov a rsync-nuť data adresár. Alebo spraviť snapshot disku.

Lepšia dostupnosť. Potrebujete nejaký server vypnúť, preinštalovať? Nie je problém. Dočasne sa kontajnery pripoja na ostatné dva.

Rozloženie záťaže – áno, toto nie je primárna úloha Mongo replikácie. Ale keď máte službu ako napríklad naše CMS API, na ktoré sa pripája vyťažený portál, tak ak službu spustíte na jednom zo serverov v samostatnom kontajneri, ktorému poviete, že má primárne čítať zo secondary servera, tak ste jednu inštanciu odbremenili a druhú adekvátne zaťažili.

Nastavuje sa to ako readPreference, buď v connection stringu, alebo pri získaní pointera na kolekciu, alebo pri konkrétnej find operácii. To už závisí od konkrétnej aplikácie. Napríklad to naše CMS je spustené v špeciálnom režime, kde dáta len číta a teda sme mu nastavili readPreference priamo v connection stringu na secondaryPreferred.