Untuk situs web yang perlu sangat skalabel, seperti jejaring sosial seperti facebook, apa cara terbaik untuk mendesain situs web?
Haruskah saya memiliki layanan web yang diminta situs untuk mendapatkan data yang dibutuhkan?
atau
- Haruskah situs meminta basis data secara langsung? (dapat dilakukan dengan menggunakan konstruksi bahasa bawaan untuk mengisi tabel secara otomatis dll).
Saya akan berpikir layanan web adalah desain yang lebih baik karena memberikan akses data terpusat dan hal-hal seperti caching dan sejenisnya menjadi lebih mudah untuk dikendalikan, tetapi apa yang dipikirkan orang lain?
design
architecture
websites
scalability
Daniel
sumber
sumber
Jawaban:
Wow, ini adalah pertanyaan sederhana, yang berisi berbagai kemungkinan jawaban. Bagian yang lebih eksplisit dari pertanyaan Anda menanyakan apakah lebih mudah untuk berinteraksi dengan basis data Anda secara langsung atau melalui layanan web. Jawabannya sederhana: query database secara langsung. Pergi melalui layanan web menambahkan sejumlah latensi yang sama sekali tidak perlu untuk kode yang beroperasi di belakang firewall (pada umumnya). Layanan web misalnya memerlukan beberapa komponen untuk menerima permintaan, deserialize itu, permintaan DB, cerita berseri tanggapan dan mengembalikannya. Jadi, jika kode Anda semuanya beroperasi di belakang firewall, selamatkan diri Anda dari masalah dan minta saja DB secara langsung.
Namun membuat situs web scalable jauh melampaui pertanyaan yang awalnya Anda ajukan. Jadi maafkan saya jika saya menggunakan garis singgung di sini, tetapi saya pikir ini mungkin berguna mengingat Anda menyebutkan Facebook secara khusus.
Saya akan merekomendasikan Anda membaca tentang pekerjaan dan alat yang dibangun oleh Brad Fitzpatrick (pendiri LiveJournal dan sekarang di Google). Ketika saya bekerja dengannya di Six Apart, berikut adalah beberapa hal yang saya pelajari darinya, dan tentang arsitektur LiveJournal yang membuatnya sangat terukur.
Gunakan tabel database sempit sebagai lawan dari yang luas . Yang menarik tentang ini adalah mempelajari apa yang memotivasi arsitektur ini, yang menciptakan sistem yang mudah dan cepatditingkatkan. Jika Anda menggunakan tabel lebar, atau tabel di mana setiap bidang atau properti adalah kolom dalam tabel, ketika tiba saatnya untuk memutakhirkan skema database, misalnya menambahkan kolom baru, maka sistem akan perlu mengunci tabel sementara skema perubahan diterapkan. Ketika beroperasi pada skala ini berarti perubahan sederhana ke skema database dapat mengakibatkan pemadaman database yang besar. Yang jelas menyebalkan. Sebuah tabel sempit di sisi lain hanya menyimpan setiap properti individu yang terkait dengan objek sebagai satu baris dalam database. Oleh karena itu ketika Anda ingin menambahkan kolom baru ke database yang perlu Anda lakukan adalah INSERT rekaman ke dalam tabel, yang merupakan operasi non-penguncian. Ok, itu sedikit latar belakang, mari kita lihat bagaimana model ini diterjemahkan dalam sistem kerja seperti LiveJournal.
Katakanlah Anda ingin memuat 10 entri jurnal terakhir di blog seseorang, dan katakanlah setiap entri jurnal memiliki sepuluh properti. Dalam tata letak tabel lebar klasik, setiap properti akan berkorelasi dengan kolom pada tabel. Seorang pengguna kemudian akan meminta tabel sekali untuk mengambil semua data yang mereka butuhkan. Kueri akan mengembalikan 10 baris dan setiap baris akan memiliki semua data yang mereka butuhkan (misalnya PILIH * DARI entri ORDER DENGAN tanggal BATAS 10). Namun dalam tata letak tabel yang sempit sedikit berbeda. Dalam contoh ini sebenarnya ada dua tabel: tabel pertama (tabel A) menyimpan kriteria sederhana yang ingin dicari, misalnya id entri, id penulis, tanggal entri, dll. Tabel kedua (tabel B) kemudian menyimpan semua properti yang terkait dengan entri. Tabel kedua ini memiliki tiga kolom: entry_id, key dan value. Untuk setiap baris di tabel A, akan ada 10 baris di tabel B (satu baris untuk setiap properti). Oleh karena itu untuk mengambil dan menampilkan sepuluh entri terakhir, Anda perlu 11 pertanyaan. Kueri pertama memberi Anda daftar ID entri, dan kemudian sepuluh kueri berikutnya akan mengambil properti yang terkait dengan masing-masing entri yang dikembalikan dalam kueri pertama.
"Moly suci!" Anda berkata, "bagaimana mungkin ini lebih skalabel ?!" Benar-benar kontra-intuitif, bukan? Dalam skenario pertama kami hanya memiliki satu permintaan basis data, tetapi dalam solusi "lebih skalabel" kedua kami memiliki 11 permintaan basis data. Itu tidak masuk akal. Jawaban atas pertanyaan itu sepenuhnya bergantung pada peluru berikutnya.
Gunakan memcache secara bebas. Jika Anda tidak sadar, memcache adalah sistem caching berbasis jaringan yang terdistribusi, stateless, latensi rendah. Ini digunakan oleh Facebook, Google, Yahoo, dan hampir setiap situs web populer dan terukur di planet ini. Itu diciptakan oleh Brad Fitzpatrick sebagian untuk membantu mengimbangi overhead database yang melekat dalam desain database tabel sempit. Mari kita lihat contoh yang sama seperti yang dibahas di # 1 di atas, tapi kali ini, mari kita kenalkan memcache.
Mari kita mulai ketika pengguna pertama kali mengunjungi halaman dan tidak ada yang ada dalam cache. Anda mulai dengan menanyakan tabel A yang mengembalikan ID dari 10 entri yang ingin Anda tampilkan di halaman. Untuk setiap entri tersebut, Anda kemudian meminta basis data untuk mengambil properti yang terkait dengan entri itu, dan kemudian menggunakan properti tersebut merupakan objek yang dapat berinteraksi dengan kode Anda (misalnya objek). Anda kemudian menyembunyikan objek itu (atau bentuk serial objek itu) dalam memcache.
Saat kedua seseorang memuat halaman yang sama, Anda memulai dengan cara yang sama: dengan menanyakan tabel A untuk daftar ID entri yang akan Anda tampilkan. Untuk setiap entri, Anda pertama-tama pergi ke memcache dan berkata, "apakah Anda memiliki entri #X dalam cache?" Jika ya, maka memcache mengembalikan objek entri kepada Anda. Jika tidak, maka Anda perlu melakukan kueri database lagi untuk mengambil propertinya, merupakan objek dan menyimpannya dalam memcache. Sebagian besar waktu, kedua kalinya seseorang mengunjungi halaman yang sama hanya ada satu permintaan basis data, semua data lain kemudian ditarik langsung dari memcache.
Dalam praktiknya, apa yang akhirnya terjadi pada sebagian besar LiveJournal adalah bahwa sebagian besar data sistem, terutama data yang kurang volatil, di-cache dalam memcache dan permintaan tambahan ke database yang diperlukan untuk mendukung skema tabel sempit semuanya sudah sepenuhnya diimbangi.
Desain ini membuat penyelesaian masalah yang terkait dengan merakit daftar posting yang terkait dengan semua teman Anda ke dalam aliran, atau "dinding", jauh lebih mudah.
Selanjutnya, pertimbangkan mempartisi basis data Anda. Model yang dibahas di atas memunculkan masalah lain, dan itu adalah tabel sempit Anda akan cenderung sangat besar / panjang. Dan semakin banyak baris tabel tersebut semakin sulit tugas administrasi lainnya. Untuk mengimbangi ini, mungkin masuk akal untuk mengelola ukuran tabel Anda dengan mempartisi tabel di suatu tempat, sehingga kelompok pengguna dilayani oleh satu database, dan sekelompok pengguna lain dilayani oleh database terpisah. Ini mendistribusikan beban pada database dan membuat kueri tetap efisien.
Akhirnya, Anda membutuhkan indeks yang mengagumkan. Kecepatan pertanyaan Anda akan sangat tergantung pada seberapa baik tabel indeks Anda. Saya tidak akan menghabiskan terlalu banyak waktu untuk membahas apa itu indeks, kecuali untuk mengatakan bahwa itu sangat mirip dengan sistem katalog kartu raksasa untuk membuat mencari jarum di tumpukan jerami lebih efisien. Jika Anda menggunakan mysql maka saya sarankan menyalakan log permintaan lambat untuk memantau permintaan yang membutuhkan waktu lama untuk dipenuhi. Ketika kueri muncul di radar Anda (misalnya karena lambat), lalu cari tahu indeks apa yang perlu Anda tambahkan ke tabel untuk mempercepatnya.
"Terima kasih untuk semua latar belakang yang luar biasa ini, tetapi kudus, itu banyak kode yang harus saya tulis."
Belum tentu. Banyak perpustakaan telah ditulis yang membuat antarmuka dengan memcache sangat mudah. Masih perpustakaan lain telah mengodifikasi seluruh proses yang dijelaskan di atas; Data :: ObjectDriver di Perl hanyalah perpustakaan seperti itu. Sedangkan untuk bahasa lain, Anda perlu melakukan riset sendiri.
Saya harap Anda menemukan jawaban ini bermanfaat. Apa yang saya temukan lebih sering daripada tidak adalah bahwa skalabilitas suatu sistem sering turun semakin sedikit ke kode, dan semakin banyak ke penyimpanan data yang sehat dan strategi manajemen / desain teknis.
sumber
Mengukur.
Kebijakan yang buruk.
Diperlukan pengukuran aktual.
sumber
Skalabilitas bukanlah fungsi dari strategi implementasi spesifik tetapi lebih pada mendesain arsitektur aplikasi Anda sehingga lapisan akses data dapat berkembang tanpa adanya refactoring dan penulisan ulang yang masif.
Teknik penting dalam membangun sistem yang berskala adalah untuk memahami persyaratan akses data tingkat tinggi Anda dan membuat kontrak antarmuka di sekitarnya. Misalnya, Anda mungkin memiliki persyaratan untuk mendapatkan satu pengguna atau membuat daftar 50 foto yang diposting paling baru oleh pengguna mana pun .
Anda tidak perlu membutuhkan saluran jaringan antara logika bisnis aplikasi Anda dan logika akses data; tipuan pemanggilan metode dengan satu metode per operasi logis akan baik untuk memulai.
Jadikan metode akses data ini sesederhana mungkin untuk memulai. Sangat sulit untuk memprediksi di mana masalah kinerja akan terjadi sampai aplikasi Anda melayani pola penggunaan nyata dan Anda mengumpulkan data tentang di mana Anda memiliki kemacetan.
Dengan memiliki antarmuka akses data yang terdefinisi dengan baik, Anda dapat mengembangkan implementasi akses data Anda tanpa membuat perubahan luas pada seluruh aplikasi Anda. Anda juga dapat memutuskan untuk beralih ke arsitektur layanan web secara transparan ke logika bisnis Anda.
Banyak jawaban di atas memberikan saran yang bagus tentang bagaimana untuk melanjutkan setelah Anda menemukan hambatan kinerja Anda, tetapi jika Anda menerapkannya terlalu dini, Anda dapat menjadi sembelih oleh kompleksitas kode Anda sebelum Anda tahu apakah kompleksitas itu bahkan diperlukan.
sumber
Kembangkan situs web sederhana dan biarkan mencapai tingkat lalu lintas tertentu. Sepanjang garis Anda akan belajar cara membuat situs web scalable.
Sampai Anda menghadapi masalah, Anda tidak dapat memikirkan solusinya .
Percayalah begitu Anda memiliki situs bergulir dan menghadapi persyaratan penskalaan, Anda pasti akan tahu bagaimana melakukannya. :-)
sumber
Sudah menjadi kebijakan umum bahwa aplikasi web harus dirancang dengan tiga tingkatan secara default - web (presentasi), aplikasi, dan lapisan basis data. Divisi ini disebabkan oleh persyaratan yang berbeda pada setiap lapisan - biasanya akses / penyimpanan disk berkualitas untuk basis data, CPU / Memori tinggi pada lapisan aplikasi, dan bandwidth / memori / dispersi geografis yang tinggi pada lapisan web. Lapisan aplikasi / basis data sering digabung menjadi satu sampai beberapa waktu kemudian dalam siklus hidup aplikasi, karena mesin basis data sering cenderung menjadi server masif yang dapat dibangun untuk menangani beban aplikasi awal juga.
Namun, jumlah lapisan tertentu dan arsitektur yang sesuai untuk aplikasi Anda tidak harus cocok dengan ini atau model lainnya.
Rencanakan untuk perlu mengukur dan memantau semua aktivitas di sistem Anda. Mulai dari desain dua atau tiga tingkat, dan fokus pada bagian-bagiannya yang, saat Anda sedang membangunnya, tampaknya akan membutuhkan sumber daya paling banyak. Biarkan aplikasi yang berjalan memandu desain Anda, pada level ini. Semakin banyak informasi yang Anda kumpulkan, dan semakin akurat dan terperinci, semakin baik keputusan yang dapat Anda ambil tentang mendesain aplikasi seiring pertumbuhannya.
Pilih kerangka kerja dan arsitektur yang nantinya, memungkinkan Anda untuk berputar / membuat perubahan yang diperlukan secepat dan tanpa rasa sakit mungkin. Bahkan jika akses data / penyimpanan / pemrosesan dan pemrosesan aplikasi Anda dilakukan di executable yang sama, jika mereka difaktorkan dengan benar, tidak akan sulit untuk membagi mereka menjadi dua lapisan di kemudian hari, misalnya.
sumber
Langkah tambahan apa pun dalam menghubungkan ke database, hanyalah overhead. Misalnya, antara
UI -> Business Facade -> Business -> Data Access -> Database
danUI -> Database
, pendekatan kedua lebih cepat. Namun, semakin banyak langkah yang Anda hapus, semakin tidak dapat dipelihara sistem Anda dan semakin banyak duplikasi muncul. Bayangkan menulis kode yang diperlukan untuk mengambil daftar teman di profil, halaman rumah, halaman manajemen iblis, dll.Jadi, Anda harus membuat keseimbangan di sini antara kinerja yang lebih tinggi (yang tentu saja secara langsung mempengaruhi skalabilitas yang lebih tinggi) dan rawatan yang lebih baik .
Tapi, jangan terbatas pada topik koneksi database ketika Anda berpikir tentang membuat situs web yang sangat skalabel. Pertimbangkan juga barang-barang ini:
sumber
Ada dua cara utama untuk meningkatkan, memperbesar dan memperkecil.
Peningkatan adalah mengganti mesin dengan yang lebih kuat. Menskalakan berarti menambahkan mesin lain untuk melakukan pekerjaan yang dilakukan mesin yang ada.
Setiap situs web lalu lintas tinggi memerlukan kemampuan untuk meningkatkan skala. Arsitektur perangkat lunak perlu dilakukan sedemikian rupa sehingga lebih banyak mesin dapat ditambahkan dengan mudah, semakin sibuk situs.
Biasanya ini berarti memecah aplikasi menjadi tingkatan sehingga seseorang dapat plug and play lebih banyak server di setiap tingkatan
Saya akan melakukan opsi 1, memiliki layanan daripada melakukannya secara langsung. Anda hanya dapat mengukur aplikasi monolitik sejauh ini.
sumber
Kembangkan situs Anda menggunakan platform teknologi yang memiliki dukungan sepenuhnya terintegrasi untuk cloud.
sumber