VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

VKontakte-ning yaratilish tarixi Vikipediyada, bu haqda Pavelning o'zi aytgan. Uni hamma allaqachon taniganga o'xshaydi. HighLoad++ Pavel-dagi saytning ichki qismlari, arxitekturasi va tuzilishi haqida 2010 yilda menga aytdi. O'shandan beri ko'plab serverlar sizib ketgan, shuning uchun biz ma'lumotni yangilaymiz: biz uni ajratamiz, ichki qismlarini chiqaramiz, tortamiz va VK qurilmasiga texnik nuqtai nazardan qaraymiz.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Aleksey Akulovich (AterCattus) VKontakte jamoasidagi backend ishlab chiqaruvchisi. Ushbu hisobotning transkripti platformaning ishlashi, infratuzilmasi, serverlari va ular o'rtasidagi o'zaro ta'sirga oid tez-tez beriladigan savollarga jamoaviy javobdir, lekin rivojlanish haqida emas, ya'ni temir haqida. Alohida-alohida, ma'lumotlar bazalari va VK o'rniga nima borligi, jurnallarni to'plash va butun loyihani umuman kuzatish haqida. Kesish ostidagi tafsilotlar.



To'rt yildan ortiq vaqt davomida men backend bilan bog'liq barcha turdagi vazifalar bilan shug'ullanaman.

  • Ommaviy axborot vositalarini yuklash, saqlash, qayta ishlash, tarqatish: video, jonli oqim, audio, fotosuratlar, hujjatlar.
  • Infratuzilma, platforma, ishlab chiquvchilar monitoringi, jurnallar, mintaqaviy keshlar, CDN, xususiy RPC protokoli.
  • Tashqi xizmatlar bilan integratsiya: push-bildirishnomalar, tashqi havolalarni tahlil qilish, RSS tasmasi.
  • Hamkasblarga turli savollar bilan yordam berish, ularning javoblari noma'lum kodga sho'ng'ishni talab qiladi.

Shu vaqt ichida men saytning ko'plab tarkibiy qismlarida qo'limga ega bo'ldim. Men bu tajribani baham ko'rmoqchiman.

Umumiy arxitektura

Har bir narsa, odatdagidek, so'rovlarni qabul qiladigan server yoki serverlar guruhidan boshlanadi.

Old server

Old server HTTPS, RTMP va WSS orqali so'rovlarni qabul qiladi.

HTTPS - bu saytning asosiy va mobil veb-versiyalari uchun so'rovlar: vk.com va m.vk.com va API-ning boshqa rasmiy va norasmiy mijozlari: mobil mijozlar, messenjerlar. Bizda ziyofat bor RTMP-alohida front serverlari bilan Jonli translyatsiyalar uchun trafik va WSS- Streaming API uchun ulanishlar.

Serverlarda HTTPS va WSS uchun bunga arziydi nginx. RTMP eshittirishlari uchun biz yaqinda o'z yechimimizga o'tdik kive, lekin u hisobot doirasidan tashqarida. Xatolarga chidamlilik uchun ushbu serverlar umumiy IP manzillarni reklama qiladi va serverlardan birida muammo yuzaga kelsa, foydalanuvchi so'rovlari yo'qolmasligi uchun guruhlarga bo'linadi. HTTPS va WSS uchun xuddi shu serverlar protsessor yukining bir qismini o'z zimmasiga olish uchun trafikni shifrlaydi.

Biz WSS va RTMP haqida boshqa gapirmaymiz, faqat odatda veb-loyiha bilan bog'liq bo'lgan standart HTTPS so'rovlari haqida.

Orqa tomon

Old tomonda odatda backend serverlari mavjud. Ular oldingi server mijozlardan oladigan so'rovlarni qayta ishlaydi.

bu kPHP serverlari, HTTP daemoni ishlayotgan, chunki HTTPS allaqachon shifrlangan. kPHP - bu ishlaydigan server prefork modellari: asosiy jarayonni, bir qator bolalar jarayonlarini boshlaydi, ularga tinglash rozetkalarini uzatadi va ular so'rovlarini qayta ishlaydi. Bunday holda, jarayonlar foydalanuvchining har bir so'rovi o'rtasida qayta boshlanmaydi, balki qayta ishga tushirish o'rniga ularning holatini dastlabki nol qiymat holatiga - so'rovdan keyin so'rovga qaytaradi.

Yuklarni taqsimlash

Bizning barcha orqa tomonlarimiz har qanday so'rovni qayta ishlay oladigan mashinalarning katta hovuzi emas. Biz ularni alohida guruhlarga ajratilgan: umumiy, mobil, api, video, sahnalashtirish ... Alohida guruhdagi mashinalardagi muammo boshqalarga ta'sir qilmaydi. Video bilan bog'liq muammolar bo'lsa, musiqa tinglayotgan foydalanuvchi muammolar haqida hatto bilmaydi. So'rovni qaysi backendga yuborish konfiguratsiyaga muvofiq old tomondan nginx tomonidan belgilanadi.

Metrik yig'ish va muvozanatni tiklash

Har bir guruhda qancha mashina bo'lishi kerakligini tushunish uchun biz QPS ga ishonmang. Backends har xil, ular turli so'rovlarga ega, har bir so'rov QPSni hisoblashning turli murakkabligiga ega. Shuning uchun biz biz butun serverda - protsessorda va perfda yuk tushunchasi bilan ishlaymiz.

Bizda minglab shunday serverlar mavjud. Har bir jismoniy server barcha yadrolarni qayta ishlash uchun kPHP guruhini ishga tushiradi (chunki kPHP bitta tishli).

Kontent serveri

CS yoki Content Server - bu saqlash. CS - bu fayllarni saqlaydigan, shuningdek yuklangan fayllarni va asosiy veb-brauzer tomonidan tayinlangan barcha turdagi fon sinxron vazifalarini qayta ishlaydigan server.

