Tulis maneh database pesen VKontakte saka awal lan urip

Pangguna kita nulis pesen menyang saben liyane tanpa ngerti kesel.
Tulis maneh database pesen VKontakte saka awal lan urip
Sing cukup akeh. Yen sampeyan arep maca kabeh pesen saka kabeh pangguna, iku bakal njupuk luwih saka 150 ewu taun. Kasedhiya sing maca cukup majeng lan nglampahi ora luwih saka detik ing saben pesen.

Kanthi volume data kasebut, penting banget yen logika kanggo nyimpen lan ngakses dibangun kanthi optimal. Yen ora, ing wayahe sing ora apik banget, bisa uga dadi jelas yen kabeh bakal salah.

Kanggo kita, wayahe iki teka setengah taun kepungkur. Kepiye carane kita teka lan apa sing kedadeyan ing pungkasan - kita pitutur marang kowe kanthi urutan.

Latar mburi

Ing implementasine pisanan, pesen VKontakte nggarap kombinasi backend PHP lan MySQL. Iki minangka solusi sing normal kanggo situs web siswa cilik. Nanging, situs iki tansaya ora bisa dikendhaleni lan wiwit nuntut optimasi struktur data kanggo awake dhewe.

Ing pungkasan 2009, repositori mesin teks pisanan ditulis, lan ing 2010 pesen ditransfer menyang.

Ing mesin teks, pesen disimpen ing dhaptar - jinis "kotak layang". Saben dhaptar kasebut ditemtokake dening uid - pangguna sing duwe kabeh pesen kasebut. Pesen nduweni seperangkat atribut: pengenal interlocutor, teks, lampiran, lan liya-liyane. Pengenal pesen ing "kothak" yaiku local_id, ora tau diganti lan ditugasake kanthi urutan kanggo pesen anyar. "Kothak" kasebut independen lan ora disinkronake ing njero mesin; komunikasi ing antarane ana ing tingkat PHP. Sampeyan bisa ndeleng struktur data lan kemampuan mesin teks saka njero kene.
Tulis maneh database pesen VKontakte saka awal lan urip
Iki cukup kanggo korespondensi antarane rong pangguna. Coba tebak apa sing kedadeyan sabanjure?

Ing Mei 2011, VKontakte ngenalake obrolan karo sawetara peserta-multi-chatting. Kanggo nggarap wong-wong mau, kita ngunggahake rong klompok anyar - obrolan anggota lan anggota obrolan. Sing pisanan nyimpen data babagan obrolan dening pangguna, sing nomer loro nyimpen data babagan pangguna kanthi obrolan. Saliyane dhaptar dhewe, iki kalebu, contone, pangguna sing ngundang lan wektu ditambahake menyang obrolan.

"PHP, ayo ngirim pesen menyang obrolan," ujare pangguna.
"Ayo, {username}," ujare PHP.
Tulis maneh database pesen VKontakte saka awal lan urip
Ana kekurangan kanggo skema iki. Sinkronisasi isih dadi tanggung jawab PHP. Obrolan gedhe lan pangguna sing ngirim pesen kanthi bebarengan minangka crita sing mbebayani. Wiwit conto mesin teks gumantung saka uid, peserta chatting bisa nampa pesen sing padha ing wektu sing beda. Siji bisa urip karo iki yen kemajuan tetep. Nanging kuwi ora bakal kelakon.

Ing pungkasan 2015, kita ngluncurake pesen komunitas, lan ing awal 2016, kita ngluncurake API kanggo wong-wong mau. Kanthi tekane chatbots gedhe ing komunitas, bisa uga lali babagan distribusi beban.

Bot sing apik ngasilake pirang-pirang yuta pesen saben dina - malah pangguna sing paling akeh ngomong ora bisa gumunggung babagan iki. Iki tegese sawetara mesin teks, ing ngendi bot kasebut urip, wiwit nandhang sangsara.

Mesin pesen ing 2016 yaiku 100 conto saka anggota obrolan lan obrolan anggota, lan 8000 mesin teks. Padha dadi tuan rumah ing sewu server, saben karo 64 memori GB. Minangka langkah darurat pisanan, kita nambah memori liyane 32 GB. Kita ngira ramalan. Tanpa owah-owahan drastis, iki bakal cukup kanggo taun liyane. Sampeyan kudu nyekel hardware utawa ngoptimalake database dhewe.

Amarga sifat arsitektur, mung bisa nambah hardware ing pirang-pirang. Sing, ing paling tikel nomer mobil - temenan, iki dalan rada larang. Kita bakal ngoptimalake.

Konsep anyar

Inti saka pendekatan anyar yaiku obrolan. Obrolan duwe dhaptar pesen sing ana gandhengane. Pangguna duwe dhaptar obrolan.

