Saya perlu membuat mekanisme penguncian objek rekursif khusus \ pola untuk sistem terdistribusi dalam C #. Pada dasarnya, saya memiliki sistem multi-node. Setiap node memiliki izin menulis eksklusif di atas n -jumlah negara bagian. Keadaan yang sama juga tersedia dalam bentuk read-only pada setidaknya satu simpul lainnya. Beberapa penulisan / pembaruan harus bersifat atomis di semua node, sementara pembaruan lainnya pada akhirnya akan menjadi konsisten melalui proses replikasi latar belakang, antrian, dll ...
Untuk pembaruan atom saya sedang mencari pola atau sampel yang secara efisien memungkinkan saya untuk menandai objek sebagai terkunci untuk menulis yang kemudian dapat saya distribusikan, komit, kembalikan, dll ... Karena sistem memiliki tingkat konkurensi yang tinggi, saya Saya berasumsi saya harus dapat menumpuk kunci yang akan habis atau dibuka setelah kunci dilepaskan.
Potongan transaksi atau pesan bukan fokus dari pertanyaan ini, tetapi saya telah memberikan mereka untuk beberapa konteks tambahan. Dengan itu, jangan ragu untuk mengartikulasikan pesan apa yang menurut Anda akan diperlukan jika Anda mau.
Berikut ini adalah contoh samar dari apa yang saya bayangkan meskipun saya terbuka untuk ide-ide baru selain menerapkan seluruh produk baru
thing.AquireLock(LockLevel.Write);
//Do work
thing.ReleaseLock();
Saya sedang berpikir untuk menggunakan metode ekstensi, yang mungkin terlihat seperti ini
public static void AquireLock(this IThing instance, TupleLockLevel lockLevel)
{
//TODO: Add aquisition wait, retry, recursion count, timeout support, etc...
//TODO: Disallow read lock requests if the 'thing' is already write locked
//TODO: Throw exception when aquisition fails
instance.Lock = lockLevel;
}
public static void ReleaseLock(this IThing instance)
{
instance.Lock = TupleLockLevel.None;
}
Untuk memperjelas detail pasangan ...
- Semua komunikasi adalah TCP / IP menggunakan protokol permintaan / respons biner
- Tidak ada teknologi perantara seperti antrian atau database
- Tidak ada simpul master pusat. Dalam hal ini, pengaturan penguncian ditentukan oleh penggagas penguncian dan mitra yang akan memenuhi permintaan dengan semacam batas waktu untuk mengatur perilakunya.
Ada yang punya saran?
Jawaban:
Terima kasih atas klarifikasi.
Dalam hal itu, apa yang saya rekomendasikan adalah menggunakan model terbitkan / berlangganan. Protokol penguncian terdistribusi Chubby Google (sebuah implementasi dari Paxos )
Saya tidak pernah menggunakan Paxos (atau Chubby), tetapi tampaknya ada implementasi open source di sini .
Jika itu tidak berhasil, Anda bisa menerapkan versi Paxos Anda sendiri menggunakan, misalnya, salah satu tersangka yang biasa dalam hal perpustakaan perpesanan: perpustakaan antrian pesan nol , RabbitMQ , atau ActiveMQ .
Jawaban sebelumnya:
Sebagian besar saran pada SO ( [A] , [B] ) menggunakan antrian pesan untuk mencapai penguncian lintas mesin.
AcquireLock
Metode Anda akan mendorong sesuatu yang mengidentifikasi objek kunci ke dalam antrian, memeriksa contoh kunci sebelumnya sebelum berhasil.ReleaseLock
Metode Anda akan menghapus objek kunci dari antrian.Pengguna SO atlantis menyarankan, dalam posting ini , posting Jeff Key untuk beberapa detail.
sumber
Menurut saya sepertinya Anda memiliki beberapa teknologi campuran di sini:
komunikasi (yang pada dasarnya Anda andalkan 100% andal ... yang bisa berakibat fatal)
mengunci / saling pengecualian
batas waktu (untuk tujuan apa)?
Kata peringatan: Timeout dalam sistem terdistribusi dapat penuh dengan bahaya dan kesulitan. Jika digunakan, mereka harus diatur dan digunakan dengan sangat hati-hati karena penggunaan timeout yang tidak membeda-bedakan tidak memperbaiki masalah, itu hanya akan mengalahkan malapetaka. (Jika Anda ingin melihat bagaimana timeout harus digunakan, baca dan pahami dokumentasi protokol komunikasi HDLC. Ini adalah contoh yang baik dari penggunaan yang cocok dan cerdas, dikombinasikan dengan sistem pengkodean bit yang pintar untuk memungkinkan deteksi hal-hal seperti jalur IDLE) .
Untuk beberapa waktu saya bekerja di sistem terdistribusi multi-prosesor yang terhubung menggunakan tautan komunikasi (bukan TCP, sesuatu yang lain). Salah satu hal yang saya pelajari adalah bahwa sebagai generalisasi kasar, ada beberapa tempat multi-pemrograman yang berbahaya untuk dikunjungi:
mengandalkan antrian biasanya berakhir dengan air mata (jika antrian mengisi, Anda dalam kesulitan. KECUALI Anda dapat menghitung ukuran antrian yang tidak akan pernah terisi, dalam hal ini Anda mungkin dapat menggunakan solusi no-antrian)
mengandalkan penguncian itu menyakitkan, coba dan pikirkan jika ada cara lain (jika Anda harus menggunakan penguncian, lihat literatur, penguncian terdistribusi multi-prosesor telah menjadi subjek banyak makalah acedemik selama 2-3 dekade terakhir)
Saya Anda harus melanjutkan menggunakan penguncian, kemudian:
Saya akan berasumsi bahwa Anda akan menggunakan batas waktu hanya sebagai alat pemulihan pilihan terakhir - yaitu untuk mendeteksi kegagalan sistem komunikasi yang mendasarinya. Saya selanjutnya akan berasumsi bahwa sistem komunikasi TCP / IP Anda adalah bandwidth tinggi dan dapat dianggap sebagai latensi rendah (idealnya nol, tetapi ini tidak pernah terjadi).
Apa yang saya sarankan adalah bahwa setiap node memiliki daftar konektivitas dari node lain yang dapat terhubung. (Node tidak akan peduli dari mana koneksi berasal.) Populasi dari tabel yang node dapat terhubung ke node dibiarkan sebagai hal yang terpisah untuk memilah, Anda belum mengatakan apakah itu akan diatur secara statis atau sebaliknya. Juga mudah diabaikan adalah hal-hal seperti alokasi nomor port IP di mana koneksi akan masuk ke sebuah simpul - mungkin ada alasan bagus untuk menerima permintaan hanya pada satu port, atau pada beberapa port. Ini perlu dipertimbangkan dengan cermat. Faktor-faktor akan mencakup antrian tersirat, pemesanan, penggunaan sumber daya, jenis dan kemampuan sistem operasi.
Setelah node tahu dengan siapa mereka terhubung, mereka dapat mengirim permintaan kunci ke simpul itu, dan harus menerima kembali dari balasan kunci dari simpul jarak jauh itu. Anda dapat mengemas kedua operasi tersebut menjadi pembungkus agar terlihat atom. Efek dari ini adalah bahwa node yang ingin memperoleh kunci akan membuat panggilan seperti:
panggilan get_lock dan release_lock harus seperti (pada prinsipnya):
Anda harus sangat berhati-hati dengan sistem penguncian terdistribusi yang unit kerjanya dilakukan saat kunci dipegang kecil dan cepat karena Anda akan memiliki banyak node jarak jauh yang berpotensi menunggu untuk mendapatkan kunci. Ini secara efektif merupakan sistem multiprosesor / komunikasi stop-and-wait yang kuat tetapi tidak memiliki kinerja setinggi mungkin.
Saran adalah mengambil pendekatan yang sama sekali berbeda. Bisakah Anda menggunakan panggilan prosedur jarak jauh di mana setiap panggilan RPC membawa paket informasi yang dapat ditangani oleh penerima, dan yang menghilangkan kebutuhan untuk kunci?
Saat membaca kembali pertanyaannya, sepertinya Anda tidak benar-benar ingin peduli dengan sisi komunikasi berbagai hal, Anda hanya ingin menyelesaikan masalah penguncian Anda.
Karena itu, jawaban saya mungkin tampak agak di luar topik, namun saya yakin Anda tidak dapat menyelesaikan masalah penguncian Anda tanpa membuat bagian di bawahnya juga benar. Analogi: Membangun rumah di atas fondasi yang buruk menyebabkannya jatuh ... Akhirnya.
sumber
Pertanyaan Anda dapat dengan mudah diimplementasikan menggunakan cache terdistribusi seperti NCache. Yang Anda butuhkan adalah mekanisme Penguncian Pesimis di mana Anda bisa memperoleh kunci menggunakan objek. Kemudian lakukan tugas dan operasi Anda dan lepaskan kunci untuk digunakan aplikasi lain nanti.
Lihatlah kode berikut;
Di sini Anda akan mendapatkan kunci pada Kunci tertentu dan kemudian melakukan tugas (mulai dari satu operasi atau lebih) lalu akhirnya melepaskan kunci ketika Anda selesai.
Diambil dari tautan: http://blogs.alachisoft.com/ncache/distributed-locking/
sumber