VKontakte билдирүүлөр базасын нөлдөн баштап кайра жазыңыз жана аман калыңыз

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

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

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

иши тарыхы

Биринчи ишке ашырууда, VKontakte билдирүүлөрү PHP backend жана MySQL айкалышында иштеген. Бул кичинекей студенттик веб-сайт үчүн кадимки чечим. Бирок, бул сайт көзөмөлсүз өсүп, өзү үчүн маалымат структураларын оптималдаштырууну талап кыла баштады.

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

Тексттик кыймылдаткычта билдирүүлөр тизмелерде сакталган - "почта кутуларынын" бир түрү. Ар бир мындай тизме uid тарабынан аныкталат - бул билдирүүлөрдүн бардыгына ээ болгон колдонуучу. Кабарда атрибуттардын жыйындысы болот: маектешинин идентификатору, текст, тиркемелер ж.б. "Кутучанын" ичиндеги билдирүү идентификатору local_id, ал эч качан өзгөрбөйт жана жаңы билдирүүлөр үчүн ырааттуу түрдө дайындалат. "Кутулар" көз карандысыз жана кыймылдаткычтын ичинде бири-бири менен синхрондоштуруу эмес, алардын ортосундагы байланыш PHP деңгээлинде ишке ашат. Тексттик кыймылдаткычтын маалымат түзүмүн жана мүмкүнчүлүктөрүн ичинен карай аласыз бул жерде.
VKontakte билдирүүлөр базасын нөлдөн баштап кайра жазыңыз жана аман калыңыз
Бул эки колдонуучунун ортосундагы кат алышуу үчүн жетиштүү болгон. Андан ары эмне болгонун билесизби?

2011-жылдын май айында "ВКонтакте" бир нече катышуучулар менен баарлашууну киргизди - көп чат. Алар менен иштөө үчүн биз эки жаңы кластер түздүк - мүчө-чат жана чат-мүчө. Биринчиси колдонуучулардын чаттары жөнүндө маалыматтарды сактаса, экинчиси чаттар аркылуу колдонуучулар жөнүндө маалыматтарды сактайт. Тизмелердин өзүнөн тышкары, бул, мисалы, чакыруучу колдонуучуну жана алардын чатта кошулган убактысын камтыйт.

"PHP, келгиле, чатта билдирүү жөнөтөлү" дейт колдонуучу.
"Кел, {username}" дейт PHP.
VKontakte билдирүүлөр базасын нөлдөн баштап кайра жазыңыз жана аман калыңыз
Бул схеманын кемчиликтери бар. Синхрондоштуруу дагы эле PHPдин жоопкерчилигинде. Чоң чаттар жана бир эле учурда аларга билдирүү жөнөткөн колдонуучулар кооптуу окуя. Тексттик кыймылдаткыч инстанциясы uid'ден көз каранды болгондуктан, чаттын катышуучулары бир эле билдирүүнү ар кайсы убакта ала алышат. Эгерде прогресс токтоп калса, муну менен жашай алмак. Бирок андай болбойт.

2015-жылдын аягында биз жамааттык билдирүүлөрдү ишке киргиздик, ал эми 2016-жылдын башында алар үчүн API ишке киргиздик. Жамааттарда чоң чатботтордун пайда болушу менен жүктү бөлүштүрүүнү унутуп коюуга мүмкүн болду.

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

2016-жылы билдирүү механизмдери чат-мүчөлөрүнүн жана мүчө-чаттарынын 100 учуру жана 8000 тексттик кыймылдаткычтар. Алар ар биринде 64 ГБ эс тутуму бар миң серверде жайгаштырылган. Биринчи өзгөчө чара катары биз эстутумду дагы 32 ГБга көбөйттүк. Биз болжолдоолорду эсептедик. Катаал өзгөртүүлөр болбосо, бул дагы бир жылга жетет. Сиз аппараттык жабдыкка ээ болушуңуз же маалымат базаларын оптималдаштырууңуз керек.

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

Жаңы концепция

Жаңы ыкманын борбордук маңызы – баарлашуу. Чатта ага тиешелүү билдирүүлөрдүн тизмеси бар. Колдонуучуда чаттар тизмеси бар.

