


Dalam pangkalan data teragih moden, keperluan untuk menskalakan data secara mendatar telah membawa kepada penggunaan meluas sharding. Walaupun sharding membantu mengurus set data yang besar merentas berbilang nod, ia memperkenalkan cabaran, terutamanya apabila melakukan menyertai dan memastikan pengambilan data yang cekap. Dalam artikel ini, kami meneroka pelbagai konsep dan teknik yang menangani cabaran ini, terutamanya memfokuskan pada sambungan siaran, penjajaran kunci pecahan dan enjin pertanyaan teragih seperti Presto dan BigQuery. Selain itu, kami menunjukkan cara menangani masalah ini dalam aplikasi dunia nyata menggunakan Node.js dan Express.
Contoh Perkongsian dalam Node.js dengan Express.js
Begini cara anda boleh melaksanakan sharding dalam PostgreSQL menggunakan Node.js dan Express.js.
Contoh Perkongsian PostgreSQL
Menggunakan Citus atau serpihan logik manual dengan Node.js:
Contoh dengan Perkongsian Logik
Sediakan Jadual untuk Serpihan:
Gunakan jadual untuk serpihan (data_pengguna pada shard1 dan data_pengguna pada shard2).Buat Express.js API:
Edarkan pertanyaan berdasarkan kunci serpihan (cth., user_id).
const express = require('express'); const { Pool } = require('pg'); const poolShard1 = new Pool({ connectionString: 'postgresql://localhost/shard1' }); const poolShard2 = new Pool({ connectionString: 'postgresql://localhost/shard2' }); const app = express(); app.use(express.json()); const getShardPool = (userId) => (userId % 2 === 0 ? poolShard1 : poolShard2); app.post('/user', async (req, res) => { const { userId, data } = req.body; const pool = getShardPool(userId); try { await pool.query('INSERT INTO user_data (user_id, data) VALUES (, )', [userId, data]); res.status(200).send('User added successfully'); } catch (err) { console.error(err); res.status(500).send('Error inserting user'); } }); app.get('/user/:userId', async (req, res) => { const userId = parseInt(req.params.userId, 10); const pool = getShardPool(userId); try { const result = await pool.query('SELECT * FROM user_data WHERE user_id = ', [userId]); res.status(200).json(result.rows); } catch (err) { console.error(err); res.status(500).send('Error retrieving user'); } }); app.listen(3000, () => console.log('Server running on port 3000'));
1. Perkongsian dalam Pangkalan Data Teragih
Sharding ialah proses membahagikan data secara mendatar merentas berbilang contoh pangkalan data, atau serpihan, untuk meningkatkan prestasi, kebolehskalaan dan ketersediaan. Perkongsian selalunya diperlukan apabila satu tika pangkalan data tidak dapat mengendalikan jumlah data atau trafik.
Strategi Perkongsian:
- Perkongsian berasaskan Julat: Data diedarkan merentas serpihan berdasarkan julat kunci, cth., membahagikan pesanan mengikut tarikh_pesanan.
- Perkongsian berasaskan cincang: Data dicincang oleh kunci serpihan (cth., id_pengguna) untuk mengagihkan data secara sama rata merentas serpihan.
- Perkongsian berasaskan direktori: Direktori pusat menjejaki tempat data berada dalam sistem.
Walau bagaimanapun, apabila jadual berkaitan dipecahkan pada kekunci yang berbeza, atau apabila jadual memerlukan penyambungan dengan jadual lain merentas berbilang serpihan, prestasi boleh merosot kerana keperluan untuk operasi pengumpul-serakan. Di sinilah pemahaman siaran bergabung dan penjajaran kunci serpihan menjadi penting.
2. Cabaran dengan Gabungan dalam Sistem Berkongsi
Apabila data berada dalam serpihan yang berbeza, melakukan cantuman antara serpihan tersebut boleh menjadi rumit. Berikut ialah pecahan cabaran biasa:
1. Shard Key Misalignment:
Dalam banyak sistem, jadual dipecahkan pada kekunci yang berbeza. Contohnya:
- Jadual pengguna mungkin dipecahkan oleh user_id.
- Jadual pesanan mungkin dipecahkan mengikut wilayah.
Apabila melakukan gabungan (cth., orders.user_id = users.user_id), sistem perlu mengambil data daripada berbilang serpihan kerana rekod yang berkaitan mungkin tidak berada dalam serpihan yang sama.
2. Scatter-Gather Joins:
Dalam gabungan scatter-gather, sistem mesti:
- Hantar permintaan kepada semua serpihan yang menyimpan data yang berkaitan.
- Agregat hasil merentas serpihan. Ini boleh merendahkan prestasi dengan ketara, terutamanya apabila data tersebar pada banyak serpihan.
3. Gabungan Siaran:
Satu sambungan siaran berlaku apabila salah satu jadual yang dicantumkan cukup kecil untuk disiarkan ke semua serpihan. Dalam kes ini:
- Jadual kecil (mis., pengguna) direplikasi merentasi semua nod di mana jadual yang lebih besar dan berpecah (mis., pesanan) berada.
- Setiap nod kemudiannya boleh menyertai data tempatannya dengan data yang disiarkan, mengelakkan keperluan untuk komunikasi silang serpihan.
3. Menggunakan Enjin Pertanyaan Teragih untuk Data Berkongsi
Enjin pertanyaan teragih seperti Presto dan BigQuery direka bentuk untuk mengendalikan data berpecah dan menyertai pertanyaan dengan cekap merentas sistem teragih.
Presto/Trino:
Presto ialah enjin pertanyaan SQL teragih yang direka untuk menanyakan set data yang besar merentas sumber data heterogen (cth., pangkalan data hubungan, pangkalan data NoSQL, tasik data). Presto melakukan gabungan merentas sumber data yang diedarkan dan boleh mengoptimumkan pertanyaan dengan meminimumkan pergerakan data antara nod.
Contoh Kes Penggunaan: Menyertai Data Berkongsi dengan Presto
Dalam senario di mana pesanan dipecahkan mengikut wilayah dan pengguna dipecahkan oleh user_id, Presto boleh melakukan gabungan merentas serpihan yang berbeza menggunakan model pelaksanaan yang diedarkan.
Pertanyaan:
const express = require('express'); const { Pool } = require('pg'); const poolShard1 = new Pool({ connectionString: 'postgresql://localhost/shard1' }); const poolShard2 = new Pool({ connectionString: 'postgresql://localhost/shard2' }); const app = express(); app.use(express.json()); const getShardPool = (userId) => (userId % 2 === 0 ? poolShard1 : poolShard2); app.post('/user', async (req, res) => { const { userId, data } = req.body; const pool = getShardPool(userId); try { await pool.query('INSERT INTO user_data (user_id, data) VALUES (, )', [userId, data]); res.status(200).send('User added successfully'); } catch (err) { console.error(err); res.status(500).send('Error inserting user'); } }); app.get('/user/:userId', async (req, res) => { const userId = parseInt(req.params.userId, 10); const pool = getShardPool(userId); try { const result = await pool.query('SELECT * FROM user_data WHERE user_id = ', [userId]); res.status(200).json(result.rows); } catch (err) { console.error(err); res.status(500).send('Error retrieving user'); } }); app.listen(3000, () => console.log('Server running on port 3000'));
Presto akan:
- Gunakan scatter-gather untuk mengambil rekod pengguna yang berkaitan.
- Sertai data merentas nod.
Google BigQuery:
BigQuery ialah gudang data tanpa pelayan yang diurus sepenuhnya, yang cemerlang dalam menjalankan pertanyaan analisis berskala besar. Walaupun BigQuery mengasingkan butiran sharding, ia secara automatik membahagikan dan mengedarkan data merentas banyak nod untuk pertanyaan yang dioptimumkan. Ia boleh mengendalikan set data yang besar dengan mudah dan amat berkesan untuk pertanyaan analitikal yang mana data dibahagikan mengikut masa atau dimensi lain.
Contoh Kes Penggunaan: Menyertai Jadual Sharded dalam BigQuery
const express = require('express'); const { Pool } = require('pg'); const poolShard1 = new Pool({ connectionString: 'postgresql://localhost/shard1' }); const poolShard2 = new Pool({ connectionString: 'postgresql://localhost/shard2' }); const app = express(); app.use(express.json()); const getShardPool = (userId) => (userId % 2 === 0 ? poolShard1 : poolShard2); app.post('/user', async (req, res) => { const { userId, data } = req.body; const pool = getShardPool(userId); try { await pool.query('INSERT INTO user_data (user_id, data) VALUES (, )', [userId, data]); res.status(200).send('User added successfully'); } catch (err) { console.error(err); res.status(500).send('Error inserting user'); } }); app.get('/user/:userId', async (req, res) => { const userId = parseInt(req.params.userId, 10); const pool = getShardPool(userId); try { const result = await pool.query('SELECT * FROM user_data WHERE user_id = ', [userId]); res.status(200).json(result.rows); } catch (err) { console.error(err); res.status(500).send('Error retrieving user'); } }); app.listen(3000, () => console.log('Server running on port 3000'));
BigQuery secara automatik mengendalikan pembahagian dan pengedaran, meminimumkan keperluan untuk pembahagian manual.
4. Mengendalikan Penyelewengan Kunci Shard dalam Aplikasi Node.js
Apabila berurusan dengan data yang dipecahkan dalam aplikasi Node.js, isu seperti kekunci serpihan yang tidak sejajar dan keperluan untuk penyatuan-pengumpulan sering timbul. Begini cara anda boleh mengharungi cabaran ini menggunakan Node.js dan Express.
Mengendalikan Penyertaan Siaran dalam Node.js
Jika gabungan memerlukan penyiaran jadual kecil (mis., pengguna) merentas semua serpihan, anda boleh melaksanakan gabungan dalam lapisan aplikasi dengan mengambil jadual kecil sekali dan menggunakannya untuk bergabung dengan data daripada jadual berpecah.
SELECT o.order_id, u.user_name FROM orders o JOIN users u ON o.user_id = u.user_id;
Mengendalikan Pertanyaan Scatter-Gather dalam Node.js
Untuk pertanyaan yang melibatkan cantuman scatter-gather (cth., apabila kekunci shard tidak sejajar), anda perlu menanyakan semua serpihan dan mengagregatkan hasil dalam lapisan aplikasi anda.
SELECT o.order_id, u.user_name FROM `project.dataset.orders` o JOIN `project.dataset.users` u ON o.user_id = u.user_id WHERE o.order_date BETWEEN '2024-01-01' AND '2024-12-31';
5. Amalan Terbaik untuk Pengoptimuman Pertanyaan dengan Data Berkongsi
Apabila berurusan dengan data yang dipecahkan dan melakukan gabungan, pertimbangkan amalan terbaik berikut:
Jajarkan Kekunci Shard: Apabila boleh, pastikan jadual berkaitan menggunakan kekunci shard yang sama. Ini meminimumkan keperluan untuk cantuman rentas serpihan dan meningkatkan prestasi.
Nyahnormalisasi: Dalam senario yang kerap disertai, pertimbangkan untuk menyahnormalkan data anda. Sebagai contoh, anda boleh menyimpan maklumat pengguna terus dalam jadual siaran, mengurangkan keperluan untuk menyertai.
Gunakan Broadcast Joins untuk Meja Kecil: Jika salah satu jadual cukup kecil, siarkan ke semua nod untuk mengelakkan pertanyaan serakan-kumpul.
Data Pra-Sertai: Untuk data yang kerap diakses, pertimbangkan untuk pra-menyertai dan menyimpan hasil dalam paparan nyata atau cache.
Memanfaatkan Enjin Pertanyaan Teragih: Untuk pertanyaan analitikal yang kompleks, gunakan sistem seperti Presto atau BigQuery yang mengendalikan gabungan dan pengoptimuman yang diedarkan secara automatik.
6. Amalan Terbaik untuk Penomboran Berasaskan Kursor dengan Data Berkongsi
Dalam sistem teragih dengan sharding sedemikian, penomboran berasaskan kursor perlu dikendalikan dengan berhati-hati, terutamanya kerana data tersebar merentasi berbilang serpihan. Kuncinya ialah:
- Pisah pertanyaan: Tanya setiap serpihan secara berasingan untuk data yang berkaitan.
- Kendalikan penomboran dalam ketulan: Tentukan cara membuat penomboran merentas data serpihan (sama ada pada siaran atau pengguna), dan kumpulkan hasil yang berkaitan.
- Sertai di peringkat aplikasi: Ambil hasil daripada setiap serpihan, sertai data dalam ingatan, dan kemudian gunakan logik kursor untuk halaman seterusnya.
Mari kita lihat bagaimana kita boleh melaksanakan perkara ini dengan Node.js dan Express, dengan mengambil kira bahawa data berada pada serpihan yang berbeza dan memerlukan gabungan pasca ambil pada peringkat aplikasi.
Cara Mengendalikan Penomboran dan Cantuman dengan Jadual Sharded
Anggap kita ada:
- siaran jadual dipecahkan oleh user_id.
- pengguna jadual dipecahkan oleh user_id.
Kami ingin mendapatkan semula siaran penomboran untuk pengguna tertentu, tetapi memandangkan pengguna dan siaran berada pada serpihan yang berbeza, kami perlu membahagikan pertanyaan, mengendalikan penomboran dan kemudian melakukan gabungan pada peringkat aplikasi.
Pendekatan:
-
Pertanyakan Serpihan Berkaitan:
- Mula-mula, anda perlu menanyakan jadual siaran merentas serpihan untuk mengambil siaran.
- Selepas mengambil siaran yang berkaitan, gunakan user_id daripada siaran untuk menanyakan jadual pengguna (sekali lagi, merentas serpihan).
-
Strategi Penomboran:
- Penomboran pada siaran: Anda boleh menggunakan created_at, post_id atau medan unik lain untuk menomborkan jadual siaran.
- Penomboran pada pengguna: Anda mungkin perlu mengambil data pengguna secara berasingan atau menggunakan user_id sebagai kursor untuk membuat penomboran melalui pengguna.
-
Sertai Peringkat Aplikasi:
- Selepas mendapatkan semula data daripada serpihan yang berkaitan (untuk kedua-dua siaran dan pengguna), sertai mereka di peringkat aplikasi.
-
Mengendalikan Kursor:
- Selepas mengambil halaman pertama, gunakan create_at terakhir atau post_id (daripada siaran) sebagai kursor untuk pertanyaan seterusnya.
Contoh Pelaksanaan
1. Siaran Pertanyaan Merentasi Serpihan
Di sini kami akan melaksanakan pertanyaan merentas serpihan siaran yang berbeza, menapis menggunakan kursor (cth., created_at atau post_id).
2. Pertanyaan Pengguna Merentasi Serpihan Menggunakan Data Pos
Sebaik sahaja kami mempunyai post_id dan user_id yang berkaitan daripada pertanyaan pertama, kami akan mengambil data pengguna daripada serpihan yang berkaitan.
const express = require('express'); const { Pool } = require('pg'); const poolShard1 = new Pool({ connectionString: 'postgresql://localhost/shard1' }); const poolShard2 = new Pool({ connectionString: 'postgresql://localhost/shard2' }); const app = express(); app.use(express.json()); const getShardPool = (userId) => (userId % 2 === 0 ? poolShard1 : poolShard2); app.post('/user', async (req, res) => { const { userId, data } = req.body; const pool = getShardPool(userId); try { await pool.query('INSERT INTO user_data (user_id, data) VALUES (, )', [userId, data]); res.status(200).send('User added successfully'); } catch (err) { console.error(err); res.status(500).send('Error inserting user'); } }); app.get('/user/:userId', async (req, res) => { const userId = parseInt(req.params.userId, 10); const pool = getShardPool(userId); try { const result = await pool.query('SELECT * FROM user_data WHERE user_id = ', [userId]); res.status(200).json(result.rows); } catch (err) { console.error(err); res.status(500).send('Error retrieving user'); } }); app.listen(3000, () => console.log('Server running on port 3000'));
Butiran Utama:
- Penomboran pada siaran: Kursor adalah berdasarkan medan create_at atau medan unik lain dalam siaran, yang digunakan untuk membuat penomboran melalui hasil.
- Query Shards Independent: Memandangkan siaran dan pengguna dipecahkan pada kunci yang berbeza, kami menanyakan setiap shard secara bebas, mengumpulkan data daripada semua shards sebelum melakukan gabungan pada peringkat aplikasi.
- Pengendalian Kursor: Selepas mendapatkan semula keputusan, kami menggunakan terakhir dicipta_pada (atau post_id) daripada siaran untuk menjana kursor untuk halaman seterusnya.
- Sertai di Peringkat Aplikasi: Selepas mengambil data daripada serpihan yang berkaitan, kami menyertai siaran dengan data pengguna berdasarkan user_id dalam ingatan.
Kesimpulan
Menguruskan data berpecah dalam sistem yang diedarkan memberikan cabaran yang unik, terutamanya dalam hal melaksanakan gabungan yang cekap. Memahami teknik seperti sambungan siaran, gabungan scatter-gather dan memanfaatkan enjin pertanyaan teragih boleh meningkatkan prestasi pertanyaan dengan ketara. Selain itu, dalam pertanyaan peringkat aplikasi, adalah penting untuk mempertimbangkan penjajaran kunci beling, nyahnormalisasi dan strategi pertanyaan yang dioptimumkan. Dengan mengikuti amalan terbaik ini dan menggunakan alatan yang betul, pembangun boleh memastikan bahawa aplikasi mereka mengendalikan data berpecah dengan berkesan dan mengekalkan prestasi pada skala.
Atas ialah kandungan terperinci Mengendalikan Data Berkongsi dalam Sistem Teragih: Penyelaman Mendalam ke dalam Gabungan, Penyiaran dan Pengoptimuman Pertanyaan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Trend terkini dalam JavaScript termasuk kebangkitan TypeScript, populariti kerangka dan perpustakaan moden, dan penerapan webassembly. Prospek masa depan meliputi sistem jenis yang lebih berkuasa, pembangunan JavaScript, pengembangan kecerdasan buatan dan pembelajaran mesin, dan potensi pengkomputeran IoT dan kelebihan.

