Bagaimana menangani batasan kunci asing ketika bermigrasi dari monolith ke layanan microser?


18

Tim saya bermigrasi dari aplikasi ASP.NET monolitik ke .NET Core dan Kubernetes. Perubahan kode tampaknya berjalan seperti yang diharapkan tetapi di mana tim saya menghadapi banyak perselisihan ada di sekitar basis data.

Saat ini kami memiliki database SQL Server yang agak besar yang menampung semua data untuk seluruh bisnis kami. Saya mengusulkan agar kita membagi basis data dengan cara yang sama untuk memisahkan kode - katalog data dalam satu basis data (logis), inventaris data di yang lain, pesanan di yang lain, dll - dan masing-masing layanan mikro akan menjadi penjaga gerbang untuk databasenya .

Implikasinya di sini adalah bahwa kunci asing yang melintasi batas layanan mikro harus dihapus dan sprocs serta pandangan yang menjangkau lintas batas akan dilarang. Semua model data mungkin atau mungkin tidak berada di database fisik yang sama, tetapi bahkan jika mereka melakukannya, mereka tidak boleh berinteraksi satu sama lain secara langsung. Pesanan mungkin masih mereferensikan item katalog dengan ID tetapi integritas data tidak akan ditegakkan secara ketat di tingkat basis data dan bahwa data harus digabungkan dalam kode daripada dalam SQL.

Saya melihat kehilangan ini sebagai trade off yang diperlukan dalam pindah ke layanan mikro dan mendapatkan manfaat skalabilitas yang menyertai. Selama kita memilih jahitan kita dengan bijak dan berkembang di sekitar mereka maka itu akan baik-baik saja. Anggota tim lainnya bersikeras bahwa semuanya harus tetap dalam database monolitik yang sama sehingga semuanya dapat ACID dan memiliki integritas referensial dipertahankan di mana-mana.

Ini membawa saya ke pertanyaan saya. Pertama, apakah pendirian saya tentang batasan kunci asing dan bergabung dengan masuk akal? Jika demikian, adakah yang mengetahui adanya bahan bacaan yang kredibel yang dapat saya tawarkan kepada kolega saya? Posisi mereka hampir religius dan mereka sepertinya tidak akan terombang-ambing oleh hal-hal singkat dari Martin Fowler sendiri yang mengatakan kepada mereka bahwa mereka salah.


5
Integritas referensial sangat berharga. Apakah skala basis data benar-benar menjadi hambatan di sini? Apakah Anda benar-benar membutuhkan skalabilitas gaya-layanan-mikro? Anda tahu lebih baik dari saya apakah perubahan dalam arsitektur itu sesuai untuk organisasi Anda, tetapi harap pertimbangkan bahwa itu tidak cocok untuk banyak kasus penggunaan. Mungkin ada cara lain untuk skala dengan pengorbanan yang lebih menarik. Misalnya jika permintaan database per detik terlalu tinggi, mungkin hanya replikasi database yang diperlukan. Dan Anda dapat secara horizontal mengukur server web tanpa harus menggunakan layanan microser.
amon

Poin bagus. Kami sedang mencari beberapa opsi untuk keuntungan jangka pendek. Pindah ke layanan microser adalah permainan yang panjang. Menurut pendapat saya, itu akan memungkinkan kami untuk skala selama bertahun-tahun daripada bulan.
Raymond Saltrelli

3
Saya yakin Anda pelanggan akan senang bahwa pesanan yang mereka tempatkan 0,05 ms lebih cepat dibatalkan karena orang lain memesan produk yang sama ketika hanya ada satu yang tersisa dalam stok.
Andy

@amon Buat ini jawaban dan saya akan membatalkannya. Ini adalah pertanyaan yang bagus dan pro dan kontra perlu diwakili secara adil.
mcottle

@mcottle ok, selesai!
amon

Jawaban:


19

