Bagaimana skala dari 1 hingga 100.000 pengguna

Banyak startup memulai ini: kerumunan pengguna baru terdaftar setiap hari, dan tim pengembangan sedang berjuang untuk mendukung pekerjaan layanan.

Ini adalah masalah yang menyenangkan, tetapi ada sedikit informasi yang jelas di Web tentang cara mengukur aplikasi web secara akurat dari nol hingga ratusan ribu pengguna. Biasanya ada solusi kebakaran atau penghapusan kemacetan (dan seringkali keduanya). Oleh karena itu, orang menggunakan trik yang cukup stereotip untuk memperbesar proyek amatir mereka menjadi sesuatu yang sangat serius.

Mari kita coba untuk menyaring informasi dan menuliskan formula utama. Kami akan meningkatkan skala langkah demi langkah situs berbagi foto Graminsta baru kami dari 1 hingga 100.000 pengguna.

Kami akan menuliskan tindakan spesifik apa yang perlu dilakukan saat meningkatkan jumlah penonton menjadi 10, 100, 1000, 10 000 dan 100 000 orang.

1 pengguna: 1 mobil


Hampir setiap aplikasi, apakah itu situs web atau aplikasi seluler, memiliki tiga komponen utama:

  • API
  • basis data
  • klien (aplikasi seluler atau situs web itu sendiri)

Basis data menyimpan data persisten. API melayani permintaan untuk dan di sekitar data ini. Klien mentransfer data ke pengguna.

Saya sampai pada kesimpulan bahwa jauh lebih mudah untuk berbicara tentang penskalaan aplikasi jika, dari sudut pandang arsitektur, entitas klien dan API sepenuhnya terpisah.

Ketika kami pertama kali mulai membuat aplikasi, ketiga komponen dapat dijalankan di server yang sama. Di satu sisi, ini mengingatkan kita pada lingkungan pengembangan kita: satu insinyur menjalankan database, API dan klien pada komputer yang sama.

Secara teoritis, kita dapat menyebarkannya di cloud pada satu contoh DigitalOcean Droplet atau AWS EC2, seperti yang ditunjukkan di bawah ini:

Dengan demikian, jika situs tersebut memiliki lebih dari satu pengguna, hampir selalu masuk akal untuk menyoroti tingkat basis data.

10 pengguna: membawa basis data ke tingkat yang terpisah


Membagi basis data menjadi layanan yang dikelola seperti Amazon RDS atau Digital Ocean Managed Database akan sangat membantu kita untuk waktu yang lama. Ini sedikit lebih mahal daripada self-hosting di satu mesin atau mesin EC2, tetapi dengan layanan ini Anda mendapatkan banyak ekstensi berguna di luar kotak yang akan berguna di masa depan: backup multi-wilayah, replika baca, backup otomatis, dan banyak lagi.

Beginilah tampilan sistem saat ini:

100 pengguna: membawa klien ke tingkat yang terpisah


Untungnya, aplikasi kami sangat menyukai pengguna pertama. Lalu lintas menjadi lebih stabil, jadi inilah saatnya untuk memindahkan klien ke tingkat yang terpisah. Perlu dicatat bahwa pemisahan entitas adalah aspek kunci dalam membangun aplikasi yang skalabel. Karena satu bagian dari sistem menerima lebih banyak lalu lintas, kita dapat membaginya untuk mengontrol penskalaan layanan berdasarkan pola lalu lintas tertentu.

Itu sebabnya saya ingin mewakili klien secara terpisah dari API. Ini membuatnya sangat mudah untuk berbicara tentang pengembangan untuk beberapa platform: web, web seluler, iOS, Android, aplikasi desktop, layanan pihak ketiga, dll. Semuanya hanyalah klien yang menggunakan API yang sama.

Misalnya, sekarang pengguna kami paling sering meminta untuk merilis aplikasi seluler. Memisahkan entitas klien dan API membuatnya lebih mudah.

Seperti apa sistemnya:



1000 pengguna: tambahkan load balancer