Bizda fayllarni saqlaydigan o'n minglab jismoniy serverlar mavjud. Foydalanuvchilar fayllarni yuklashni yaxshi ko'radilar va biz ularni saqlash va almashishni yaxshi ko'ramiz. Ushbu serverlarning ba'zilari maxsus pu/pp serverlari tomonidan yopilgan.

pu/pp

Agar siz VK-da tarmoq yorlig'ini ochgan bo'lsangiz, siz pu/pp ni ko'rdingiz.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Pu/pp nima? Agar biz bir serverni birin-ketin yopsak, faylni yopilgan serverga yuklash va yuklab olishning ikkita varianti mavjud: to'g'ridan-to'g'ri ichidan http://cs100500.userapi.com/path yoki oraliq server orqali - http://pu.vk.com/c100500/path.

Pu rasm yuklashning tarixiy nomi, pp esa foto proksi. Ya'ni, bitta server fotosuratlarni yuklash uchun, ikkinchisi esa yuklash uchun. Endi nafaqat fotosuratlar yuklangan, balki nom saqlanib qolgan.

Bu serverlar HTTPS seanslarini tugatishprotsessor yukini xotiradan olib tashlash uchun. Bundan tashqari, foydalanuvchi fayllari ushbu serverlarda qayta ishlanganligi sababli, ushbu mashinalarda saqlangan kamroq sezgir ma'lumotlar shunchalik yaxshi bo'ladi. Masalan, HTTPS shifrlash kalitlari.

Mashinalar bizning boshqa mashinalarimiz tomonidan yopilganligi sababli, biz ularga "oq" tashqi IP-larni bermasligimiz mumkin va "kulrang" bering. Shunday qilib, biz IP-pulni saqlab qoldik va mashinalarni tashqi kirishdan himoya qilishni kafolatladik - unga kirish uchun IP yo'q.

Umumiy IP-larga nisbatan chidamlilik. Xatolarga chidamlilik nuqtai nazaridan, sxema bir xil ishlaydi - bir nechta jismoniy serverlar umumiy jismoniy IP-ga ega va ularning oldidagi apparat so'rovni qaerga yuborishni tanlaydi. Boshqa variantlar haqida keyinroq gaplashaman.

Bahsli nuqta shundaki, bu holatda mijoz kamroq ulanishlarni saqlaydi. Agar bir nechta mashinalar uchun bir xil IP mavjud bo'lsa - bir xil xost bilan: pu.vk.com yoki pp.vk.com, mijoz brauzeri bitta xostga bir vaqtning o'zida so'rovlar soni bo'yicha cheklovga ega. Ammo hamma joyda mavjud bo'lgan HTTP/2 davrida, bu endi unchalik ahamiyatli emasligiga ishonaman.

Sxemaning aniq kamchiligi shundaki, u kerak barcha trafikni pompalang, boshqa server orqali saqlashga o'tadi. Biz mashinalar orqali trafikni pompalaganimiz sababli, xuddi shu sxemadan foydalanib, biz hali ham og'ir trafikni, masalan, videoni pompalay olmaymiz. Biz uni to'g'ridan-to'g'ri uzatamiz - video uchun alohida saqlash uchun alohida to'g'ridan-to'g'ri ulanish. Biz proksi-server orqali engilroq kontentni uzatamiz.

Yaqinda biz proksi-serverning takomillashtirilgan versiyasini oldik. Endi men sizga ular oddiylardan qanday farq qilishini va nima uchun bu kerakligini aytaman.

quyosh

2017-yil sentabr oyida avval Sun’ni sotib olgan Oracle, juda ko'p sonli Sun xodimlarini ishdan bo'shatdi. Aytishimiz mumkinki, ayni paytda kompaniya o'z faoliyatini to'xtatdi. Yangi tizim uchun nom tanlashda bizning ma'murlarimiz ushbu kompaniya xotirasiga hurmat bajo keltirishga qaror qilishdi va yangi tizimga Sun deb nom berishdi. Bizning oramizda biz uni shunchaki "quyoshlar" deb ataymiz.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

pp bir nechta muammolarga duch keldi. Har bir guruh uchun bitta IP - samarasiz kesh. Bir nechta jismoniy serverlar umumiy IP-manzilga ega va so'rov qaysi serverga borishini nazorat qilishning hech qanday usuli yo'q. Shuning uchun, agar bir xil fayl uchun turli foydalanuvchilar kelsa, u holda ushbu serverlarda kesh mavjud bo'lsa, fayl har bir server keshida tugaydi. Bu juda samarasiz sxema, ammo hech narsa qilish mumkin emas.

Natijada - biz tarkibni parchalay olmaymiz, chunki biz ushbu guruh uchun ma'lum bir serverni tanlay olmaymiz - ular umumiy IPga ega. Bundan tashqari, bizda ba'zi ichki sabablarga ko'ra hududlarda bunday serverlarni o'rnatish mumkin emas edi. Ular faqat Sankt-Peterburgda turishgan.

Quyosh bilan biz tanlov tizimini o'zgartirdik. Endi bizda bor anycast marshrutlash: dinamik marshrutlash, anycast, o'z-o'zini tekshirish demoni. Har bir server o'zining shaxsiy IP-ga ega, ammo umumiy quyi tarmoqqa ega. Hammasi shunday tuzilganki, agar bitta server ishlamay qolsa, trafik xuddi shu guruhning boshqa serverlariga avtomatik ravishda tarqaladi. Endi ma'lum bir serverni tanlash mumkin, ortiqcha keshlash yo'q, va ishonchlilik ta'sir ko'rsatmadi.

Og'irlikni qo'llab-quvvatlash. Endi biz kerak bo'lganda turli xil quvvatdagi mashinalarni o'rnatishimiz mumkin, shuningdek, vaqtinchalik muammolar yuzaga kelganda, ular "dam olish" va qaytadan ishlay boshlashlari uchun ulardagi yukni kamaytirish uchun ishlaydigan "quyoshlar" ning og'irliklarini o'zgartiring.

