VKontakte архитектурасы жана иши боюнча КБС

ВКонтактенин жаралуу тарыхы Википедияда, бул тууралуу Павел өзү айтып берген. Аны баары эле билет окшойт. HighLoad++ Pavelдагы сайттын ички түзүлүштөрү, архитектурасы жана түзүмү жөнүндө 2010-жылы мага айткан. Ошондон бери көптөгөн серверлер агып кетти, ошондуктан биз маалыматты жаңыртабыз: биз аны бөлүп алабыз, ичин алып чыгып, таразалап, VK аппаратын техникалык көз караштан карайбыз.

VKontakte архитектурасы жана иши боюнча КБС

Алексей Акулович (AterCattus) ВКонтакте командасында бэкенддин иштеп чыгуучусу. Бул отчеттун стенограммасы платформанын иштеши, инфраструктура, серверлер жана алардын ортосундагы өз ара аракеттенүү жөнүндө көп берилүүчү суроолорго жамааттык жооп болуп саналат, бирок өнүгүү жөнүндө эмес, тактап айтканда темир жөнүндө. Өзүнчө, маалымат базалары жана анын ордуна VK эмнеси бар, журналдарды чогултуу жана бүтүндөй долбоорду көзөмөлдөө жөнүндө. Кесилгендин астында майда-чүйдөсүнө чейин.



Төрт жылдан ашык убакыттан бери мен артка байланыштуу ар кандай тапшырмалар менен алектенип келем.

  • Жүктөө, сактоо, иштетүү, медианы жайылтуу: видео, түз агым, аудио, сүрөттөр, документтер.
  • Инфраструктура, платформа, иштеп чыгуучулардын мониторинги, журналдар, аймактык кэштер, CDN, проприетардык RPC протоколу.
  • Тышкы кызматтар менен интеграция: push эскертмелери, тышкы шилтемени талдоо, RSS каналы.
  • Кесиптештерге ар кандай суроолор менен жардам берүү, алардын жообу белгисиз кодго сүңгүүнү талап кылат.

Бул убакыттын ичинде, мен сайттын көптөгөн компоненттерине колум бар болчу. Мен бул тажрыйба менен бөлүшкүм келет.

Жалпы архитектура

Баары, адаттагыдай, суроо-талаптарды кабыл алган серверден же серверлердин тобунан башталат.

Алдыңкы сервер

Алдыңкы сервер HTTPS, RTMP жана WSS аркылуу суроо-талаптарды кабыл алат.

HTTPS - бул сайттын негизги жана мобилдик веб-версияларына суроо-талаптар: vk.com жана m.vk.com, жана биздин API'нин башка расмий жана расмий эмес кардарлары: мобилдик кардарлар, мессенджерлер. Бизде кабыл алуу бар RTMP- өзүнчө алдыңкы серверлер менен Түз берүүлөр үчүн трафик жана СКС- Streaming API үчүн байланыштар.

Серверлердеги HTTPS жана WSS үчүн бул баалуу жөргөмүш. RTMP берүүлөрү үчүн биз жакында өзүбүздүн чечимге өттүк киве, бирок ал отчеттун чегинен тышкары. Мүчүлүштүккө чыдамдуулук үчүн бул серверлер жалпы IP даректерди жарнамалайт жана серверлердин биринде көйгөй жаралса, колдонуучунун суроо-талаптары жоголуп кетпеши үчүн топторго бөлүнөт. HTTPS жана WSS үчүн ушул эле серверлер CPU жүктөмүнүн бир бөлүгүн өзүнө алуу үчүн трафикти шифрлейт.

Биз WSS жана RTMP жөнүндө мындан ары сүйлөшпөйбүз, бирок адатта веб-долбоор менен байланышкан стандарттуу HTTPS сурамдары жөнүндө гана сүйлөшөбүз.

Backend

Фронттун артында көбүнчө серверлер бар. Алар алдыңкы сервер кардарлардан алган суроо-талаптарын иштетет.

бул kPHP серверлери, HTTP демону иштеп жаткан, анткени HTTPS мурунтан эле шифрленген. kPHP – бул иштеген сервер префорк моделдери: башкы процессти, бир топ бала процесстерин баштайт, аларга угуу розеткаларын өткөрүп берет жана алар өздөрүнүн суроо-талаптарын иштеп чыгышат. Бул учурда, процесстер колдонуучунун ар бир суроо-талабынын ортосунда кайра башталбайт, жөн гана алардын абалын баштапкы нөлдүк абалга - кайра баштоонун ордуна суроо-талаптан кийин калыбына келтирет.

Жүк бөлүштүрүү

Биздин бардык резервдер ар кандай суроо-талапты иштете ала турган машиналардын чоң бассейни эмес. Биз аларды өзүнчө топторго бөлүнөт: жалпы, жылжымалы, api, бейне, сахналау... Машиналардын б!р топтагы проблемасы баскалардын бэр! Видео менен көйгөйлөр пайда болгон учурда, музыка уккан колдонуучу көйгөйлөр жөнүндө билбей да калат. Сурам жөнөтүү үчүн кайсы бэкэнд конфигурацияга ылайык алдыңкы жагындагы nginx тарабынан чечилет.

Метрикалык чогултуу жана кайра баланстоо

Ар бир топто канча унаа болушу керек экенин түшүнүү үчүн, биз QPSке таянбаңыз. Backends ар түрдүү, алардын ар кандай суроо-талаптары бар, ар бир суроо QPS эсептөө ар кандай татаалдыгы бар. Ошондуктан биз биз бүтүндөй серверге жүктөө түшүнүгү менен иштейбиз - CPU жана перф.