Semuanya berjalan baik. Pengguna Graminsta mengunggah lebih banyak foto. Jumlah pendaftaran juga bertambah. Server API mandiri kami mengalami kesulitan mengelola semua lalu lintas. Butuh lebih banyak zat besi!

Load balancer adalah konsep yang sangat kuat. Gagasan utamanya adalah kami menempatkan penyeimbang di depan API, dan mendistribusikan lalu lintas di antara mesin virtual individual. Ini adalah cara penskalaan horizontal, yaitu, kami menambahkan lebih banyak server dengan kode yang sama, meningkatkan jumlah permintaan yang dapat kami proses.

Kami akan menempatkan penyeimbang beban terpisah di depan klien web dan di depan API. Ini berarti Anda dapat menjalankan beberapa instance yang mengeksekusi kode API dan kode klien web. Load balancer akan meneruskan permintaan ke server yang kurang dimuat.

Di sini kita mendapatkan keuntungan penting lainnya - redundansi. Ketika satu instance gagal (mungkin overload atau crash), kami masih memiliki yang lain yang masih merespons permintaan yang masuk. Jika satu instance bekerja, maka jika terjadi kegagalan seluruh sistem akan jatuh.

Penyeimbang beban juga menyediakan penskalaan otomatis. Kita dapat mengkonfigurasinya untuk menambah jumlah instance sebelum beban puncak, dan mengurangi ketika semua pengguna tidur.

Dengan penyeimbang beban, level API dapat diskalakan hingga tak terbatas, kami hanya menambahkan contoh baru saat jumlah permintaan meningkat.


. , PaaS, Heroku Elastic Beanstalk AWS ( ). Heroku , - API. , Heroku β€” .

10 000 : CDN


Mungkin itu harus dilakukan sejak awal. Memproses permintaan dan mengambil foto baru mulai memuat server kami terlalu banyak.

Pada tahap ini, Anda perlu menggunakan layanan cloud untuk menyimpan konten statis - gambar, video, dan banyak lagi lainnya (AWS S3 atau Digital Ocean Spaces). Secara umum, API kami harus menghindari pemrosesan hal-hal seperti mengunggah gambar dan mengunggah gambar ke server.

Keuntungan lain dari cloud hosting adalah CDN-nya (dalam AWS, add-on ini disebut Cloudfront, tetapi banyak layanan penyimpanan cloud menawarkannya di luar kotak). CDN secara otomatis menyimpan gambar kita di berbagai pusat data di seluruh dunia.

Meskipun pusat data utama kami dapat berlokasi di Ohio, tetapi jika seseorang meminta gambar dari Jepang, penyedia cloud akan membuat salinan dan menyimpannya di pusat data Jepang mereka. Orang berikutnya yang meminta gambar ini di Jepang akan menerimanya lebih cepat. Ini penting ketika kita bekerja dengan file besar, seperti foto atau video yang membutuhkan waktu lama untuk mengunggah dan mengirimkan seluruh planet.



100.000 pengguna: penskalaan tingkat data


CDN sangat membantu: lalu lintas tumbuh dengan kecepatan penuh. Video blogger terkenal, Maid Mobrick, baru saja mendaftar dengan kami dan memposting kisahnya, seperti yang mereka katakan. Berkat load balancer, tingkat penggunaan CPU dan memori pada server API dijaga tetap rendah (sepuluh instance API berjalan), tetapi kami mulai mendapatkan banyak waktu tunggu untuk permintaan ... dari mana datangnya penundaan ini?

Setelah menggali sedikit dalam metrik, kita melihat bahwa CPU pada server database dimuat 80-90%. Kami berada di batas.

Penskalaan lapisan data mungkin merupakan bagian tersulit dari persamaan. Server API melayani permintaan tanpa kewarganegaraan, jadi kami hanya menambahkan lebih banyak instance API. Tetapi dengan sebagian besarbasis data tidak berhasil. Kami akan membahas sistem manajemen basis data relasional yang populer (PostgreSQL, MySQL, dll.).

Caching


