Berinteraksi Dengan Data Menggunakan Banyak Database / Server


18

Semua proyek yang harus saya tangani sejauh ini hanya membutuhkan satu database pada satu server. Saya tertarik untuk mempelajari lebih lanjut tentang bagaimana proyek-proyek yang perlu skala pindah ke beberapa database dan / atau server untuk membantu mengelola beban. Saya menyadari Skalabilitas Tinggi , tetapi saya sangat tertarik pada beberapa contoh kode atau sumber daya tambahan di mana saya bisa membaca lebih lanjut tentang masalah ini.

Contohnya:

  • Bagaimana gabungan dibangun antara dua tabel pada banyak basis data? (Contoh kode di sini akan sangat membantu).
  • Apakah ada strategi khusus untuk melacak tabel mana di basis data mana?
  • Apakah kode aplikasi perlu tahu bahwa satu atau lebih database tersebar di beberapa server? Jika tidak, pada tingkat apa permintaan difilter?
  • Kapan waktu untuk bergerak melampaui pengaturan 1 database / 1 server? Seberapa umum perlu melakukan ini?

Pertanyaan ini mungkin lebih baik dijawab pada Administrator Database . Tidak ada yang salah dengan itu di sini, jadi aku hanya akan memeriksa dengan mod DBA. Jika cocok di sana, apakah Anda ingin dimigrasikan?
Adam Lear

@AnnaLear - Saya kira itu tergantung pada jawaban. Pada titik ini, saya lebih tertarik pada sisi aplikasi masalah ini, jadi untuk sekarang, saya pikir mungkin lebih baik di sini.
VirtuosiMedia

@AnnaLear ack, setuju dengan OP lalu jika mereka menginginkan kode khusus aplikasi.
jcolebrand

Jawaban:


13

Ok, mari kita jabarkan:

  • Bagaimana gabungan dibangun antara dua tabel pada banyak basis data? (Contoh kode di sini akan sangat membantu).

Ini sangat mudah. Objek SQL memiliki konvensi penamaan satu hingga empat bagian:

Servername.databasename.schemaname.tablename

Jika semua tabel Anda berada di server yang sama pada database yang sama, dengan pemilik / skema yang sama, Anda bisa mengabaikan tiga bagian pertama dan menggunakan apa yang paling sering Anda gunakan untuk:

Select a.*,b.* from 
tableA a inner join 
tableB b on a.col1=b.col1

Jika salah satu tabel Anda berada di database yang berbeda dan keduanya menggunakan skema default untuk database mereka, maka Anda cukup menambahkan database ke tabel kedua:

Select a.*,b.* from 
tableA a inner join 
databaseC..tableB b on a.col1 = b.col1

Jika Anda berada di basis data ketiga yang berbeda dari yang Anda tanyakan, Anda menggunakan kedua nama basis data secara eksplisit:

Select a.*,b.* from 
databaseD..tableA a inner join 
databaseC..tableB b on a.col1 = b.col1

Jika Anda akhirnya menggunakan skema dan / atau pemilik yang berbeda, Anda dapat menambahkannya di:

Select a.*,b.* from 
databaseD.john.tableA a inner join 
databaseC.accounting.tableB b on a.col1 = b.col1

Dan terakhir, jika Anda sangat berhati-hati tentang hal itu dan memiliki alasan yang sangat baik, Anda dapat bergabung dengan tabel (biasanya kecil) di server lain:

Select a.* from 
databaseD.john.TableA a inner join 
ATLANTA.databaseC.accounting.tableB b on a.col1 = b.col1
  • Kapan waktu untuk bergerak melampaui pengaturan 1 database / 1 server? Seberapa umum perlu melakukan ini? Apakah ada strategi khusus untuk melacak tabel mana di basis data mana?

Saya akan menggabungkan keduanya karena mereka pergi bersama. Anda hampir selalu umumnya baik-baik saja untuk memulai dengan asumsi bahwa satu database satu server sudah cukup sampai kendala desain / bisnis / teknis Anda memaksa Anda untuk menggunakan lebih banyak.

