August 2015

DynamoDB-ын талаар, зах зухаас

AWS(Amazon Web Services) гэж мэдээж сонссон байх. Тэрний нэг үйлчилгээ нь DynamDB юм. NoSQL төрлийн database. Яагаад энэ талаар ярих болсон бэ гэхээр, миний ажиллаж байгаа тоглоом, infrastructure-аа аль болох AWS-руу шилжүүлэхээр ажиллаж байгаа юм. Яагаад гэхээр, өөрсдөө зөвхөн тоглоом хөгжүүлэх тал дээрээ төвлөрч ажиллаад, сервер талын асуудлуудаа автоматжуулах үүднээс. Мэдээж AWS ашигласанаар зардал гарах ч, dev ops-уудыг ажлуулах зардал болон, өөрсдөө бас хариуцаж байгаа серверүүдийн зардал багасах юм. Тэгэхдээ хамгийн гол зорилго нь найдвартай, high scaling болгох явдал юм.

DynamoDB
NoSQL database гэж дурьдсан. Маш энгийнээр хэлбэл, advanced KVS(Key/Value Store) юм.
Давуу талууд гэвэл
– Ямар ч их хэмжээний өгөгдөл байсан хамаагүй, auto-scaling.
– 10ms-ын дотор өгөгдлийг чинь буцаана. (Scan болон Query ашиглаагүй тохиолдолд)
– Document-тэй ажиллана. Өөрөөр хэлбэл MongoDB шиг JSON өгөгдлийг хадгалаад, тэрнийхээ нэг хэсгийг дуудах, эсвэл нэг хэсгийг өөрчлөх гэсэн үйлдлүүдийг хийх боломжтой.
– Ямар ч их хүсэлт ирсэн хүлээж авах боломжтой. Хүснэгтэндээ read/write throughput тохируулж өгнө. Мэдээж их тохируулах тусам ихийг төлнө. Тэгэхээр илүү уян хатан болж байгаа юм. Хэрвээ site руу чинь секунданд 10 хэрэглэгч ханддаг бол, throughput-ээ багаар тохируулаад, хэрвээ 10,000 хэрэглэгч ханддаг бол, 1000 дахин ихэсгэхэд л хангалттай.

Сул талууд
– MySQL гэх мэт RDBMS-үүд ACID(Atomicity, Consistency, Isolation, and Durability) гэсэн зүйлийг танд амлаж чаддаг. Харин DynamDB-ын хувьд зөвхөн CD(Consistency and Durability) амлаж чадна.
– DynamoDB-ын consistency нь тэгэхдээ eventually consistency юм. Тэр нь юу гэсэн үг вэ гэвэл, нэг өгөгдлийг database-рүү бичих үед, тэр өгөгдөл чинь яг тэр дороо database-д бичигдсэн гэсэн баталгаа байхгүй. Тэгэхдээ хэзээ нэгэн цагт бичигдэнэ гэсэн үг. Тэр нь тэгэхдээ сайндаа л хэдэн ms болохоор, санаа зовох зүйлгүй ч, тэрийг бодолцож системээ хөгжүүлэх хэрэгтэй. Бас eventually consistency ч гэсэн, өгөгдөл унших үед, consistent унших боломжтой, тэр нь inconsistent уншсанаас 2 дахин үнэтэй тул, аль болох шаардлагатай үед л consistent read-ыг ашиглавал зүгээр юм.
– Atomicity болон isolation байхгүй тул, transaction бичих боломжгүй. Системээ, transaction байхгүйгээр зохион байгуулах, эсвэл тэрийг орлох зүйл бодож олох хэрэгтэй.