Керектүү минималдуу эки жаңы маалымат базасы болуп саналат:

  • чат кыймылдаткычы. Бул чат векторлорунун репозиторийи. Ар бир чатта ага тиешелүү билдирүүлөрдүн вектору болот. Ар бир билдирүүдө текст жана чатта уникалдуу билдирүү идентификатору бар - chat_local_id.
  • колдонуучу кыймылдаткыч. Бул колдонуучулардын векторлорунун сактагычы - колдонуучуларга шилтемелер. Ар бир колдонуучу peer_id векторуна ээ (маектешүүлөр - башка колдонуучулар, мульти-чат же жамааттар) жана билдирүүлөрдүн вектору. Ар бир peer_id ага тиешелүү билдирүүлөрдүн векторуна ээ. Ар бир билдирүүдө chat_local_id жана ошол колдонуучу үчүн уникалдуу билдирүү ID бар - user_local_id.

VKontakte билдирүүлөр базасын нөлдөн баштап кайра жазыңыз жана аман калыңыз
Жаңы кластерлер TCP аркылуу бири-бири менен байланышат - бул суроо-талаптардын тартиби өзгөрбөшүн камсыздайт. Сурамдардын өзү жана алар боюнча ырастоолор катуу дискке жазылат - ошондуктан биз кыймылдаткыч иштен чыккандан же кайра күйгүзүлгөндөн кийин каалаган убакта кезектин абалын калыбына келтире алабыз. Колдонуучу кыймылдаткыч жана чат кыймылдаткычы ар бири 4 миң сыныктан тургандыктан, кластерлердин ортосундагы суроо-талап кезеги бирдей бөлүштүрүлөт (бирок чындыгында эч нерсе жок - жана ал абдан тез иштейт).

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

Ошол эле учурда, катуу дисктеги маалыматтар бир күндө бир жолу гана өзгөрөт - Москвада түн ичинде, жүк минималдуу болгондо. Ушунун аркасында (дисктеги структура сутка бою туруктуу экенин билип) биз векторлорду белгиленген өлчөмдөгү массивдер менен алмаштыра алабыз - жана ошонун аркасында эс тутумга ээ болобуз.

Жаңы схемада билдирүү жөнөтүү төмөнкүдөй көрүнөт:

  1. PHP сервери билдирүү жөнөтүү өтүнүчү менен колдонуучу кыймылдаткычы менен байланышат.
  2. колдонуучу кыймылдаткычы сурамды каалаган чат кыймылдаткычынын инстанциясына проксиге жөнөтөт, ал chat_local_id колдонуучу кыймылдаткычына кайтып келет - бул чатта жаңы билдирүүнүн уникалдуу идентификатору. Андан кийин chat_engine билдирүүнү чатта бардык алуучуларга таратат.
  3. user-engine chat-mengineден chat_local_id алат жана user_local_idди PHPге кайтарат - бул колдонуучу үчүн уникалдуу билдирүү идентификатору. Бул идентификатор, мисалы, API аркылуу билдирүүлөр менен иштөө үчүн колдонулат.

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

  • Кошумча тизмелер, мисалы, баарлашуу тизмесин ачууда сиз көргөн эң акыркы билдирүүлөр. Окула элек билдирүүлөр, теги бар билдирүүлөр («Маанилүү», «Спам» ж.б.).
  • Чат кыймылдаткычында билдирүүлөрдү кысуу
  • Колдонуучу кыймылдаткычында билдирүүлөрдү кэштөө
  • Издөө (бардык диалогдор аркылуу жана белгилүү биринин ичинде).
  • Реалдуу убакытта жаңыртуу (Longpolling).
  • Мобилдик кардарларда кэшти ишке ашыруу үчүн тарыхты сактоо.

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

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

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

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

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

Маалыматтарды көчүрүү

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

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