JavaScript adalah asas kepada pembangunan web moden, dan fungsi utamanya termasuk pengaturcaraan yang didorong oleh peristiwa, penjanaan kandungan dinamik dan pengaturcaraan tak segerak. 1) Pengaturcaraan yang didorong oleh peristiwa membolehkan laman web berubah secara dinamik mengikut operasi pengguna. 2) Penjanaan kandungan dinamik membolehkan kandungan halaman diselaraskan mengikut syarat. 3) Pengaturcaraan Asynchronous memastikan bahawa antara muka pengguna tidak disekat. JavaScript digunakan secara meluas dalam interaksi web, aplikasi satu halaman dan pembangunan sisi pelayan, sangat meningkatkan fleksibiliti pengalaman pengguna dan pembangunan silang platform.

Python lebih sesuai untuk sains data dan pembelajaran mesin, manakala JavaScript lebih sesuai untuk pembangunan front-end dan penuh. 1. Python terkenal dengan sintaks ringkas dan ekosistem perpustakaan yang kaya, dan sesuai untuk analisis data dan pembangunan web. 2. JavaScript adalah teras pembangunan front-end. Node.js menyokong pengaturcaraan sisi pelayan dan sesuai untuk pembangunan stack penuh.

JavaScript tidak memerlukan pemasangan kerana ia sudah dibina dalam pelayar moden. Anda hanya memerlukan editor teks dan penyemak imbas untuk memulakan. 1) Dalam persekitaran penyemak imbas, jalankan dengan memasukkan fail HTML melalui tag. 2) Dalam persekitaran Node.js, selepas memuat turun dan memasang node.js, jalankan fail JavaScript melalui baris arahan.