Minimal sing dibutuhake yaiku rong database anyar:

  • mesin chatting. Iki minangka gudang saka vektor chatting. Saben obrolan duwe vektor pesen sing ana gandhengane. Saben pesen duwe teks lan pengenal pesen sing unik ing obrolan - chat_local_id.
  • mesin pangguna. Iki minangka panyimpenan saka vektor pangguna - pranala menyang pangguna. Saben pangguna duwe vektor peer_id (interlocutors - pangguna liyane, multi-chat utawa komunitas) lan vektor pesen. Saben peer_id nduweni vektor pesen sing ana gandhengane. Saben pesen duwe chat_local_id lan ID pesen unik kanggo pangguna - user_local_id.

Tulis maneh database pesen VKontakte saka awal lan urip
Kluster anyar komunikasi karo saben liyane nggunakake TCP - iki mesthekake yen urutan panjalukan ora ngganti. Panjalukan dhewe lan konfirmasi kanggo wong-wong mau direkam ing hard drive - supaya kita bisa mulihake negara antrian ing sembarang wektu sawise Gagal utawa miwiti maneh mesin. Wiwit pangguna-mesin lan chatting-engine saben 4 ewu shards, antrian panjalukan antarane kluster bakal mbagekke roto-roto (nanging nyatane ora ana - lan bisa cepet banget).

Nggarap disk ing basis data kita biasane adhedhasar kombinasi log pangowahan binar (binlog), gambar statis lan gambar sebagean ing memori. Owah-owahan sak dina ditulis kanggo binlog a, lan gambar asli seko saka negara saiki periodik digawe. Snapshot minangka kumpulan struktur data sing dioptimalake kanggo tujuan kita. Iku kasusun saka header (metaindex saka gambar) lan sakumpulan metafiles. Header disimpen kanthi permanen ing RAM lan nuduhake ngendi kanggo nggoleki data saka gambar asli. Saben metafile kalebu data sing bisa uga dibutuhake ing wektu sing cedhak-contone, sing ana gandhengane karo pangguna siji. Nalika sampeyan takon database nggunakake header gambar asli seko, metafile sing dibutuhake diwaca, banjur owah-owahan ing binlog sing kedaden sawise gambar asli seko digawe dijupuk menyang akun. Sampeyan bisa maca liyane babagan keuntungan saka pendekatan iki kene.

Ing wektu sing padha, data ing hard drive dhewe diganti mung sapisan dina - ing wayah wengi ing Moscow, nalika mbukak minimal. Thanks kanggo iki (ngerti manawa struktur ing disk tetep sedina muput), kita bisa ngganti vektor kanthi susunan ukuran tetep - lan amarga iki, entuk memori.

Ngirim pesen ing skema anyar katon kaya iki:

  1. Backend PHP ngubungi mesin pangguna kanthi panjaluk ngirim pesen.
  2. user-engine proxies request menyang chat-engine instance sing dikarepake, sing bali menyang user-engine chat_local_id - pengenal unik saka pesen anyar ing chatting iki. Mesin chatting banjur ngirim pesen menyang kabeh panampa ing obrolan.
  3. user-engine nampa chat_local_id saka chat-engine lan ngasilake user_local_id menyang PHP - pengenal pesen unik kanggo pangguna iki. Pengenal iki banjur digunakake, contone, kanggo nggarap pesen liwat API.

Tulis maneh database pesen VKontakte saka awal lan urip
Nanging saliyane ngirim pesen, sampeyan kudu ngetrapake sawetara perkara sing luwih penting:

  • Sublist, contone, pesen paling anyar sing sampeyan deleng nalika mbukak dhaptar obrolan. Pesen sing durung diwaca, pesen kanthi tag ("Penting", "Spam", lsp.).
  • Ngompres pesen ing chat-engine
  • Caching pesen ing pangguna-mesin
  • Telusuri (liwat kabeh dialog lan ing siji tartamtu).
  • Nganyari wektu nyata (Longpolling).
  • Nyimpen riwayat kanggo ngleksanakake caching ing klien seluler.

Kabeh sublist kanthi cepet ngganti struktur. Kanggo nggarap wong-wong mau, kita nggunakake Splay wit. Pilihan iki diterangake dening kasunyatan sing ing ndhuwur wit kadhangkala nyimpen kabeh bagean pesen saka gambar asli - contone, sawise reindexing nightly wit kasusun saka siji ndhuwur, kang ngemot kabeh pesen saka sublist. Wit Splay nggawe gampang dilebokake ing tengah-tengah simpul kasebut tanpa mikir babagan imbangan. Kajaba iku, Splay ora nyimpen data sing ora perlu, sing nyimpen memori.