Tidak ada solusi yang jelas karena ini sepenuhnya tergantung pada konteks Anda - khususnya, di mana dimensi sistem Anda seharusnya skala dan apa masalah Anda yang sebenarnya. Apakah database benar-benar menjadi hambatan Anda?

Jawaban ini (sayangnya agak panjang) akan berbunyi seperti "layanan microser buruk, monolit seumur hidup!", Tapi itu bukan maksud saya. Maksud saya adalah bahwa microservices dan database terdistribusi dapat menyelesaikan berbagai masalah, tetapi tidak tanpa memiliki masalah mereka sendiri. Untuk membuat argumen yang kuat untuk arsitektur Anda, Anda harus menunjukkan bahwa masalah ini tidak berlaku, dapat dikurangi, dan bahwa arsitektur ini adalah pilihan terbaik untuk kebutuhan bisnis Anda.

Data yang didistribusikan sulit.

Fleksibilitas yang sama yang memungkinkan penskalaan yang lebih baik adalah sisi lain dari jaminan yang lebih lemah. Khususnya, sistem terdistribusi jauh lebih sulit untuk dipikirkan.

Pembaruan atom, transaksi, konsistensi / integritas referensial, dan daya tahan sangat berharga dan tidak boleh diabaikan dengan gegabah. Ada sedikit gunanya memiliki data jika tidak lengkap, ketinggalan zaman, atau salah total. Ketika Anda memiliki ACID sebagai persyaratan bisnis tetapi menggunakan teknologi database yang tidak dapat menawarkannya secara otomatis (mis. Banyak basis data NoSQL, atau arsitektur DB-per-microservice), maka aplikasi Anda harus mengisi kesenjangan dan memberikan jaminan tersebut.

  • Ini bukan tidak mungkin dilakukan, tetapi sulit untuk dilakukan dengan benar. Sangat rumit. Terutama dalam pengaturan terdistribusi di mana ada banyak penulis untuk setiap basis data. Kesulitan ini diterjemahkan menjadi kemungkinan besar bug, mungkin termasuk data yang jatuh, data yang tidak konsisten, dan sebagainya.

    Sebagai contoh, pertimbangkan untuk membaca analisis Jepsen dari sistem basis data terdistribusi yang terkenal , mungkin dimulai dengan analisis Cassandra . Saya tidak mengerti setengah dari analisis itu, tetapi TL; DR adalah bahwa sistem terdistribusi sangat sulit bahkan proyek-proyek industri terkemuka kadang-kadang salah, dengan cara yang tampak jelas di belakang.

  • Sistem terdistribusi juga menyiratkan upaya pengembangan yang lebih besar. Untuk tingkat tertentu, ada trade-off langsung antara biaya pengembangan atau menjatuhkan uang pada perangkat keras yang lebih besar.

Contoh: referensi menggantung

Dalam praktiknya, Anda tidak boleh melihat pada ilmu komputer tetapi pada persyaratan bisnis Anda untuk melihat apakah dan bagaimana ACID bisa santai. Misalnya, banyak hubungan kunci asing mungkin tidak sepenting kelihatannya. Pertimbangkan hubungan kategori - produk n: m. Dalam RDBMS kita dapat menggunakan batasan kunci asing sehingga hanya produk yang ada dan kategori yang ada yang dapat menjadi bagian dari hubungan itu. Apa yang terjadi jika kami memperkenalkan layanan produk dan kategori terpisah, dan produk atau kategori dihapus?

