Tulis ulang database pesen VKontakte ti scratch tur salamet

Pamaké urang nulis pesen ka silih tanpa nyaho kacapean.
Tulis ulang database pesen VKontakte ti scratch tur salamet
Éta cukup loba. Upami anjeun badé maca sadaya pesen sadaya pangguna, éta peryogi langkung ti 150 rébu taun. Upami anjeun maca anu cukup maju sareng nyéépkeun henteu langkung ti sadetik dina unggal pesen.

Kalayan volume data sapertos kitu, penting pisan yén logika pikeun nyimpen sareng ngaksés éta diwangun sacara optimal. Upami teu kitu, dina hiji momen teu-kitu-hébat, éta bisa jadi jelas yén sagalana baris geura-giru jadi salah.

Pikeun urang, moment ieu sumping sataun satengah katukang. Kumaha urang sumping ka ieu sareng naon anu kajantenan dina tungtungna - kami nyarioskeun ka anjeun dina urutan.

sajarah hal

Dina palaksanaan pisan munggaran, seratan VKontakte digawé dina kombinasi backend PHP jeung MySQL. Ieu mangrupikeun solusi anu normal pikeun halaman wéb murid leutik. Sanajan kitu, situs ieu tumuwuh uncontrollably sarta mimiti nungtut optimasi struktur data keur dirina.

Dina ahir 2009, Repository téks-mesin munggaran ditulis, sarta dina 2010 pesen ditransferkeun ka dinya.

Dina mesin téks, pesen disimpen dina daptar - jinis "kotak surat". Unggal daptar sapertos ditangtukeun ku uid - pangguna anu gaduh sadaya pesen ieu. Hiji talatah ngabogaan sakumpulan atribut: interlocutor identifier, téks, kantétan, jeung saterusna. Identifier pesen di jero "kotak" nyaeta local_id, eta pernah robah sarta ditugaskeun sequentially pikeun pesen anyar. The "kotak" bebas sarta henteu disingkronkeun saling di jero mesin; komunikasi antara aranjeunna lumangsung dina tingkat PHP. Anjeun tiasa ningali struktur data sareng kamampuan mesin téks ti jero di dieu.
Tulis ulang database pesen VKontakte ti scratch tur salamet
Ieu cukup pikeun korespondensi antara dua pamaké. Tebak naon anu lumangsung saterusna?

Dina Méi 2011, VKontakte ngawanohkeun paguneman jeung sababaraha pamilon-multi-chat. Pikeun damel sareng aranjeunna, kami ngangkat dua klaster énggal - obrolan anggota sareng anggota obrolan. Anu kahiji nyimpen data ngeunaan obrolan ku pangguna, anu kadua nyimpen data ngeunaan pangguna ku obrolan. Salian daptar sorangan, ieu kalebet, contona, pangguna anu ngondang sareng waktos aranjeunna ditambahkeun kana obrolan.

"PHP, hayu urang ngirim pesen ka obrolan," saur pangguna.
"Hayu, {username}," saur PHP.
Tulis ulang database pesen VKontakte ti scratch tur salamet
Aya kalemahan pikeun skéma ieu. Sinkronisasi masih tanggung jawab PHP. Obrolan ageung sareng pangguna anu sakaligus ngirim pesen ka aranjeunna mangrupikeun carita anu bahaya. Kusabab conto mesin téks gumantung kana uid, pamilon obrolan tiasa nampi pesen anu sami dina waktos anu béda. Hiji bisa hirup kalawan ieu lamun kamajuan nangtung kénéh. Tapi éta moal kajadian.

Dina ahir 2015, kami ngaluncurkeun pesen komunitas, sareng dina awal 2016, kami ngaluncurkeun API pikeun aranjeunna. Kalayan munculna chatbots ageung di komunitas, mungkin waé hilap ngeunaan distribusi beban.

Bot anu saé ngahasilkeun sababaraha juta pesen per dinten - bahkan pangguna anu paling seueur ngobrol henteu tiasa ngagungkeun ieu. Ieu ngandung harti yén sababaraha instansi téks-mesin, on nu bot misalna cicing, mimiti sangsara ka fullest.