Pesen nglibatake akeh informasi, biasane teks, sing migunani supaya bisa dikompres. Penting yen kita bisa mbusak kanthi akurat sanajan siji pesen. Digunakake kanggo compress pesen Algoritma Huffman Kanthi heuristik kita dhewe - contone, kita ngerti manawa ing pesen tembung gantian karo "non-tembung" - spasi, tandha wacan - lan kita uga ngelingi sawetara keanehan nggunakake simbol kanggo basa Rusia.

Wiwit ana akeh kurang kedhaftar saka chats, kanggo nyimpen panjalukan acak-akses disk ing chatting-mesin, kita cache pesen ing pangguna-mesin.

Panelusuran pesen ditindakake minangka pitakon diagonal saka mesin pangguna menyang kabeh mesin obrolan sing ngemot obrolan pangguna iki. Asil digabungake ing mesin pangguna dhewe.

Inggih, kabeh rincian wis dijupuk menyang akun, kabeh sing isih kanggo ngalih menyang skema anyar - lan luwih tanpa kedhaftar ngelingi.

Migrasi data

Dadi, kita duwe mesin teks sing nyimpen pesen dening pangguna, lan rong klompok chatting-anggota lan anggota-chatting sing nyimpen data babagan multi-chat room lan pangguna ing wong-wong mau. Kepiye carane pindhah saka iki menyang mesin pangguna lan mesin obrolan anyar?

anggota-chatting ing rencana lawas iki digunakake utamanΓ© kanggo Optimization. Kita cepet nransfer data sing perlu saka iku kanggo chatting-anggota, lan banjur ora melu ing proses migrasi.

Antrian kanggo chatting-anggota. Iku kalebu 100 kedadean, nalika chatting-mesin duwe 4 ewu. Kanggo nransfer data, sampeyan kudu nggawa menyang selaras - kanggo iki, chatting-anggota dipΓ©rang dadi padha 4 ewu salinan, lan banjur maca binlog chatting-anggota diaktifake ing chatting-mesin.
Tulis maneh database pesen VKontakte saka awal lan urip
Saiki chatting-mesin ngerti bab multi-chatting saka chatting-anggota, nanging durung ngerti apa-apa bab dialog karo loro interlocutors. Dialog kasebut ana ing mesin teks kanthi referensi kanggo pangguna. Ing kene kita njupuk data "head-on": saben conto mesin chatting takon kabeh conto mesin teks yen dheweke duwe dialog sing dibutuhake.

Great - chatting-engine mangertΓ©ni apa multi-chat chatting ana lan ngerti apa dialog ana.
Sampeyan kudu nggabungake pesen ing chatting multi-chat supaya sampeyan entuk dhaptar pesen ing saben chatting. Kaping pisanan, mesin chatting njupuk saka mesin teks kabeh pesen pangguna saka obrolan iki. Ing sawetara kasus ana cukup akèh wong (nganti atusan yuta), nanging karo istiméwa arang banget chatting mathuk tanggung menyang RAM. We have unordered messages, each in several copy - after all, they are all pulled from different text-engine instances related to users. Tujuane kanggo ngurutake pesen lan nyingkirake salinan sing njupuk papan sing ora perlu.

Saben pesen duwe stempel wektu sing ngemot wektu dikirim lan teks. Kita nggunakake wektu kanggo ngurutake - kita nyelehake pitunjuk menyang pesen paling tuwa saka peserta multichat lan mbandhingake hash saka teks salinan sing dituju, terus nambah cap wektu. Iku logis yen salinan bakal duwe hash lan timestamp sing padha, nanging ing laku iki ora mesthi. Nalika sampeyan ngelingi, sinkronisasi ing skema lawas ditindakake dening PHP - lan ing kasus sing jarang, wektu ngirim pesen sing padha beda-beda ing antarane pangguna sing beda. Ing kasus iki, kita ngidini dhΓ©wΓ© kanggo ngowahi timestamp - biasane ing detik. Masalah kapindho yaiku urutan pesen sing beda kanggo panampa sing beda. Ing kasus kaya mengkono, kita ngidini salinan ekstra kanggo digawe, karo opsi pesenan beda kanggo pangguna beda.

Sawise iki, data babagan pesen ing multichat dikirim menyang mesin pangguna. Lan ing kene ana fitur pesen sing diimpor sing ora nyenengake. Ing operasi normal, pesen sing teka ing mesin diurutake kanthi urutan munggah dening user_local_id. Pesen sing diimpor saka mesin lawas menyang mesin pangguna ilang properti sing migunani iki. Ing wektu sing padha, kanggo nyenengake tes, sampeyan kudu bisa ngakses kanthi cepet, goleki apa wae lan nambah sing anyar.

Kita nggunakake struktur data khusus kanggo nyimpen pesen sing diimpor.

