Blok bangunan aplikasi yang diedarkan. Pengiraan kedua

Pengumuman

Rakan sekerja, pada pertengahan musim panas saya bercadang untuk mengeluarkan satu lagi siri artikel mengenai reka bentuk sistem baris gilir: "Eksperimen VTrade" - percubaan untuk menulis rangka kerja untuk sistem perdagangan. Siri ini akan mengkaji teori dan amalan membina pertukaran, lelongan dan kedai. Pada akhir artikel, saya menjemput anda untuk mengundi topik yang paling anda minati.

Blok bangunan aplikasi yang diedarkan. Pengiraan kedua

Ini ialah artikel terakhir dalam siri mengenai aplikasi reaktif teragih dalam Erlang/Elixir. DALAM artikel pertama anda boleh menemui asas teori seni bina reaktif. Artikel kedua menggambarkan corak dan mekanisme asas untuk membina sistem tersebut.

Hari ini kami akan membangkitkan isu pembangunan asas kod dan projek secara umum.

Organisasi perkhidmatan

Dalam kehidupan sebenar, apabila membangunkan perkhidmatan, anda sering perlu menggabungkan beberapa corak interaksi dalam satu pengawal. Contohnya, perkhidmatan pengguna, yang menyelesaikan masalah mengurus profil pengguna projek, mesti bertindak balas terhadap permintaan req-resp dan melaporkan kemas kini profil melalui sub-pub. Kes ini agak mudah: di sebalik pemesejan terdapat satu pengawal yang melaksanakan logik perkhidmatan dan menerbitkan kemas kini.

Keadaan menjadi lebih rumit apabila kita perlu melaksanakan perkhidmatan pengedaran yang bertolak ansur terhadap kesalahan. Mari bayangkan bahawa keperluan untuk pengguna telah berubah:

  1. kini perkhidmatan harus memproses permintaan pada 5 nod kluster,
  2. dapat melaksanakan tugas pemprosesan latar belakang,
  3. dan juga boleh mengurus senarai langganan secara dinamik untuk kemas kini profil.

Ulasan: Kami tidak mempertimbangkan isu penyimpanan yang konsisten dan replikasi data. Mari kita anggap bahawa isu ini telah diselesaikan lebih awal dan sistem sudah mempunyai lapisan storan yang boleh dipercayai dan berskala, dan pengendali mempunyai mekanisme untuk berinteraksi dengannya.

Penerangan rasmi perkhidmatan pengguna telah menjadi lebih rumit. Dari sudut pandangan pengaturcara, perubahan adalah minimum kerana penggunaan pemesejan. Untuk memenuhi keperluan pertama, kita perlu mengkonfigurasi pengimbangan pada titik pertukaran req-resp.

Keperluan untuk memproses tugas latar belakang kerap berlaku. Dalam pengguna, ini mungkin menyemak dokumen pengguna, memproses multimedia yang dimuat turun, atau menyegerakkan data dengan media sosial. rangkaian. Tugas-tugas ini perlu diagihkan dalam kluster dan kemajuan pelaksanaan dipantau. Oleh itu, kami mempunyai dua pilihan penyelesaian: sama ada menggunakan templat pengedaran tugas daripada artikel sebelumnya, atau, jika ia tidak sesuai, tulis penjadual tugas tersuai yang akan mengurus kumpulan pemproses mengikut cara yang kami perlukan.

Perkara 3 memerlukan sambungan templat sub-pub. Dan untuk pelaksanaan, selepas mencipta titik pertukaran pub-sub, kami perlu melancarkan lagi pengawal titik ini dalam perkhidmatan kami. Oleh itu, ia seolah-olah kita mengalihkan logik untuk memproses langganan dan berhenti melanggan dari lapisan pemesejan ke dalam pelaksanaan pengguna.

Akibatnya, penguraian masalah menunjukkan bahawa untuk memenuhi keperluan, kami perlu melancarkan 5 contoh perkhidmatan pada nod yang berbeza dan mencipta entiti tambahan - pengawal sub-pub, bertanggungjawab untuk langganan.
Untuk menjalankan 5 pengendali, anda tidak perlu menukar kod perkhidmatan. Satu-satunya tindakan tambahan ialah menyediakan peraturan pengimbangan di titik pertukaran, yang akan kita bincangkan sedikit kemudian.
Terdapat juga kerumitan tambahan: pengawal pub-sub dan penjadual tugas tersuai mesti berfungsi dalam satu salinan. Sekali lagi, perkhidmatan pemesejan, sebagai asas, mesti menyediakan mekanisme untuk memilih pemimpin.