Бизде миңдеген мындай серверлер бар. Ар бир физикалык сервер бардык өзөктөрдү кайра иштетүү үчүн kPHP тобун иштетет (анткени kPHP бир жиптүү).

Мазмун сервери

CS же Content Server - бул сактагыч. CS - бул файлдарды сактаган сервер, ошондой эле жүктөлгөн файлдарды жана негизги веб фронтонду ага дайындаган ар кандай фондо синхрондуу тапшырмаларды иштетет.

Бизде файлдарды сактаган он миңдеген физикалык серверлер бар. Колдонуучулар файлдарды жүктөгөндү жакшы көрүшөт, биз болсо аларды сактап, бөлүшүүнү жакшы көрөбүз. Бул серверлердин айрымдары атайын pu/pp серверлери тарабынан жабылат.

pu/pp

Эгер сиз ВКда тармак өтмөгүн ачсаңыз, анда pu/pp дегенди көрдүңүз.

VKontakte архитектурасы жана иши боюнча КБС

pu/pp деген эмне? Эгерде биз серверди биринин артынан бирин жапсак, анда жабылган серверге файлды жүктөө жана жүктөө үчүн эки вариант бар: түздөн-түз через http://cs100500.userapi.com/path же аралык сервер аркылуу - http://pu.vk.com/c100500/path.

Pu - сүрөт жүктөөнүн тарыхый аталышы, ал эми pp - прокси сүрөт. Башкача айтканда, бир сервер сүрөттөрдү жүктөө үчүн, экинчиси жүктөө үчүн. Азыр сүрөттөр гана жүктөлбөстөн, аты сакталып калды.

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

Машиналар биздин башка машиналар менен жабылгандыктан, биз аларга "ак" тышкы IPдерди бербей коё алабыз жана "боз" бер. Ушундай жол менен биз IP бассейнде сактадык жана машиналарды сырттан кирүүдөн коргоого кепилдик бердик - ага кирүү үчүн IP жок.

Бөлүшүлгөн IP боюнча туруктуулук. Мүчүлүштүккө чыдамдуулук жагынан схема бирдей иштейт - бир нече физикалык серверлерде жалпы физикалык IP бар жана алардын алдындагы аппаратура суроо-талапты каякка жөнөтүүнү тандайт. Башка варианттар тууралуу кийинчерээк айтам.

Талаштуу жагдай бул учурда кардар азыраак байланыштарды сактайт. Эгерде бир нече машиналар үчүн бир эле IP бар болсо - бир эле хост менен: pu.vk.com же pp.vk.com, кардар браузеринде бир хостко бир убактагы суроо-талаптардын саны боюнча чектөө бар. Бирок HTTP/2 бардык жерде кездешкенде, бул мындан ары актуалдуу эмес деп эсептейм.

Схеманын айкын кемчилиги - бул керек бардык трафикти насостоо, башка сервер аркылуу сактагычка барат. Биз трафикти машиналар аркылуу айдагандыктан, ошол эле схеманы колдонуп, оор трафикти, мисалы, видеону азырынча айдай албайбыз. Биз аны түздөн-түз өткөрүп беребиз - атайын видео үчүн өзүнчө сактагычтар үчүн өзүнчө түз байланыш. Биз прокси аркылуу жеңилирээк мазмунду өткөрөбүз.

Жакында биз проксидин жакшыртылган версиясын алдык. Эми мен алар жөнөкөй адамдардан эмнеси менен айырмаланарын жана бул эмне үчүн зарыл экенин айтып берем.

күн

2017-жылдын сентябрында мурда Sun сатып алган Oracle, сан кызматкерлерин жумуштан бошотту. Бул учурда компания өз ишин токтотту деп айта алабыз. Жаңы системага ат тандоодо биздин администраторлор бул компаниянын элесине таазим кылууну чечишти жана жаңы системаны Күн деп атап коюшту. Арабызда аны жөн эле “күн” деп атайбыз.

VKontakte архитектурасы жана иши боюнча КБС

pp бир нече көйгөйлөргө дуушар болгон. Топко бир IP - натыйжасыз кэш. Бир нече физикалык серверлер жалпы IP даректи бөлүшөт жана сурам кайсы серверге бараарын көзөмөлдөөнүн эч кандай жолу жок. Ошондуктан, эгерде ар кандай колдонуучулар бир эле файл үчүн келсе, анда бул серверлерде кэш бар болсо, файл ар бир сервердин кэшинде аяктайт. Бул абдан натыйжасыз схема, бирок эч нерсе кыла алган жок.

Натыйжада - биз мазмунду бөлө албайбыз, анткени биз бул топ үчүн белгилүү бир серверди тандай албайбыз - алардын жалпы IP бар. Ошондой эле кээ бир ички себептерден улам бизде бар аймактарда мындай серверлерди орнотуу мүмкүн эмес болчу. Алар Санкт-Петербургда гана турушкан.

Күн менен биз тандоо системасын өзгөрттүк. Азыр бизде anycast багыттоо: динамикалык багыттоо, каалагандай чыгаруу, өзүн-өзү текшерүү демону. Ар бир сервердин өзүнүн жеке IP бар, бирок жалпы ички тармак. Бардыгы конфигурацияланган, эгер бир сервер иштебей калса, трафик ошол эле топтун башка серверлерине автоматтык түрдө тарайт. Эми белгилүү бир серверди тандоого болот, ашыкча кэш жок, жана ишенимдүүлүгүнө таасир эткен эмес.