Jadi, untuk menjawab pertanyaan kedua Anda terlebih dahulu, karena Anda umumnya memiliki alasan untuk memiliki basis data yang terpisah, itu harus cukup jelas dari mengetahui desain sistem Anda di mana ada sesuatu.

Seperti kapan / mengapa itu perlu untuk bergerak melampaui satu basis data tunggal. Biasanya itu campuran aturan bisnis, politik, dan / atau alasan teknis.

Misalnya, tempat saya bekerja, kami memiliki 16 basis data yang tersebar di 4 server. Kami memiliki MainDB, ImageDB, referencetableDB, HighvolumeTransactionDB, ReportingDB, StagingDB, ProcessingDB, ArchiveDB, FinancialDB. Untuk memberikan beberapa contoh mengapa mereka berbeda:

  • FinancialDB, informasi sensitif
  • Image DB, persyaratan penyimpanan dan pemulihan berbeda yang spesifik
  • ReferenceDB, transaksi rendah, baca tinggi
  • ReportingDB, baca sangat tinggi, perlu dipulihkan / direplikasi ke berbagai lingkungan lain tidak seperti banyak data lainnya
  • StagingDB, tidak ada yang permanen, hanya tempdb yang lebih besar yang kita punya lebih banyak kontrol
  • MainDB, antarmuka dengan semua DB lain tetapi membutuhkan cadangan diferensial jadi ... kami membagi
  • Tabel HighVolumeTransaction, (yang relatif sementara), ke DB mereka sendiri untuk menjaga ukuran wajar cadangan.
  • Arsip, Banyak data yang sama dari Utama dan Pelaporan, tetapi dengan periode retensi yang lebih lama dan kueri yang lebih keras, menggali lebih dalam data. Jika ini masih dikombinasikan dengan Utama / Pelaporan itu akan merusak sistem kami.

Apakah kode aplikasi perlu tahu bahwa satu atau lebih database tersebar di beberapa server? Jika tidak, pada tingkat apa permintaan difilter?

Dalam arti luas, mereka mungkin melakukannya. Minimal mereka perlu tahu server apa yang mereka tunjuk dalam string koneksi database. Memproses, Melaporkan, Utama, dll.

Dari sana, mereka membutuhkan konteks basis data untuk dieksekusi di bawah. Secara umum itu akan menjadi yang paling banyak digunakan untuk aplikasi, bahkan mungkin yang asli dari satu database / satu hari server aplikasi. Anda BISA memiliki aplikasi secara eksplisit beralih konteks database pada setiap panggilan tetapi itu membuatnya sangat sulit untuk menyesuaikan database tanpa mengubah aplikasi.

Pendekatan yang biasa, (atau paling tidak, SAYA biasa), adalah untuk selalu mengakses melalui satu atau mungkin dua basis data utama.

Kemudian buat tampilan ke database lain yang diperlukan dikombinasikan dengan interfacing dengan database melalui prosedur yang tersimpan.

Jadi untuk menggambarkan:

Katakanlah Anda ingin mendapatkan informasi demografis, data penjualan, dan saldo Kredit Klien dan yang tersebar di tiga tabel pada awalnya semuanya di MainDB.

Jadi Anda menulis panggilan dari aplikasi Anda:

Select c.ClientName, c.ClientAddress, s.totalSales,f.CreditBlance from
Clients c join Sales s on c.clientid = s.clientid inner join AccountReceivable f on 
c.clientid=f.clientid where c.clientid = @clientid

Luar biasa. Namun, sekarang kapan pun kami mengubah nama kolom, atau mengganti nama / memindahkan tabel, Anda harus memperbarui kode aplikasi. Jadi alih-alih, kami melakukan dua hal:
Buat Klien, Penjualan, Tampilan Akun yang Dapat Diterima (Anda tidak akan menggunakan Pilih * tetapi saya sedang melakukan demo di sini)

Use MainDB
GO
Create view v_Clients as select * from Clients
Create view v_Sales as select * from Sales
Create view v_AccountReceivable as select * from AccountReceivable
Go

