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!