Iku nggambarake vektor ukuran Tulis maneh database pesen VKontakte saka awal lan uripngendi kabeh wong Tulis maneh database pesen VKontakte saka awal lan urip - beda lan diurutake kanthi urutan mudhun, kanthi urutan unsur khusus. Ing saben bagean kanthi indeks Tulis maneh database pesen VKontakte saka awal lan urip unsur diurutake. Nggoleki unsur ing struktur kasebut mbutuhake wektu Tulis maneh database pesen VKontakte saka awal lan urip liwat Tulis maneh database pesen VKontakte saka awal lan urip telusuran binar. Tambahan saka unsur wis amortized liwat Tulis maneh database pesen VKontakte saka awal lan urip.

Dadi, kita ngerti carane nransfer data saka mesin lawas menyang sing anyar. Nanging proses iki njupuk sawetara dina - lan iku ora kamungkinan sing ing dina iki kedhaftar kita bakal ninggalake pakulinan saka nulis kanggo saben liyane. Supaya ora ilang pesen sajrone wektu iki, kita ngalih menyang skema kerja sing nggunakake klompok lawas lan anyar.

Data ditulis kanggo chatting-anggota lan pangguna-mesin (lan ora kanggo teks-mesin, kaya ing operasi normal miturut skema lawas). user-engine proxy request kanggo chatting-engine - lan ing kene prilaku gumantung apa chatting iki wis digabung utawa ora. Yen obrolan durung digabung, mesin chatting ora nulis pesen kasebut dhewe, lan pangolahan mung ana ing mesin teks. Yen chatting wis digabung menyang chat-engine, chat_local_id bali menyang user-engine lan ngirim pesen menyang kabeh panampa. pangguna-mesin proxy kabeh data kanggo teks-mesin - supaya yen soko mengkono, kita bisa tansah muter maneh, duwe kabeh data saiki ing mesin lawas. text-engine ngasilake user_local_id, sing disimpen dening mesin pangguna lan bali menyang backend.
Tulis maneh database pesen VKontakte saka awal lan urip
AkibatΓ©, proses transisi katon kaya iki: kita nyambungake kluster mesin pangguna lan mesin chatting kosong. chat-engine maca kabeh chatting-anggota binlog, banjur proxying diwiwiti miturut skema kasebut ing ndhuwur. Kita nransfer data lawas lan entuk rong klompok sing disinkronake (lawas lan anyar). Sing isih ana yaiku ngalih maca saka mesin teks menyang mesin pangguna lan mateni proxy.

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹

Thanks kanggo pendekatan anyar, kabeh metrik kinerja mesin wis apik lan masalah karo konsistensi data wis ditanggulangi. Saiki kita bisa kanthi cepet ngleksanakake fitur-fitur anyar ing pesen (lan wis wiwit nindakake iki - kita nambah jumlah maksimum peserta chatting, nindakake panelusuran kanggo pesen diterusake, dibukak pesen pinned lan mundhakaken watesan ing jumlah pesen saben pangguna) .

Owah-owahan ing logika pancen gedhe banget. Lan aku pengin Wigati sing iki ora ateges kabeh taun pembangunan dening tim ageng lan myriad baris kode. chatting-engine lan user-engine bebarengan karo kabeh crita tambahan kaya Huffman kanggo komprèsi pesen, Splay wit lan struktur kanggo pesen diimpor kurang saka 20 ewu baris kode. Lan padha ditulis dening 3 pangembang mung 10 sasi (Nanging, iku worth mbudidaya sing kabeh telu pangembang - juara donya ing program olahraga).

Menapa malih, tinimbang tikel kaping pindho jumlah server, kita nyuda jumlahe nganti setengah - saiki mesin pangguna lan mesin chatting manggon ing 500 mesin fisik, dene skema anyar duwe ruang utama kanggo mbukak. Kita ngirit dhuwit akeh kanggo peralatan - kira-kira $ 5 yuta + $ 750 ewu saben taun ing biaya operasi.

Kita ngupayakake golek solusi sing paling apik kanggo masalah sing paling rumit lan gedhe. Kita duwe akeh - lan mulane kita nggolek pangembang sing duwe bakat ing departemen database. Yen sampeyan tresna lan ngerti carane ngatasi masalah kasebut, duwe kawruh banget babagan algoritma lan struktur data, kita ngajak sampeyan gabung karo tim kasebut. Hubungi kita HRkanggo rincian.

Sanajan crita iki dudu babagan sampeyan, elinga yen kita menehi rekomendasi. Marang kanca bab lowongan developer, lan yen dheweke kasil ngrampungake wektu percobaan, sampeyan bakal nampa bonus 100 ewu rubel.

Source: www.habr.com

Add a comment