Kontent identifikatori bo'yicha taqsimlash. Sharding haqida kulgili narsa: biz odatda tarkibni turli foydalanuvchilar umumiy keshga ega bo'lishlari uchun bir xil "quyosh" orqali bitta faylga o'tishlari uchun parchalaymiz.

Biz yaqinda "Clover" ilovasini ishga tushirdik. Bu jonli efirdagi onlayn viktorina boʻlib, u yerda boshlovchi savollar beradi va foydalanuvchilar real vaqt rejimida javob berishadi, variantlarni tanlashadi. Ilovada foydalanuvchilar suhbatlasha oladigan chat mavjud. Bir vaqtning o'zida translyatsiyaga ulanishi mumkin 100 mingdan ortiq kishi. Ularning barchasi barcha ishtirokchilarga yuboriladigan xabarlarni yozadilar va xabar bilan birga avatar keladi. Agar bitta "quyosh"da bitta avatar uchun 100 ming kishi kelsa, u ba'zan bulut orqasida aylanib ketishi mumkin.

Xuddi shu faylga bo'lgan so'rovlarning portlashiga dosh berish uchun biz ma'lum turdagi kontent uchun fayllarni mintaqadagi barcha mavjud "quyoshlar" bo'ylab tarqatadigan ahmoqona sxemani yoqamiz.

Ichkaridan quyosh

Nginx-da teskari proksi-server, operativ xotirada yoki tezkor Optane/NVMe disklarida kesh. Misol: http://sun4-2.userapi.com/c100500/path — to'rtinchi mintaqada, ikkinchi server guruhida joylashgan "quyosh" ga havola. U jismoniy jihatdan 100500 serverida joylashgan yo'l faylini yopadi.

qoplama

Biz arxitektura sxemamizga yana bitta tugunni qo'shamiz - keshlash muhiti.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Quyida tartib diagrammasi keltirilgan mintaqaviy keshlar, ularning 20 ga yaqini bor. Bu keshlar va "quyoshlar" joylashgan joylar, ular o'zlari orqali trafikni keshlashlari mumkin.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Bu multimedia kontentini keshlash; bu yerda foydalanuvchi ma'lumotlari saqlanmaydi - faqat musiqa, video, fotosuratlar.

Foydalanuvchining hududini aniqlash uchun biz biz hududlarda e'lon qilingan BGP tarmoq prefikslarini yig'amiz. Qayta tiklash holatida, agar biz IP-ni prefikslar bo'yicha topa olmasak, geoip ma'lumotlar bazasini tahlil qilishimiz kerak. Biz hududni foydalanuvchining IP-si bo'yicha aniqlaymiz. Kodda biz foydalanuvchining bir yoki bir nechta mintaqalarini - u geografik jihatdan eng yaqin bo'lgan nuqtalarni ko'rib chiqishimiz mumkin.

U qanday ishlaydi?

Biz fayllarning mashhurligini mintaqalar bo'yicha hisoblaymiz. Foydalanuvchi joylashgan bir qator mintaqaviy kesh va fayl identifikatori mavjud - biz bu juftlikni olamiz va har bir yuklab olishda reytingni oshiramiz.

Shu bilan birga, jinlar - mintaqalardagi xizmatlar vaqti-vaqti bilan API-ga kelib: "Men falon keshman, menga mintaqamdagi eng mashhur fayllar ro'yxatini bering, ular hali menda yo'q. ” API reyting bo'yicha saralangan bir qancha fayllarni yetkazib beradi, demon ularni yuklab oladi, mintaqalarga olib boradi va fayllarni u yerdan yetkazib beradi. Bu pu/pp va Sunning keshlardan asosiy farqi: ular faylni o'zlari orqali, garchi bu fayl keshda bo'lmasa ham, darhol beradilar va kesh avval faylni o'ziga yuklaydi va keyin uni qaytarib berishni boshlaydi.

Bunday holda biz olamiz kontent foydalanuvchilarga yaqinroq va tarmoq yukini tarqatish. Misol uchun, faqat Moskva keshidan biz eng yuqori soatlarda 1 Tbit / s dan ortiq tarqatamiz.

Ammo muammolar bor - kesh-serverlar kauchuk emas. Juda mashhur kontent uchun ba'zida alohida server uchun tarmoq etarli emas. Bizning kesh-serverlarimiz 40-50 Gbit / s ni tashkil qiladi, ammo bunday kanalni butunlay yopib qo'yadigan kontent mavjud. Biz mintaqadagi mashhur fayllarning bir nechta nusxalarini saqlashni amalga oshirishga harakat qilmoqdamiz. Umid qilamanki, biz uni yil oxirigacha amalga oshiramiz.

Biz umumiy arxitekturani ko'rib chiqdik.

  • So'rovlarni qabul qiladigan oldingi serverlar.
  • So'rovlarni qayta ishlaydigan backends.
  • Ikki turdagi proksi-serverlar tomonidan yopilgan omborlar.
  • Mintaqaviy keshlar.

Ushbu diagrammada nima etishmayapti? Albatta, biz ma'lumotlarni saqlaydigan ma'lumotlar bazalari.

Ma'lumotlar bazalari yoki dvigatellar

Biz ularni ma'lumotlar bazalari emas, balki dvigatellar deb ataymiz - Dvigatellar, chunki bizda amalda umumiy qabul qilingan ma'noda ma'lumotlar bazalari mavjud emas.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Bu zarur chora. Bu 2008-2009 yillarda VK mashhurligi keskin o'sganida, loyiha to'liq MySQL va Memcache-da ishlagani va muammolar yuzaga kelganligi sababli sodir bo'ldi. MySQL fayllarni buzish va buzishni yaxshi ko'rardi, shundan so'ng u tiklanmaydi va Memcache asta-sekin ish faoliyatini yomonlashtirdi va uni qayta ishga tushirishga to'g'ri keldi.

