Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Mail.ru группт бидэнд Tarantool байдаг - энэ нь Луа дахь програмын сервер бөгөөд мэдээллийн баазын үүрэг гүйцэтгэдэг (эсвэл эсрэгээр?). Энэ нь хурдан бөгөөд гайхалтай боловч нэг серверийн боломжууд хязгааргүй хэвээр байна. Босоо масштаблах нь эм биш тул Tarantool-д хэвтээ масштаблах хэрэгслүүд байдаг - vshard модуль [1]. Энэ нь танд хэд хэдэн сервер дээр өгөгдлийг хуваах боломжийг олгодог боловч үүнийг тохируулах, бизнесийн логикийг хавсаргахын тулд үүнтэй таарах хэрэгтэй.

Сайн мэдээ: бид хэд хэдэн том зургуудыг цуглуулсан (жишээ нь [2], [3]) мөн энэ асуудлын шийдлийг ихээхэн хялбаршуулах өөр нэг тогтолцоог бий болгосон.

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

Яг ямар асуудал байна вэ?

Бидэнд тарантул байна, бид vshard байна - чи өөр юу хүсэх вэ?

Нэгдүгээрт, энэ нь тав тухтай байдлын асуудал юм. Vshard тохиргоог Lua хүснэгтээр дамжуулан тохируулсан. Tarantool-ийн олон процессын тархсан систем зөв ажиллахын тулд тохиргоо нь хаа сайгүй ижил байх ёстой. Үүнийг гараар хийхийг хэн ч хүсэхгүй. Тиймээс бүх төрлийн скрипт, Ansible, байршуулах системийг ашигладаг.

Cartridge нь өөрөө vshard тохиргоог удирддаг бөгөөд үүнд үндэслэн үүнийг хийдэг өөрийн түгээсэн тохиргоо. Энэ нь үндсэндээ энгийн YAML файл бөгөөд хуулбар нь Tarantool-ийн тохиолдол бүрт хадгалагддаг. Хялбаршуулсан зүйл бол уг хүрээ нь өөрөө тохиргоогоо хянаж, хаа сайгүй ижил байхыг баталгаажуулдаг явдал юм.

Хоёрдугаарт, энэ нь дахин ая тухтай байдлын асуудал юм. Vshard тохиргоо нь бизнесийн логикийг хөгжүүлэхтэй ямар ч холбоогүй бөгөөд зөвхөн програмистыг ажлаас нь сатааруулдаг. Төслийн архитектурын талаар ярихдаа бид бие даасан бүрэлдэхүүн хэсгүүд, тэдгээрийн харилцан үйлчлэлийн талаар ихэвчлэн ярьдаг. Гурван дата төвд кластер гаргах талаар бодоход эрт байна.

Бид эдгээр асуудлыг дахин дахин шийдэж, зарим үед программыг бүтээх, хөгжүүлэх, турших, CI/CD, засвар үйлчилгээ хийх бүхий л амьдралынхаа туршид ажиллахыг хялбаршуулсан арга барилыг боловсруулж чадсан.

Cartridge нь Tarantool процесс бүрийн үүргийн тухай ойлголтыг танилцуулж байна. Roles гэдэг нь хөгжүүлэгчид код бичихэд анхаарлаа төвлөрүүлэх боломжийг олгодог ойлголт юм. Төсөлд байгаа бүх үүргийг нэг Tarantool жишээн дээр ажиллуулах боломжтой бөгөөд энэ нь тест хийхэд хангалттай байх болно.

Tarantool Cartridge-ийн гол онцлогууд:

  • автоматжуулсан кластер зохион байгуулалт;
  • шинэ үүрэг ашиглан програмын функцийг өргөжүүлэх;
  • хөгжүүлэх, байршуулах програмын загвар;
  • суурилуулсан автомат хуваалт;
  • Luatest тестийн хүрээтэй нэгтгэх;
  • WebUI болон API ашиглан кластерын удирдлага;
  • баглаа боодол, байршуулах хэрэгсэл.

Сайн уу!

Би уг хүрээг харуулахыг тэсэн ядан хүлээж байгаа тул архитектурын тухай түүхийг дараа нь үлдээж, энгийн зүйлээс эхлэх болно. Хэрэв бид Tarantool-ийг өөрөө суулгасан гэж үзвэл зөвхөн хийх л үлдлээ

$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATH

Эдгээр хоёр тушаал нь тушаалын мөрийн хэрэгслүүдийг суулгаж, загвараас анхны програмаа үүсгэх боломжийг танд олгоно.

$ cartridge create --name myapp

Мөн бидний олж авсан зүйл бол:

myapp/
├── .git/
├── .gitignore
├── app/roles/custom.lua
├── deps.sh
├── init.lua
├── myapp-scm-1.rockspec
├── test
│   ├── helper
│   │   ├── integration.lua
│   │   └── unit.lua
│   ├── helper.lua
│   ├── integration/api_test.lua
│   └── unit/sample_test.lua
└── tmp/

Энэ бол бэлэн болсон "Сайн уу, Дэлхий!" програм. Өмнө нь хамаарлыг (хүрээг оруулаад) суулгасны дараа шууд ажиллуулахыг хичээцгээе.

$ tarantoolctl rocks make
$ ./init.lua --http-port 8080

Тиймээс бид ирээдүйн sharded програмд ​​зориулж нэг зангилаа ажиллаж байна. Сонирхолтой энгийн хүн вэб интерфэйсийг нэн даруй нээж, хулганаар нэг зангилааны кластерыг тохируулж, үр дүнд нь таашаал авах боломжтой боловч баярлахад эрт байна. Одоогоор програм нь ямар ч ашигтай зүйл хийж чадахгүй байгаа тул дараа нь байршуулах талаар танд хэлэх болно, гэхдээ одоо код бичих цаг болжээ.

Хэрэглээний хөгжүүлэлт

Бид өдөрт нэг удаа өгөгдөл хүлээн авч, хадгалж, тайлан гаргах ёстой төслийг боловсруулж байна гэж төсөөлөөд үз дээ.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Бид диаграммыг зурж, дээр нь гарц, хадгалалт, хуваарь гэсэн гурван бүрэлдэхүүн хэсгийг байрлуулна. Бид цаашид архитектурын тал дээр ажиллаж байна. Бид vshard-г хадгалалт болгон ашигладаг тул схемд vshard-router болон vshard-storage-г нэмж оруулдаг. Гарц болон хуваарьлагчийн аль нь ч хадгалах санд шууд хандахгүй; чиглүүлэгч нь ийм л зориулалттай, үүний тулд бүтээгдсэн юм.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Бүрэлдэхүүн хэсгүүд нь хийсвэр харагдаж байгаа тул энэ диаграм нь төсөлд бидний барьж буй зүйлийг яг таг илэрхийлээгүй хэвээр байна. Энэ нь жинхэнэ Tarantool-д хэрхэн тусгагдахыг бид харах хэрэгтэй хэвээр байна - бүрэлдэхүүн хэсгүүдээ процессоор нь бүлэглэцгээе.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Vshard-router болон gateway-г тус тусад нь байлгах нь утгагүй юм. Хэрэв энэ нь чиглүүлэгчийн үүрэг хариуцлага юм бол бид яагаад дахин сүлжээгээр аялах хэрэгтэй байна вэ? Тэдгээрийг ижил процессын хүрээнд ажиллуулах ёстой. Өөрөөр хэлбэл, gateway болон vsard.router.cfg аль аль нь нэг процесст нээгдэж, тэдгээрийг дотооддоо харьцах боломжийг олгоно.

Загварын үе шатанд гурван бүрэлдэхүүн хэсэгтэй ажиллахад тохиромжтой байсан ч би хөгжүүлэгчийн хувьд код бичиж байхдаа Tarnatool-ийн гурван хувилбарыг ажиллуулах талаар бодохыг хүсэхгүй байна. Би тест хийж, гарцыг зөв бичсэн эсэхээ шалгах хэрэгтэй. Эсвэл би нэг онцлог шинжээ хамт ажиллагсаддаа үзүүлэхийг хүсч байна. Би яагаад гурван хувь байршуулах гэж төвөг удах ёстой гэж? Ингэж л дүрийн тухай ойлголт төрсөн. Дүр бол амьдралын мөчлөгийг Cartridge-ээр удирддаг ердийн luash модуль юм. Энэ жишээнд тэдгээрийн дөрөв нь байна - гарц, чиглүүлэгч, хадгалах сан, хуваарь. Өөр төсөлд илүү их байж магадгүй. Бүх үүргийг нэг процессоор ажиллуулж болох бөгөөд энэ нь хангалттай байх болно.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Үзүүлэлт эсвэл үйлдвэрлэлд байршуулах тухайд бид Tarantool процесс бүрийг техник хангамжийн чадвараас хамааран өөрийн гэсэн багц үүргийг хуваарилах болно.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Топологийн менежмент