Lalu kami juga akan membuat prosedur tersimpan, spGetClientSalesAR

Create proc spGetClientSalesAR @clientID int
as
Select c.ClientName as ClientName, 
       c.ClientAddress as ClientAddress, 
       s.totalSales as TotalSales, 
       f.CreditBlance as CreditBalance 
from
v_Clients c join v_Sales s 
    on c.clientid = s.clientid 
inner join v_AccountReceivable f 
    on c.clientid=f.clientid 
where c.clientid = @clientid

Dan mintalah panggilan aplikasi Anda itu.

Sekarang selama saya tidak mengubah antarmuka pada proc yang disimpan itu, saya bisa melakukan apa saja yang perlu saya lakukan pada database backend untuk memperbesar atau memperkecil.

Secara ekstrem, saya bahkan bisa membuat MainDB lama saya hanya sekelompok prosedur dan pandangan tersimpan yang tersimpan sehingga di bawah pandangan yang kami buat tampak seperti ini:

Create view v_Clients as select * from ServerX.DatabaseY.dbo.Clients
Create view v_Sales as select * from ServerQ.DatabaseP.dbo.Sales
Create view v_AccountReceivable as select * from ServerJ.DatabaseK.dbo.AccountReceivable

Dan aplikasi Anda tidak akan pernah tahu bedanya, (dengan asumsi pipa cepat dan data yang dipentaskan dengan baik antara lain).

Jelas itu ekstrem dan saya akan berbohong jika saya mengatakan semuanya sudah direncanakan dengan cara ini, tetapi menggunakan prosedur / tampilan yang tersimpan bahkan jika Anda melakukannya saat refactoring akan memungkinkan Anda banyak fleksibilitas ketika aplikasi Anda tumbuh dari satu database / satu server yang sederhana awal.


TetonSig - Terima kasih atas jawabannya. Saya tidak dapat kembali ke pertanyaan tepat waktu untuk memberi Anda hadiah penuh (saya bepergian), tetapi saya menciptakan hadiah baru untuk pertanyaan tersebut dan akan dapat memberikannya kepada Anda dalam 24 jam.
VirtuosiMedia

Wow terima kasih. Saya menghargai itu. Sangat menyenangkan menjawab pertanyaan itu.
TetonSig

5

Cara utama saya menjumpai beberapa server basis data di dunia web (karena pertanyaannya ditandai PHP) adalah pengaturan di mana ada satu basis data 'master' (tulis), dan kemudian satu atau lebih basis data 'budak' (baca) yang direplikasi . Penulisan basis data dilakukan terhadap basis data 'master'. Isi dari basis data itu direplikasi ke server 'budak' dalam waktu dekat. Pertanyaan - terutama laporan intensif - kemudian dijalankan terhadap salah satu database 'budak' untuk memindahkan beban ke server-server itu. Ingat, pengaturan khusus itu terbaik untuk aplikasi yang banyak membaca, tetapi tidak banyak menulis. Ini bukan satu-satunya cara untuk mengatur berbagai hal.


3

Bagaimana gabungan dibangun antara dua tabel pada banyak basis data? (Contoh kode di sini akan sangat membantu).

Mereka tidak. Basis data NoSQL tidak melakukan "bergabung" sama sekali, dan bahkan jika Anda bisa melakukan SQL join di server RDBMS, Anda tidak akan mau jika Anda menghargai kinerja (cf fallacy of distributed computing ).

Apakah ada strategi khusus untuk melacak tabel mana di basis data mana?

Dalam database relasional / SQL, partisi biasanya dilakukan dalam batas-batas satu server / database, menggunakan file yang berbeda ditempatkan pada disk yang berbeda. Hampir secara definisi, solusi penskalaan horizontal berarti bahwa semua database memiliki semua tabel dan Anda memiliki semacam mirroring transaksional, replikasi, atau solusi konsistensi akhir kustom untuk memastikan semua data sampai ke tempat seharusnya.

Jika Anda benar-benar memecah basis data secara logis dan bukan hanya secara fisik, maka pemetaan yang ditentukan dalam DAL atau ORM Anda akan menyatakan tabel mana di dalam basis data mana.

