Replication

Replication

Kur nje projekt arrin nje fare volumi informacioni, vihet re qe nuk eshte me e lehte te administrohet databaza e tij. Ne rastin tone, Projekti i Infoarkives, (http://lajme.shqiperia.com), kaloi mbi 2.1 Giga informacion. Per kete projekt ne kishim vendosur nje server te dedikuar ne dispozicion. Megjithe sistemin e cache per te rritur performancen apo procesorin e mire, duke qene se disa here brenda dites serveri terhiqte lajme dhe i shkruante ne DB, sherbimi web u be teper i ngadalte dhe po krijonte problem.

Nga natyra, tabelat myisam jane teper te shpejta ne lexim dhe nxjerrje te informacionit, por problemi kryesor shkrimi ne databaze. Rrobotet e kerkimit terhiqnin informacion i cili shkruhet ne disa tabela dhe nje prej tyre me madhesi prej afro 2Giga. Procesi i shkrimit ne nje tabele te madhe MySQL rrezultoi teper i shtrenjte. Ne nje situate kur shkrimi zgjat disa seconda dhe vendos nje “kycje” per leximin apo indeksimin e leximeve ne DB, nga mysql krijohej nje bottleneck dhe webserveri nuk pergjigjej me shpejtesine e duhur.

Per te zgjidhur probleme te tilla ka disa skenare.

  • Shtimi i RAM ne server per te lejuar cache me te mire per mysql
  • Ndarja e tabelave te informacionit ne tabela me te vogla. Per kete do duhej kalimi ne InnoDB ku perseri kerkesat per RAM do ishin me te larta
  • Kalimi ne nje strukture no-sql, pra ruajtje statike e informacionit
  • Ndarja e sherbimit te mysql ne nje server te ndryshem nga webserveri

Megjithese kishim bere disa optimizime ne MySQL dhe ne Apache per te lehtesuar proceset e secilit, ekzekutimi i te dy ketyre sherbimeve krijonte probleme. Ne nje situate te tille, shtimi i RAM ne server (qe eshte i kushtueshem) nuk ishte nje zgjidhje afatgjate.

Fatmiresisht, MySQL lejon Replikimin e databazes. Praktikisht nje server i cilesuar si kryesori (MASTER) mund te replikohet (kopjohet) nga motorri i MySQl ne disa servera te tjere qe quhen Skllever (Slaves). Ne nje situate te tille, eshte e mundur qe serveri kryesor (master) te perdoret per shkrimin e te dhenave nga rrobotet, dhe serveri skllav mund te perdoret per leximin e te dhenave nga webserveri. Ishte kjo zgjidhja qe zgjodhem per rastin e Infoarkives, praktikisht hapat e implementimit jane me poshte.

Krijimi i Log File te MySQL

Replikimi ne MySQL funksionon mbi loget e serverit.  Ketu nuk flitet per loget normal qe tregojne logimin e userave, por logu binar i MySQL.

Logu Binar permban te gjithe komandat qe ndryshojne te dhenat ose qe mund te ndryshojne te dhenat (psh INSERT). Keto komanda (statements) ruhen ne menyre kronologjike qe pershkruajne modifikimet. Nje nga qellimet e ketij logu binar eshte pikerisht replikimi.
Per replikimet, logu binar perdoret tek serveri kryesor (master) si nje rekord i komandave qe duhet ti dergohen sklleverve. Servero kryesor i dergon ngjarjet qe ndodhen ne logun binar tek serveri skllav i cili i ekzekuton ato ne menyren kronologjike (Shih me shume: Manualin e References se MySQL).

Per te krijuar logun binar, modifikohet skedari: my.cnf (zakonisht gjendet nen /etc/my.cnf) qe te permbaje komandat me poshte:

log-bin = /var/lib/mysqllog/mysql-bin.log
binlog-do-db=db_arkivaime
server-id=1

Rrjeshti i pare komandon mySQL qe te shkruaje nje Log dhe ta shkruaje ate pikerisht ne direktorine mesiper. (Kjo direktori duhet te jete me te drejta shkrimi nga perdoruesi mysql).  Rrjeshti i dyte eshte nje reference per databazen qe do te replikohet (kujdes, replikohet nje DB dhe jo te gjitha DBte e serverit.) Ne rastin me siper po replikoj db_arkivaime. Ndersa rrjeshti i trete percakton nga nje Identifikim (unik sigurisht) te ketij serveri.  Nje identifikim unik do percaktohet pak me pas dhe tek serveri skllav.

Ne menyre qe databaza qe do replikohet te lexohet nga serveri skllav, duhet qe ne mysql te krijohet nje user i cili ka te drejta replikimi.

Ne phpmyadmin apo ne mysql console (mysql -u root -p) duhet te krijohet nje perdoures me sintaksen si me poshte:

GRANT REPLICATION SLAVE ON *.* TO 'perdoruesiSkllav'@'IPjaeserveritSkllav' IDENTIFIED BY 'fjalekalimi';
FLUSH PRIVILEGES;

Me tej, ne serverin skllav duhet te modifikohet my.cnf duke shtuar informacionin si me poshte:

server-id=2
master-host=IPeMasterServer
master-connect-retry=60
master-user=perdoruesiSkllav
master-password=fjalekalimi
replicate-do-db=db_arkivaime

relay-log = /var/lib/mysql/skllav-relay.log
relay-log-index = /var/lib/mysql/skllav-relay-log.index

Sintaksa pak a shume eshte e qarte, rrjeshti i pare percakton nje identifikim per kete server dhe i percakton atij nr 2 si emertim. Rrjeshtat me poshte tregojne perdoruesin me te cilin mund te lidhet serveri skllav me serverin kryesor dhe ne fund ka disa loge qe i duhen motorrit te MySQL per te mbajtur shenim positionin ne te cilin serveri kryesor eshte tek logs.

Ne kete cast eshte e nevojshme te ndalohet serveri kryesor dhe te kopjohet databaza aktuale ne serverin skllav (ne kete menyre te dy serverat do te nisin replikimin duke pasur te njejtin informacion). Metoda ime e preferuar eshte me rsync dhe pasi te jete krijuar dhe databaza “db_arkivaime” dhe tek serveri skllav, mund te kopjohen te gjitha te dhenat nga serveri kryesor tek serveri skllav me sintaksen me poshte:

rsync -avz -e ssh root@IPserveriKryesor:/var/lib/mysql/db_arkivaime/ /var/lib/mysql/db_arkivaime/

Sintaksa me siper, ekzekutohet ne serverin skllav dhe kopjon ne menyre binare gjithcka qe ndodhet nen /var/lib/mysql/db_arkivaime/ tek e njejta direktori ne serverin tjeter. Normalisht ky eshte path-i ku ruhen te dhenat e DBve (nje bashkesi skedaresh, .MYI, frm, MYD).

Pervec rsync (per databaza te medha), mysqldump (apo phpmyadmin dump) mund te perdoren per te kopjuar databazen nga masteri tek serveri.

Per te gjetur pozicionin e serverit kryesor ne Logs duhet te ekzekutohet (serveri duhet startuar me pare):

SHOW MASTER STATUS;

ne mysql console apo phpmyadmin te serverit Master. Pergjigja do jete dicka e tipit:

+------------------+----------+----------------+------------------+
| File                    |   Position | Binlog_Do_DB   | Binlog_Ignore_DB |
+------------------+----------+----------------+------------------+
| mysql-bin.000003 |   199749   | db_arkivaime |                  |
+------------------+----------+----------------+------------------+
1 row in set (0.00 sec)

Ne kete cast tek Serveri Skllav duhet te ekzekutohet:

slave stop;
CHANGE MASTER TO MASTER_HOST='IPKryesor', MASTER_USER='perdoruesiSkllav', MASTER_PASSWORD='fjalekalimi', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=199749;
slave start;

Pas nje restarti te serveri te slave mund te shikohet qe cdo veprim Update, Insert apo Delete ne serverin master reflektohet real time tek serveri skllav.