Pemilihan pemimpin

Dalam sistem teragih, pemilihan pemimpin ialah prosedur untuk melantik satu proses yang bertanggungjawab untuk menjadualkan pemprosesan teragih bagi beberapa beban.

Dalam sistem yang tidak terdedah kepada pemusatan, algoritma universal dan berasaskan konsensus, seperti paxos atau rakit, digunakan.
Memandangkan pemesejan ialah broker dan elemen utama, ia mengetahui tentang semua pengawal perkhidmatan - calon pemimpin. Pemesejan boleh melantik pemimpin tanpa mengundi.

Selepas memulakan dan menyambung ke titik pertukaran, semua perkhidmatan menerima mesej sistem #'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}. Jika LeaderPid bertepatan dengan pid proses semasa, ia dilantik sebagai ketua, dan senarai Servers termasuk semua nod dan parameternya.
Pada masa yang baharu muncul dan nod kluster yang berfungsi diputuskan, semua pengawal perkhidmatan menerima #'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts} ΠΈ #'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts} masing-masing.

Dengan cara ini, semua komponen menyedari semua perubahan, dan kluster dijamin mempunyai satu ketua pada bila-bila masa.

Pengantara

Untuk melaksanakan proses pemprosesan teragih yang kompleks, serta dalam masalah mengoptimumkan seni bina sedia ada, adalah mudah untuk menggunakan pengantara.
Untuk tidak menukar kod perkhidmatan dan menyelesaikan, sebagai contoh, masalah pemprosesan tambahan, penghalaan atau mesej log, anda boleh mendayakan pengendali proksi sebelum perkhidmatan, yang akan melaksanakan semua kerja tambahan.

Contoh klasik pengoptimuman sub-pub ialah aplikasi yang diedarkan dengan teras perniagaan yang menjana peristiwa kemas kini, seperti perubahan harga dalam pasaran dan lapisan akses - N pelayan yang menyediakan API soket web untuk pelanggan web.
Jika anda membuat keputusan terus, maka perkhidmatan pelanggan kelihatan seperti ini:

  • pelanggan mewujudkan hubungan dengan platform. Di sebelah pelayan yang menamatkan trafik, satu proses dilancarkan untuk menyediakan perkhidmatan sambungan ini.
  • Dalam konteks proses perkhidmatan, kebenaran dan langganan kemas kini berlaku. Proses ini memanggil kaedah langganan untuk topik.
  • Sebaik sahaja peristiwa dijana dalam kernel, ia dihantar ke proses yang memberi perkhidmatan kepada sambungan.

Bayangkan kita mempunyai 50000 pelanggan kepada topik "berita". Pelanggan diagihkan sama rata di 5 pelayan. Akibatnya, setiap kemas kini, yang tiba di titik pertukaran, akan direplikasi 50000 kali: 10000 kali pada setiap pelayan, mengikut bilangan pelanggan padanya. Bukan skim yang sangat berkesan, bukan?
Untuk memperbaiki keadaan, mari perkenalkan proksi yang mempunyai nama yang sama dengan titik pertukaran. Pendaftar nama global mesti dapat mengembalikan proses terdekat dengan nama, ini penting.

Mari kita lancarkan proksi ini pada pelayan lapisan akses, dan semua proses kami yang menyediakan api soket web akan melanggannya, dan bukan kepada titik pertukaran sub-pub asal dalam kernel. Proksi melanggan teras hanya dalam kes langganan unik dan mereplikasi mesej masuk kepada semua pelanggannya.
Akibatnya, 5 mesej akan dihantar antara kernel dan pelayan akses, bukannya 50000.

Penghalaan dan pengimbangan

Req-Resp