Basis data NoSQL adalah campuran dari solusi partisi. Terkadang "tabel" (atau lebih umum, "koleksi") yang dipartisi. Di lain waktu itu adalah "baris" (atau "dokumen"). Dalam beberapa kasus itu sebenarnya kolom , seperti dalam database berorientasi kolom seperti HBase. Ini sepenuhnya tergantung pada teknologi yang Anda gunakan. Satu hal yang semuanya memiliki kesamaan adalah bahwa mesin itu sendiri melacak semuanya, jadi yang harus Anda lakukan hanyalah meminta dokumen atau baris.

Itu tentu saja dengan asumsi Anda benar-benar memanfaatkan fitur sharding dan tidak hanya membuat banyak database yang berbeda. Jika Anda melakukan yang terakhir, maka Anda sendiri.

Apakah kode aplikasi perlu tahu bahwa satu atau lebih database tersebar di beberapa server? Jika tidak, pada tingkat apa permintaan difilter?

Jika mereka database logis yang berbeda , ya. Jika mereka hanya didistribusikan secara fisik maka tidak - dengan asumsi bahwa baik database spesifik Anda mendukung sharding atau Anda menggunakan solusi load balancing (untuk database SQL). Juga dengan asumsi bahwa semua operasi Anda tidak memiliki kewarganegaraan; jika Anda ingin penskalaan horizontal, Anda harus menyerah ACID.

Kapan waktu untuk bergerak melampaui pengaturan 1 database / 1 server? Seberapa umum perlu melakukan ini?

Saatnya Anda mengoptimalkan semua yang Anda bisa di satu server dan masih tidak bisa memeras kinerja yang cukup karena kendala pada beban I / O. Jika Anda harus mengajukan pertanyaan, maka itu masih terlalu dini.

Perhatikan bahwa masalah kinerja dalam produk RDBMS yang layak (Oracle, SQL Server) lebih sering disebabkan oleh desain yang buruk, pengindeksan yang buruk, permintaan yang buruk, pertikaian kunci, dan sebagainya; produk-produk ini dapat menskalakan secara vertikal hingga tingkat yang konyol. Jadi sekali lagi, Anda harus mempertimbangkan "bergerak melampaui pengaturan database 1/1 server" ketika Anda benar-benar yakin bahwa masalah kinerja Anda disebabkan oleh keterbatasan perangkat keras dan bukan hanya desain / implementasi sub-par.

Atau, saya kira, alasan lain beberapa orang beralih ke database terdistribusi adalah ketika mereka tidak siap untuk membayar banyak (atau apa pun) uang dalam biaya lisensi dan ingin membuang SQL sebagai pilihan sadar untuk memperdagangkan biaya rendah untuk peningkatan kompleksitas aplikasi. Alasan yang benar-benar valid jika Anda adalah startup perangkat lunak tetapi biasanya tidak berlaku di sektor korporasi.


+1 - Saya tidak benar-benar mempertimbangkan NoSQL, tetapi ini sangat membantu. Terima kasih.
VirtuosiMedia

1

Ada tiga jenis utama konfigurasi replikasi untuk database:

  • Tuan-Budak
  • Tuan-Tuan
  • Konsensus

Contoh Master-Slave: MySQL master + MySQL slave, MongoDB

Contoh Master-Master: CouchDB, Cassandra, Riak

Contoh konsensus: ScalienDB

... untuk beberapa nama.

Ini memiliki karakteristik berbeda. Konfigurasi master-slave memungkinkan node slave untuk mengejar master pada tingkat maksimumnya sambil melayani permintaan baca dengan sangat cepat, sementara server master bertanggung jawab atas integritas data. Karena semua penulisan mengarah ke master, tidak pernah ada pertengkaran karena satu penulis yang relatif lambat memblokir banyak pembaca, tetapi di sisi lain, server slave akhirnya konsisten dan Anda tidak mendapatkan jaminan isolasi transaksi bahwa Anda akan memiliki dari hanya membaca dari master. (bacaan lebih lanjut; ACID vs BASE, tingkat isolasi transaksi, replikasi basis data, MVCC / Isolasi: Snapshot, Replikasi Transaksional)