Салмак колдоо. Эми биз ар кандай кубаттуулуктагы машиналарды зарылчылыкка жараша орнотууга, ошондой эле убактылуу көйгөйлөр болгон учурда, иштеп жаткан «күндөрдүн» салмагын өзгөртүп, аларга жүктөмдү азайтып, «эс алып», кайра иштей башташыбыз мүмкүн.

Мазмун ID боюнча бөлүшүү. Бөлүп алуу жөнүндө күлкүлүү нерсе: биз адатта мазмунду бөлөбүз, ар кандай колдонуучулар бир эле файлга бирдей "күн" аркылуу өтүшөт, алардын жалпы кэш бар.

Жакында “Беде” тиркемесин ишке киргиздик. Бул түз эфирдеги онлайн викторина, анда алып баруучу суроолорду берип, колдонуучулар реалдуу убакыт режиминде жооп берип, варианттарды тандап беришет. Колдонмодо колдонуучулар баарлаша ала турган чат бар. Бир эле учурда трансляцияга туташа алат 100 миңден ашык адам. Алардын баары бардык катышуучуларга жөнөтүлгөн билдирүүлөрдү жазышат жана аватар кабар менен бирге келет. Бир "күнгө" бир аватар үчүн 100 миң адам келсе, анда ал кээде булуттун артына айланып кетиши мүмкүн.

Бир эле файлга болгон суроо-талаптардын жарылуусуна туруштук берүү үчүн, мазмундун белгилүү бир түрү үчүн биз файлдарды аймактагы бардык жеткиликтүү "күнгө" тараткан акылсыз схеманы иштетебиз.

Күн ичинен

Nginxтеги тескери прокси, оперативдүү эс тутумда же тез Optane/NVMe дисктеринде кэш. Мисал: http://sun4-2.userapi.com/c100500/path — төртүнчү аймакта, экинчи сервер тобунда жайгашкан "күнгө" шилтеме. Ал физикалык жактан 100500 серверинде турган жол файлын жаап салат.

жабуу

Архитектуралык схемабызга дагы бир түйүн кошобуз - кэш чөйрөсү.

VKontakte архитектурасы жана иши боюнча КБС

Төмөндө жайгашуу диаграммасы болуп саналат аймактык кэштер, алардын 20га жакыны бар. Бул кэштер жана "күндөр" жайгашкан жерлер, алар трафикти өздөрү аркылуу кэштей алышат.

VKontakte архитектурасы жана иши боюнча КБС

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

Колдонуучунун аймагын аныктоо үчүн биз биз аймактарда жарыяланган BGP тармагынын префикстерин чогултабыз. Кайтарылып калган учурда, биз IPди префикстер боюнча таба албасак, геоип базасын анализдешибиз керек. Биз аймакты колдонуучунун IP менен аныктайбыз. Коддо колдонуучунун бир же бир нече аймактарын - географиялык жактан ал эң жакын болгон чекиттерди карай алабыз.

Бул кандай иштейт?

Биз файлдардын популярдуулугун аймактар ​​боюнча эсептейбиз. Колдонуучу жайгашкан бир катар аймактык кэш жана файл идентификатору бар - биз бул жупту алып, ар бир жүктөө менен рейтингди жогорулатабыз.

Ошол эле учурда, жин-перилер - аймактардагы кызматтар - мезгил-мезгили менен API'ге келип: "Мен баланча кэшмин, мага менин аймагымдагы эң популярдуу файлдардын тизмесин бергиле, алар менде жок. ” API рейтинг боюнча сорттолгон бир топ файлдарды жеткирет, демон аларды жүктөп алып, аймактарга алып барат жана файлдарды ошол жерден жеткирет. Бул pu/pp менен Sunдын кэштерден принципиалдуу айырмасы: алар файлды дароо өздөрү аркылуу беришет, ал тургай бул файл кэште болбосо да, кэш алгач файлды өзүнө жүктөйт, анан кайра бере баштайт.

Бул учурда биз алабыз колдонуучуларга жакыныраак мазмун жана тармактык жүктү жайылтуу. Мисалы, Москванын кэшинен гана биз жогорку ылдамдыкта 1 Тбит/с ашык таратабыз.

Бирок көйгөйлөр бар - кэш серверлери резина эмес. Супер популярдуу мазмун үчүн кээде өзүнчө сервер үчүн тармак жетишсиз. Биздин кэш серверлер 40-50 Гбит/с, бирок мындай каналды толугу менен жаап салган контент бар. Биз аймактагы популярдуу файлдардын бирден ашык көчүрмөсүн сактоону ишке ашырууну көздөп жатабыз. Жылдын аягына чейин ишке ашырабыз деп ишенем.

Биз жалпы архитектураны карап чыктык.

  • Сурамдарды кабыл алган алдыңкы серверлер.
  • Сурамдарды иштеп чыгуучу фон.
  • Проксилердин эки түрү менен жабылган сактагычтар.
  • Регионалдык кэштер.

Бул диаграммада эмне жетишпейт? Албетте, биз маалыматтарды сактаган маалымат базалары.

Маалымат базалары же кыймылдаткычтар

Биз аларды маалымат базасы эмес, кыймылдаткычтар деп атайбыз, анткени бизде жалпы кабыл алынган мааниде маалымат базалары жок.

VKontakte архитектурасы жана иши боюнча КБС

Бул зарыл чара болуп саналат. Бул 2008-2009-жылдары ВКнын популярдуулугу кескин өскөндө, долбоор толугу менен MySQL жана Memcache менен иштегендиктен жана көйгөйлөр болгон. MySQL файлдарды бузуп, бузуп салганды жакшы көрчү, андан кийин ал калыбына келбейт жана Memcache акырындык менен иштөөсүн начарлатып, кайра иштетүүгө туура келди.