Dalam hal ini, itu mungkin bukan masalah besar dan kita dapat menulis aplikasi kita sehingga menyaring semua produk atau kategori yang tidak ada lagi. Tapi ada pengorbanan!

  • Perhatikan bahwa ini mungkin memerlukan tingkat aplikasi JOINlebih dari beberapa basis data / layanan mikro, yang hanya memindahkan pemrosesan dari server database ke aplikasi Anda. Ini meningkatkan total muatan dan harus memindahkan data tambahan melalui jaringan.

  • Ini dapat mengacaukan pagination. Misalnya Anda meminta 25 produk berikutnya dari suatu kategori, dan memfilter produk yang tidak tersedia dari respons itu. Sekarang aplikasi Anda menampilkan 23 produk. Secara teori, halaman dengan nol produk juga dimungkinkan!

  • Anda ingin sesekali menjalankan skrip yang membersihkan referensi yang menggantung, baik setelah setiap perubahan yang relevan atau secara berkala. Perhatikan bahwa skrip semacam itu cukup mahal karena mereka harus meminta setiap produk / kategori dari basis data dukungan / layanan mikro untuk melihat apakah masih ada.

  • Ini harus jelas, tetapi untuk kejelasan: jangan menggunakan kembali ID. ID gaya kenaikan otomatis mungkin atau mungkin tidak baik-baik saja. GUID atau hash memberi Anda lebih banyak fleksibilitas, misalnya dengan mampu memberikan ID sebelum item dimasukkan ke dalam database.

Contoh: pesanan bersamaan

Sekarang alih-alih pertimbangkan hubungan produk-pesanan. Apa yang terjadi pada pesanan jika suatu produk dihapus atau diubah? Ok, kita cukup menyalin data produk yang relevan ke dalam entri pesanan agar tetap tersedia - memperdagangkan ruang disk untuk kesederhanaan. Tetapi bagaimana jika harga produk berubah atau produk menjadi tidak tersedia sebelum pesanan untuk produk itu dibuat? Dalam sistem terdistribusi, efek membutuhkan waktu untuk disebarkan dan pesanan kemungkinan akan berlanjut dengan data yang sudah ketinggalan zaman.

Sekali lagi, cara pendekatan ini tergantung pada kebutuhan bisnis Anda. Mungkin pesanan usang dapat diterima, dan Anda kemudian dapat membatalkan pesanan jika tidak dapat dipenuhi.

Tapi mungkin itu bukan pilihan, misalnya untuk pengaturan yang sangat bersamaan. Pertimbangkan 3000 orang yang terburu-buru untuk membeli tiket konser dalam 10 detik pertama, dan mari kita asumsikan perubahan ketersediaan akan membutuhkan 10 ms untuk disebarkan. Berapa probabilitas menjual tiket terakhir ke banyak orang? Bergantung pada bagaimana tabrakan itu ditangani, tetapi menggunakan distribusi Poisson dengan λ = 3000 / (10s / 10ms) = 3kami mendapatkan P(k > 1) = 1 - P(k = 0) - P(k = 1) = 80%peluang tabrakan per interval 10 ms. Apakah menjual dan kemudian membatalkan sebagian besar pesanan Anda adalah mungkin tanpa melakukan penipuan dapat menyebabkan percakapan yang menarik dengan departemen hukum Anda.

Pragmatisme berarti memetik ceri fitur terbaik.

Berita baiknya adalah Anda tidak harus pindah ke model database terdistribusi, jika itu tidak diperlukan sebaliknya. Tidak ada yang akan mencabut keanggotaan Microservice Club Anda jika Anda tidak melakukan layanan microser "dengan benar", karena tidak ada klub seperti itu - dan tidak ada satu cara yang benar untuk membangun layanan microser.

Pragmatisme menang setiap saat, jadi padukan dan padukan berbagai pendekatan saat mereka memecahkan masalah Anda. Ini bahkan bisa berarti layanan microser dengan basis data terpusat. Sungguh, jangan melalui rasa sakit dari database terdistribusi jika Anda tidak perlu.

Anda dapat mengatur skala tanpa layanan microser.

Layanan Microsoft memiliki dua manfaat utama:

  • Manfaat organisasi yang dapat dikembangkan dan digunakan secara independen oleh tim yang terpisah (yang pada gilirannya membutuhkan layanan untuk menawarkan antarmuka yang stabil).
  • Manfaat operasional bahwa setiap layanan mikro dapat diskalakan secara independen .