Mesin pesen dina 2016 nyaéta 100 instansi obrolan-anggota sareng obrolan-anggota, sareng 8000 mesin téks. Tembok hosted on sarébu server, unggal kalawan 64 GB memori. Salaku ukuran darurat munggaran, urang ngaronjat memori ku sejen 32 GB. Urang estimasi ramalan. Tanpa parobahan drastis, ieu bakal cukup pikeun ngeunaan sataun sejen. Anjeun kudu boh nyekel hardware atawa ngaoptimalkeun database sorangan.

Kusabab sifat arsitéktur, éta ngan ukur tiasa ningkatkeun hardware dina sababaraha kali. Hartina, sahenteuna dua kali jumlah mobil - écés, ieu jalan rada mahal. Urang bakal ngaoptimalkeun.

Konsep anyar

Intina sentral tina pendekatan anyar nyaéta obrolan. Obrolan ngagaduhan daptar pesen anu aya hubunganana sareng éta. Pangguna gaduh daptar obrolan.

Minimum anu diperyogikeun nyaéta dua pangkalan data énggal:

  • obrolan-mesin. Ieu mangrupikeun gudang vektor obrolan. Unggal obrolan gaduh vektor pesen anu aya hubunganana sareng éta. Unggal pesen ngagaduhan téks sareng identifier pesen anu unik di jero obrolan - chat_local_id.
  • pamaké-mesin. Ieu mangrupikeun panyimpen vektor pangguna - tautan ka pangguna. Unggal pamaké boga vektor peer_id (interlocutors - pamaké séjén, multi-chat atawa komunitas) jeung vektor pesen. Unggal peer_id gaduh vektor pesen anu aya hubunganana sareng éta. Unggal pesen gaduh chat_local_id sareng ID pesen unik pikeun pangguna éta - user_local_id.

Tulis ulang database pesen VKontakte ti scratch tur salamet
Kluster anyar saling komunikasi nganggo TCP - ieu mastikeun yén urutan pamundut henteu robih. Paménta sorangan sareng konfirmasi pikeun aranjeunna kacatet dina hard drive - ku kituna urang tiasa mulangkeun kaayaan antrian iraha waé saatos gagal atanapi balikan deui mesin. Kusabab mesin-pamaké sareng mesin obrolan masing-masing 4 rébu beling, antrian pamundut antara klaster bakal disebarkeun merata (tapi dina kanyataanana henteu aya - sareng éta tiasa dianggo gancang pisan).

Gawe sareng disk dina basis data urang dina kalolobaan kasus dumasar kana kombinasi log binér parobahan (binlog), snapshots statik sarta gambar parsial dina mémori. Parobahan beurang ditulis ka binlog a, sarta snapshot tina kaayaan ayeuna périodik dijieun. Snapshot mangrupikeun kumpulan struktur data anu dioptimalkeun pikeun tujuan urang. Ieu diwangun ku lulugu (metaindex gambar) jeung sakumpulan metafiles. Lulugu disimpen sacara permanen dina RAM sareng nunjukkeun dimana milarian data tina snapshot. Unggal metafile ngawengku data nu dipikaresep diperlukeun dina titik deukeut waktu-contona, patali jeung hiji pamaké. Lamun anjeun query database ngagunakeun lulugu snapshot, metafile diperlukeun dibaca, lajeng parobahan dina binlog anu lumangsung sanggeus snapshot dijieun dicokot kana rekening. Anjeun tiasa maca langkung seueur ngeunaan kauntungan tina pendekatan ieu di dieu.

Dina waktu nu sarua, data dina hard drive sorangan robah ngan sakali sapoé - telat peuting di Moscow, nalika beban minimal. Hatur nuhun kana ieu (nyaho yén struktur dina disk téh konstan sapopoe), urang bisa mampuh ngaganti vektor kalawan arrays tina ukuran tetep - sarta alatan ieu, gain memori.