Salah satu cara termudah untuk meningkatkan kinerja database kami adalah dengan memperkenalkan komponen baru: tingkat cache. Metode caching yang paling umum adalah untuk menyimpan catatan nilai kunci dalam RAM, seperti Redis atau Memcached. Sebagian besar cloud memiliki versi terkelola dari layanan ini: Elasticache pada AWS dan Memorystore di Google Cloud.

Cache berguna ketika suatu layanan melakukan banyak panggilan berulang ke database untuk mendapatkan informasi yang sama. Bahkan, kami mengakses database hanya sekali, menyimpan informasi dalam cache - dan jangan menyentuhnya lagi.

Misalnya, di layanan Graminsta kami, setiap kali seseorang pergi ke halaman profil bintang Mobric, server API meminta informasi dari profilnya di database. Itu terjadi berulang-ulang. Karena informasi profil Mobrick tidak berubah dengan setiap permintaan, itu bagus untuk caching.

Kami akan menyimpan hasil dari database di Redis dengan kunci user:iddengan masa berlaku 30 detik. Sekarang, ketika seseorang memasuki profil Mobrick, kami pertama-tama memeriksa Redis, dan jika datanya ada, kami cukup mentransfernya langsung dari Redis. Sekarang, pertanyaan tentang profil paling populer di situs itu praktis tidak memuat basis data kami.

Keuntungan lain dari sebagian besar layanan caching adalah bahwa mereka lebih mudah untuk diukur daripada server database. Redis memiliki mode cluster Redis Cluster bawaan. Seperti penyeimbang beban1, ini memungkinkan Anda untuk mendistribusikan cache Redis di beberapa mesin (di ribuan server, jika perlu).

Hampir semua aplikasi skala besar menggunakan caching, ini merupakan bagian yang tidak terpisahkan dari API cepat. Pemrosesan permintaan yang lebih cepat dan kode yang lebih produktif - semua ini penting, tetapi tanpa cache hampir tidak mungkin untuk skala layanan ke jutaan pengguna.

Membaca replika


Ketika jumlah kueri ke basis data telah meningkat secara signifikan, kita dapat melakukan satu hal lagi - tambahkan replika baca dalam sistem manajemen basis data. Menggunakan layanan terkelola yang dijelaskan di atas, ini dapat dilakukan dalam satu klik. Replika baca akan tetap relevan dalam database utama dan tersedia untuk pernyataan SELECT.

Inilah sistem kami sekarang:



Tindakan selanjutnya


Ketika aplikasi terus meningkat, kami akan terus memisahkan layanan untuk mengukurnya secara mandiri. Misalnya, jika kita mulai menggunakan Websockets, masuk akal untuk menarik kode pemrosesan Websockets ke layanan terpisah. Kita dapat menempatkannya pada instance baru di belakang load balancer kita sendiri, yang dapat meningkatkan dan menurunkan tergantung pada koneksi Websockets yang terbuka dan terlepas dari jumlah permintaan HTTP.

Kami juga terus berjuang melawan pembatasan di tingkat basis data. Pada tahap inilah saatnya untuk mempelajari partisi dan sharding database. Kedua pendekatan ini membutuhkan biaya tambahan, tetapi memungkinkan Anda untuk menskalakan database hingga hampir tak terbatas.

Kami juga ingin menginstal layanan pemantauan dan analitik seperti New Relic atau Datadog. Ini akan mengidentifikasi permintaan yang lambat dan memahami di mana perbaikan diperlukan. Saat kami mengukur, kami ingin fokus pada menemukan kemacetan dan menyelesaikannya - sering menggunakan beberapa ide dari bagian sebelumnya.

Sumber


Posting ini terinspirasi oleh salah satu posting skalabilitas tinggi favorit saya . Saya ingin mengkonkretkan artikel sedikit untuk tahap awal proyek dan melepaskannya dari satu vendor. Pastikan untuk membaca jika Anda tertarik dengan topik ini.

Catatan kaki


  1. Terlepas dari kesamaan dalam hal penyeimbangan beban di beberapa kejadian, implementasi dasar dari cluster Redis sangat berbeda dari penyeimbang beban. [mengembalikan]



Source: https://habr.com/ru/post/undefined/


All Articles