Jika penskalaan independen tidak diperlukan, layanan microsoft jauh kurang menarik.

Server database sudah merupakan jenis layanan yang Anda dapat skala (agak) secara mandiri, misalnya dengan menambahkan replika baca. Anda menyebutkan prosedur tersimpan. Mengurangi mereka mungkin memiliki efek besar sehingga diskusi skalabilitas lainnya diperdebatkan.

Dan sangat mungkin untuk memiliki monolith yang dapat diskalakan yang mencakup semua layanan sebagai perpustakaan. Anda kemudian dapat meningkatkan dengan meluncurkan lebih banyak instance dari monolith, yang tentu saja mengharuskan setiap instance menjadi stateless.

Ini cenderung berfungsi dengan baik sampai monolith terlalu besar untuk digunakan secara wajar, atau jika beberapa layanan memiliki persyaratan sumber daya khusus sehingga Anda mungkin ingin skala mereka secara mandiri. Domain masalah yang melibatkan sumber daya tambahan mungkin tidak melibatkan model data terpisah.

Apakah Anda memiliki kasus bisnis yang kuat?

Anda mengetahui kebutuhan bisnis organisasi Anda, dan karenanya dapat membuat argumen untuk arsitektur basis data per layanan-mikro, berdasarkan analisis:

  • bahwa skala tertentu diperlukan, dan arsitektur ini adalah pendekatan yang paling hemat biaya untuk mendapatkan skalabilitas itu, dengan mempertimbangkan upaya pengembangan yang meningkat untuk pengaturan dan solusi alternatif semacam itu; dan
  • bahwa persyaratan bisnis Anda memungkinkan jaminan ACID yang relevan untuk dilonggarkan, tanpa mengarah ke berbagai masalah seperti yang dibahas di atas.

Sebaliknya, jika Anda tidak dapat menunjukkan ini, khususnya jika desain basis data saat ini mampu mendukung skala yang cukup di masa depan (seperti yang diyakini oleh rekan kerja Anda), maka Anda juga memiliki jawaban.

Ada juga komponen YAGNI besar untuk skalabilitas. Dalam menghadapi ketidakpastian, ini adalah keputusan bisnis strategis untuk membangun skalabilitas sekarang (biaya total lebih rendah, tetapi melibatkan biaya peluang dan mungkin tidak diperlukan) dibandingkan menunda beberapa pekerjaan pada skalabilitas (total biaya lebih tinggi jika diperlukan, tetapi Anda memiliki yang lebih baik ide skala aktual). Ini terutama bukan keputusan teknis.


Jawaban yang bagus, terima kasih. Bisakah Anda menguraikan pernyataan ini? Apakah maksud Anda mengurangi jumlah prosedur mungkin memiliki pengaruh besar pada kinerja? Anda menyebutkan prosedur tersimpan. Mengurangi mereka mungkin memiliki efek besar sehingga diskusi skalabilitas lainnya diperdebatkan.
alan

1
@alan Prosedur tersimpan dapat digunakan untuk kebaikan, tetapi mereka menimbulkan dua masalah kinerja: (1) Permintaan yang lebih kompleks lebih sulit untuk dioptimalkan oleh database. (2) Menggunakan sprocs berarti melakukan lebih banyak pekerjaan di server DB. OP ingin membagi DB untuk meningkatkan skala, tetapi menghindari sprocs yang rumit mungkin sudah menyediakan ruang kepala itu. Tentu saja, sprocs dan kueri kompleks juga bisa bagus untuk kinerja, misalnya ketika mereka meminimalkan jumlah data yang harus ditransfer keluar dari DB untuk respons permintaan. Memisahkan DB akan memperburuk masalah saat JOIN lintas-server diperlukan.
amon

0