Көрсө, барган сайын популярдуу болгон долбоордо маалыматтарды бузуп турган туруктуу сактагыч жана жайлатуучу кэш бар экен. Мындай шарттарда өсүп жаткан долбоорду иштеп чыгуу кыйын. Долбоор биздин велосипедибизге багытталган сындуу нерселерди кайра жазууга аракет кылууну чечтик.

Чечим ийгиликтүү болду. Муну ишке ашырууга мүмкүнчүлүк да, өтө зарылчылык да бар болчу, анткени ал кезде масштабдаштыруунун башка жолдору жок болчу. Бир топ маалымат базалары жок болчу, NoSQL али жок болчу, MySQL, Memcache, PostrgreSQL гана бар болчу - ушуну менен.

Универсалдуу операция. Иштеп чыгууну биздин C иштеп чыгуучулар командасы жетектеген жана бардыгы ырааттуу түрдө аткарылган. Кыймылдаткычка карабастан, алардын бардыгы дискке жазылган болжол менен бирдей файл форматына, бирдей ишке киргизүү параметрлерине, сигналдарды бир эле жол менен иштетип, четтеги кырдаалдарда жана көйгөйлөрдө болжол менен бирдей иш алып барышкан. Кыймылдаткычтардын өсүшү менен администраторлор үчүн системаны иштетүү ыңгайлуу болуп калды - аны күтүүнү талап кылган зоопарк жок жана алар үчүнчү тараптын ар бир жаңы маалымат базасын иштетүүнү кайра үйрөнүшү керек, бул тез жана тез иштөөгө мүмкүндүк берди. алардын санын ыңгайлуу көбөйтүү.

Моторлордун түрлөрү

Команда бир нече кыймылдаткычтарды жазган. Бул жерде алардын айрымдары гана: дос, кеңештер, сүрөт, ipdb, каттар, тизмелер, журналдар, memcached, meowdb, жаңылыктар, nostradamus, фото, ойнотмо тизмелер, pmemcached, құмсалгыч, издөө, сактоо, жактыруулар, тапшырмалар, ...

Белгилүү бир маалымат структурасын талап кылган же атипикалык суроо-талаптарды иштеткен ар бир тапшырма үчүн C командасы жаңы кыймылдаткычты жазат. Эмне үчүн жок.

Бизде өзүнчө мотор бар memcached, бул кадимкидей окшош, бирок бир топ жакшы нерселер менен жана жайлабаган. ClickHouse эмес, бирок ал да иштейт. Өзүнчө жеткиликтүү pmemcached - аны туруктуу memcached, ал ошондой эле дискте маалыматтарды сактай алат, андан тышкары, кайра күйгүзгөндө маалыматтарды жоготуп албаш үчүн, оперативдүү эс тутумга туура келет. Жеке тапшырмалар үчүн ар кандай кыймылдаткычтар бар: кезектер, тизмелер, топтомдор - биздин долбоор талап кылган нерселердин бардыгы.

Кластерлер

Коддун көз карашынан алганда, кыймылдаткычтарды же маалымат базаларын процесстер, объекттер же инстанциялар катары кароонун кереги жок. Код кластерлер менен, кыймылдаткыч топтору менен иштейт - кластерге бир түрү. Memcached кластер бар дейли - бул жөн гана машиналар тобу.

Коддун физикалык жайгашкан жерин, өлчөмүн же серверлердин санын такыр билүүнүн кереги жок. Ал белгилүү бир идентификатордун жардамы менен кластерге барат.

Бул иштеши үчүн, код менен кыймылдаткычтардын ортосунда жайгашкан дагы бир объектти кошуу керек - прокси.

RPC прокси

Прокси туташтыруучу автобус, дээрлик бүт сайт иштейт. Ошол эле учурда бизде эч кандай кызмат ачылышы — анын ордуна, бул прокси үчүн конфигурация бар, ал бардык кластерлердин жана бул кластердин бардык сыныктарынын жайгашкан жерин билет. Бул админдердин кылганы.

Программисттерге анын канча, кайда жана канча турганы кызыктырбайт - алар жөн гана кластерге барышат. Бул бизге көп мүмкүнчүлүк берет. Суроо-талапты кабыл алууда прокси кайда экенин билип, суроо-талапты башка жакка багыттайт - муну өзү аныктайт.

VKontakte архитектурасы жана иши боюнча КБС

Бул учурда прокси кызматтын бузулушунан коргоо чекити болуп саналат. Эгер кандайдыр бир кыймылдаткыч басаңдаса же бузулса, прокси муну түшүнөт жана кардар тарапка жараша жооп берет. Бул тайм-аутту алып салууга мүмкүндүк берет - код кыймылдаткычтын жооп беришин күтпөйт, бирок ал иштебей жатканын түшүнөт жана кандайдыр бир башкача жүрүш керек. Код маалымат базалары дайыма иштебей тургандыгы үчүн даярдалышы керек.

Конкреттүү ишке ашыруулар

Кээде биз дагы эле кыймылдаткыч катары кандайдыр бир стандарттуу эмес чечимге ээ болгубуз келет. Ошол эле учурда, биздин кыймылдаткычтар үчүн атайын түзүлгөн даяр rpc-проксиди колдонбостон, тапшырма үчүн өзүнчө прокси жасоону чечтик.

Бизде дагы эле бар болгон MySQL үчүн биз db-прокси колдонобуз, ал эми ClickHouse үчүн - Котенка.