DynamoDB-рүү хөрвүүлэх гэж байгаа тоглоом
Тоглоомын хувьд гар утасны тоглоом бөгөөд, тоглогч ихсэх тусам, шинээр нэг ертөнц(world) үүсгэн, тэрэн дээрээ шинэ тоглогчидоо хүлээж авдаг юм. Өөрөөр хэлбэл horizontal scaling.
Ертөнц бүр өөрийн world server(GoLang дээр бичигдсэн), тэрний failover, мөн хэд хэдэн ертөнцүүд дундаа 2-3 MySQL server-тэй.
Тэгэхээр 50 ертөнц байлаа гэхэд 50(master world server) + 50(standby world server) + 10(master MySQL server) + 10(standby MySQL server) = 120 орчим server юмуудаа. Эдгээрийг цөөхөн хүнтэй баг өөрсдөө арчлана гэдэг жаахан ядаргаатай юм. Энэ тоо нь зөвхөн нэг тоглоомны server-ын тоо бөгөөд, компаний хэмжээнд яривал 10,000-аад server юм. Өдөр болгон аль нэг серверийн hard disk шатна, ямар нэгэн юм болохоо болино. Тэгэхээр миний хувьд, үнэхээр л том компани биш бол, өөрсдөө арчлах гэж байхаар AWS-ыг ашиглавал их зүгээр санагдсан.
Энэ тоглоомын хувьд болохоор, MySQL server-тэй ерөөсөө харьцдаггүй, зөвхөн world server-тэйгээ харьцдаг. World server нь in-memory болохоор, асар хурдан хариу өгдөг. Бараг хүссэн өгөгдөл чинь 1ms-ээс бага хугацаанд ирнэ. Харин world server нь тогтмол давталттай, өөр дээрх өөрчлөлтөө, MySQL рүү бичнэ. In-memory тул ямар нэгэн асуудал гарвал, бүх өгөгдлөө алдах тул, MySQL-руу бичиж байгаа юм.
Аз болж, тоглоомын бүх код, world server-тэйгээ харьцахдаа, зөвхөн нэг гарцаар дамждаг байсан юм.
Тэгэхээр миний хувьд, тэр гарцийг world server-тэй биш DynamoDB-тэй харьцдаг болгож өөрчлөхөд л хангалттай.
Гарсан асуудлууд
– World server нь зөвхөн өгөгдөл хадгалахаас гадна, өөр дээрээ логик агуулдаг тул тэдгээр логикуудыг application layer-рүү зөөх
– DynamoDB-ын Query болон Scan нь 10ms-ээс бага хугацуунд ирнэ гэсэн баталгаа байхгүй тул бүх өгөгдлийг GetItem, болон BatchGetItem-аар авч болдог байхаар өгөгдлийн бүтцүүдээ өөрчлөх
– Consistent read гэж байгаа ч, зардал хэмнэх үүднээс ямар үед consistent read, ямар үед inconsistent read ашиглахыг шийдэх
– Манайх зарим хэсэг дээрээ, transaction(world server нь бас transaction-тай) ашигладаг тул тэдгээр хэсгийг DynamoDB дээр асуудалгүй ажилладаг болгох
Transaction-ын хувьд, яг одоогоор шийдээгүй байгаа бөгөөд, application layer дээр кодын логикийг өөрчлөх, эсвэл Redis ашиглан өөрчлөх гэж байгаа өгөгдлүүдээ lock хийж байгаад бичих гэсэн 2 санал дээр ярилцаж байгаа.
Бараг Redis л ашиглаж lock бичих аргаар л хийх байх.

Have a nice weekend!

Vagrant болон Docker-ын тухай хальт