Ma'lum bo'lishicha, tobora ommalashib borayotgan loyihada ma'lumotlarni buzadigan doimiy xotira va sekinlashtiruvchi kesh mavjud edi. Bunday sharoitda o'sib borayotgan loyihani ishlab chiqish qiyin. Loyiha o'zimizning velosipedlarimizga qaratilgan muhim narsalarni qayta yozishga qaror qilindi.

Yechim muvaffaqiyatli bo'ldi. Buni qilish imkoniyati, shuningdek, o'ta zarurat bor edi, chunki o'sha paytda masshtablashning boshqa usullari mavjud emas edi. Ma'lumotlar bazalari to'plami yo'q edi, NoSQL hali mavjud emas edi, faqat MySQL, Memcache, PostrgreSQL bor edi - va bu.

Universal operatsiya. Rivojlanishni bizning C dasturchilar jamoasi boshqargan va hamma narsa izchil amalga oshirilgan. Dvigateldan qat'i nazar, ularning barchasi diskga yozilgan taxminan bir xil fayl formatiga, bir xil ishga tushirish parametrlariga ega, signallarni bir xil tarzda qayta ishlagan va chekka vaziyatlarda va muammolarda taxminan bir xil harakat qilgan. Dvigatellarning o'sishi bilan ma'murlar uchun tizimni boshqarish qulay - parvarish qilinishi kerak bo'lgan hayvonot bog'i yo'q va ular har bir yangi uchinchi tomon ma'lumotlar bazasini qanday boshqarishni qayta o'rganishlari kerak, bu esa tez va samarali ishlashga imkon berdi. ularning sonini qulay tarzda oshirish.

Dvigatellar turlari

Jamoa juda ko'p dvigatellarni yozgan. Mana ulardan ba'zilari: do'st, maslahatlar, rasm, ipdb, harflar, ro'yxatlar, jurnallar, memcached, meowdb, yangiliklar, nostradamus, foto, pleylistlar, pmemcached, sandbox, qidiruv, saqlash, yoqtirishlar, vazifalar, ...

Muayyan ma'lumotlar strukturasini talab qiladigan yoki atipik so'rovlarni qayta ishlaydigan har bir vazifa uchun C jamoasi yangi dvigatelni yozadi. Nega yo'q.

Bizda alohida dvigatel bor yodlangan, bu oddiy biriga o'xshash, lekin juda ko'p shirinliklar bilan va sekinlashmaydi. ClickHouse emas, lekin u ham ishlaydi. Alohida mavjud pmemcached Ismi? doimiy memkeshlangan, shuningdek, ma'lumotlarni diskda saqlashi mumkin, bundan tashqari, qayta ishga tushirishda ma'lumotlarni yo'qotmaslik uchun operativ xotiraga sig'maydi. Shaxsiy vazifalar uchun turli xil dvigatellar mavjud: navbatlar, ro'yxatlar, to'plamlar - bizning loyihamiz talab qiladigan hamma narsa.

Klasterlar

Kod nuqtai nazaridan, dvigatellar yoki ma'lumotlar bazalarini jarayonlar, ob'ektlar yoki misollar deb o'ylashning hojati yo'q. Kod maxsus klasterlar, dvigatellar guruhlari bilan ishlaydi - har bir klaster uchun bitta tur. Aytaylik, memkeshli klaster mavjud - bu shunchaki mashinalar guruhi.

Kod serverlarning jismoniy joylashuvi, hajmi yoki sonini bilishi shart emas. U ma'lum bir identifikator yordamida klasterga boradi.

Buning ishlashi uchun kod va dvigatellar o'rtasida joylashgan yana bitta ob'ektni qo'shishingiz kerak - proksi.

RPC proksi-server

Proksi bog'lovchi avtobus, unda deyarli butun sayt ishlaydi. Ayni paytda bizda ham bor hech qanday xizmat topilmadi — buning oʻrniga, ushbu proksi-server uchun barcha klasterlar va ushbu klasterning barcha parchalari joylashuvini biladigan konfiguratsiya mavjud. Buni adminlar qiladi.

Dasturchilar bu qancha, qayerda va qancha turadiganiga umuman ahamiyat bermaydilar - ular shunchaki klasterga boradilar. Bu bizga ko'p narsa beradi. So'rovni qabul qilganda, proksi-server so'rovni qayerga yo'naltiradi - buni o'zi belgilaydi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Bunday holda, proksi-server xizmat ko'rsatishning buzilishidan himoya nuqtasidir. Agar ba'zi dvigatel sekinlashsa yoki ishdan chiqsa, proksi-server buni tushunadi va mijoz tomoniga mos ravishda javob beradi. Bu sizga vaqt tugashini olib tashlash imkonini beradi - kod dvigatelning javob berishini kutmaydi, lekin u ishlamayotganini va qandaydir tarzda boshqacha yo'l tutish kerakligini tushunadi. Kod ma'lumotlar bazalari har doim ham ishlamasligi uchun tayyorlanishi kerak.

Maxsus ilovalar

Ba'zan biz hali ham dvigatel sifatida qandaydir nostandart yechimga ega bo'lishni xohlaymiz. Shu bilan birga, bizning dvigatellarimiz uchun maxsus yaratilgan tayyor rpc-proksi-serverimizdan foydalanmaslikka, balki vazifa uchun alohida proksi-server yaratishga qaror qilindi.

Hali ham u erda va u erda mavjud bo'lgan MySQL uchun biz db-proxy-dan foydalanamiz va ClickHouse uchun - Mushukcha uyi.