Master-Master selalu mengizinkan penulisan, sehingga Anda akan memiliki banyak otoritas tentang apa yang benar. Ini mungkin atau mungkin bukan masalah, tergantung pada apa yang sedang dilakukan aplikasi Anda, tetapi jika Anda menulis data yang bertentangan, Anda mungkin mendapatkan beberapa hasil saat berikutnya Anda membaca kunci / baris / kolom yang harus Anda gabungkan dengan logika aplikasi dan simpan kembali ke database. (bacaan lebih lanjut: teorema CAP, replikasi CouchDB, replikasi Riak, hashing konsisten, Bitcask & StormDB, Quorum-w / MongoDB pada perpecahan jaringan, menggabungkan strategi resolusi)

Basis data berbasis konsensus dengan replikasi antar node, seperti Scalien akan selalu konsisten pada penulisan, tetapi dengan biaya pertukaran banyak pesan sebelum ACKing menulis. Ini tidak terlalu menjadi masalah jika Anda memiliki ethernet yang cepat dan Anda tidak perlu menulis ke disk sebelum ACKing, yang tidak akan Anda perlukan jika minimal tiga server berada di rak server berbeda dengan catu daya terpisah (satu mati; dua lainnya memastikan mereka telah disimpan pada disk). (bacaan lebih lanjut; PAXOS, PAXOS COMMIT, komitmen dua fase dengan transaksi terdistribusi, komitmen tiga fase)

Bacaan lebih lanjut: (buku: 'Elemen Komputasi Terdistribusi', jam vektor, vektor versi, vektor matriks, jam logis, algoritma toko roti, jam interval pohon, aktor dan pemrograman reaktif dan reaktor, memori transaksional perangkat lunak, transactors, AKKA, Stact, kekeliruan komputasi terdistribusi, protokol gosip, ekstensi protokol gosip anti-entropi Cassandra, tabel hash terdistribusi, makalah tentang penggabungan data dalam pengaturan terdistribusi, arsitektur ZooKeeper, InfoQ-presentasi tentang "protokol asinkron", arsitektur HBase, kertas MapReduce, kertas Amazon Dynamo yang memulai semua barang NoSQL, antrian, pengelompokan ketersediaan tinggi rabbitmq)

Saya harap saya memberikan beberapa pemikiran :). Anda dapat mengikuti saya di twitter @henrikfeldt jika Anda ingin tweet tentang hal ini juga.


1

OK, jadi inilah sudut pandang lain tentang skalabilitas.

Mari kita bahas apa artinya hal-hal menjadi data, apa artinya memiliki perilaku dan apa artinya memiliki logika aplikasi.

Biasanya, ketika seseorang menjelajah ke tanah aplikasi perusahaan dan sejenisnya, orang akan memiliki ide untuk layering. Tentu saja, layering ada di semua tempat di komputer, seperti di tumpukan jaringan (model ISO), atau di grafik (Photoshop), atau di SOA (layanan dapat memanggil saudara kandung atau anak-anak, tetapi tidak pernah orang tua).

Namun, jenis pelapisan khusus yang telah disalahgunakan tanpa memperhatikan apa yang pernah ada pada 'GUI', 'Business Logic Layer' dan kemudian 'Data Access Layer'. Maksud saya, ya, idenya baik pada prinsipnya, seperti komunisme baik pada prinsipnya, tetapi pada kenyataannya tidak.

Mari kita lihat alasannya. Argumen yang akan saya gunakan adalah tentang kopling; poin dari satu lapisan yang menyentuh titik di lapisan lain. Setiap kali Anda mulai membuat aplikasi n-tier alias layered dalam mode default-enterprisey-yang digunakan orang, mereka menciptakan begitu banyak titik kontak di antara lapisan.

Pada intinya, idenya adalah bahwa lapisan dapat dipertukarkan; tetapi tidak! Mengapa? Karena semua sambungan situs panggilan.