Ямар үүрэг гүйцэтгэж байгаа тухай мэдээллийг хаа нэгтээ хадгалах ёстой. Энэ "хаа нэгтээ" нь дээр дурдсан тархсан тохиргоо юм. Үүний хамгийн чухал зүйл бол кластерын топологи юм. Tarantool-ийн 3 процессын 5 хуулбарлах бүлэг энд байна:

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Бид өгөгдлийг алдахыг хүсэхгүй байгаа тул ажиллаж байгаа процессуудын талаарх мэдээллийг анхааралтай авч үздэг. Cartridge нь хоёр үе шаттай коммент ашиглан тохиргоог хянадаг. Нэгэнт бид тохиргоог шинэчлэхийг хүсвэл эхлээд бүх тохиолдлууд бэлэн байгаа бөгөөд шинэ тохиргоог хүлээн авахад бэлэн эсэхийг шалгана. Үүний дараа хоёр дахь үе шатанд тохиргоог хийнэ. Тиймээс нэг хуулбарыг түр хугацаагаар ашиглах боломжгүй болсон ч муу зүйл тохиолдохгүй. Тохиргоо зүгээр л хэрэгжихгүй бөгөөд та алдааг урьдчилан харах болно.

Мөн топологийн хэсэгт хуулбарлах бүлэг бүрийн удирдагч гэх мэт чухал параметрийг зааж өгсөн болно. Ихэнхдээ энэ нь бичигдсэн хуулбар юм. Үлдсэн хэсэг нь ихэвчлэн зөвхөн унших боломжтой байдаг ч үл хамаарах зүйлүүд байж болно. Заримдаа зоригтой хөгжүүлэгчид зөрчилдөөнөөс айдаггүй бөгөөд хэд хэдэн хуулбарт өгөгдлийг зэрэгцүүлэн бичиж чаддаг боловч ямар ч байсан хоёр удаа хийх ёсгүй зарим үйлдлүүд байдаг. Үүний тулд удирдагчийн шинж тэмдэг байдаг.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Дүрүүдийн амьдрал

Ийм архитектурт хийсвэр үүрэг байхын тулд хүрээ нь тэдгээрийг ямар нэгэн байдлаар удирдах ёстой. Мэдээжийн хэрэг, хяналт нь Tarantool процессыг дахин эхлүүлэхгүйгээр явагддаг. Үүрэг удирдахын тулд 4 дахин дуудлага байна. Картриж нь тараагдсан тохиргоонд юу бичсэнээс хамаарч тэдгээрийг дуудаж, ингэснээр тохиргоог тодорхой үүрэгт хэрэглэнэ.

function init()
function validate_config()
function apply_config()
function stop()

Дүр бүр өөрийн гэсэн үүрэгтэй init. Энэ нь дүрийг идэвхжүүлсэн эсвэл Tarantool-г дахин эхлүүлэх үед нэг удаа дуудагдана. Тэнд жишээлбэл, box.space.create-г эхлүүлэх нь тохиромжтой, эсвэл төлөвлөгч нь тодорхой хугацааны интервалд ажиллах зарим арын утас ажиллуулж болно.

Нэг функц init хангалтгүй байж магадгүй. Картриж нь топологийг хадгалахад ашигладаг хуваарилагдсан тохиргооны давуу талыг ашиглах боломжийг олгодог. Бид ижил тохиргоонд шинэ хэсгийг зарлаж, түүнд бизнесийн тохиргооны фрагментийг хадгалах боломжтой. Миний жишээнд энэ нь өгөгдлийн схем эсвэл хуваарьлагчийн дүрд зориулсан хуваарийн тохиргоо байж болно.

Кластер дуудлага validate_config и apply_config тархсан тохиргоо өөрчлөгдөх бүрт. Тохиргоог хоёр үе шаттай гүйцэтгэх үед кластер нь үүрэг тус бүр нь энэхүү шинэ тохиргоог хүлээн авахад бэлэн байгаа эсэхийг шалгаж, шаардлагатай бол алдааны талаар хэрэглэгчдэд мэдээлдэг. Тохиргоо хэвийн байна гэдэгтэй хүн бүр санал нийлэх үед apply_config.