Ngirim pesen dina skéma énggal sapertos kieu:

  1. Backend PHP ngahubungi mesin-pamaké sareng pamundut pikeun ngirim pesen.
  2. mesin-pamaké proksi pamundut ka conto mesin obrolan nu dipikahoyong, nu balik deui ka mesin-pamaké chat_local_id - identifier unik tina pesen anyar dina obrolan ieu. Chat_engine teras nyiarkeun pesen ka sadaya panarima dina obrolan.
  3. mesin-pamaké narima chat_local_id ti chat-engine sarta mulangkeun user_local_id kana PHP - identifier pesen unik pikeun pamaké ieu. Identifier ieu lajeng dipaké, contona, pikeun digawe sareng pesen via API.

Tulis ulang database pesen VKontakte ti scratch tur salamet
Tapi salian leres ngirim pesen, anjeun kedah ngalaksanakeun sababaraha hal anu langkung penting:

  • Sublist nyaéta, contona, pesen panganyarna anu anjeun tingali nalika muka daptar paguneman. Pesen anu henteu dibaca, pesen anu nganggo tag ("Penting", "Spam", jsb.).
  • Compressing pesen dina chat-mesin
  • Pesen cache dina mesin-pamaké
  • Pilarian (ngaliwatan sadaya dialog sareng dina anu khusus).
  • Pembaruan waktos nyata (Longpolling).
  • Nyimpen sajarah pikeun nerapkeun cache on klien mobile.

Kabéh sublists anu gancang ngarobah struktur. Pikeun digawe sareng aranjeunna kami nganggo Tangkal splay. Pilihan ieu dijelaskeun ku kanyataan yén di luhureun tangkal urang kadang nyimpen sakabeh bagean pesen ti snapshot a - contona, sanggeus reindexing nightly tangkal diwangun ku hiji luhureun, nu ngandung sakabéh pesen tina sublist. Tangkal Splay ngagampangkeun pikeun nyelapkeun kana tengah-tengah vertex sapertos kitu tanpa kedah mikirkeun kasaimbangan. Sajaba ti éta, Splay teu nyimpen data nu teu perlu, nu ngaheéat memori urang.

Talatah ngalibetkeun jumlah badag informasi, lolobana téks, nu mangpaat pikeun bisa niiskeun. Kadé urang akurat bisa unarchive malah hiji pesen individu. Dipaké pikeun ngompres pesen Algoritma Huffman kalawan heuristik urang sorangan - contona, urang terang yén dina pesen kecap diganti ku "non-kecap" - spasi, tanda baca - sarta kami ogé apal sababaraha peculiarities tina ngagunakeun simbol pikeun basa Rusia.

Kusabab aya loba pamaké leuwih saeutik ti obrolan, pikeun nyimpen requests disk acak-aksés dina chat-mesin, urang cache pesen dina pamaké-mesin.

Pilarian pesen dilaksanakeun salaku pamundut diagonal tina mesin-pamaké ka sadaya instansi mesin obrolan anu ngandung obrolan pangguna ieu. Hasilna digabungkeun dina mesin-pamaké sorangan.

Nya, sadaya detil parantos diperhatoskeun, sadayana anu tetep nyaéta ngalih ka skéma énggal - sareng langkung saé tanpa perhatikeun pangguna.

Migrasi data

Janten, kami gaduh mesin téks anu nyimpen pesen ku pangguna, sareng dua klaster obrolan-anggota sareng obrolan-anggota anu nyimpen data ngeunaan kamar multi-chat sareng pangguna di jerona. Kumaha carana ngalih tina ieu kana mesin-pamaké sareng mesin obrolan énggal?

anggota-obrolan dina skéma heubeul ieu dipaké utamana pikeun optimasi. Urang gancang mindahkeun data diperlukeun ti eta ka obrolan-anggota, lajeng eta euweuh ilubiung dina prosés migrasi.

Antrian pikeun obrolan-anggota. Ieu ngawengku 100 instansi, bari obrolan-mesin boga 4 sarébu. Pikeun nransper data, Anjeun kudu mawa kana patuh - pikeun ieu, obrolan-anggota dibagi kana sarua 4 sarébu éksemplar, lajeng maca binlog obrolan-anggota diaktipkeun dina obrolan-mesin.
Tulis ulang database pesen VKontakte ti scratch tur salamet
Ayeuna obrolan-mesin terang ngeunaan multi-obrolan ti obrolan-anggota, tapi teu acan terang nanaon ngeunaan dialog jeung dua interlocutors. Dialog sapertos kitu aya dina mesin téks kalayan ngarujuk ka pangguna. Di dieu kami nyandak data "sirah-on": unggal conto chat-mesin naroskeun sadaya instansi téks-mesin upami aranjeunna gaduh dialog anu diperyogikeun.