Cara Menghantar Pemberitahuan Tugas di Quartz terlebih dahulu Apabila menggunakan pemasa kuarza untuk menjadualkan tugas, masa pelaksanaan tugas ditetapkan oleh ekspresi cron. Sekarang ...

Cara mendapatkan parameter fungsi pada rantaian prototaip dalam JavaScript dalam pengaturcaraan JavaScript, pemahaman dan memanipulasi parameter fungsi pada rantaian prototaip adalah tugas yang biasa dan penting ...

Analisis sebab mengapa kegagalan anjakan gaya dinamik menggunakan vue.js dalam pandangan web applet weChat menggunakan vue.js ...

Bagaimana untuk membuat permintaan serentak untuk pelbagai pautan dan hakim mengikut urutan untuk mengembalikan hasil? Dalam skrip Tampermonkey, kita sering perlu menggunakan pelbagai rantai ...


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

SublimeText3 Linux versi baharu
SublimeText3 Linux versi terkini

MantisBT
Mantis ialah alat pengesan kecacatan berasaskan web yang mudah digunakan yang direka untuk membantu dalam pengesanan kecacatan produk. Ia memerlukan PHP, MySQL dan pelayan web. Lihat perkhidmatan demo dan pengehosan kami.

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Pelayar Peperiksaan Selamat
Pelayar Peperiksaan Selamat ialah persekitaran pelayar selamat untuk mengambil peperiksaan dalam talian dengan selamat. Perisian ini menukar mana-mana komputer menjadi stesen kerja yang selamat. Ia mengawal akses kepada mana-mana utiliti dan menghalang pelajar daripada menggunakan sumber yang tidak dibenarkan.