Dalam pelaksanaan pemesejan semasa, terdapat 7 strategi pengedaran permintaan:

  • default. Permintaan dihantar kepada semua pengawal.
  • round-robin. Permintaan dikira dan diedarkan secara kitaran antara pengawal.
  • consensus. Pengawal yang melayani perkhidmatan dibahagikan kepada pemimpin dan hamba. Permintaan dihantar hanya kepada ketua.
  • consensus & round-robin. Kumpulan itu mempunyai ketua, tetapi permintaan diedarkan di kalangan semua ahli.
  • sticky. Fungsi cincang dikira dan diberikan kepada pengendali tertentu. Permintaan seterusnya dengan tandatangan ini dihantar kepada pengendali yang sama.
  • sticky-fun. Apabila memulakan titik pertukaran, fungsi pengiraan cincang untuk sticky mengimbangi.
  • fun. Sama seperti sticky-fun, hanya anda yang boleh mengubah hala, menolak atau mempraprosesnya.

Strategi pengedaran ditetapkan apabila titik pertukaran dimulakan.

Selain mengimbangi, pemesejan membolehkan anda menandai entiti. Mari lihat jenis teg dalam sistem:

  • Tag sambungan. Membolehkan anda memahami melalui sambungan mana peristiwa itu datang. Digunakan apabila proses pengawal bersambung ke titik pertukaran yang sama, tetapi dengan kekunci penghalaan yang berbeza.
  • Tag perkhidmatan. Membolehkan anda untuk menggabungkan pengendali ke dalam kumpulan untuk satu perkhidmatan dan mengembangkan penghalaan dan keupayaan mengimbangi. Untuk corak req-resp, penghalaan adalah linear. Kami menghantar permintaan ke pusat pertukaran, kemudian menghantarnya kepada perkhidmatan. Tetapi jika kita perlu membahagikan pengendali kepada kumpulan logik, maka pemisahan dilakukan menggunakan tag. Apabila menentukan teg, permintaan akan dihantar kepada kumpulan pengawal tertentu.
  • Minta tag. Membolehkan anda membezakan antara jawapan. Memandangkan sistem kami tidak segerak, untuk memproses respons perkhidmatan kami perlu dapat menentukan RequestTag semasa menghantar permintaan. Daripadanya kita akan dapat memahami jawapan kepada permintaan yang datang kepada kita.

Subtitle pub

Untuk pub-sub semuanya lebih mudah sedikit. Kami mempunyai titik pertukaran untuk mesej yang diterbitkan. Titik pertukaran mengedarkan mesej di kalangan pelanggan yang telah melanggan kekunci penghalaan yang mereka perlukan (kita boleh mengatakan bahawa ini adalah analog dengan topik).

Kebolehskalaan dan toleransi kesalahan

Kebolehskalaan sistem secara keseluruhan bergantung pada tahap kebolehskalaan lapisan dan komponen sistem:

  • Perkhidmatan diskalakan dengan menambahkan nod tambahan pada kluster dengan pengendali untuk perkhidmatan ini. Semasa operasi percubaan, anda boleh memilih dasar pengimbangan optimum.
  • Perkhidmatan pemesejan itu sendiri dalam kluster yang berasingan secara amnya diskalakan sama ada dengan mengalihkan titik pertukaran yang dimuatkan secara khusus ke nod kluster yang berasingan, atau dengan menambahkan proses proksi ke kawasan kluster yang dimuatkan secara khusus.
  • Skala keseluruhan sistem sebagai ciri bergantung pada fleksibiliti seni bina dan keupayaan untuk menggabungkan kelompok individu menjadi entiti logik yang sama.

Kejayaan projek selalunya bergantung pada kesederhanaan dan kelajuan penskalaan. Pemesejan dalam versi semasanya berkembang bersama dengan aplikasi. Walaupun kita kekurangan kumpulan 50-60 mesin, kita boleh menggunakan persekutuan. Malangnya, topik persekutuan berada di luar skop artikel ini.

Tempahan

Semasa menganalisis pengimbangan beban, kami telah membincangkan lebihan pengawal perkhidmatan. Walau bagaimanapun, pemesejan juga mesti ditempah. Sekiranya berlaku ranap nod atau mesin, pemesejan akan pulih secara automatik dan dalam masa yang sesingkat mungkin.

Dalam projek saya, saya menggunakan nod tambahan yang mengambil beban sekiranya berlaku kejatuhan. Erlang mempunyai pelaksanaan mod teragih standard untuk aplikasi OTP. Mod teragih melakukan pemulihan sekiranya berlaku kegagalan dengan melancarkan aplikasi yang gagal pada nod lain yang dilancarkan sebelum ini. Prosesnya adalah telus; selepas kegagalan, aplikasi secara automatik bergerak ke nod failover. Anda boleh membaca lebih lanjut tentang fungsi ini di sini.