Bu odatda shunday ishlaydi. Ma'lum bir server mavjud, u kPHP, Go, Python ishlaydi - umuman olganda, bizning RPC protokolimizdan foydalanishi mumkin bo'lgan har qanday kod. Kod mahalliy RPC proksi-serverida ishlaydi - kod joylashgan har bir server o'zining mahalliy proksi-serverini boshqaradi. So'rov bo'yicha proksi qaerga borishni tushunadi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Agar bir dvigatel boshqasiga o'tishni xohlasa, hatto qo'shni bo'lsa ham, u proksi-server orqali o'tadi, chunki qo'shni boshqa ma'lumotlar markazida bo'lishi mumkin. Dvigatel o'zidan boshqa narsaning joylashishini bilishga tayanmasligi kerak - bu bizning standart echimimiz. Lekin, albatta, istisnolar mavjud :)

Barcha dvigatellar ishlaydigan TL sxemasiga misol.

memcache.not_found                                = memcache.Value;
memcache.strvalue	value:string flags:int = memcache.Value;
memcache.addOrIncr key:string flags:int delay:int value:long = memcache.Value;

tasks.task
    fields_mask:#
    flags:int
    tag:%(Vector int)
    data:string
    id:fields_mask.0?long
    retries:fields_mask.1?int
    scheduled_time:fields_mask.2?int
    deadline:fields_mask.3?int
    = tasks.Task;
 
tasks.addTask type_name:string queue_id:%(Vector int) task:%tasks.Task = Long;

Bu ikkilik protokol bo'lib, uning eng yaqin analogi protobuf. Sxema ixtiyoriy maydonlarni, murakkab turlarni - o'rnatilgan skalerlarning kengaytmalarini va so'rovlarni oldindan tavsiflaydi. Hamma narsa ushbu protokolga muvofiq ishlaydi.

TCP/UDP orqali TL orqali RPC… UDP?

Bizda TL sxemasi ustida ishlaydigan vosita so'rovlarini bajarish uchun RPC protokoli mavjud. Bularning barchasi TCP/UDP ulanishi orqali ishlaydi. TCP tushunarli, lekin nima uchun bizga tez-tez UDP kerak?

UDP yordam beradi serverlar o'rtasidagi juda ko'p ulanishlar muammosidan qochish. Agar har bir serverda RPC proksi-server mavjud bo'lsa va umuman olganda, u har qanday dvigatelga o'tishi mumkin bo'lsa, unda har bir serverda o'n minglab TCP ulanishlari mavjud. Yuk bor, lekin foydasiz. UDP holatida bu muammo mavjud emas.

Ortiqcha TCP qoʻl siqish yoʻq. Bu odatiy muammo: yangi dvigatel yoki yangi server ishga tushirilganda bir vaqtning o'zida ko'plab TCP ulanishlari o'rnatiladi. Kichik engil so'rovlar uchun, masalan, UDP foydali yuki, kod va vosita o'rtasidagi barcha aloqa Ikki UDP paketi: biri bir tomonga, ikkinchisi boshqa tomonga uchadi. Bitta safar - va kod dvigateldan qo'l siqishsiz javob oldi.

Ha, hammasi ishlaydi paketlarni yo'qotishning juda kichik foizi bilan. Protokolda retranslyatsiyalar va taym-autlarni qo'llab-quvvatlaydi, lekin agar biz ko'p narsani yo'qotsak, biz deyarli TCP ni olamiz, bu foydali emas. Biz UDPni okeanlar bo'ylab haydamaymiz.

Bizda minglab bunday serverlar mavjud va sxemasi bir xil: har bir jismoniy serverga dvigatellar to'plami o'rnatilgan. Ular, asosan, bloklanmasdan imkon qadar tezroq ishlash uchun bir torli bo'lib, bitta ipli echimlar sifatida ajratiladi. Shu bilan birga, bizda ushbu dvigatellardan ishonchliroq narsa yo'q va ma'lumotlarni doimiy saqlashga katta e'tibor beriladi.

Doimiy ma'lumotlarni saqlash

Dvigatellar binloglarni yozadilar. Binlog - bu fayl bo'lib, uning oxirida holat yoki ma'lumotlar o'zgarishi uchun hodisa qo'shiladi. Turli xil echimlarda u boshqacha nomlanadi: ikkilik jurnal, DEVOR, AOF, lekin printsip bir xil.

Dvigatelni qayta ishga tushirishda ko'p yillar davomida butun binlogni qayta o'qishni oldini olish uchun dvigatellar yozadilar oniy tasvirlar - joriy holat. Agar kerak bo'lsa, avval undan o'qiydilar, keyin esa binlogdan o'qishni tugatadilar. Barcha binloglar bir xil ikkilik formatda - TL sxemasiga muvofiq yoziladi, shuning uchun administratorlar ularni o'z vositalaridan foydalangan holda teng ravishda boshqarishi mumkin. Snapshotlarga bunday ehtiyoj yo'q. Umumiy sarlavha mavjud bo'lib, u kimning surati int ekanligini, dvigatelning sehrini va qaysi tanasi hech kim uchun muhim emasligini ko'rsatadi. Bu suratni yozib olgan dvigatelda muammo.

Men tezda ishlash tamoyilini tasvirlab beraman. Dvigatel ishlaydigan server mavjud. U yozish uchun yangi bo'sh binlogni ochadi va uni o'zgartirish uchun voqea yozadi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Bir nuqtada u o'zi suratga olishga qaror qiladi yoki signal oladi. Server yangi fayl yaratadi, unga butun holatini yozadi, fayl oxiriga joriy binlog hajmini - ofsetni qo'shadi va yozishni davom ettiradi. Yangi binlog yaratilmagan.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Bir nuqtada, vosita qayta ishga tushirilganda, diskda ham binlog, ham oniy rasm bo'ladi. Dvigatel butun suratni o'qiydi va ma'lum bir nuqtada uning holatini oshiradi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Surat yaratilgan paytdagi joyni va binlog hajmini o'qiydi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Joriy holatni olish uchun binlogning oxirini o'qiydi va keyingi voqealarni yozishni davom ettiradi. Bu oddiy sxema, bizning barcha dvigatellarimiz unga muvofiq ishlaydi.

Ma'lumotlarni replikatsiya qilish