Бараг бүх startup компаниуд энэ 2 tool-ыг ашигладаг байх. Startup гэлтгүй томууд нь ч бас ашигладаг байх л даа.
Ямар тохиолдолд ашиглавал зүгээр вэ гэдгийг хальт тайлбарлах гэж оролдъё.
Ямар нэгэн систем хөгжүүлээд дууссаныхаа дараа, бид нар серверрүүгээ кодоо deploy хийдэг. Тэр үед янз бүрийн л асуудалтай тулгарч байсан байлгүй.
Яагаад хөгжүүлж байхад асуудал гараагүй хэрнээ, яг production сервер рүүгээ deploy хийх үед асуудал гарав?
Яагаад гэвэл, хөгжүүлж байгаа орчин(development environment) чинь бүтээгдхүүн болж ажиллах орчин(production environment)-оос чинь өөр байгаа болохоор.
Ихэнх тохиолдолд, Vagrant болон Docker-ыг ашиглахгүйгээр, production-тай яг адилхан орчин үүсгэхэд хэцүү. Ихэнх сервер-үүд Linux based, харин хөгжүүлэгчид ихэвчлэн Mac OS X эсвэл Windows ашигладаг. Mac OS X-ын хувьд UNIX based болохоор, Windows-ыг бодвол арай дээр ч гэсэн, 100% ижилхэн орчин үүсгэхэд бас л хүндрэл гарна.
Ижилхэн орчин гэдгээр би, яг адилхан OS version, яг адилхан PHP version, яг адилхан Ruby version, яг адилхан MySQL version тэй байхыг илэрхийлж байгаа шүү.
MySQL-ын жижиг version-ын өөрчлөлт хүртэл, системээс чинь хамаараад, өөр ажиллах тохиолдол үүсч болно.

Vagrant
Веб хуудас: https://www.vagrantup.com/
Энэ tool нь VirtualBox ашиглан, virtual machine үүсгэн, тэрэн дээр өөрийн чинь хүссэн орчинг бүрдүүлдэг tool юм.
Ашиглахад их энгийн. Vagrantfile дотор, ямар virtual machine үүсгэмээр байгаа, ямар OS ашигламаар байгаа, OS-ээ initialize хийсний дараа юу юу суулгамаар байгаагаа бичиж өгөөд л болоо. Vagrantfile-аа үүсгэсэнийхээ дараа дараах 2 мөр коммандыг бичихэд л хангалттай.

vagrant up // Virtual Machine-ийг initialize хийх
vagrant ssh // SSH-ээр Virtual Machine-рүүгээ орох

Vagrant-ын веб хуудас руу нь ороод харвал, Vagrantfile хэрхэн үүсгэх талаар, их дэлгэрэнгүй тайлбарласан байгаа.
TIP: Synced Folders үүсгэхдээ NFS ашиглавал, мэдэгдэхүйцээр хурдан ажиллана.

Docker
Веб хуудас: https://www.docker.com/
Зорилгын хувьд бол Vagrant-тай бараг төстэй. Тэгэхдээ Docker нь олон Linux based VM үүсгэх үед kernel-ээ share хийдэг юм. Хэрвээ чи Linux ашигладаг бол, чиний ашиглаж байгаа Linux-ын kernel-ийг шинээр үүсгэх OS-ынхээ kernel-ын оронд ашиглана гэсэн үг. Mac OS X болон, Windows-ын хувьд kernel share хийх боломжгүй тул, эхлээд VirtualBox-оор Linux OS-тэй virtual machine үүсгээд, тэрэн дээрээ container үүсгээд явна. Kernel-ээ share хийж байгаа болохоор, Vagrant-ыг бодвол арай хөнгөхөн ажиллана. Тэгэхдээ Mac OS X болон Windows дээр ашиглах гэж байгаа бол, Vagrant-аас ямар ч ялгаагүй. Харин олон container үүсгэх гэж байгаа бол, Docker-нь хамаагүй илүү байх.

Эцэст нь
2-уулаа сурахад нээх хүнд зүйл биш болохоор, завтай үедээ 2-ууланг нь туршиж үзэж байгаад сурсан нь дээр. Манай компаний хувьд, Vagrant-уудаа Dockerize хийж байгаа. Тэгэхдээ “No Silver Bullet”. 2-ууланг нь сурч байгаад, хэрэгцээндээ тохируулж алийг нь ашиглахаа шийдвэл зүгээр.

Cocos 2d-x Demo

Энийг Cocos 2d-x сурч байхдаа хийсэн юм. 1 сарын турш, өдөр бүр 8-16 цаг ажилласан. Clash of Clans-ыг хальт хуулбарлаж хийх гэж оролдсон. Clash of Clans, 1 өдрийн 1,5 сая долларын орлоготой тоглоом гэж бараг бүгд мэдэж байгаа байх. Уг нь үнэхээр хичээвэл боломж бол байгаа л юм шиг санагдсан.