January 2016

Өгөгдлийг scaling хийх нь

Та нэг энгийн web server болон өгөгдлийн сангаас бүтэх систем хийлээ гэж үзье. Хэрвээ тэр систем чинь ачаалал даахгүй байвал яах вэ?
Хэрвээ web server чинь ачааллаа даахгүй байгаа бол шийдэхэд амархан Яг адилхан 1 instance үүсгэхэд л хангалттай.
Харин өгөгдлийн сан чинь ачааллаа дийлэхгүй бол шийдэхэд нэлээн яривигтай. Мэдээж эхний алхам бол бүх хандалт(query)-аа optimization хийх, хэд хэдэн давхар cache давхарга нэмэх.
Ихэнх системийн хувьд өгөгдөл унших тоо нь бичих тооноосоо хэд дахин, эсвэл хэдэн арав дахин их байдаг. Жишээ нь, хүмүүс Facebook-ын profile-аа сардаа эсвэл бараг жилдээ 1 л өөрчилдөг байх. Харин тэр хүний profile-ыг өдөрт хэдэн арваас, хэдэн зуун хүн харж байгаа. Тиймээс, таны хийж буй систем чинь, яг үүнтэй адил уншилтын тоо нь бичилтийн тооноосоо хамаагүй их бол, master-slave загвар луу шилжүүлж болох юм.

Master Толгой өгөгдлийн сан ба, бүх бичилтүүд ийшээ хийгдэнэ
Slave Дагавар өгөгдлийн сан ба, бүх уншилтууд эндээс хийгдэнэ

Ажиллах зарчим нь маш энгийн. Master луу бичилт хийх болгонд master нь slave-үүд рүүгээ давхар бичилт хийгээд шинэчлээд, бүх server дээрх мэдээлэл яг адил мэдээлэл агуулаад явах юм. Үүнийг replication гэж нэрлэдэг. Харин одоо их хэмжээний унших хүсэлт ирэхэд slave-үүд рүүгээ тэнцүү хуваагаад явуулчихна. Дараах зурганд дүрслэх гэж оролдлоо.

Replication

Ихэнх төрлийн өгөгдлийн сангууд replication хийх чадвартай бөгөөд, ихэнхдээ 2 төрөл байдаг. Sync болон async. Sync replication нь бичих хүсэлт авангуутаа slave-үүдээ шинэчлэх бөгөөд, шинэчилж дууссаны дараа, бичилт амжилттай боллоо гэсэн хариултыг буцаана. Харин async нь, master дээр бичилтээ хийсэний дараа бичилт амжилттай боллоо гэсэн хариуг буцаагаад, дараа нь slave-үүдээ шинэчилнэ.
2 арга нь 2-уулаа сайн ба муу талуудтай бөгөөд, хамгийн гол анхаарах ёстой зүйл гэвэл consistency юм. Async үед inconsistent буюу, нэг агшинд нэг өгөгдөл, 2 өөр утга агуулах боломж үүсч байгаа юм. Өөрөөр хэлбэл дөнгөж бичсэний дараа, уншилт хийвэл хуучин утга уншигдах магадлалтай гэсэн үг.

Харин одоо, бүүр их ачаалаллын талаар ярилцая. 100 сая хэрэглэгчийн мэдээлэл хадгалах ёстой гэж үзье. Урьдчилсан тооцооны дүнд 10 сая хэрэглэгчийн мэдээлэлийг 1 server-т хадгалахад ачаалал даана гэж үзье. Тэгвэл одоо бидэнд 1 биш 10 master хэрэг болно. Өөрөөр хэлбэл 1 том хүснэгтийг 10 жижиг хэсэг болгож хувааж байнаа гэсэн үг. Үүнийг sharding гэх бөгөөд, хуваагдсан хэсгүүдийг shard гэнэ. Дараах зурганд дүрслэв.

Sharding

Янз бүрийн байдлаар хувааж болно. Жишээ нь 1-1000000 ID-тай хэрэглэгчийг Master 1-д, 10000001-20000000 ID-тай хэрэглэгчдийг Master 2-т гэх мэт. Эсвэл 10-т хуваагаад гарах үлдэгдлээр нь 10 master-руугаа хувааж болно. Эсвэл хэрэглэгчийн амьдарч буй улсаар нь гэх мэт, хамгийн гол нь системдээ тааруулаад, яаж хуваавал хамгийн хялбар аргаар хүссэн мэдээлллээ авч чадах вэ, мөн ачаалал болон, мэдээллийн хувьд тэнцвэртэй баланстай байж чадах уу гэдгийг бодох хэрэгтэй.
Жишээ нь Facebook дээрх post-ын comment-ыг хадгалах ёстой гэж үзье. Тэгвэл comment-ынх нь ID-аар биш, post-ынх нь ID-г ашиглан sharding хийвэл, адил post дээрх бүх comment-ууд нэг server дээр хадгалагдах тул, comment-уудыг уншихын тулд, олон server-рүү хандах шаардлагагүй болох юм.

Эцэст нь нэг юм хэлэхэд, энд нэг ч өгөгдлийн сангийн нэр(MySQL, MongoDB гэх мэт) дурдаагүй байгааг анзаарсан байх. Ямар ч өгөгдлийн сан дээр, автомат sharding байсан ч, ард нь нэг иймэрхүү л зүйл явагдаж байгаа гэдгийг ойлгуулах гэсэн юм. KVS төрлийн NoSQL-уудын хувьд, key-ийнхээ hash-аар хуваадаг ба ихэнх нь автоматаар, эсвэл хангалттай их library-ууд байдаг тул хөгжүүлэгч талаас нээх асуудал гараад байхгүй. Харин RDBMS-үүдийн хувьд, системийн шаардлага янз бүр тул, бараг өөрсдөө системдээ тохирсон sharder хөгжүүлж таарах байх.