Чат мүчөлөрү үчүн кезек. Ал 100 инстанцияны камтыйт, ал эми чат кыймылдаткычында 4 миң. Маалыматтарды өткөрүп берүү үчүн, аны ылайыкташтыруу керек - бул үчүн чат-мүчөлөр бирдей 4 миң нускага бөлүнгөн, андан кийин чат кыймылдаткычында чат мүчөлөрүнүн бинлогун окуу иштетилген.
VKontakte билдирүүлөр базасын нөлдөн баштап кайра жазыңыз жана аман калыңыз
Азыр чат кыймылдаткычы чат-мүчөлөрүнүн мульти-чаттарын билет, бирок эки маектешинин диалогу жөнүндө азырынча эч нерсе билбейт. Мындай диалогдор тексттик кыймылдаткычта колдонуучуларга шилтеме менен жайгашкан. Бул жерде биз маалыматтарды “баш-кабат” алдык: ар бир чат кыймылдаткычы бардык тексттик кыймылдаткыч инстанцияларынан аларда керектүү диалог бар-жогун сурады.

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

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

Андан кийин, мультичаттагы билдирүүлөр жөнүндө маалымат колдонуучуга жөнөтүлөт. Жана бул жерде импорттук билдирүүлөрдүн жагымсыз өзгөчөлүгү келип чыгат. Кадимки иштөөдө, кыймылдаткычка келген билдирүүлөр user_local_id тарабынан өсүү тартибинде катуу иреттелет. Эски кыймылдаткычтан колдонуучу кыймылдаткычына импорттолгон билдирүүлөр бул пайдалуу касиетин жоготкон. Ошол эле учурда, тестирлөөнүн ыңгайлуулугу үчүн аларга тез кирип, алардан бир нерсени издеп, жаңыларын кошууга жөндөмдүү болушуңуз керек.

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

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

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

Маалыматтар чат-мүчөлөрүнө жана колдонуучу кыймылдаткычына жазылат (эски схема боюнча нормалдуу иштөөдөгүдөй тексттик кыймылдаткычка эмес). колдонуучу кыймылдаткычы чат кыймылдаткычына суроо-проксилерди жөнөтөт - жана бул жерде жүрүм-турум бул чат мурунтан эле бириктирилген же кошулбаганына жараша болот. Эгерде чат бириктириле элек болсо, чат кыймылдаткычы билдирүүнү өзүнө жазбайт жана аны иштетүү тексттик кыймылдаткычта гана ишке ашат. Эгер чат мурунтан эле чат кыймылдаткычына бириктирилген болсо, ал chat_local_id дегенди колдонуучу кыймылдаткычына кайтарып, билдирүүнү бардык алуучуларга жөнөтөт. Колдонуучу кыймылдаткычы бардык маалыматтарды тексттик кыймылдаткычка проксилейт - эгер бир нерсе болуп кетсе, биз ар дайым эски кыймылдаткычта учурдагы бардык маалыматтарга ээ болуу менен артка кайтара алабыз. text-engine user_local_id кайтарып берет, аны колдонуучу кыймылдаткыч сактайт жана кайра артка кайтарат.
VKontakte билдирүүлөр базасын нөлдөн баштап кайра жазыңыз жана аман калыңыз
Натыйжада, өтүү процесси мындай көрүнөт: биз бош колдонуучу-кыймылдаткыч жана чат-кыймылдаткыч кластерлерин бириктиребиз. чат кыймылдаткычы чат мүчөлөрүнүн бинлогун толугу менен окуйт, андан кийин прокси жогоруда сүрөттөлгөн схемага ылайык башталат. Биз эски маалыматтарды өткөрүп, эки синхрондуу кластерлерди алабыз (эски жана жаңы). Окууну тексттик кыймылдаткычтан колдонуучу кыймылдаткычына которуу жана проксисин өчүрүү гана калды.

натыйжалары

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

Логикадагы өзгөрүүлөр чындап эле эбегейсиз. Бул дайыма эле чоң команда жана сансыз код саптары тарабынан бүтүндөй жылдар бою өнүгүүнү билдирбейт экенин белгилегим келет. чат кыймылдаткычы жана колдонуучу кыймылдаткычы менен бирге Хаффман сыяктуу билдирүүлөрдү кысуу, Splay дарактары жана импорттолгон билдирүүлөр үчүн структура 20 миң саптан аз кодду түзөт. Жана алар 3 айдын ичинде 10 иштеп чыгуучу тарабынан жазылган (бирок, бул эстен чыгарбоо керек бардык үч иштеп чыгуучу - дүйнө чемпиондору спорттук программалоодо).

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

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

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

Source: www.habr.com

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