Hébat - mesin obrolan terang naon anu aya seueur obrolan sareng terang naon dialog anu aya.
Anjeun kudu ngagabungkeun talatah dina multi-chat chats jadi Anjeun mungkas nepi ka daptar talatah di unggal chat. Kahiji, chat-engine retrieves tina téks-mesin sadaya pesen pamaké ti obrolan ieu. Dina sababaraha kasus aya cukup loba di antarana (nepi ka ratusan juta), tapi kalawan iwal langka pisan obrolan fits sagemblengna kana RAM. Kami ngagaduhan pesen anu henteu teratur, masing-masing dina sababaraha salinan - saatosna, aranjeunna sadayana ditarik tina instansi-mesin téks anu béda-béda anu cocog sareng pangguna. Tujuanana nyaéta pikeun nyortir pesen sareng nyingkirkeun salinan anu nyéépkeun rohangan anu teu perlu.

Unggal pesen gaduh cap waktu anu ngandung waktos dikirim sareng téks. Kami nganggo waktos pikeun nyortir - kami nempatkeun petunjuk kana pesen pangkolotna pamilon multichat sareng ngabandingkeun hashes tina téks salinan anu dimaksud, nuju kanaékan cap waktu. Logis yén salinan bakal gaduh hash sareng timestamp anu sami, tapi dina prakna ieu henteu salawasna kitu. Sakumaha anjeun émut, sinkronisasi dina skéma lami dilaksanakeun ku PHP - sareng dina kasus anu jarang, waktos ngirim pesen anu sami bénten diantara pangguna anu béda. Dina kasus ieu, urang ngantepkeun diri pikeun ngédit timestamp - biasana dina sadetik. Masalah kadua nyaéta urutan pesen anu béda pikeun panarima anu béda. Dina kasus kawas, urang diwenangkeun hiji salinan tambahan dijieun, kalawan pilihan susunan béda pikeun pamaké béda.

Saatos ieu, data ngeunaan pesen dina multichat dikirim ka mesin-pamaké. Sareng didieu aya fitur anu teu pikaresepeun tina pesen anu diimpor. Dina operasi normal, pesen nu datang ka mesin anu maréntahkeun mastikeun dina urutan naek ku user_local_id. Pesen diimpor ti mesin heubeul kana pamaké-mesin leungit sipat mangpaat ieu. Dina waktos anu sami, pikeun genah tés, anjeun kedah tiasa gancang ngaksés aranjeunna, milarian anu aya di aranjeunna sareng nambihan anu énggal.

Kami nganggo struktur data khusus pikeun nyimpen pesen anu diimpor.

Ieu ngagambarkeun vektor ukuranana Tulis ulang database pesen VKontakte ti scratch tur salametmana dulur Tulis ulang database pesen VKontakte ti scratch tur salamet - béda jeung maréntahkeun dina urutan nurun, kalawan urutan husus elemen. Dina unggal ruas kalawan indéks Tulis ulang database pesen VKontakte ti scratch tur salamet unsur diurutkeun. Milarian unsur dina struktur sapertos kitu peryogi waktos Tulis ulang database pesen VKontakte ti scratch tur salamet через Tulis ulang database pesen VKontakte ti scratch tur salamet pilarian binér. Penambahan hiji unsur ieu amortized leuwih Tulis ulang database pesen VKontakte ti scratch tur salamet.

Janten, urang terang kumaha cara nransper data tina mesin lami ka mesin énggal. Tapi prosés ieu butuh sababaraha dinten - sareng teu mungkin dina dinten-dinten ieu pangguna urang bakal nyerah kabiasaan nyerat masing-masing. Dina raraga teu leungit pesen salila ieu, urang pindah ka skéma karya anu ngagunakeun duanana klaster heubeul jeung anyar.