Saya percaya kedua pendekatan itu masuk akal. Anda dapat memilih untuk mendapatkan skalabilitas dengan mengorbankan manfaat ACID dan database monolitik, serta tetap menggunakan arsitektur saat ini dan mengorbankan skalabilitas dan ketangkasan arsitektur yang lebih terdistribusi. Keputusan yang tepat akan datang dari model bisnis saat ini dan strategi bisnis untuk tahun-tahun mendatang. Murni dari sudut pandang teknologi ada rasa sakit menjaganya tetap monolitik serta pindah ke pendekatan yang lebih terdistribusi. Saya akan menganalisis sistem dan melihat aplikasi / modul / proses bisnis apa yang lebih penting untuk mengukur dan mengevaluasi risiko, biaya, dan manfaat untuk memutuskan mana yang harus menunggu atau melanjutkan dalam arsitektur monolitik.


-1

Sikap Anda masuk akal dan benar.

Bagaimana meyakinkan dicelup dalam pecandu wol db adalah pertanyaan lain. Saya akan mengatakan Anda memiliki dua opsi.

  1. Temukan contoh konkret di mana DB telah mencapai batasnya. Apakah Anda memiliki 'tabel arsip' misalnya? Kenapa tidak apa-apa? Berapa jumlah maksimum pesanan per detik yang dapat Anda ambil? dll. Tunjukkan bahwa DB tidak memenuhi persyaratan dan solusi Anda memperbaikinya.

  2. Sewa kontraktor mahal untuk memberi tahu Anda solusi terbaik. Karena mereka mahal dan ada blog yang semua orang akan percaya


1
Saya bukan -1 tetapi untuk ini menjadi jawaban yang baik saya akan kehilangan snark dari poin 2 dan memperluas ketika itu akan sesuai untuk membutuhkan beberapa database. Saya tidak berpikir tabel arsip selalu merupakan antipattern dalam database yang tidak mendukung, mempartisi. Basis data yang saya gunakan saat ini memiliki sekitar 130GB data dengan 26 tabel> 10 juta baris dan kinerja tidak cukup jauh dari suatu masalah sehingga perlu membagi basis data; jadi saya sangat skeptis dan saya ingin mendengar mengapa ini adalah ide yang bagus, dan ketika itu perlu dilakukan - jawaban ini adalah yang paling dekat yang pernah saya lihat sejauh ini.
mcottle

baik. Saya menyebutkan tabel arsip karena mereka membersihkan kendala FK. itu celah dalam baju besi. membelah dengan microservice bukan ukuran db hal yang membuat microservices Anda hal yang terpisah. Jika Anda tidak dapat mematikannya dan membuangnya, itu bukan layanan mikro. kembali poin 2. OP menyebutkan MF, mereka benar-benar dapat mempekerjakannya / pemikiran untuk datang dan memberitahu mereka untuk membagi db
Ewan

"Jika Anda tidak dapat mematikan dan membuangnya, itu bukan layanan mikro." Itu benar dari layanan itu sendiri, tetapi belum tentu argumen mengapa layanan membutuhkan database sendiri. Pada akhirnya, basis data itu sendiri adalah layanan yang digunakan oleh microservice. Layanan microsoft tidak benar-benar tahu atau peduli apakah data yang digunakannya berada dalam database terpisah atau database bersama. Anda dapat memutar ke atas atau ke bawah salinan layanan microser ini dan tidak ada yang benar-benar berubah.
Chris Pratt

Argumen terbaik untuk basis data per layanan adalah batas koneksi. Ini tidak biasa untuk koneksi pool untuk digunakan, sehingga setiap layanan microser sudah memerlukan beberapa koneksi ke instance database, maka Anda bisa memiliki beberapa instance dari masing-masing layanan microser ini, masing-masing dengan kumpulan mereka sendiri. Akhirnya segala sesuatunya bisa datang ke kepala, di mana Anda hanya kehabisan kemampuan database untuk menangani semua koneksi yang didapatnya.
Chris Pratt
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.