Natijada, ma'lumotlarning replikatsiyasi bizning bayonotga asoslangan — biz binlogga hech qanday sahifa o'zgarishlarini emas, balki yozamiz so'rovlarni o'zgartirish. Tarmoq orqali keladigan narsalarga juda o'xshash, faqat biroz o'zgartirilgan.

Xuddi shu sxema faqat replikatsiya uchun emas, balki qo'llaniladi zaxira nusxalarini yaratish uchun. Bizda dvigatel bor - binlogga yozuvchi yozuv ustasi. Administratorlar uni o'rnatgan har qanday boshqa joyda, bu binlog nusxalanadi va tamom - bizda zaxira nusxasi bor.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Agar kerak bo'lsa replika o'qishCPU o'qish yukini kamaytirish uchun o'qish mexanizmi oddiygina ishga tushiriladi, u binlogning oxirini o'qiydi va ushbu buyruqlarni mahalliy ravishda bajaradi.

Bu erda kechikish juda kichik va replika ustadan qanchalik orqada qolganligini aniqlash mumkin.

RPC proksi-serverida ma'lumotlarni taqsimlash

Sharding qanday ishlaydi? Proksi qaysi klaster parchasini yuborish kerakligini qanday tushunadi? Kodda aytilmagan: "15 ta shardga yuboring!" - yo'q, bu proksi tomonidan amalga oshiriladi.

Eng oddiy sxema - firstint — so‘rovdagi birinchi raqam.

get(photo100_500) => 100 % N.

Bu oddiy memkeshli matn protokoli uchun misol, lekin, albatta, so'rovlar murakkab va tuzilgan bo'lishi mumkin. Misol so'rovdagi birinchi raqamni va klaster o'lchamiga bo'linganda qolganini oladi.

Bu biz bitta ob'ektning ma'lumotlar joylashuviga ega bo'lishni xohlaganimizda foydalidir. Aytaylik, 100 foydalanuvchi yoki guruh identifikatori va biz bitta ob'ektning barcha ma'lumotlari murakkab so'rovlar uchun bitta bo'lakda bo'lishini xohlaymiz.

Agar so'rovlar klaster bo'ylab qanday tarqalishi bizni qiziqtirmasa, boshqa variant ham bor - butun parchani xeshlash.

hash(photo100_500) => 3539886280 % N

Shuningdek, biz xeshni, bo'linishning qolgan qismini va parcha raqamini olamiz.

Bu ikkala variant ham, agar biz klaster hajmini oshirganimizda, uni bo'lishimizga yoki bir necha marta oshirishga tayyor bo'lsak ishlaydi. Masalan, bizda 16 ta bo'lak bor edi, bizda yetarli emas, biz ko'proq narsani xohlaymiz - biz 32 ta to'xtamasdan turib olishimiz mumkin. Agar biz ko'paytmalarni emas, balki ko'paytirmoqchi bo'lsak, ishlamay qolishi mumkin, chunki biz hamma narsani yo'qotishlarsiz aniq taqsimlay olmaymiz. Bu variantlar foydali, lekin har doim ham emas.

Agar biz ixtiyoriy sonli serverlarni qo'shishimiz yoki olib tashlashimiz kerak bo'lsa, biz foydalanamiz Ring a la Ketama ustida izchil xeshlash. Ammo shu bilan birga, biz ma'lumotlarning lokalizatsiyasini butunlay yo'qotamiz; biz so'rovni klasterga birlashtirishimiz kerak, shunda har bir qism o'zining kichik javobini qaytaradi va keyin proksi-serverga javoblarni birlashtiradi.

Juda o'ziga xos so'rovlar mavjud. Bu shunday ko'rinadi: RPC proksi-server so'rovni qabul qiladi, qaysi klasterga o'tishni belgilaydi va parchani aniqlaydi. Keyin yoki yozish ustalari mavjud yoki agar klasterda replikatsiya qo'llab-quvvatlansa, u so'rov bo'yicha replikaga yuboriladi. Proksi bularning barchasini bajaradi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Jurnallar

Biz jurnallarni bir necha usulda yozamiz. Eng oddiy va tushunarlisi memcache-ga jurnallarni yozish.

ring-buffer: prefix.idx = line

Kalit prefiksi mavjud - jurnalning nomi, chiziq va bu jurnalning o'lchami - qatorlar soni. Biz tasodifiy sonni 0 dan minus 1 qatorlar soniga olamiz. Memcache-dagi kalit bu tasodifiy son bilan birlashtirilgan prefiksdir. Biz jurnal chizig'ini va joriy vaqtni qiymatga saqlaymiz.

Jurnallarni o'qish kerak bo'lganda, biz bajaramiz Multi Get vaqt bo'yicha tartiblangan barcha kalitlar va shu bilan real vaqtda ishlab chiqarish jurnalini oling. Sxema real vaqt rejimida ishlab chiqarishda biror narsani disk raskadrovka qilish kerak bo'lganda, hech narsani buzmasdan, to'xtatmasdan yoki boshqa mashinalarga harakatlanishga ruxsat bermasdan foydalaniladi, ammo bu jurnal uzoq davom etmaydi.

Jurnallarni ishonchli saqlash uchun bizda dvigatel mavjud jurnallar-dvigatel. Aynan shuning uchun u yaratilgan va juda ko'p klasterlarda keng qo'llaniladi. Men biladigan eng katta klaster 600 TB o'ralgan jurnallarni saqlaydi.

Dvigatel juda eski, allaqachon 6-7 yoshda bo'lgan klasterlar mavjud. Biz hal qilmoqchi bo'lgan muammolar mavjud, masalan, biz jurnallarni saqlash uchun ClickHouse-dan faol foydalanishni boshladik.

ClickHouse-da jurnallarni yig'ish

