Layanan microser tanpa duplikasi data

19

Saya merasa sulit untuk menghindari duplikasi data atau database bersama bahkan untuk desain layanan microser yang paling sederhana, yang membuat saya berpikir saya kehilangan sesuatu. Inilah contoh dasar masalah yang saya hadapi. Dengan asumsi seseorang menggunakan aplikasi web untuk mengelola inventaris, mereka membutuhkan dua layanan; satu untuk inventaris yang mengelola item dan jumlah dalam stok dan layanan pengguna yang akan mengelola data pengguna. Jika kita menginginkan audit tentang siapa yang menyimpan basis data, kita bisa menambahkan ID pengguna ke basis data untuk layanan inventaris sebagai persediaan terakhir yang diukur berdasarkan nilai.

Dengan menggunakan aplikasi ini, kami mungkin ingin melihat semua item yang menipis, dan daftar siapa yang menyimpannya terakhir kali sehingga kami dapat meminta mereka untuk menyimpannya kembali. Menggunakan arsitektur yang dijelaskan di atas, permintaan akan dilakukan ke layanan inventaris untuk mengambil detail item dari semua item yang jumlahnya kurang dari 5. Ini akan mengembalikan daftar termasuk ID pengguna. Kemudian permintaan terpisah akan dibuat untuk layanan pengguna untuk mendapatkan nama pengguna dan detail kontak untuk daftar ID pengguna yang diperoleh dari layanan inventaris.

Ini tampaknya sangat tidak efisien dan tidak membutuhkan banyak layanan lagi sebelum kami membuat beberapa permintaan ke berbagai API layanan yang pada gilirannya membuat beberapa permintaan basis data. Alternatifnya adalah mereplikasi detail pengguna dalam data inventaris. Ketika seorang pengguna mengubah detail kontak mereka, kami perlu mereplikasi perubahan melalui semua layanan lainnya. Tetapi ini sepertinya tidak sesuai dengan ide konteks terbatas dari layanan-layanan microser. Kami juga dapat menggunakan satu basis data dan membagikannya di antara berbagai layanan, dan memiliki semua masalah pada basis data integrasi .

Apa cara yang benar / terbaik untuk mengimplementasikan ini?

Geraint Anderson
sumber
5
Selamat datang di paradoks layanan mikro. Apa yang kelihatannya membuat hal-hal menjadi lebih sederhana sebenarnya dapat membuat hal-hal menjadi lebih kompleks.
Robert Harvey
Cara yang "benar" sama seperti sebelumnya: mencari cara untuk melakukan hal-hal yang paling sesuai dengan tujuan spesifik Anda.
Robert Harvey
1
@ RobertTarvey Itu selalu terjadi tetapi saya mencoba untuk memahami cara microservices buku teks. Setelah saya mengerti bagaimana itu harus bekerja di dunia yang ideal saya akan dengan senang hati mengubahnya agar sesuai dengan kasus penggunaan saya.
Geraint Anderson
1
Tapi Anda membingkai pertanyaan Anda dalam hal efisiensi, yang merupakan persyaratan perangkat lunak non-fungsional. Cara Anda memecahkan masalah efisiensi adalah dengan bertanya langsung ke basis data.
Robert Harvey
1
Saya akan menulis pertanyaan persis seperti pertanyaan Anda. Saya masih tidak melihat keuntungan dalam MSA untuk aplikasi web yang cukup sederhana. Saya pikir dalam banyak kasus modularitas dapat dicapai tanpa membuat hal-hal begitu kompleks.
Glasnhost

Jawaban:

10

Saya benar-benar merindukan di mana Anda diminta untuk menggandakan.

Prinsip utama layanan mikro adalah agar layanan menjadi otoritas tunggal. Itu berarti inventaris dan manajemen pengguna dapat sepenuhnya terpisah. Saya akan merancang manajemen pengguna sehingga bahkan tidak tahu sistem persediaan ada.

Tapi saya akan merancang sistem inventaris sehingga tidak pernah menyimpan apa pun tentang pengguna selain ID pengguna. Itu menangani masalah Anda menyebarkan perubahan info pengguna.

Adapun hal-hal yang membutuhkan info inventaris dan info pengguna seperti log, audit, dan print out, mereka tidak diperbarui karena info berubah. Mereka adalah catatan tentang apa itu. Sekali lagi, Anda tidak menyebarkan perubahan.

Jadi dalam setiap kasus, ketika Anda menginginkan info pengguna terbaru, Anda meminta layanan info pengguna.

