Saya merasa harus ada pola sinkronisasi client-server di luar sana. Tetapi saya benar-benar gagal untuk google satu.
Situasinya cukup sederhana - server adalah simpul pusat, yang terhubung ke banyak klien dan memanipulasi data yang sama. Data dapat dipecah dalam atom, jika terjadi konflik, apa pun yang ada di server, memiliki prioritas (untuk menghindari pengguna masuk ke penyelesaian konflik). Sinkronisasi parsial lebih disukai karena jumlah data yang berpotensi besar.
Apakah ada pola / praktik yang baik untuk situasi seperti itu, atau jika Anda tidak tahu - apa pendekatan Anda?
Di bawah ini adalah bagaimana saya sekarang berpikir untuk menyelesaikannya: Paralel dengan data, jurnal modifikasi akan diadakan, memiliki semua transaksi dicap waktu. Ketika klien terhubung, ia menerima semua perubahan sejak pemeriksaan terakhir, dalam bentuk gabungan (server memeriksa daftar dan menghapus tambahan yang diikuti oleh penghapusan, menggabungkan pembaruan untuk setiap atom, dll.). Et voila, kami terbaru.
Alternatif akan menjaga tanggal modifikasi untuk setiap catatan, dan alih-alih melakukan penghapusan data, tandai saja sebagai dihapus.
Adakah pikiran?
Jawaban:
Anda harus melihat bagaimana manajemen perubahan yang didistribusikan bekerja. Lihatlah SVN, CVS dan repositori lain yang mengelola pekerjaan delta.
Anda memiliki beberapa kasus penggunaan.
Sinkronisasi perubahan. Pendekatan perubahan-log (atau sejarah delta) Anda terlihat bagus untuk ini. Klien mengirim delta mereka ke server; server mengkonsolidasikan dan mendistribusikan delta ke klien. Ini adalah kasus khas. Basis data menyebut ini "replikasi transaksi".
Klien telah kehilangan sinkronisasi. Baik melalui backup / restore atau karena bug. Dalam hal ini, klien perlu mendapatkan status saat ini dari server tanpa melalui delta. Ini adalah salinan dari master hingga detail, delta dan kinerja dikutuk. Itu adalah satu hal; klien rusak; jangan mencoba untuk mengoptimalkan ini, cukup terapkan salinan yang dapat diandalkan.
Klien curiga. Dalam hal ini, Anda perlu membandingkan klien dengan server untuk menentukan apakah klien mutakhir dan membutuhkan delta.
Anda harus mengikuti pola desain basis data (dan SVN) penomoran berurutan setiap perubahan. Dengan cara itu klien dapat membuat permintaan sepele ("Revisi apa yang harus saya miliki?") Sebelum mencoba menyinkronkan. Dan meskipun begitu, kueri ("Semua delta sejak 2149") sangat sederhana dan mudah untuk diproses oleh klien dan server.
sumber
Sebagai bagian dari tim, saya melakukan banyak proyek yang melibatkan sinkronisasi data, jadi saya harus kompeten untuk menjawab pertanyaan ini.
Sinkronisasi data adalah konsep yang cukup luas dan ada terlalu banyak untuk didiskusikan. Ini mencakup berbagai pendekatan yang berbeda dengan kelebihan dan kekurangannya. Berikut adalah salah satu klasifikasi yang mungkin didasarkan pada dua perspektif: Sinkron / Asinkron, Klien / Server / Peer-to-Peer. Implementasi sinkronisasi sangat tergantung pada faktor-faktor ini, kompleksitas model data, jumlah data yang ditransfer dan disimpan, dan persyaratan lainnya. Jadi dalam setiap kasus tertentu pilihan harus mendukung implementasi yang paling sederhana memenuhi persyaratan aplikasi.
Berdasarkan ulasan dari solusi yang ada, kami dapat menggambarkan beberapa kelas utama sinkronisasi, berbeda dalam granularitas objek yang akan disinkronkan:
Jadi, kami mengambil pengetahuan kami dalam artikel ini yang saya pikir mungkin sangat berguna bagi semua orang yang tertarik pada topik => Sinkronisasi Data di aplikasi iOS Berbasis Data Inti ( http://blog.denivip.ru/index.php/2014/04 / data-syncing-in-core-data-based-ios-apps /? lang = en )
sumber
Yang benar-benar Anda butuhkan adalah Operational Transform (OT). Ini bahkan dapat memenuhi konflik dalam banyak kasus.
Ini masih merupakan area penelitian aktif, tetapi ada implementasi dari berbagai algoritma PL sekitar. Saya telah terlibat dalam penelitian semacam itu selama beberapa tahun sekarang, jadi beri tahu saya jika rute ini menarik minat Anda dan saya akan dengan senang hati mengarahkan Anda ke sumber daya yang relevan.
sumber
Pertanyaannya tidak sejernih kristal, tetapi saya akan mencari penguncian optimis jika saya adalah Anda. Ini dapat diimplementasikan dengan nomor urut yang dikembalikan server untuk setiap catatan. Ketika klien mencoba untuk menyimpan catatan kembali, itu akan termasuk nomor urut yang diterima dari server. Jika nomor urut cocok dengan apa yang ada di database pada saat pembaruan diterima, pembaruan diizinkan dan nomor urut bertambah. Jika nomor urut tidak cocok, pembaruan tidak diizinkan.
sumber
Saya membangun sistem seperti ini untuk aplikasi sekitar 8 tahun yang lalu, dan saya dapat berbagi beberapa cara bahwa itu telah berevolusi karena penggunaan aplikasi telah berkembang.
Saya mulai dengan mencatat setiap perubahan (masukkan, perbarui atau hapus) dari perangkat apa pun ke tabel "riwayat". Jadi jika, misalnya, seseorang mengubah nomor telepon mereka di tabel "kontak", sistem akan mengedit bidang contact.phone, dan juga menambahkan catatan riwayat dengan action = update, field = phone, record = [ID kontak], value = [nomor telepon baru]. Kemudian kapan pun suatu perangkat disinkronkan, ia mengunduh item sejarah sejak sinkronisasi terakhir dan menerapkannya ke basis data lokalnya. Ini terdengar seperti pola "replikasi transaksi" yang dijelaskan di atas.
Satu masalah adalah menjaga ID unik ketika item dapat dibuat pada perangkat yang berbeda. Saya tidak tahu tentang UUID ketika saya memulai ini, jadi saya menggunakan ID penambahan-otomatis dan menulis beberapa kode berbelit-belit yang berjalan di server pusat untuk memeriksa ID baru yang diunggah dari perangkat, mengubahnya ke ID unik jika ada konflik, dan beri tahu perangkat sumber untuk mengubah ID di database lokalnya. Hanya mengubah ID catatan baru tidak seburuk itu, tetapi jika saya membuat, misalnya, item baru di tabel kontak, lalu membuat item terkait baru di tabel acara, sekarang saya memiliki kunci asing yang saya juga perlu periksa dan perbarui.
Akhirnya saya mengetahui bahwa UUID dapat menghindari hal ini, tetapi pada saat itu basis data saya semakin besar dan saya takut implementasi penuh UUID akan menciptakan masalah kinerja. Jadi alih-alih menggunakan UUID penuh, saya mulai menggunakan kunci alfanumerik 8 karakter yang dibuat secara acak sebagai ID, dan saya meninggalkan kode saya yang ada untuk menangani konflik. Di suatu tempat antara kunci 8-karakter saya saat ini dan 36 karakter UUID harus ada sweet spot yang akan menghilangkan konflik tanpa mengasapi yang tidak perlu, tetapi karena saya sudah memiliki kode resolusi konflik, itu belum menjadi prioritas untuk bereksperimen dengan itu .
Masalah berikutnya adalah bahwa tabel sejarah sekitar 10 kali lebih besar dari seluruh database. Ini membuat penyimpanan menjadi mahal, dan perawatan apa pun di atas tabel riwayat bisa jadi menyakitkan. Menjaga seluruh tabel memungkinkan pengguna untuk memutar kembali perubahan sebelumnya, tetapi itu mulai terasa seperti berlebihan. Jadi saya menambahkan rutin ke proses sinkronisasi di mana jika item riwayat yang terakhir diunduh perangkat tidak lagi ada di tabel riwayat, server tidak memberikannya item riwayat baru-baru ini, tetapi sebaliknya memberikannya file yang berisi semua data untuk akun itu. Kemudian saya menambahkan cronjob untuk menghapus item riwayat yang lebih lama dari 90 hari. Ini berarti pengguna masih dapat memutar kembali perubahan yang berumur kurang dari 90 hari, dan jika mereka menyinkronkan setidaknya sekali setiap 90 hari, pembaruan akan menjadi tambahan seperti sebelumnya. Tetapi jika mereka menunggu lebih dari 90 hari,
Perubahan itu mengurangi ukuran tabel riwayat hampir 90%, jadi sekarang mempertahankan tabel sejarah hanya membuat database dua kali lebih besar daripada sepuluh kali lebih besar. Manfaat lain dari sistem ini adalah bahwa sinkronisasi masih dapat bekerja tanpa tabel histori jika diperlukan - seperti jika saya perlu melakukan beberapa pemeliharaan yang menjadikannya offline untuk sementara. Atau saya dapat menawarkan periode waktu pengembalian yang berbeda untuk akun pada titik harga yang berbeda. Dan jika ada lebih dari 90 hari perubahan untuk diunduh, file lengkap biasanya lebih efisien daripada format inkremental.
Jika saya memulai hari ini, saya akan melewatkan pemeriksaan konflik ID dan hanya bertujuan untuk panjang kunci yang cukup untuk menghilangkan konflik, dengan semacam pengecekan kesalahan untuk berjaga-jaga. Tetapi tabel riwayat dan kombinasi unduhan tambahan untuk pembaruan terbaru atau unduhan lengkap saat diperlukan telah berfungsi dengan baik.
sumber
Untuk sinkronisasi delta (perubahan), Anda dapat menggunakan pola pubsub untuk mempublikasikan perubahan kembali ke semua klien berlangganan, layanan seperti pusher dapat melakukan ini.
Untuk cermin basis data, beberapa kerangka kerja web menggunakan basis data mini lokal untuk menyinkronkan basis data sisi server ke lokal dalam basis data peramban, sinkronisasi sebagian didukung. Periksa meter atau .
sumber