Ал жалпысынан ушундай иштейт. Белгилүү бир сервер бар, ал kPHP, Go, Python иштейт - жалпысынан биздин RPC протоколубузду колдоно ала турган каалаган код. Код жергиликтүү түрдө RPC проксисинде иштейт - код жайгашкан ар бир сервер өзүнүн жергиликтүү проксисин иштетет. Сураныч боюнча, прокси кайда барарын түшүнөт.

VKontakte архитектурасы жана иши боюнча КБС

Бир кыймылдаткыч экинчисине баргысы келсе, кошуна болсо да, прокси аркылуу өтөт, анткени кошуна башка маалымат борборунда болушу мүмкүн. Мотор өзүнөн башка нерсенин жайгашкан жерин билүүгө ишенбеши керек - бул биздин стандарттуу чечимибиз. Бирок, албетте, өзгөчөлүктөр бар :)

Бардык кыймылдаткычтар иштеген TL-схемасынын мисалы.

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;

Бул экилик протокол, анын эң жакын аналогу протобуф. Схема кошумча талааларды, татаал типтерди - орнотулган скалярлардын кеңейтүүлөрүн жана сурамдарды алдын ала сүрөттөйт. Баары ушул протокол боюнча иштейт.

TCP/UDP аркылуу TL аркылуу RPC… UDP?

Бизде TL схемасынын үстүндө иштеген кыймылдаткыч суроо-талаптарын аткаруу үчүн RPC протоколу бар. Мунун баары TCP/UDP байланышы аркылуу иштейт. TCP түшүнүктүү, бирок эмне үчүн бизге UDP көп керек?

UDP жардам берет серверлердин ортосундагы байланыштардын көп сандагы көйгөйүн болтурбоо. Эгерде ар бир серверде RPC проксиси болсо жана жалпысынан ал каалаган кыймылдаткычка бара алса, анда ар бир серверде он миңдеген TCP байланыштары бар. Жүк бар, бирок пайдасы жок. UDP учурда бул көйгөй жок.

Ашыкча TCP кол алышуу жок. Бул типтүү көйгөй: жаңы кыймылдаткыч же жаңы сервер ишке киргенде, бир эле учурда көптөгөн TCP байланыштары түзүлөт. Чакан жеңил суроо-талаптар үчүн, мисалы, UDP пайдалуу жүк, код менен кыймылдаткычтын ортосундагы бардык байланыш эки UDP пакеттери: бири бир тарапка, экинчиси экинчи тарапка учат. Бир айланма сапар - жана код мотордон кол алышпастан жооп алды.

Ооба, баары жөн гана иштейт пакет жоготуу абдан аз пайызы менен. Протоколдо ретрансляцияларды жана тайм-ауттарды колдоо бар, бирок биз көп нерсени жоготсок, дээрлик TCP алабыз, бул кирешелүү эмес. Биз океандар аркылуу UDP айдабайбыз.

Бизде миңдеген мындай серверлер бар жана схема бирдей: ар бир физикалык серверде кыймылдаткычтардын пакети орнотулган. Алар бөгөттөлбөстөн, мүмкүн болушунча тезирээк иштөө үчүн, негизинен, бир жиптүү жана бир жиптүү чечимдер катары бөлүштүрүлөт. Ошол эле учурда, бизде бул кыймылдаткычтардан ишенимдүү эч нерсе жок жана маалыматтарды туруктуу сактоого көп көңүл бурулат.

Туруктуу маалыматтарды сактоо

Моторлор бинлогдорду жазат. Бинлог - бул файл, анын аягында абалды же маалыматтарды өзгөртүү үчүн окуя кошулат. Ар кандай чечимдерде ал башкача аталат: бинардык журнал, WAL, AOF, бирок принцип бирдей.

Кыймылдаткычты кайра иштетүүдө көп жылдар бою бүтүндөй бинлогду кайра окууга жол бербөө үчүн, кыймылдаткычтар жазат сүрөттөр - учурдагы абалы. Керек болсо адегенде андан окушат, анан бинлогдон окуп бүтүшөт. Бардык бинлогдор бир эле бинардык форматта жазылат - TL схемасына ылайык, администраторлор аларды куралдары менен бирдей башкара алышат. Мындай көз ирмемдик сүрөттөрдүн кереги жок. Кимдин сүрөтү int, кыймылдаткычтын сыйкырдуулугу жана кайсы орган эч ким үчүн маанилүү эмес экенин көрсөткөн жалпы аталыш бар. Бул сүрөттү жаздырган кыймылдаткычтын көйгөйү.

Мен тез арада иштөө принцибин сүрөттөп берем. Мотор иштеген сервер бар. Ал жазуу үчүн жаңы бош бинлог ачат жана аны өзгөртүү үчүн окуя жазат.

VKontakte архитектурасы жана иши боюнча КБС

Кайсы бир убакта ал сүрөткө тартууну чечет, же сигнал алат. Сервер жаңы файл түзүп, анын бүт абалын ага жазат, файлдын аягына учурдагы бинлог өлчөмүн - офсетти - кошот жана андан ары жазууну улантат. Жаңы бинлог түзүлгөн жок.

VKontakte архитектурасы жана иши боюнча КБС

Кайсы бир учурда, кыймылдаткыч кайра иштетилгенде, дискте бинлог да, сүрөт да болот. Мотор сүрөттү толугу менен окуйт жана анын абалын белгилүү бир учурда көтөрөт.

VKontakte архитектурасы жана иши боюнча КБС

Сүрөт түзүлгөн учурда болгон позицияны жана бинлогдун өлчөмүн окуйт.

VKontakte архитектурасы жана иши боюнча КБС

Учурдагы абалды алуу үчүн бинлогдун соңун окуйт жана кийинки окуяларды жазууну улантат. Бул жөнөкөй схема, биздин бардык кыймылдаткычтар ага ылайык иштейт.