Microservices

Microservices нь нэгэн төрлийн архитектур загвар юм. Microservices-ын талаар ярихын өмнө, эхлээд дараах ойлголтуудыг тайлбарлъя.

Monolithic – Энэ нь, нэг бүхэл гэсэн утгатай бөгөөд, хийж байгаа систем чинь тэр чигээрээ ганцхан хэл дээр бичигдсэн нэг бүхэл код байхыг хэлнэ. Монголд хийгдэж байгаа вебүүдийн ихэнх нь ийм байх гэж бодож байна. Мөн олон startup компаниуд, анх гарч ирэхдээ ийм загвартай байдаг.

Microservices – Энэ нь, систем чинь олон жижиг системээс бүрэлдхийг хэлж байгаа юм. Жишээ нь онгоцны тийз захиалдаг систем байлаа гэж үзвэл, тооцоо хийдэг систем, хайлт хийдэг систем, худалдаж авсан тийзийг илгээдэг систем гэх мэт, бизнес логиктойгоо уялдуулан, хоорондоо харилцах чадвартай олон жижиг систем хөгжүүлэх юм.

Polyglot Microservices – Энэ зүгээр л microservices. Харин, бүх систем чинь адилхан хэл дээр хөгжүүлэлт хийгдсэн байх албагүй, системийн онцлогоос хамааран өөр өөр хэл дээр хөгжүүлэгдсэн байхыг ингэж нэрлэнэ.

Microservices-ын талаар бага зэрэг ойлголттой болсон байх. Хэрвээ жижиг систем хөгжүүлж байгаа бол, зүгээр monolithic-ээр явсан нь дээр байх. Нэг нийтлэл уншиж байхад, “систем хөгжүүлэлтийн сүүлийн шат нь microservices юм” гэсэн байна лээ. Тэгэхээр, системийн чинь хэрэглэгчийн тоо нь ихсээд, scaling шаардлагатай болж ирэх үед, нэгэн төрлийн сонголт болгон харахад гэмгүй болов уу.

Одоо microservices давуу талуудын талаар ярилцъя.

Хялбар код менежмент болон хөгжүүлэлт
Monolithic системийн хувьд, ямар нэгэн шинэ зүйл нэмэх болгонд кодын чинь хэмжээ ихсэнэ. Бүхэл нэг код тул, аль нэг газар алдаа гаргахад л бусад газарт нөлөөлөх болно. Мөн, хөгжүүлэгч бүр тэр код руу хандаж байгаа тул, явцын дунд, хэн нь аль хэсгийг хариуцаж байгаа нь харагдахаа больж эхлэнэ. Харин microservices-ын хувьд, систем тус бүр тус тусдаа кодтой байх тул, кодын хэмжээ замбараагүй өсөж хяналтаас гарахаас сэргийлж чадах юм. Мөн систем бүрийг тусгай багуудад хариуцуулснаар, тэр систем нь өөрийн гэсэн эзэнтэй болж, байнга арчилж, сайжруулахад амар болно. Мөн дараагийн хувилбарыг тэс өөрөөр хийхээр шийдсэн бол, зөвхөн тэр системээ л дахин бичихэд хангалттай. Харин monolithic системийн хувьд, аль хэдийн өөр зүйлүүдтэй хэт уялдаа хамааралтай болчихсон байх тул, өөрчлөлт хийхэд хэцүү байх болно.

Availability
Монгол хэл рүү юу гэж орчуулахаа мэдсэнгүй. Ер нь бол, систем чинь унахгүй, зогсолтгүй ажиллах чадвар л юм уу даа. Monolithic системийн хувьд, нэг газар л алдаа гарахад систем чинь тэр чигээрээ унах магадлалтай. Жишээ нь асар том PHP дээр бичигдсэн систем байлаа гэхэд, нэг semicolon мартахад л систем чинь тэр чигээрээ зогсоно.
Харин microservices-ын хувьд, ямар систем унаснаас хамаарч систем-ын зарим хэсгүүд ажиллах боломжтой юм.

Уян хатан scaling
Одоо бараг ихэнх газрууд auto-scaling хийдэг болсон байх. Серверийн ачааллаас хамаараад, шинэ instance үүсгэх эсвэл устгадаг. Microservices-ын хувьд систем тус бүр дээр scaling хийх боломжтой юм.

Гэх мэт олон давуу талтай юм. Өөр давуу талууд бас байгаа, тэгэхдээ яг одоо санаанд орж ирэхгүй байна.

Жишээ болгож миний блогоо бичиж байгаа WordPress-ыг monolithic болон microservices байдлаар дүрслэх гэж оролдъё.
Monolithic WordPress
Microservices WordPress (2)

Харж байгаачлан, microservices загвар нь жижиг систем болон, цөөн хүнтэй компанид тохиромжгүй байж мэдэх юм. Харин дээр дурьдсанчлан, хэрвээ хэрэгчлэгчийн тоо ихсээд scaling хийх шаардлагатай болсон үед хэрэгтэй загвар юм.
Миний мэдэхээр ямар ч байсан, Amazon, Netflix, LinkedIn гэх мэт бараг бүх их хэрэглэгчтэй компаниуд microservices загварыг ашигладаг. Миний хувьд, өөрөө ийм архитектур гаргаж байгаагүй ч, одоо ажиллаж байгаа прожект дээр, ирээдүйд ийм загвар луу шилжих талаар ярилцаж байгаа болохоор судалж байгаа юм.

За дараагийн бичлэгээр уулзах хүртэй баяртай!