Ushbu diagramma bizning dvigatelimizga qanday kirib borishimizni ko'rsatadi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Mahalliy ravishda RPC orqali RPC-proksi-serverga o'tadigan kod mavjud va u dvigatelga qaerga borishni tushunadi. Agar biz ClickHouse-da jurnallar yozmoqchi bo'lsak, biz ushbu sxemaning ikkita qismini o'zgartirishimiz kerak:

  • ba'zi dvigatellarni ClickHouse bilan almashtiring;
  • ClickHouse-ga kira olmaydigan RPC proksi-serverini RPC orqali ba'zi bir yechim bilan almashtiring.

Dvigatel oddiy - biz uni server yoki ClickHouse bilan serverlar klasteri bilan almashtiramiz.

ClickHouse-ga borish uchun biz buni qildik KittenHouse. Agar biz to'g'ridan-to'g'ri KittenHouse-dan ClickHouse-ga borsak, u bardosh bera olmaydi. Hatto so'rovlarsiz ham, u juda ko'p sonli mashinalarning HTTP ulanishlaridan qo'shiladi. Sxema ishlashi uchun ClickHouse serverida mahalliy teskari proksi-server ko'tariladi, u ulanishlarning kerakli hajmlariga bardosh bera oladigan tarzda yozilgan. Bundan tashqari, u o'z ichidagi ma'lumotlarni nisbatan ishonchli tarzda buferlashi mumkin.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Ba'zan biz RPC sxemasini nostandart echimlarda, masalan, nginx-da amalga oshirishni xohlamaymiz. Shuning uchun, KittenHouse UDP orqali jurnallarni qabul qilish imkoniyatiga ega.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Agar jurnallarni jo'natuvchi va qabul qiluvchi bir xil mashinada ishlayotgan bo'lsa, mahalliy xost ichida UDP paketini yo'qotish ehtimoli juda past. Uchinchi tomon yechimida RPC ni amalga oshirish zarurati va ishonchlilik o'rtasidagi kelishuv sifatida biz shunchaki UDP yuborishdan foydalanamiz. Ushbu sxemaga keyinroq qaytamiz.

Monitoring

Bizda ikki turdagi jurnallar mavjud: ma'murlar o'z serverlarida to'plaganlar va dasturchilar tomonidan koddan yozilganlar. Ular ikki turdagi ko'rsatkichlarga mos keladi: tizim va mahsulot.

Tizim ko'rsatkichlari

U barcha serverlarimizda ishlaydi Netma'lumotlar, bu statistik ma'lumotlarni to'playdi va ularni yuboradi Grafit uglerod. Shuning uchun ClickHouse, masalan, Whisper emas, balki saqlash tizimi sifatida ishlatiladi. Agar kerak bo'lsa, to'g'ridan-to'g'ri ClickHouse'dan o'qishingiz yoki foydalanishingiz mumkin grafana ko'rsatkichlar, grafiklar va hisobotlar uchun. Ishlab chiquvchilar sifatida bizda Netdata va Grafana’dan foydalanish imkoniyati yetarli.

Mahsulot ko'rsatkichlari

Qulaylik uchun biz juda ko'p narsalarni yozdik. Masalan, Statistikaga Counts, UniqueCounts qiymatlarini yozishga imkon beradigan oddiy funktsiyalar to'plami mavjud bo'lib, ular boshqa joyga yuboriladi.

statlogsCountEvent   ( ‘stat_name’,            $key1, $key2, …)
statlogsUniqueCount ( ‘stat_name’, $uid,    $key1, $key2, …)
statlogsValuetEvent  ( ‘stat_name’, $value, $key1, $key2, …)

$stats = statlogsStatData($params)

Keyinchalik, biz saralash va guruhlash filtrlaridan foydalanishimiz va statistikadan xohlagan hamma narsani qilishimiz mumkin - grafiklarni yaratish, Watchdogs-ni sozlash.

Biz juda yozamiz ko'plab ko'rsatkichlar hodisalar soni kuniga 600 milliarddan 1 trilliongacha. Biroq, biz ularni saqlab qolmoqchimiz kamida bir necha yilko'rsatkichlardagi tendentsiyalarni tushunish. Bularning barchasini bir joyga jamlash biz haligacha hal qilmagan katta muammo. Men sizga so'nggi bir necha yil ichida qanday ishlayotganini aytib beraman.

Bizda ushbu ko'rsatkichlarni yozadigan funktsiyalar mavjud mahalliy memcache-gayozuvlar sonini kamaytirish uchun. Qisqa vaqt ichida bir marta mahalliy miqyosda ishga tushirildi statistika-daemon barcha yozuvlarni to'playdi. Keyinchalik, iblis o'lchovlarni ikkita server qatlamiga birlashtiradi jurnallar-kollektorlar, bu bizning mashinalarimiz to'plamining statistik ma'lumotlarini to'playdi, shunda ularning orqasidagi qatlam o'lmaydi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Agar kerak bo'lsa, biz to'g'ridan-to'g'ri jurnallar-kollektorlarga yozishimiz mumkin.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Ammo koddan to'g'ridan-to'g'ri kollektorlarga yozish, stas-daemomni chetlab o'tish, yomon kengaytiriladigan yechimdir, chunki u kollektorga yukni oshiradi. Yechim, agar biron sababga ko'ra biz mashinada memcache stats-demonini ko'tara olmasak, yoki u qulab tushsa va biz to'g'ridan-to'g'ri ketdik.

Keyinchalik, jurnallar kollektorlari statistikani birlashtiradi meowDB - bu bizning ma'lumotlar bazasi bo'lib, u ko'rsatkichlarni ham saqlashi mumkin.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Keyin biz koddan ikkilik "yaqin SQL" usulida tanlov qilishimiz mumkin.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Tajriba