Мөн дүрүүд нь арга барилтай байдаг stop, энэ нь дүрийн гаралтыг цэвэрлэхэд шаардлагатай. Хэрэв бид энэ серверт хуваарьлагч хэрэггүй болсон гэж хэлбэл энэ нь эхлүүлсэн утаснуудыг зогсоож чадна init.

Дүрүүд бие биетэйгээ харьцаж болно. Бид Луа хэл дээр функцийн дуудлагыг бичиж дассан боловч өгөгдсөн процесс бидэнд шаардлагатай үүрэг гүйцэтгэхгүй байж магадгүй юм. Сүлжээгээр дамжуулан дуудлагыг хөнгөвчлөхийн тулд бид Tarantool-д суурилуулсан стандарт нетбокс дээр суурилсан rpc (алсын процедурын дуудлага) туслах модулийг ашигладаг. Жишээлбэл, таны гарц нэг өдөр хүлээхээс илүүтэйгээр хуваарь гаргагчаас ажлаа яг одоо хийхийг хүсч байвал энэ нь ашигтай байж болно.

Өөр нэг чухал зүйл бол алдааг тэсвэрлэх чадвар юм. Cartridge нь эрүүл мэндийг хянахын тулд SWIM протоколыг ашигладаг [4]. Товчхондоо, үйл явц нь UDP-ээр бие биетэйгээ "цуу яриа" солилцдог - үйл явц бүр хөршүүддээ хамгийн сүүлийн үеийн мэдээг хэлж, тэд хариу үйлдэл үзүүлдэг. Гэнэт хариулт ирэхгүй бол Тарантоол ямар нэг зүйл буруу байна гэж сэжиглэж, хэсэг хугацааны дараа үхлийг уншиж, энэ мэдээний эргэн тойронд байгаа бүх хүмүүст хэлж эхэлдэг.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Энэхүү протоколд үндэслэн Cartridge нь автоматаар бүтэлгүйтлийн боловсруулалтыг зохион байгуулдаг. Процесс бүр орчноо хянадаг бөгөөд хэрэв удирдагч гэнэт хариу үйлдэл үзүүлэхээ больсон тохиолдолд хуулбар нь түүний үүргийг хүлээн авах боломжтой бөгөөд Cartridge ажиллаж байгаа дүрүүдийг зохих ёсоор тохируулдаг.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Байн байн нааш цааш шилжих нь хуулбарлах явцад өгөгдлийн зөрчилд хүргэж болзошгүй тул та энд болгоомжтой байх хэрэгтэй. Мэдээжийн хэрэг, та санамсаргүй байдлаар автомат шилжүүлэлтийг идэвхжүүлэх ёсгүй. Бид юу болж байгааг тодорхой ойлгож, удирдагчийг сэргээж, титмийг түүнд буцааж өгсний дараа хуулбарлах нь тасрахгүй гэдэгт итгэлтэй байх ёстой.

Энэ бүхнээс харахад үүрэг нь микро үйлчилгээтэй төстэй юм шиг санагдаж магадгүй. Нэг ёсондоо тэдгээр нь зөвхөн Tarantool процессын доторх модулиуд юм. Гэхдээ бас хэд хэдэн үндсэн ялгаа бий. Нэгдүгээрт, төслийн бүх үүрэг нь нэг кодын үндсэн дээр амьдрах ёстой. Мөн бүх Tarantool процессуудыг ижил кодын баазаас эхлүүлэх ёстой бөгөөд ингэснээр бид төлөвлөгчийг эхлүүлэх гэж оролдох үед гэнэтийн зүйл гарахгүй, гэхдээ энэ нь ердөө байхгүй. Түүнчлэн, та кодын хувилбаруудын ялгааг зөвшөөрөх ёсгүй, учир нь ийм нөхцөлд системийн үйл ажиллагааг урьдчилан таамаглах, дибаг хийхэд маш хэцүү байдаг.

Докероос ялгаатай нь бид зүгээр л дүрд "зураг" авч, өөр машин руу аваачиж, тэнд ажиллуулж чадахгүй. Бидний үүрэг бол Docker контейнер шиг тусгаарлагдмал биш юм. Мөн бид нэг жишээн дээр хоёр ижил үүргийг гүйцэтгэх боломжгүй. Дүр байдаг эсвэл байхгүй; нэг ёсондоо энэ нь ганц бие юм. Гуравдугаарт, бүх хуулбарлах бүлэгт үүрэг нь ижил байх ёстой, эс тэгвээс энэ нь утгагүй байх болно - өгөгдөл нь ижил боловч тохиргоо нь өөр юм.