Берилиштерди репликациялоо

Натыйжада, маалыматтар биздин билдирүүгө негизделген — биз бинлогго эч кандай барактагы өзгөрүүлөрдү эмес, тактап айтканда, жазабыз өтүнүчтөрдү өзгөртүү. Тармак аркылуу келгендерге абдан окшош, бир аз гана өзгөртүлгөн.

Ошол эле схема репликация үчүн гана эмес, ошондой эле колдонулат камдык көчүрмөлөрдү түзүү. Бизде мотор бар - бинлогго жазган жазуу чебери. Администраторлор орноткон башка жерде бул бинлог көчүрүлөт, жана бүттү - бизде камдык көчүрмө бар.

VKontakte архитектурасы жана иши боюнча КБС

Керек болсо репликасын окууCPU окуу жүгүн азайтуу үчүн, окуу кыймылдаткычы жөн эле ишке киргизилет, ал бинлогдун аягында окуйт жана бул буйруктарды жергиликтүү түрдө аткарат.

Бул жерде артта калуу абдан аз жана реплика мастерден канчалык артта калганын билүүгө болот.

RPC проксисинде берилиштерди бөлүштүрүү

Sharding кантип иштейт? Прокси кайсы кластердин сыныгына жөнөтүүнү кантип түшүнөт? Код: "15 сыныкка жөнөт!" деп айтылбайт. - Жок, бул прокси тарабынан жасалат.

Эң жөнөкөй схема - бул firstint — өтүнүчтөгү биринчи сан.

get(photo100_500) => 100 % N.

Бул жөнөкөй memcached текст протоколу үчүн мисал, бирок, албетте, суроолор татаал жана структуралык болушу мүмкүн. Мисал суроодогу биринчи санды, ал эми калганын кластердин өлчөмүнө бөлгөндө алат.

Бул биз бир объекттин маалымат локалдуулугуна ээ болгубуз келгенде пайдалуу. 100 колдонуучу же топтун идентификатору дейли, жана биз бир объекттин бардык маалыматтары татаал сурамдар үчүн бир сыныкта болушун каалайбыз.

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

hash(photo100_500) => 3539886280 % N

Биз ошондой эле хэшти, бөлүмдүн калганын жана сынык санын алабыз.

Бул эки вариант тең, эгерде биз кластердин көлөмүн чоңойткондо, аны бөлөбүз же бир нече эсе көбөйтөбүз деп даяр болсок гана иштейт. Мисалы, бизде 16 сынык бар болчу, бизде жетишсиз, биз дагы көптү каалайбыз - биз токтоп калбастан 32 сынык ала алабыз. Эгерде биз эселенген эмес, көбөйтүүнү кааласак, иштебей калуулар болот, анткени биз баарын жоготуусуз так бөлүштүрө албайбыз. Бул параметрлер пайдалуу, бирок дайыма эмес.

Эгер биз каалаган серверлерди кошуу же алып салуу керек болсо, биз колдонобуз Ring a la Ketama боюнча ырааттуу хэшинг. Бирок, ошол эле учурда, биз маалыматтардын локалдуулугун толугу менен жоготуп алабыз; биз кластерге суроо-талапты бириктиришибиз керек, ар бир бөлүгү өзүнүн кичинекей жообун кайтарып, андан кийин проксиге жоопторду бириктиришибиз керек.

Өзгөчө суроо-талаптар бар. Бул төмөнкүдөй көрүнөт: RPC прокси сурамды кабыл алып, кайсы кластерге өтүүнү аныктайт жана сыныкчыны аныктайт. Андан кийин же жазуу чеберлери бар, же кластерде реплика колдоого ээ болсо, талап боюнча репликага жөнөтүлөт. Мунун баары прокси тарабынан жасалат.

VKontakte архитектурасы жана иши боюнча КБС

журналдар |

Биз журналдарды бир нече жол менен жазабыз. Эң айкын жана жөнөкөй болуп саналат memcache журналдарын жазуу.

ring-buffer: prefix.idx = line

Ачкыч префикси бар - журналдын аты, сызык жана бул журналдын өлчөмү бар - саптардын саны. Биз 0дөн 1ге чейинки кокустук санды алабыз. Биз журнал сызыгын жана учурдагы убакытты мааниге сактайбыз.

Журналдарды окуу зарыл болгондо, биз аткарабыз Multi Get убакыт боюнча сорттолгон бардык баскычтар, жана ошентип, реалдуу убакытта өндүрүш журналын алуу. Схема реалдуу убакытта өндүрүштөгү бир нерсени оңдоо керек болгондо, эч нерсени бузбастан, башка машиналарга трафикти токтотпостон же уруксат бербестен колдонулат, бирок бул журнал көпкө созулбайт.

журналдарды ишенимдүү сактоо үчүн биз кыймылдаткычы бар журналдар-мотор. Дал ушундан улам ал түзүлүп, көп сандагы кластерлерде кеңири колдонулат. Мен билген эң чоң кластер 600 ТБ пакеттелген журналдарды сактайт.

Мотор абдан эски, 6-7 жаштагы кластерлер бар. Биз чечүүгө аракет кылып жаткан көйгөйлөр бар, мисалы, журналдарды сактоо үчүн ClickHouse-ды активдүү колдоно баштадык.

ClickHouse'да журналдарды чогултуу

Бул диаграмма биздин кыймылдаткычтарга кантип кирип жатканыбызды көрсөтөт.

VKontakte архитектурасы жана иши боюнча КБС

Жергиликтүү RPC аркылуу RPC-проксиге өтүүчү код бар жана ал кыймылдаткычка кайда баруу керектигин түшүнөт. Эгерде биз ClickHouseда журналдарды жазгыбыз келсе, бул схеманын эки бөлүгүн өзгөртүүбүз керек:

  • ClickHouse менен кээ бир кыймылдаткычты алмаштыруу;
  • ClickHouse кире албаган RPC проксисин RPC аркылуу кандайдыр бир чечим менен алмаштырыңыз.

Мотор жөнөкөй - биз аны серверге же ClickHouse менен серверлердин кластерине алмаштырабыз.

Ал эми ClickHouseга баруу үчүн, биз жасадык KittenHouse. Эгерде биз түздөн-түз KittenHouseдан ClickHouseга өтсөк, ал туруштук бере албайт. Суранычсыз да, ал көптөгөн машиналарды HTTP туташуусунан кошот. Схема иштеши үчүн, ClickHouse менен серверде жергиликтүү тескери прокси көтөрүлдү, ал байланыштардын талап кылынган көлөмүнө туруштук бере ала тургандай кылып жазылган. Ал ошондой эле өзүнүн ичиндеги маалыматтарды салыштырмалуу ишенимдүү буферлей алат.

VKontakte архитектурасы жана иши боюнча КБС

Кээде биз RPC схемасын стандарттуу эмес чечимдерде, мисалы, nginxте ишке ашырууну каалабайбыз. Ошондуктан, KittenHouse UDP аркылуу журналдарды кабыл алуу мүмкүнчүлүгүнө ээ.

VKontakte архитектурасы жана иши боюнча КБС

Эгерде журналдарды жөнөтүүчү жана алуучу бир эле машинада иштесе, анда жергиликтүү хосттун ичинде UDP пакетин жоготуу ыктымалдыгы өтө төмөн. Үчүнчү тараптын чечими менен RPCди ишке ашыруу зарылдыгынын ортосунда компромисс катары биз жөн гана UDP жөнөтүүнү колдонобуз. Бул схемага кийинчерээк кайрылабыз.

Мониторинг

Бизде журналдардын эки түрү бар: алардын серверлеринде администраторлор тарабынан чогултулгандар жана коддон иштеп чыгуучулар тарабынан жазылгандар. Алар көрсөткүчтөрдүн эки түрүнө туура келет: системасы жана продукт.

Системанын көрсөткүчтөрү

Ал биздин бардык серверлерде иштейт netdata, ал статистиканы чогултуп, аларды жөнөтөт Графит көмүртек. Ошондуктан, ClickHouse, мисалы, Whisper эмес, сактоо тутуму катары колдонулат. Зарыл болсо, сиз түздөн-түз ClickHouseдан окуй аласыз же колдоно аласыз Графана метрикалар, графиктер жана отчеттор үчүн. Иштеп чыгуучулар катары бизде Netdata жана Grafanaга жетиштүү мүмкүнчүлүк бар.

Продукт көрсөткүчтөрү

Ыңгайлуулук үчүн биз көп нерселерди жаздык. Мисалы, Counts, UniqueCounts баалуулуктарын статистикага жазууга мүмкүндүк берген кадимки функциялардын жыйындысы бар, алар андан ары бир жерге жөнөтүлөт.

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

$stats = statlogsStatData($params)

Кийинчерээк, биз сорттоо жана топтоо чыпкаларын колдоно алабыз жана статистикадан каалаганыбызды жасай алабыз - графиктерди курабыз, Watchdogs конфигурациялайбыз.

Биз абдан жазабыз көп көрсөткүчтөр окуялардын саны күнүнө 600 миллиарддан 1 триллионго чейин. Бирок, биз аларды сактап калгыбыз келет жок дегенде бир эки жылметрикадагы тенденцияларды түшүнүү. Мунун баарын чогултуу биз чече элек чоң көйгөй. Акыркы бир нече жылда кандай иштеп жатканын айтып берейин.

Бизде бул көрсөткүчтөрдү жазган функциялар бар жергиликтүү memcacheжазуулардын санын кыскартуу. Кыска убакыттын ичинде бир жолу жергиликтуу ишке киргизилди статистика-демон бардык жазууларды чогултат. Андан кийин, жин метрикаларды серверлердин эки катмарына бириктирет журналдарды жыйноочулар, алардын артындагы катмар өлбөшү үчүн биздин бир топ машиналарыбыздын статистикасын бириктирет.

VKontakte архитектурасы жана иши боюнча КБС

Керек болсо, биз түздөн-түз журналдарды-жыйноочуларга жаза алабыз.

VKontakte архитектурасы жана иши боюнча КБС

Бирок коддон түздөн-түз коллекторлорго жазуу, stas-daemomду кыйгап өтүү, начар масштабдалуучу чечим, анткени ал коллектордун жүгүн жогорулатат. Чечим кандайдыр бир себептерден улам биз статс-демонду машинада көтөрө албасак, же ал бузулуп, биз түз эле кеттик.

Андан кийин журналдарды чогултуучулар статистиканы бириктиришет meowDB - бул биздин маалымат базасы, ал көрсөткүчтөрдү да сактай алат.

VKontakte архитектурасы жана иши боюнча КБС

Андан кийин биз коддон бинардык "SQLге жакын" тандоолорду жасай алабыз.

VKontakte архитектурасы жана иши боюнча КБС

тажрыйба

2018-жылдын жай айларында бизде ички хакатон болуп, диаграмманын кызыл бөлүгүн ClickHouse-да метрикаларды сактай турган нерсе менен алмаштыруу идеясы пайда болду. Бизде ClickHouse журналдары бар - эмне үчүн аны сынап көрбөйсүз?

VKontakte архитектурасы жана иши боюнча КБС

Бизде KittenHouse аркылуу журналдарды жазган схема бар болчу.

VKontakte архитектурасы жана иши боюнча КБС

Биз чечтик диаграммага дагы бир "*Үй" кошуу, биздин код аларды UDP аркылуу жазган форматта так метрика алат. Андан кийин бул *Үй аларды KittenHouse түшүнгөн журналдар сыяктуу кошумчаларга айлантат. Ал бул журналдарды ClickHouseга эң сонун жеткире алат, ал аларды окуй алат.

VKontakte архитектурасы жана иши боюнча КБС

Memcache, stats-demon жана logs-collectors маалымат базасы менен схема ушул менен алмаштырылган.

VKontakte архитектурасы жана иши боюнча КБС

Memcache, stats-demon жана logs-collectors маалымат базасы менен схема ушул менен алмаштырылган.

  • Бул жерде коддон жөнөтүү бар, ал StatsHouse жергиликтүү түрдө жазылган.
  • StatsHouse SQL кыстармаларына айландырылган UDP метрикасын KittenHouseга партиялар менен жазат.
  • KittenHouse аларды ClickHouseга жөнөтөт.
  • Эгерде биз аларды окугубуз келсе, анда биз StatsHouse'ту кыйгап өтүп окуйбуз - кадимки SQL аркылуу түздөн-түз ClickHouseдан.

Дагы эле барбы тажрыйба, бирок бизге анын кандайча чыкканы жагат. Схемадагы көйгөйлөрдү оңдосок, балким, биз ага толугу менен өтөбүз. Жеке мен ошондой үмүттөнөм.

схемасы темирди сактабайт. Азыраак серверлер керектелет, жергиликтүү статистика-демондор жана лог-коллекторлор талап кылынбайт, бирок ClickHouse учурдагы схемадагыларга караганда чоңураак серверди талап кылат. Азыраак серверлер керек, бирок алар кымбатыраак жана күчтүүрөөк болушу керек.

Жайгаштыруу

Биринчиден, PHP жайгаштырылышын карап көрөлү. Биз өнүгүп жатабыз Мурунку: колдонуу GitLab и TeamCity жайгаштыруу үчүн. Өнүктүрүү бутактары башкы тармакка бириктирилет, мастерден тестирлөө үчүн алар сахналаштырууга жана коюудан өндүрүшкө бириктирилет.

Жайгаштыруунун алдында учурдагы өндүрүш тармагы жана мурункусу алынат жана аларда айырма файлдары каралат - өзгөртүүлөр: түзүлгөн, өчүрүлгөн, өзгөртүлгөн. Бул өзгөртүү биздин бүт сервердик флотубуздагы өзгөрүүлөрдү тез кайталай алган атайын copyfast кыймылдаткычынын бинлогунда жазылган. Бул жерде колдонулган нерсе түздөн-түз көчүрүү эмес, бирок ушактарды кайталоо, бир сервер өзгөрүүлөрдү эң жакын кошуналарына жөнөткөндө, аларды кошуналарына ж.б.у.с. Бул сизге кодду ондогон жана секунданын бирдиктеринде бүткүл флот боюнча жаңыртууга мүмкүндүк берет. Өзгөртүү жергиликтүү репликага жеткенде, ал бул патчтарды ага колдонот жергиликтүү файл системасы. Артка кайтаруу да ошол эле схема боюнча жүзөгө ашырылат.

Биз ошондой эле kPHPди көп колдонобуз жана анын өзүнүн өнүгүүсү да бар Мурунку жогорудагы диаграммага ылайык. Ушундан бери HTTP сервер экилик, анда биз айырманы чыгара албайбыз - релиз бинардыкы жүздөгөн МБ салмакка ээ. Ошондуктан, бул жерде дагы бир вариант бар - версия жазылган binlog copyfast. Ар бир куруу менен ал көбөйөт, ал эми артка кайтаруу учурунда да көбөйөт. Версия серверлерге кайталанат. Жергиликтүү копифасттар бинлогго жаңы версия киргенин көрүшөт жана ошол эле ушак репликациясы менен алар экиликтин эң акыркы версиясын өздөрүнө алышат, биздин мастер серверди чарчатпай, бирок жүктү кылдаттык менен тармакка таратышат. Эмне болот жагымдуу кайра ишке киргизүү жаңы версия үчүн.

Негизинен экилик болгон биздин кыймылдаткычтарыбыз үчүн схема абдан окшош:

  • git мастер филиалы;
  • бинардык .deb;
  • версия binlog copyfast үчүн жазылган;
  • серверлерге репликацияланган;
  • сервер жаңы .dep чыгарат;
  • dpkg -i;
  • жаңы версияга сонун кайра иштетүү.

Айырмачылыгы биздин бинардык архивде топтолгондугунда .deb, жана аларды сордурганда dpkg -i системасына жайгаштырылат. Эмне үчүн kPHP бинардык, ал эми кыймылдаткычтар dpkg катары жайгаштырылган? Ушундай болгон. Ал иштейт - ага тийбеңиз.

Пайдалуу шилтемелер:

Программалык комитеттин составында жардам берип жаткандардын бири — Алексей Акулович PHP Россия 17-майда акыркы мезгилдеги PHP иштеп чыгуучулары үчүн эң чоң окуя болуп калат. Карачы, бизде кандай сонун компьютер бар, эмне баяндамачылар (алардын экөөсү PHP өзөгүн иштеп чыгууда!) - PHP жазсаңыз, аны өткөрүп жибере албайсыз.

Source: www.habr.com

Комментарий кошуу