Produktiviti

Mari cuba bandingkan secara kasar prestasi rabbitmq dan pemesejan tersuai kami.
saya jumpa keputusan rasmi ujian rabbitmq dari pasukan openstack.

Dalam perenggan 6.14.1.2.1.2.2. Dokumen asal menunjukkan hasil RPC CAST:
Blok bangunan aplikasi yang diedarkan. Pengiraan kedua

Kami tidak akan membuat sebarang tetapan tambahan pada kernel OS atau erlang VM terlebih dahulu. Syarat untuk ujian:

  • erl memilih: +A1 +sbtu.
  • Ujian dalam satu nod erlang dijalankan pada komputer riba dengan i7 lama dalam versi mudah alih.
  • Ujian kluster dijalankan pada pelayan dengan rangkaian 10G.
  • Kod berjalan dalam bekas docker. Rangkaian dalam mod NAT.

Kod ujian:

req_resp_bench(_) ->
  W = perftest:comprehensive(10000,
    fun() ->
      messaging:request(?EXCHANGE, default, ping, self()),
      receive
        #'$msg'{message = pong} -> ok
      after 5000 ->
        throw(timeout)
      end
    end
  ),
  true = lists:any(fun(E) -> E >= 30000 end, W),
  ok.

Senario 1: Ujian dijalankan pada komputer riba dengan versi mudah alih i7 lama. Ujian, pemesejan dan perkhidmatan dilaksanakan pada satu nod dalam satu bekas Docker:

Sequential 10000 cycles in ~0 seconds (26987 cycles/s)
Sequential 20000 cycles in ~1 seconds (26915 cycles/s)
Sequential 100000 cycles in ~4 seconds (26957 cycles/s)
Parallel 2 100000 cycles in ~2 seconds (44240 cycles/s)
Parallel 4 100000 cycles in ~2 seconds (53459 cycles/s)
Parallel 10 100000 cycles in ~2 seconds (52283 cycles/s)
Parallel 100 100000 cycles in ~3 seconds (49317 cycles/s)

Senario 2: 3 nod berjalan pada mesin yang berbeza di bawah docker (NAT).

Sequential 10000 cycles in ~1 seconds (8684 cycles/s)
Sequential 20000 cycles in ~2 seconds (8424 cycles/s)
Sequential 100000 cycles in ~12 seconds (8655 cycles/s)
Parallel 2 100000 cycles in ~7 seconds (15160 cycles/s)
Parallel 4 100000 cycles in ~5 seconds (19133 cycles/s)
Parallel 10 100000 cycles in ~4 seconds (24399 cycles/s)
Parallel 100 100000 cycles in ~3 seconds (34517 cycles/s)

Dalam semua kes, penggunaan CPU tidak melebihi 250%

Keputusan

Saya harap kitaran ini tidak kelihatan seperti longgokan minda dan pengalaman saya akan memberi manfaat sebenar kepada kedua-dua penyelidik sistem teragih dan pengamal yang pada awal membina seni bina teragih untuk sistem perniagaan mereka dan melihat Erlang/Elixir dengan penuh minat , tetapi ragu-ragu adakah ia berbaloi...

Photo @chuttersnap

Hanya pengguna berdaftar boleh mengambil bahagian dalam tinjauan. Log masuk, Sama-sama.

Apakah topik yang perlu saya bincangkan dengan lebih terperinci sebagai sebahagian daripada siri Eksperimen VTrade?

  • Teori: Pasaran, pesanan dan masanya: DAY, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC

  • Buku pesanan. Teori dan amalan melaksanakan buku dengan kumpulan

  • Visualisasi perdagangan: Kutu, bar, resolusi. Cara menyimpan dan cara melekat

  • Pejabat belakang. Perancangan dan pembangunan. Pemantauan pekerja dan penyiasatan insiden

  • API. Mari kita fikirkan antara muka yang diperlukan dan cara melaksanakannya

  • Penyimpanan maklumat: PostgreSQL, Timescale, Tarantool dalam sistem perdagangan

  • Kereaktifan dalam sistem perdagangan

  • Lain-lain. Saya akan menulis dalam komen

6 pengguna mengundi. 4 pengguna berpantang.

Sumber: www.habr.com

Tambah komen