2018 yilning yozida bizda ichki xakaton o‘tkazildi va diagrammaning qizil qismini ClickHouse-da o‘lchovlarni saqlay oladigan narsa bilan almashtirish g‘oyasi paydo bo‘ldi. Bizda ClickHouse-da jurnallar mavjud - nega buni sinab ko'rmaysiz?

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Bizda KittenHouse orqali jurnallar yozadigan sxema bor edi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Biz qaror qildik diagrammaga yana bir "*Uy" qo'shing, bu bizning kodimiz ularni UDP orqali yozganda, aniq ko'rsatkichlarni formatda oladi. Keyin bu *Uy ularni KittenHouse tushunadigan loglar kabi qo'shimchalarga aylantiradi. U ushbu jurnallarni o'qiy olishi kerak bo'lgan ClickHouse-ga mukammal tarzda etkazib berishi mumkin.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Memcache, stats-daemon va logs-collectors ma'lumotlar bazasi bilan sxema shu bilan almashtirildi.

VKontakte arxitekturasi va ishi bo'yicha tez-tez so'raladigan savollar

Memcache, stats-daemon va logs-collectors ma'lumotlar bazasi bilan sxema shu bilan almashtirildi.

  • Bu erda koddan jo'natish mavjud, u StatsHouse'da mahalliy ravishda yozilgan.
  • StatsHouse allaqachon SQL qo'shimchalariga aylantirilgan UDP ko'rsatkichlarini KittenHouse-ga to'plamlarda yozadi.
  • KittenHouse ularni ClickHouse-ga yuboradi.
  • Agar biz ularni o'qimoqchi bo'lsak, biz ularni StatsHouse-ni chetlab o'tamiz - to'g'ridan-to'g'ri ClickHouse-dan oddiy SQL-dan foydalangan holda.

Hali ham tajriba, lekin bizga qanday qilib chiqishi yoqadi. Agar biz sxema bilan bog'liq muammolarni tuzatsak, ehtimol biz unga to'liq o'tamiz. Shaxsan men shunday umid qilaman.

Sxema temirni saqlamaydi. Kamroq serverlar kerak, mahalliy statistika-demonlar va jurnallar-kollektorlar kerak emas, lekin ClickHouse joriy sxemadagidan kattaroq serverni talab qiladi. Kamroq serverlar kerak, lekin ular qimmatroq va kuchliroq bo'lishi kerak.

Joylashtirish

Birinchidan, keling, PHP tarqatilishini ko'rib chiqaylik. Biz rivojlanmoqdamiz borish: foydalanish GitLab и TeamCity joylashtirish uchun. Rivojlanish tarmoqlari asosiy filialga, masterdan sinov uchun ular sahnalashtirishga va sahnalashtirishdan ishlab chiqarishga birlashtiriladi.

Joylashtirishdan oldin joriy ishlab chiqarish filiali va avvalgisi olinadi va ulardagi farq fayllari ko'rib chiqiladi - o'zgarishlar: yaratilgan, o'chirilgan, o'zgartirilgan. Ushbu o'zgarish maxsus nusxa ko'chirish mexanizmining binlogida qayd etilgan bo'lib, u bizning butun server parkimizdagi o'zgarishlarni tezda takrorlay oladi. Bu erda ishlatiladigan narsa to'g'ridan-to'g'ri nusxa ko'chirish emas, balki g'iybatni takrorlash, bir server o'zgarishlarni eng yaqin qo'shnilariga yuborganda, o'z qo'shnilariga va hokazo. Bu sizga butun park bo'ylab kodni o'nlab va soniya birliklarida yangilash imkonini beradi. O'zgartirish mahalliy nusxaga yetganda, u ushbu yamoqlarni o'ziga qo'llaydi mahalliy fayl tizimi. Orqaga qaytarish ham xuddi shu sxema bo'yicha amalga oshiriladi.

Biz kPHP-ni ham ko'p ishlatamiz va u ham o'z rivojlanishiga ega borish yuqoridagi diagrammaga muvofiq. Shundan beri HTTP server ikkilik, keyin biz farqni ishlab chiqara olmaymiz - reliz ikkilik faylining og'irligi yuzlab MB ni tashkil qiladi. Shuning uchun, bu erda yana bir variant bor - versiya yozilgan binlog copyfast. Har bir qurish bilan u ko'payadi va orqaga qaytarish paytida u ham ortadi. Versiya serverlarga takrorlanadi. Mahalliy copyfastlar binlogga yangi versiya kirganini ko'rishadi va xuddi shu g'iybat replikatsiyasi bilan ular bizning asosiy serverimizni charchatmasdan, balki yukni tarmoq bo'ylab ehtiyotkorlik bilan tarqatish orqali ikkilik faylning so'nggi versiyasini o'zlari uchun olishadi. Keyingi nima oqlangan qayta ishga tushirish yangi versiya uchun.

Asosan ikkilik bo'lgan bizning dvigatellarimiz uchun sxema juda o'xshash:

  • git master filiali;
  • ikkilik ichida .deb;
  • versiya binlog copyfast-ga yozilgan;
  • serverlarga takrorlanadi;
  • server yangi .depni chiqaradi;
  • dpkg -i;
  • yangi versiyaga ajoyib qayta ishga tushirish.

Farqi shundaki, bizning ikkilik faylimiz arxivga qadoqlangan .deb, va ularni pompalaganda dpkg -i tizimga joylashtiriladi. Nima uchun kPHP ikkilik, dvigatellar esa dpkg sifatida joylashtirilgan? Bu shunday sodir bo'ldi. U ishlaydi - unga tegmang.

Foydali havolalar:

Aleksey Akulovich Dastur qo'mitasining bir qismi sifatida yordam beradiganlardan biri PHP Rossiya 17 may kuni PHP ishlab chiquvchilari uchun so'nggi vaqtlardagi eng yirik voqea bo'ladi. Qarang, bizda qanday ajoyib kompyuter bor, nima ma'ruzachilar (Ulardan ikkitasi PHP yadrosini ishlab chiqmoqda!) - PHP yozsangiz, o'tkazib yuborib bo'lmaydigan narsaga o'xshaydi.

Manba: www.habr.com

a Izoh qo'shish