Data ditulis ka obrolan-anggota jeung pamaké-mesin (jeung teu téks-mesin, sakumaha dina operasi normal nurutkeun skéma heubeul). pamaké-mesin proxies pamundut ka obrolan-mesin - sarta di dieu kabiasaan gumantung kana naha obrolan ieu geus dihijikeun atawa henteu. Lamun obrolan teu acan dihijikeun, chat-mesin teu nulis pesen ka dirina, sarta ngolah na lumangsung ngan dina téks-mesin. Upami obrolan parantos dihijikeun kana mesin obrolan, éta bakal ngabalikeun chat_local_id ka mesin-pamaké sareng ngirim pesen ka sadaya panampi. pamaké-mesin proxies sadaya data kana téks-mesin - ambéh lamun hal kajadian, urang salawasna bisa gulung deui, ngabogaan sakabéh data ayeuna dina mesin heubeul. text-engine mulih user_local_id, nu nyimpen-mesin pamaké sarta balik deui ka backend nu.
Tulis ulang database pesen VKontakte ti scratch tur salamet
Hasilna, prosés transisi kasampak kawas kieu: urang nyambungkeun kosong pamaké-mesin jeung obrolan-mesin klaster. obrolan-mesin maca sakabéh obrolan-anggota binlog, lajeng proxying dimimitian nurutkeun skéma ditétélakeun di luhur. Urang mindahkeun data heubeul tur meunangkeun dua klaster nyingkronkeun (heubeul jeung anyar). Sadaya anu tetep nyaéta ngalihkeun bacaan tina mesin téks ka mesin-pamaké sareng nganonaktipkeun proxy.

Hasil

Hatur nuhun kana pendekatan énggal, sadaya métrik kinerja mesin parantos ningkat sareng masalah konsistensi data parantos direngsekeun. Ayeuna urang tiasa gancang nerapkeun fitur-fitur anyar dina pesen (sareng parantos ngamimitian ngalakukeun ieu - urang ningkatkeun jumlah maksimal pamilon obrolan, ngalaksanakeun milarian pesen anu diteruskeun, ngaluncurkeun pesen anu disematkeun sareng ningkatkeun wates jumlah pesen per pangguna) .

Parobahan dina logika sabenerna gede pisan. Sareng kuring hoyong dicatet yén ieu sanés hartosna sadayana taun pangwangunan ku tim ageung sareng seueur garis kode. obrolan-mesin jeung pamaké-mesin sapanjang kalawan sagala carita tambahan kawas Huffman pikeun komprési pesen, Splay tangkal jeung struktur pikeun pesen diimpor kirang ti 20 sarébu garis kode. Sareng aranjeunna ditulis ku 3 pamekar dina ngan 10 sasih (tapi, kedah émut yén sadaya tilu pamekar - juara dunya dina programming olahraga).

Leuwih ti éta, tinimbang duka kali jumlah server, urang ngurangan jumlah maranéhanana ku satengah - ayeuna pamaké-mesin jeung obrolan-mesin hirup dina 500 mesin fisik, sedengkeun skéma anyar ngabogaan headroom badag pikeun beban. Kami ngahémat artos kanggo alat-alat - sakitar $ 5 juta + $ 750 rébu per taun dina biaya operasi.

Kami narékahan pikeun milari solusi anu pangsaéna pikeun masalah anu paling rumit sareng ageung. Kami ngagaduhan seueur - sareng éta sababna urang milarian pamekar anu berbakat dina jabatan database. Upami anjeun resep sareng terang kumaha ngabéréskeun masalah sapertos kitu, gaduh pangaweruh anu saé ngeunaan algoritma sareng struktur data, kami ngajak anjeun gabung sareng tim. Kontak urang HRpikeun detil.

Sanaos carita ieu sanés ngeunaan anjeun, perhatikeun yén kami ngahargaan rekomendasi. Ngabejaan babaturan ngeunaan lowongan pamekar, sarta lamun anjeunna hasil ngalengkepan periode probationary, anjeun bakal nampa bonus 100 sarébu rubles.

sumber: www.habr.com

Tambahkeun komentar