candied_orange
sumber
@Geraint: Bisakah Anda lebih spesifik tentang jenis duplikasi apa yang terjadi di sistem Anda?
Robert Harvey
1
Terima kasih. Duplikasi mengacu pada menyalin rincian kontak pengguna ke layanan inventaris tetapi Anda telah mengatasinya (artinya tidak diperlukan). Tampaknya kontra-intuitif untuk berpindah dari satu basis data relasional di mana saya bisa mendapatkan data inventaris dan data pengguna dengan gabungan untuk membuat dua panggilan API yang berbeda di mana yang kedua tidak dapat dimulai sampai yang pertama mengembalikan hasil. Tapi saya kira itu bagian dari evaluasi, apakah saya menggunakan layanan microser atau sesuatu yang lain.
Geraint Anderson
Ini trik yang sama yang akan digunakan DB jika berhasil keduanya. Anda tidak menyalin informasi pengguna ke tabel inventaris. Anda memberinya kunci asing. ID pengguna melakukan pekerjaan yang sama di seluruh layanan. Jadikan itu unik.
candied_orange
It seems counter-intuitive to move from a single relational database where I could get the inventory data and the user data with a joinIngatlah bahwa "idealnya" ada satu toko per layanan (atau lebih!). Jadi, tidak ada yang seperti "bergabung" antara "batas". Alasannya sederhana, DB menghasilkan kopling antar layanan. Tidak seperti yang disarankan @CandiedOrange, saya pikir kita dapat menduplikasi data minimum dari satu layanan ke layanan lainnya. Saya mengacu pada data yang tidak mungkin berubah. Jika dups ini meningkatkan efisiensi dan kinerja (dan keduanya diperlukan) "pro" mungkin akan menonaktifkan "kontra"
Laiv
@ GaintaintAnderson Maksud saya, jika Anda memerlukan efisiensi (yang menurut definisi merupakan persyaratan non-fungsional), ada cara untuk melakukan itu. Yaitu meminta halaman data dari Layanan Inventaris (seperti 10 elemen), ambil setiap halaman dan gunakan halaman itu untuk meminta data dari Layanan Pengguna, dan agregat di bagian akhir. Dengan cara itu Anda menjaga batas-batas Anda sambil memanfaatkan paralelisme layanan independen. Meskipun begitu, jangan repot-repot sampai Anda mengidentifikasinya sebagai hambatan nyata dari aplikasi yang harus diselesaikan - menunggu 1/2 detik tambahan pada pekerjaan 1 detik semalam tidak masalah bagi siapa pun.
Delioth
11

Saya merasa sulit untuk menghindari duplikasi data ....

Menurut Microsoft ebook on microservice architecture , tidak ada yang salah dengan duplikasi data. Pada dasarnya, data ganda meningkatkan pemisahan antara layanan dan karenanya memperkuat peran mereka sebagai otoritas tunggal. Bagian yang relevan:

Dan akhirnya (dan di sinilah sebagian besar masalah muncul ketika membangun layanan microser), jika layanan microser awal Anda membutuhkan data yang awalnya dimiliki oleh layanan microser lainnya, jangan mengandalkan membuat permintaan sinkron untuk data tersebut. Sebagai gantinya, gandakan atau sebarkan data itu (hanya atribut yang Anda butuhkan) ke dalam basis data layanan awal dengan menggunakan konsistensi akhir (biasanya dengan menggunakan acara integrasi ...

Maurits Moeys
sumber
1
Saya sepenuhnya tidak setuju. Itu membuatnya lebih sulit untuk dipertahankan. Itu membuat Anda menerapkan transaksi di antara layanan microser ketika sesuatu harus ditambahkan, diperbarui atau dihapus. Jika Anda ingin mencegah satu titik kegagalan, Anda dapat menggunakan permintaan atau jenis caching lainnya.
Alan Sereb
1
@AlanSereb Lebih sulit untuk dipertahankan, tetapi intinya kadang-kadang Anda tidak punya pilihan lain. Misalnya, bagaimana jika Anda perlu membuat FK antara objek yang hidup dalam dua database? Satu-satunya cara untuk memastikan konsistensi ketika membuat pertanyaan dalam DB lokal, adalah memiliki replikasi data. Lihatlah ke: stackoverflow.com/a/4452586/2255491
David D.
Saya setuju. Pendekatan hebat lainnya adalah mengambil rute sumber acara. Dan minta semua mutasi dieksekusi melalui pipeline acara
Alan Sereb
4

permintaan akan dilakukan ke layanan inventaris untuk mengambil detail item dari semua item yang jumlahnya kurang dari 5. Ini akan mengembalikan daftar termasuk ID pengguna. Kemudian permintaan terpisah akan dibuat untuk layanan pengguna untuk mendapatkan nama pengguna dan detail kontak untuk daftar ID pengguna yang diperoleh dari layanan inventaris.

Memang benar.

Memang, dalam monolit Anda bisa memiliki model Inventaris yang Anda kueri untuk item yang relevan, masukkan itu ke dalam Model pengguna dan dapatkan data yang sama.

Atau Anda bisa mengambilnya lebih jauh, jika Anda memilikinya dalam database relasional yang sama dan menulis SQL itu dan database akan mengambil tabel inventaris dan tabel pengguna, itu sihir, dan Anda mendapatkan data yang Anda cari.

Terlepas dari bagaimana Anda melakukannya, di suatu tempat di sana akan ada kode yang pada dasarnya mengambil daftar id pengguna dari sistem persediaan, memasukkannya ke dalam sistem pengguna dan menyusun daftar data.

Pertanyaan yang perlu Anda jawab adalah tentang kinerja dan pemeliharaan dan kualitas "lunak" lainnya.

Manfaat utama dari layanan-mikro adalah penskalaan. Jika Anda memiliki sepuluh ribu pengguna pada satu mesin dan itu agak lamban, Anda dapat menambahkan mesin lain dan sistem menjadi dua kali lebih cepat. Tambahkan delapan lebih dan sepuluh kali lebih cepat. (Skala linear mungkin optimis, tetapi ideal dan tidak yang masuk akal untuk harapan bagi.)

Dan ini per layanan . Jika sistem persediaan adalah penghambat, ini digunakan untuk lebih dari sekadar laporan tentang pengguna, Anda dapat menambahkan lebih banyak mesin layanan itu saja . Mesin-mesin juga dapat dikhususkan; layanan ini membutuhkan banyak memori, layanan itu melakukan perhitungan berat dan membutuhkan lebih banyak CPU.

Jika Anda tidak membutuhkan penskalaan, ada satu manfaat lain dari layanan-mikro: mereka modular . Tentu saja, aplikasi monolitik juga dapat bersifat modular, dan Anda memiliki basis data yang dinormalisasi dan ... tetapi dalam praktiknya dinding antar modul seperti dinding kaca dalam kasus terbaik, dan garis-garis di pasir dalam kondisi terburuk. Layanan microser dipisahkan oleh baja padat.

Jika sistem pengguna Anda benar-benar terbakar, itu tidak akan mempengaruhi sistem inventaris Anda sedikit pun. Anda tidak akan dapat mencetak laporan cantik tentang siapa yang menyimpan apa, tetapi pelanggan akan dapat melakukan pemesanan dengan aman karena mengetahui bahwa barang yang ditebar ada di sana.

Dan Anda tidak menduplikasi data dalam layanan microser , tidak seperti yang Anda lakukan dalam database relasional (*). Dalam database relasional Anda dapat melakukan join , dan yang setara adalah menggabungkan daftar dalam kode seperti yang dijelaskan.

Anda juga dapat menambahkan tampilan , yang setara adalah menambahkan layanan baru yang melakukan penggabungan untuk Anda; itu akan menghasilkan tiga permintaan; satu ke layanan baru dan kemudian layanan itu melakukan dua yang asli. Database relasional memiliki hal-hal mewah yang mengoptimalkan tampilan, yang harus diimplementasikan pada tingkat layanan. Anda tidak mendapatkannya "gratis".

Caching berbeda dari duplikasi data karena jika dua nilai tidak cocok, Anda tahu mana yang salah. Ini sering digunakan dalam layanan microser untuk meningkatkan ketersediaan dengan mengorbankan konsistensi (teorema CAP). Karena basis data relasional benar-benar membantai ketersediaan di altar konsistensi, itu kurang umum di dalamnya. Saya akan mengatakan tidak ada yang melekat pada microservices yang membuat caching lebih mudah, tetapi dalam praktiknya caching adalah perhatian utama dan yang membuat caching lebih mudah dalam microservices .

(*) Jika masuk akal untuk menggandakan data dalam gerombolan layanan-mikro maka mungkin masuk akal dalam database relasional yang setara.

Odalrick
sumber
3
Saya benar-benar menyukai jawaban Anda sampai bagian "jangan duplikat data dalam layanan microser". Saya pikir ada kasus di mana duplikasi data adalah pendekatan yang tepat. Ini meningkatkan toleransi kesalahan dan otonomi. Jika layanan pengguna turun, layanan inventaris masih dapat menampilkan daftar inventaris rendah dengan yang terakhir menyimpannya.
Peter Pompeii
1
@peterpompeii Saya sebut caching itu, bukan duplikasi data. Duplikasi data adalah ketika Anda memiliki dua tempat untuk memperbarui untuk satu datum, caching ketika ada satu tempat dan propagasi otomatis ke tempat lain. Saya juga mengatakan lebih dari sekadar hubungan. Jika masuk akal dalam basis data relasional untuk menggandakan data, itu masuk akal dalam layanan mikro. Saya pikir kami setuju dan bagian itu bisa lebih jelas, tetapi saya hanya punya telepon sekarang sehingga tidak akan memperbarui teks sekarang.
Odalrick
@PeterPompeii Semoga bagian tambahan tentang caching mengatasi beberapa masalah Anda.
Odalrick
1
@Odalrick apa yang Anda gambarkan terdengar seperti replikasi data. Replikasi dan caching adalah kedua bentuk data duplikat. Replikasi adalah ketika salinan dijamin untuk selalu memiliki semua data yang dibutuhkan. Caching adalah berdasarkan permintaan. Caching dapat memiliki kehilangan. Caching untuk ketersediaan tidak masuk akal seperti caching untuk kinerja. TL; DR jika Anda menyimpan salinan lengkap dari sesuatu dengan jaminan konsistensi yang cukup bahwa Anda tidak perlu memeriksa kesalahan, maka itu bukan cache.
Brandon
1
@Brandon Perbedaan lain antara replikasi dan caching adalah bagaimana Anda tahu data mana yang salah ketika ada perbedaan. Replikasi mendefinisikan beberapa aturan tentang cara menggabungkan data. Caching di sisi lain selalu : cache salah.
Odalrick