Байршуулах хэрэгслүүд

Би Cartridge нь програмуудыг байрлуулахад хэрхэн тусалдаг болохыг харуулахаа амласан. Бусдын амьдралыг хөнгөвчлөхийн тулд хүрээ нь RPM багцуудыг багцалдаг:

$ cartridge pack rpm myapp -- упакует для нас ./myapp-0.1.0-1.rpm
$ sudo yum install ./myapp-0.1.0-1.rpm

Суулгасан багц нь танд хэрэгтэй бараг бүх зүйлийг агуулдаг: програм болон суулгасан хамаарлууд. Tarantool нь RPM багцын хамаарлаар сервер дээр ирэх бөгөөд манай үйлчилгээг эхлүүлэхэд бэлэн байна. Энэ нь systemd-ээр хийгддэг боловч эхлээд та бага зэрэг тохиргоо бичих хэрэгтэй. Хамгийн багадаа процесс бүрийн URI-г зааж өгнө үү. Жишээлбэл, гурав нь хангалттай.

$ sudo tee /etc/tarantool/conf.d/demo.yml <<CONFIG
myapp.router: {"advertise_uri": "localhost:3301", "http_port": 8080}
myapp.storage_A: {"advertise_uri": "localhost:3302", "http_enabled": False}
myapp.storage_B: {"advertise_uri": "localhost:3303", "http_enabled": False}
CONFIG

Энд нэг сонирхолтой нюанс байна. Зөвхөн хоёртын протоколын портыг зааж өгөхийн оронд бид хостын нэрийг оруулаад процессын нийтийн хаягийг бүхэлд нь зааж өгдөг. Энэ нь кластерын зангилаанууд хоорондоо хэрхэн холбогдохыг мэдэхийн тулд зайлшгүй шаардлагатай. 0.0.0.0-г advertise_uri хаяг болгон ашиглах нь муу санаа бөгөөд энэ нь залгуур биш харин гадаад IP хаяг байх ёстой. Үүнгүйгээр юу ч ажиллахгүй тул Cartridge нь танд буруу advertise_uri бүхий зангилаа эхлүүлэхийг зөвшөөрөхгүй.

Одоо тохиргоо бэлэн болсон тул та процессуудыг эхлүүлж болно. Ердийн системийн нэгж нь нэгээс олон процессыг эхлүүлэхийг зөвшөөрдөггүй тул Cartridge дээрх програмуудыг суулгадаг. дараах байдлаар ажилладаг үүсгэсэн нэгжүүд:

$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_B

Тохиргоонд бид Cartridge вэб интерфэйсээр үйлчилдэг HTTP портыг зааж өгсөн - 8080. Түүн рүү очоод харцгаая:

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Процессууд ажиллаж байгаа ч тэдгээр нь хараахан тохируулагдаагүй байгааг бид харж байна. Хайрцаг нь хэн хэнтэй давтах ёстойг хараахан мэдэхгүй байгаа бөгөөд бие даан шийдвэр гаргаж чадахгүй байгаа тул бидний үйлдлийг хүлээж байна. Гэхдээ бидэнд тийм ч их сонголт байхгүй: шинэ кластерын амьдрал эхний зангилааны тохиргооноос эхэлдэг. Дараа нь бид бусдыг кластерт нэмж, үүрэг хуваарилах бөгөөд энэ үед байршуулалт амжилттай дууссан гэж үзэж болно.

Удаан хугацааны ажлын долоо хоногийн дараа дуртай ундаагаа аягалж, тайвширцгаая. Програмыг ашиглах боломжтой.

Tarantool Cartridge: Lua backend-ийг гурван мөрөнд хуваах

Үр дүн

Үр дүн нь юу вэ? Оролдоод, ашигла, санал хүсэлтээ үлдээ, Github дээр тасалбар үүсгэ.

лавлагаа

[1] Tarantool » 2.2 » Лавлагаа » Чулуулгийн лавлагаа » Модуль vshard

[2] Альфа-Банкны хөрөнгө оруулалтын бизнесийн гол цөмийг бид Tarantool-д суурилсан хэрхэн хэрэгжүүлсэн

[3] Шинэ үеийн тооцооны архитектур: Tarantool-д шилжих өөрчлөлт

[4] SWIM - кластер байгуулах протокол

[5] GitHub - tarantool/cartridge-cli

[6] GitHub - tarantool/cartridge

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх