Menskalakan aplikasi web Anda: langkah-langkah dasar

Diterbitkan: 2022-09-13

Tidak cukup hanya membuat aplikasi untuk bisnis Anda, Anda perlu mengoptimalkannya. Cara yang efektif adalah dengan skala. Dalam artikel ini Anda akan belajar tentang pengoptimalan kode, pengoptimalan arsitektur, dan cara membangun aplikasi web yang skalabel secara umum.

Mengoptimalkan

Gearheart menyarankan untuk bertanya pada diri sendiri pertanyaan-pertanyaan berikut:

  • apakah kueri basis data optimal (Jelaskan analisis, penggunaan indeks)?
  • apakah data disimpan dengan benar (SQL vs NoSQL)?
  • apakah cache digunakan?
  • tidak ada permintaan yang tidak perlu ke FS atau database?
  • apakah algoritma pemrosesan data sudah optimal?
  • apakah pengaturan lingkungan optimal: Apache/Nginx, MySQL/PostgreSQL, PHP/Python?

Masing-masing pertanyaan ini dapat dicakup dalam artikel terpisah, jadi pertimbangan terperinci dari mereka dalam kerangka artikel ini jelas berlebihan. Penting untuk dipahami bahwa sebelum Anda mulai menskalakan aplikasi, sangat diinginkan untuk mengoptimalkan pekerjaannya sebanyak mungkin – bahkan, mungkin saja tidak diperlukan penskalaan sama sekali.

penskalaan

Misalkan Anda telah mengoptimalkan aplikasi Anda, tetapi masih tidak dapat menangani beban. Dalam hal ini, solusi yang jelas adalah mendistribusikan aplikasi ke beberapa host untuk meningkatkan kinerja aplikasi secara keseluruhan dengan meningkatkan sumber daya yang tersedia. Pendekatan ini secara resmi disebut "penskalaan" aplikasi. Lebih tepatnya, skalabilitas adalah kemampuan sistem untuk meningkatkan kinerjanya dengan meningkatkan jumlah sumber daya yang tersedia untuknya.

Ada dua jenis skalabilitas: vertikal dan horizontal. Skalabilitas vertikal menyiratkan peningkatan kinerja aplikasi dengan menambahkan sumber daya (CPU, memori, disk) dalam satu node (host). Penskalaan horizontal adalah tipikal untuk aplikasi terdistribusi dan menyiratkan peningkatan kinerja aplikasi dengan menambahkan node lain.

Jelas bahwa cara termudah adalah upgrade perangkat keras sederhana (prosesor, memori, disk) – yaitu, penskalaan vertikal. Selain itu, pendekatan ini tidak memerlukan modifikasi apa pun pada aplikasi. Namun, penskalaan vertikal dengan cepat mencapai batasnya, setelah itu pengembang dan administrator tidak punya pilihan selain beralih ke penskalaan horizontal aplikasi.

Arsitektur Aplikasi

Sebagian besar aplikasi web terdistribusi secara apriori, karena arsitekturnya dapat dibagi menjadi setidaknya tiga lapisan: server web, logika bisnis (aplikasi), data (basis data, statis).

Masing-masing lapisan ini dapat diskalakan. Jadi, jika sistem Anda memiliki aplikasi dan database yang berada di host yang sama, langkah pertama yang harus dilakukan adalah memisahkannya pada host yang berbeda.

Kemacetan

Lanjutkan ke penskalaan sistem, hal pertama yang harus dilakukan adalah menentukan lapisan mana yang merupakan "bottleneck", yaitu, lebih lambat dari bagian sistem lainnya. Untuk memulainya, Anda dapat menggunakan utilitas sepele seperti top (htop) untuk mengevaluasi konsumsi CPU/memori dan df, iostat untuk mengevaluasi konsumsi disk. Namun, diinginkan untuk menyediakan host terpisah dengan emulasi beban pertempuran (menggunakan AB atau JMeter), di mana Anda dapat membuat profil aplikasi menggunakan utilitas seperti xdebug, oprofile, dan sebagainya. Anda dapat menggunakan utilitas seperti pgFouine untuk mengidentifikasi kueri basis data yang sempit (tentu saja, lebih baik melakukannya berdasarkan log dari server pertempuran).