Sebagai gantinya, lihat mengapa jaringan dipisahkan! Karena antarmuka adalah byte-stream melalui penunjuk file tunggal yang menunjuk ke soket terbuka! Semua lapisan dalam model ISO seperti apa pola desain yang disebut 'rantai tanggung jawab' untuk orientasi objek! Setiap lapisan membungkus lapisan yang mendasarinya, tanpa mengetahui semantik data dalam lapisan yang mendasarinya.

Ketika satu paket data berjalan menuju sinyal ethernet dan listrik mentah di bagian bawahnya akan terus dibungkus oleh lapisan-lapisan yang hanya mengetahui amplop pesan spesifiknya sendiri, 'kumpulan byte' spesifiknya sendiri yang dapat dikirimkannya; dan tidak ada lagi. Tidak perlu mengubah jalur panggilan tergantung pada isi paket.

Bandingkan ini dengan n-tier di mana Anda harus mengubah jalur panggilan di lapisan aplikasi Anda pada 'panggilan' yang melintasi lapisan Anda dalam perjalanan ke basis data - misalnya, 'pelanggan emas' secara polimorfis merupakan superset dari 'pelanggan normal' dan karena kita menggunakan 'table-per-subclass' kita perlu tahu tentang ini sekarang karena data (entitas) melintasi lapisan-lapisan; baik dalam apa yang disebut 'lapisan logika bisnis' dan di lapisan data yang sebenarnya melakukan penghematan.

Ini tidak scalable atau optimal dari perspektif komputasi.

Mengapa tidak bisa diukur? Karena arsitekturnya digabungkan, dan kemudian Anda masih berada di dalam DB lama yang sama yang Anda coba untuk skala ke banyak node! Tetapi, karena Anda memerlukan ACID untuk ini, itu, dan entitas ketiga (objek data), Anda perlu memilikinya dalam satu basis data yang melakukan transaksi!

Benar, begitu dengan kata-kata kasar keluar dari jalan; apa ada cara lain?

Nah, ada akronim yang dibenci yang disebut 'SOA', yaitu arsitektur berorientasi layanan. Tentu saja, Tomas Erls dunia , akan meminta Anda mengimplementasikan semua layer Anda tetapi dengan XML dan SOAP saja.

Untuk semua alasan di atas, ini adalah cara yang salah, karena Anda akan menggabungkan diri Anda dengan proxy XML seperti halnya Anda akan memasangkan diri Anda ke lapisan aplikasi seperti dijelaskan di atas.

Alih-alih, gunakan pesan dan biarkan apa pun yang mengimplementasikan fungsionalitas untuk mereka, dengarkan mereka. Permukaan layanan Anda kemudian menjadi daftar pesan yang dapat Anda kirim dan Anda belum menambahkan operasi Anda ke fasad layanan Anda; dan Anda bahkan tidak perlu tahu aplikasi atau titik akhir apa yang mengimplementasikan operasi ini, karena semua yang Anda lakukan hanyalah menerbitkan pesan bahwa beberapa mekanisme perutean lainnya akan merutekan ke konsumen yang benar!

Karena Anda telah memisahkan fasad layanan dari operasi aktual yang ingin Anda lakukan, sekarang Anda dapat menambahkan beberapa layanan; sebenarnya, ini adalah bagaimana Netflix melakukannya. Lihatlah presentasi ini: http://www.slideshare.net/adrianco/global-netflix-platform . http://www.slideshare.net/adrianco/global-netflix-platform . Itu bagus!


0

Ada database SQL (ACID) baru dalam versi beta yang diklaim memiliki sifat penskalaan elastis. Ada program beta gratis yang sedang berlangsung sekarang dan saya sarankan Anda melihatnya, ini disebut NuoDB.

Rupanya itu dengan mudah mengungguli MySQL bahkan pada mesin berulir tunggal, tetapi timbangan dengan senang hati sampai 70 + contoh dalam tolok ukur tertentu.


Satu utas? Bagaimana itu patokan yang relevan?
Henrik
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.