Biasanya itu tergantung pada arsitektur aplikasi, tetapi secara umum kandidat yang paling mungkin untuk kemacetan adalah database dan kode. Jika aplikasi Anda menangani banyak data pengguna, kemungkinan hambatannya adalah penyimpanan statis.

Penskalaan basis data

Seperti disebutkan di atas, hambatan dalam aplikasi modern sering kali adalah database. Masalah dengan itu biasanya dibagi menjadi dua kelas: kinerja dan kebutuhan untuk menyimpan sejumlah besar data.

Anda dapat mengurangi beban pada database dengan membaginya menjadi beberapa host. Ada kesulitan akut sinkronisasi di antara mereka, yang dapat diselesaikan dengan menerapkan skema master/slave dengan replikasi sinkron atau asinkron. Untuk PostgreSQL, Anda dapat menggunakan Slony-I untuk replikasi sinkron dan PgPool-II atau WAL (9.0) untuk replikasi asinkron. Untuk mengatasi masalah pemisahan permintaan baca dan tulis, serta menyeimbangkan beban antar slave, Anda dapat mengonfigurasi lapisan akses basis data khusus (PgPool-II).

Kekhawatiran menyimpan sejumlah besar data dalam kasus database relasional dapat diselesaikan dengan mempartisi ("partisi" di PostgreSQL), atau dengan menyebarkan database pada database terdistribusi seperti Hadoop DFS.

Anda dapat membaca tentang kedua solusi di buku yang sangat bagus tentang mengonfigurasi PostgreSQL.

1.Namun, untuk menyimpan data dalam jumlah besar, solusi terbaik adalah sharding, yang merupakan keunggulan yang melekat pada sebagian besar basis data NoSQL (misalnya, MongoDB).

2.Selain itu, database NoSQL secara umum bekerja lebih cepat daripada saudara-saudara SQL mereka karena kurangnya overhead untuk parsing/optimasi kueri, memeriksa integritas struktur data, dll. Topik membandingkan database relasional dan NoSQL juga cukup luas dan layak artikel terpisah.

3.Secara terpisah yang perlu diperhatikan adalah pengalaman Facebook, yang menggunakan MySQL tanpa pilihan JOIN. Strategi ini memungkinkan mereka untuk menskalakan database dengan lebih mudah, sambil mentransfer beban dari database ke kode, yang, seperti yang akan dijelaskan di bawah, lebih mudah diskalakan daripada database.

Penskalaan Kode

  • Kompleksitas kode penskalaan bergantung pada berapa banyak sumber daya bersama yang dibutuhkan host Anda untuk menjalankan aplikasi Anda. Apakah ini hanya sesi, atau Anda perlu berbagi cache dan file? Either way, hal pertama yang harus dilakukan adalah menjalankan salinan aplikasi pada banyak host dengan lingkungan yang sama.
  • Selanjutnya, Anda perlu mengatur load/request balancing antara host ini. Anda dapat melakukannya di TCP (HAProxy), HTTP (nginx) atau DNS.
  • Langkah selanjutnya, kata Gearheart, adalah membuat file statis, cache, dan sesi aplikasi web tersedia di setiap host. Untuk sesi, Anda dapat menggunakan server yang bekerja melalui jaringan (misalnya, Memcached). Sebagai server cache, masuk akal untuk menggunakan Memcached yang sama, tetapi pada host yang berbeda, tentu saja.
  • File statis dapat dipasang dari beberapa penyimpanan file bersama melalui NFS/CIFS atau menggunakan FS terdistribusi (HDFS, GlusterFS, Ceph).

Hal ini juga memungkinkan untuk menyimpan file dalam database (misalnya, Mongo GridFS), sehingga memecahkan masalah ketersediaan dan skalabilitas (dengan mempertimbangkan bahwa untuk masalah skalabilitas database NoSQL diselesaikan dengan sharding).

Secara terpisah perlu dicatat, masalah penyebaran ke beberapa host. Bagaimana memastikan bahwa pengguna dengan mengklik "Perbarui" tidak melihat versi aplikasi yang berbeda? Solusi paling sederhana, menurut saya, adalah mengecualikan dari penyeimbang beban konfigurasi (server web) host yang tidak diperbarui, dan mengaktifkannya secara berurutan saat pembaruan dilakukan. Anda juga dapat mengikat pengguna ke host tertentu dengan cookie atau IP. Jika pembaruan memerlukan perubahan signifikan pada database, cara termudah adalah menutup proyek untuk sementara.