S: Bir servis sunucusu, bir veritabanı, işlem: kullanıcının mevcut bakiyesini sorgulamak, mevcut bakiyenin %3'ünü işlem ücreti olarak kesmek
Senkronize kilit DB kilidi
S: İki hizmet sunucusu, bir veritabanı, işlem: kullanıcının mevcut bakiyesini sorgulamak, mevcut bakiyenin %3'ünü işlem ücreti olarak kesmek; Dağıtılmış kilitler
Ne tür dağıtık kilide ihtiyacımız var? Dağıtık bir uygulama kümesinde, aynı yöntemin aynı anda yalnızca bir iş parçacığı tarafından bir makinede çalıştırılabilmesini sağlar.
Eğer bu kilit yeniden giriş kilidi ise (deadlocklardan kaçının)
Bu kilit en iyi bloklayıcı kilit olarak kullanılır (bunu iş ihtiyaçlarınıza göre isteyip istemediğinizi düşünün).
Bu kilit adil bir kilit olarak en iyisidir (bunu iş ihtiyaçlarına göre isteyip istemediğinizi düşünün).
Oldukça erişilebilir olan edinme ve açma kilit fonksiyonları vardır
Alma ve serbest bırakma kilitlerinin performansı daha iyidir
1. Veritabanlarına dayalı dağıtık kilitler
Tablo tabanlı uygulamalara dayalı dağıtık kilitler
Bir metodu kilitlemek istediğimizde, aşağıdaki SQL çalıştırın: metodLock(method_name,desc) değerlerini ('method_name','desc') içine ekleyin
method_name için bir benzersizlik kısıtlaması koyduğumuz için, veritabanına aynı anda birden fazla talep gönderilirse, veritabanı yalnızca bir işlemin başarılı olmasını sağlar, o zaman yöntem kilidini başarıyla elde eden iş parçacığının metod gövde içeriğini çalıştırabileceğini varsayabiliriz.
Yöntem çalıştırıldığında, kilidi açmak istiyorsanız aşağıdaki SQL'i çalıştırmanız gerekir: metodLock'tan sil, burada method_name ='method_name'
Yukarıdaki bu basit uygulamanın şu sorunları vardır:
- Bu kilit, veritabanının kullanılabilirliğine bağlıdır; veritabanı tek bir noktadır ve veritabanı kapatıldıktan sonra iş sisteminin erişilmez hale gelmesine neden olur.
- Bu kilidin son kullanma süresi yoktur ve kilit açma işlemi başarısız olduğunda, kilit kaydı veritabanında kalır ve diğer iş parçacıkları kilidi alamaz.
- Bu kilit yalnızca engelleyici olmayabilir, çünkü veri ekleme işlemi başarısız olduğunda doğrudan hata bildirecektir. Kilit edinmeyen iş parçacıkları kuyruğun içine girmez ve kilidi tekrar elde etmek için kilit edinme işlemini tekrar tetiklemeleri gerekir.
- Kilit yeniden giriş yapmaz ve aynı iplik, kilidi serbest bırakana kadar tekrar alamaz. Çünkü verilerdeki veriler zaten mevcut.
- Bu kilit haksız bir kilit ve kilidi bekleyen tüm iplikler şans eseri kilit için yarışır.
Elbette, yukarıdaki sorunları başka şekillerde de çözebiliriz.
- Veritabanı tek bir nokta mı? İki veritabanı oluşturun, veri her iki yönde de senkronize olur. Telefonu kapattıktan sonra hızlıca yedek kütüphanesine geç.
- Son kullanma tarihi yok mu? Veritabanındaki zaman aşımına dayalı verileri düzenli aralıklarla temizlemek için planlanmış bir görev yapın.
- Engelleyici mi? Insert başarılı olana kadar bir süre döngüsü yapın ve ardından başarı döner.
- Yeniden girmeyen mi? Veritabanı tablosuna bir alan ekleyin ve şu anda kilidi alan olan makinenin ana bilgisayar bilgisi ve iş parçacağı bilgilerini kaydedersiniz, sonra bir dahaki kilidi aldığınızda önce veritabanını sorgulayın; mevcut makinenin ana bilgisayar bilgileri ve iş parçacığı bilgileri veritabanında bulunuyorsa, kilidi doğrudan ona ataabilirsiniz.
- Haksız mı? Kilidi bekleyen tüm iş parçacıklarını kaydetmek için başka bir ara tablo oluşturun ve bunları oluşturulma zamanına göre sıralayın; sadece ilk oluşturulan iş başlıkları kilidi edinebilir
Özel kilitlere dayalı dağıtılmış kilitler
Veri tablosundaki kayıtları eklemek ve silmekten, veriyle birlikte gelen kilitler sayesinde dağıtılmış kilitler de uygulanabilir.
Ayrıca yeni oluşturduğumuz veritabanı tablosunu da kullanıyoruz. Dağıtılmış kilitler, veritabanlarında özel kilitler aracılığıyla uygulanabilir. MySql tabanlı InnoDB motoru, kilitleme işlemlerini uygulamak için aşağıdaki yöntemleri kullanabilir:
Sorgu ifadesinden sonra güncelleme için eklerseniz, veritabanı sorgu işlemi sırasında veritabanı tablosuna özel bir kilit ekler. Bir kayda özel kilit eklendiğinde, diğer iş parçacıkları artık o satırdaki plaklara özel bir kilit ekleyemez.
Münhasır kilidi elde eden iş parçacığının dağıtılmış kilidi elde edebileceğini düşünebiliriz ve kilit alındığında, yöntemin iş mantığı çalıştırılıp aşağıdaki yöntemlerle açılabilir:
public void unlock(){ connection.commit(); }
connection.commit(aracılığıyla); Kilidi açma operasyonu.
Bu yöntem, kilidi açamayıp kilidi engelleyememe gibi yukarıda bahsedilen sorunları etkili bir şekilde çözebilir.
Kilitleri engellemek mi? for update ifadesi başarılı yürütmeden hemen sonra geri döner ve başarılı olana kadar bloklanmış kalır.
Servis kilitten sonra kesildi, serbest bırakılamıyor mu? Bu şekilde, veritabanı hizmet kapandıktan sonra kilidi kendi başına serbest bırakır.
Ancak, veritabanı tek nokta, yeniden kontrol ve adil kilitleme sorununu doğrudan çözmez.
Veritabanını dağıtık kilitleri uygulamak için kullanış şeklini özetlemek gerekirse, ki her ikisi de veritabanındaki bir tabloya dayanır; biri tablodaki kayıtların varlığıyla kilidin olup olmadığını belirlemek, diğeri ise veritabanının münhasır kilidi aracılığıyla dağıtık kilitleri uygulamaktır.
Veritabanlarında Dağıtık Kilitlemenin Avantajları
Doğrudan veritabanı yardımıyla anlaşılması kolaydır.
Veritabanlarında dağıtık kilitlerin uygulanmasının dezavantajları
Çeşitli sorunlar olacak ve çözüm süreci boyunca giderek daha karmaşık hale gelecektir.
Veritabanını işletmek belirli ek yükler gerektirir ve performans sorunları dikkate alınmalıdır.
2. Önbelleğe dayalı dağıtılmış kilitler
Veritabanı tabanlı dağıtık kilitleme çözümüyle karşılaştırıldığında, önbellek tabanlı uygulama performans açısından daha iyi performans gösterecektir.
Şu anda Redis, memcached gibi birçok olgun önbellek ürünü bulunmaktadır. Burada, dağıtık kilitleri uygulamak için önbellek kullanma şemasını analiz etmek için Redis'i örnek olarak alıyoruz.
İnternette Redis tabanlı dağıtık kilitlerin uygulanmasıyla ilgili birçok makale vardır ve ana uygulama yöntemi Jedis.setNX yöntemini kullanmaktır.
Yukarıdaki uygulamada ayrıca birkaç sorun vardır:
1. Tek puan problemi.
2. Bu kilidin son kullanma süresi yoktur, kilit açma işlemi başarısız olduğunda kilit kaydı sürekli kırmızı halde kalır ve diğer iş parçacıkları kilidi artık elde edemez.
3. Bu kilit yalnızca engelleyici olmayabilir ve başarı ya da başarısızlık fark etmeksizin doğrudan geri dönecektir.
4. Bu kilit yeniden girmez; bir iplik kilidi aldıktan sonra, kilidi serbest bırakmadan önce kilidi tekrar alamaz, çünkü kullanılan anahtar zaten redis'te mevcuttur. setNX işlemleri artık yürütülemez.
5. Bu kilit adil değil, tüm bekleyen iş parçacıkları setNX işlemlerini aynı anda başlatıyor ve şanslı iş parçacıkları kilidi alabiliyor.
Elbette, bunu çözmenin yolları da var.
- Günümüzde, ana akım önbellek servisleri, küme dağıtımını destekler ve kümeleme yoluyla tek nokta problemlerini çözür.
- Son kullanma tarihi yok mu? Redis için setExpire yöntemi gelen son kullanma süresini destekler ve bu süre geçtikten sonra veri otomatik olarak silinir.
- Engelleyici mi? defalarca idam edilirken.
- Yeniden girmek mümkün değil mi? Bir iş parçacağı kilidi edindikten sonra, mevcut ana bilgisayar bilgilerini ve iş parçacığı bilgilerini kaydedin ve bir dahaki sefere almadan önce mevcut kilidin sahibi olup olmadığınızı kontrol edin.
- Haksız mı? Bir iş parçası kilidi almadan önce tüm bekleyen iş parçacıklarını kuyruğa koyun ve ardından kilidi ilk girer, ilk çıkar sistemiyle edinir.
Redis kümesinin senkronizasyon politikası zaman alır ve NX başarılı bir şekilde ayarlandıktan sonra iş parçacığı A kilitlenmesi mümkündür, ancak bu değer, iş parçacığı B'nin setNX'i çalıştırdığı sunucuya güncellenmemiştir ve bu da eşzamanlılık sorunlarına yol açar.
redis yazarı Salvatore Sanfilippo, tek bir düğümden daha güvenli ve güvenilir dağıtık kilit yönetimi (DLM) uygulayan Redlock algoritmasını önerdi.
Redlock algoritması, genellikle N=5 olarak ayarlanmış ve birbirinden bağımsız olan N N redis düğümü olduğunu varsayar ve bu N düğümün fiziksel bağımsızlığı korumak için farklı makinelerde çalıştığını varsayır.
Algoritmanın adımları şunlardır:
1. Müşteri, mevcut zamanı milisaniye cinsinden elde eder. 2. İstemci N düğümün kilidini elde etmeye çalışır (her düğüm, daha önce bahsedilen önbellek kilidi gibi kilidi alır) ve N düğüm aynı anahtar ve değere sahip kilidi alır. İstemcinin arayüz erişim zaman aşımını ayarlaması gerekir ve arayüz zaman aşımının kilitlenme süresinden çok daha kısa olması gerekir; örneğin, kilidin otomatik olarak serbest bırakılması süresi 10 saniyedir, ardından arayüz zaman aşımı yaklaşık 5-50ms olarak ayarlanır. Bu, redis düğümü kapandıktan sonra erişim sırasında mümkün olan en kısa sürede zaman aşımını sağlamanızı sağlar ve kilidin normal kullanımını azaltır. 3. İstemci, kilidin alınmasının ne kadar sürdüğünü, 1. adımda elde edilen zamanı mevcut zamanla çıkararak hesaplar; ancak istemci kilidin 3'ten fazla düğümünü elde ettiğinde ve kilidi edinme süresi kilidin zaman aşım süresinden daha azsa, dağıtılmış kilidi elde eder. 4. Müşterinin kilidi edinme süresi, 3. adımda hesaplanan kilidi elde etmek için harcanan sürenin belirlenmiş kilit zaman aşımına çıkarılmasıdır. 5. İstemci kilidi alamazsa, istemci sırayla tüm kilitleri silecektir. Redlock algoritması kullanılarak, dağıtık kilit hizmetinin 2 düğüme kadar bağlandığında da çalışmaya devam edebileceği garanti edilebilir; bu da önceki veritabanı kilidi ve önbellek kilidi ile karşılaştırıldığında erişilebilirliği büyük ölçüde artırır.
Ancak, dağıtılmış bir uzman, Redlock'un doğruluğunu sorgulayan "Dağıtık kilitleme nasıl yapılır" adlı bir makale yazdı.
Uzman, dağıtılmış kilitler değerlendirilirken dikkate alınması gereken iki unsur olduğunu belirtti: performans ve doğruluk.
Yüksek performanslı dağıtık kilit kullanıyorsanız ve doğruluk gerekmiyorsa, önbellek kilidi kullanmak yeterlidir.
Eğer çok güvenilir bir dağıtık kilit kullanıyorsanız, kesinlikle güvenilirlik sorunlarını göz önünde bulundurmalısınız. Öte yandan Redlock doğruluğu karşılamaz. Neden olmasın? Uzmanlar birkaç yönü listeliyor.
Günümüzde birçok programlama dili, GC fonksiyonlu sanal makineler kullanır, Full GC'de program GC'yi işlemeyi durdurur, bazen Full GC uzun sürer ve programda birkaç dakikalık gecikme olur, makalede HBase örneğini verilebilir, HBase bazen birkaç dakika GC verilir, bu da kiralamanın zaman bitmesine neden olur. Örneğin, aşağıdaki şekilde, istemci 1 bir kilit alır ve paylaşılan bir kaynağı işlemek üzereyken, kilit süresi dolana kadar tam GC gerçekleşir. Bu şekilde, istemci 2 tekrar kilidi alır ve paylaşılan kaynak üzerinde çalışmaya başlar. İstemci 2 işlendiğinde, istemci 1 tam GC'yi tamamlar ve paylaşılan kaynakları işlemeye başlar, böylece her iki istemci de paylaşılan kaynakları işliyor.
Uzmanlar bir çözüm sundu, aşağıdaki şekilde gösterildiği gibi, MVCC gibi görünüyor, kilide token getir, token versiyon kavramıdır, işlem kilidi tamamlandığında token eklenir 1, paylaşılan kaynaklar işlenirken token getirilir, paylaşılan kaynakları işlerken sadece belirtilen token sürümü paylaşılan kaynağı yönetebilir.
Sonra uzman ayrıca algoritmanın yerel zamana dayandığını ve Redis'in anahtar kullanma süresini yönetirken monoton saat yerine getTimeOfDay yöntemine güvendiğini ve bunun da zaman hatalarına yol açtığını söyledi. Örneğin, bir senaryoda, iki istemci 1 ve istemci 2 5 redis düğümüne (A, B, C, D ve E) sahiptir.
1. İstemci 1, A, B ve C'den kilidi başarıyla alır ve D ile E'den kilit ağı zaman aşımını alır. 2. C düğümünün saati doğru değil, bu da kilit zamanlamasına neden oluyor. 3. İstemci 2, C, D ve E'den kilidi başarıyla alır ve A ile B'den kilit ağı zamanaşımını alır. 4. Bu şekilde, hem müşteri 1 hem de istemci 2 kilitlenir. Redlock'un müsait olmaması hakkında uzmanların söylediği iki noktayı özetlemek gerekirse:
1. GC ve diğer senaryolar herhangi bir anda meydana gelebilir, bu da istemcinin kilidi almasına ve işlem zamanının sonunda başka bir istemcinin kilidi almasına neden olur. Uzmanlar ayrıca kendi kendine artan tokenların kullanılmasına dair bir çözüm sundular. 2. Algoritma yerel zamana dayanır ve saat yanlış olur, bu da iki istemcinin aynı anda kilitlenme almasına yol açar. Bu nedenle, uzmanların verdiği sonucu, Redlock'un yalnızca sınırlı ağ gecikmesi, sınırlı program kesintisi ve sınırlı saat hata aralığında normal çalışabileceğidir; ancak bu üç senaryonun sınırları doğrulanamaz, bu nedenle uzmanlar Redlock kullanımını önermez. Yüksek doğruluk gereksinimi olan senaryolar için uzmanlar Zookeeper'ı önerir; bu durum daha sonra Zookeeper'ın dağıtılmış kilit olarak kullanılması ele alınacaktır.
Redis yazarından gelen yanıt
Redis yazarı, uzmanın makalesini gördükten sonra bir blog yazarak yanıt verdi. Yazar uzmana nazikçe teşekkür etti ve ardından uzmanın görüşüne katılmadığını belirtti.
REDIS yazarının kilit zaman aşımı problemini çözmek için tokenların kullanılması üzerine yaptığı tartışma aşağıdaki beş noktada özetlenebilir:
Birinci nokta, dağıtık kilitlerin kullanımı genellikle paylaşılan kaynakları kontrol etmenin başka bir yolu olmadığı, uzmanların paylaşılan kaynakların işlenmesini sağlamak için tokenlar kullandığı ve dağıtılmış kilitlere gerek olmadığı anlamına gelir. Nokta 2: Token üretimi için, farklı istemciler tarafından elde edilen tokenların güvenilirliğini sağlamak için, token üreten hizmetin güvenilirliğini sağlamak için dağıtılmış kilitlere ihtiyaç duyar. Madde 3, uzmanların kendi kendine artan tokenları söylediği için, redis yazarı bunun tamamen gereksiz olduğuna inanır; her istemci token olarak benzersiz bir uuid oluşturabilir ve paylaşılan kaynağı yalnızca uuid istemcinin halledebileceği bir duruma ayarlayabilir, böylece diğer istemciler kilidi alan istemci kilidi serbest bırakana kadar paylaşılan kaynağı işleyemez. Yukarıdaki şekilde gösterildiği gibi, token 34'ün istemcisi yazma işlemi sırasında GC gönderir ve kilidin zaman aşımına neden olursa, başka bir istemci token 35'in kilidini alıp tekrar yazmaya başlayabilir ve bu da kilit çatışmasına yol açabilir. Bu nedenle, tokenların sırası paylaşılan kaynaklarla birleştirilemez. 5. Noktada, redis yazarı, çoğu senaryoda, dağıtık kilitlerin işlem dışı senaryolarda güncelleme sorunlarını çözmek için kullanıldığına inanır. Yazar, bazı durumlarda paylaşımlı kaynakları yönetmek için tokenları birleştirmenin zor olduğu, bu yüzden kaynakları kilitlemek ve işlemek için kilitlere güvenmek zorunda kaldığınız bazı senaryolar olduğunu belirtmeli. Uzmanların bahsettiği bir diğer saat sorunu da Redis yazarlarının bir açıklaması var. Kilidi edinme süresi çok uzun ve kilitin varsayılan zaman aşım süresini aşıyorsa, müşteri şu anda kilidi elde edemez ve uzmanlar tarafından önerilen örnekler yoktur.
Kişisel duygular
Özetlediğim ilk sorun, bir istemci dağıtılmış bir kilit elde ettikten sonra, kilidin istemcinin işleme sırasında bir zaman aşımı sonrası serbest bırakılmasıdır. Daha önce, veritabanı kilidi ile belirlenen 2 dakikalık zaman aşımından bahsedilirken, bir görev bir emir kilidi 2 dakikadan fazla süre kalırsa, diğer ticaret merkezi bu emir kilidini elde edebilir ve böylece iki ticaret merkezi aynı emri aynı anda işleyebilir. Normal koşullarda görev saniyeler içinde işleniyor, ancak bazen bir RPC isteğine katılarak belirlenen zaman aşımı çok uzun olur ve bir görevde birden fazla zaman aşım isteği bulunur, bu yüzden otomatik açma süresinin aşılması muhtemeldir. Java ile yazarsak, ortada Full GC olabilir, böylece kilit zaman aşımından sonra kilit açıldıktan sonra istemci bunu algılayamaz, ki bu çok ciddi bir durum. Bence bu kilidin kendisinde bir sorun değil, yukarıda bahsedilen herhangi bir dağıtık kilit, zaman aşımına sahip bırakma özelliklerine sahip olduğu sürece böyle bir sorun yaşanır. Eğer kilit zaman aşımı fonksiyonunu kullanırsanız, istemci kilit zaman aşımını ayarlamalı ve paylaşılan kaynağı işlemeye devam etmek yerine buna göre işlem görmelidir. Redlock'un algoritması, müşterinin kilidi edindikten sonra tutabileceği kilit süresini geri getirir ve istemci bu süreyi işleyerek görevi durdurmak zorundadır.
İkinci sorun ise dağıtık uzmanların Redlock'u anlamaması. Redlock'un temel özelliklerinden biri, kilidin alınma süresinin, kilidin varsayılan olarak zaman aşımına girdiği toplam süre eksik kilidin alınma süresi olmasıdır; böylece istemcinin işleme süresi, yerel zamana bakılmaksızın göreceli bir zamandır.
Bu açıdan bakıldığında, Redlock'un doğruluğu kesinlikle garanti edilebilir. Redlock'un dikkatli analizi, bir düğümün redis'ine kıyasla Redlock'un sunduğu ana özellik daha yüksek güvenilirliktir ve bu bazı senaryolarda önemli bir özelliktir. Ama bence Redlock güvenilirlik için çok fazla para harcadı.
- İlk olarak, Redlock'u daha güvenilir kılmak için 5 düğüm dağıtılmalıdır.
- Sonra kilidi almak için 5 düğüm talep etmeniz gerekir ve Future yöntemiyle önce 5 düğüme aynı anda talep talep edebilir, ardından yanıt sonucunu bir arada alabilirsiniz; bu da yanıt süresini kısaltabilir ama yine de tek düğümlü redis kilidinden daha fazla zaman alır.
- Sonra, 5 düğümden 3'ten fazlası elde edilmek zorunda olduğundan, bir kilit çatışması olabilir, yani herkes 1-2 kilit elde etmiş olur ve sonuç olarak kimse kilidi alamaz, bu problemi Redis yazarı sal algoritmasının özünü ödünç alır, rastgele zamandaki çarpışma yoluyla çatışma süresi büyük ölçüde azaltılabilir, ancak bu sorun çok iyi önlenemez, özellikle kilit ilk kez alındığında, kilidi edinmenin zaman maliyeti artar.
- 5 düğümden 2'si kapalıysa, kilidin kullanılabilirliği büyük ölçüde azalır, öncelikle, bu iki düğümün sonuçlarının zaman aşımını beklemeniz gerekir ve sadece 3 düğüm vardır, ayrıca istemcinin kilidi elde etmek için tüm 3 düğümün kilidini alması gerekir, ki bu da daha zordur.
- Bir ağ bölümü varsa, istemcinin kilidi asla elde edemeyeceği bir durum olabilir.
Bu kadar çok nedeni analiz ettikten sonra, Redlock'un sorununun en kritik noktasının Redlock'un istemcilerden yazımların tutarlılığını sağlamasını gerektirmesi ve arka uç 5 düğümün tamamen bağımsız olması ve tüm istemcinin bu 5 düğümü çalıştırması olduğunu düşünüyorum. Eğer 5 düğüm arasında bir lider varsa, istemci liderin verisini senkronize edebilir; yeter kilidi liderden aldığı sürece, böylece bölümleme, zaman aşımı ve çatışma gibi sorunlar olmaz. Bu nedenle, dağıtılmış kilitlerin doğruluğunu sağlamak için, güçlü tutarlılığa sahip dağıtık koordinasyon hizmeti kullanmanın sorunu daha iyi çözebileceğini düşünüyorum.
Yine soru ortaya çıkıyor: Son kullanma süresini ne kadar süre belirlemeliyim? Geçersiz kalma süresinin nasıl ayarlanacağı çok kısa ve kilit yöntem yürütilmeden otomatik olarak açılır, bu zaman eşzamanlılık sorunları yaşanır. Çok uzun sürerse, kilitlenen diğer iş parçacıkları uzun süre beklemek zorunda kalabilir.
Bu sorun, dağıtık kilitlerin uygulanmasında veritabanlarının kullanımında da mevcuttur.
Bu soruna yönelik mevcut ana akım yaklaşım, elde edilen her kilit için kısa bir zaman aşımına sahip bir zaman sınırı belirlemek ve her zaman zaman bitişiğini yenilemek için bir konu başlatmaktır. Bu konuyu kilidi açarken bitirin. Örneğin, redis'in resmi dağıtık kilit bileşeni olan redisson, bu çözümü kullanır.
Dağıtık kilitleri uygulamak için önbelleklemeyi kullanmanın avantajları İyi performans.
Dağıtık kilitleri uygulamak için önbellekleme kullanmanın dezavantajları Uygulama çok sorumlu, dikkate alınması gereken çok fazla faktör var.
Zookeeper uygulamasına dayalı dağıtık kilitler
Zookeeper geçici sıralı düğümlere dayalı dağıtılmış kilitler.
Genel fikir, her istemci bir metodu kilitlediğinde, zookeeper'daki yönteme karşılık gelen belirtilen düğümün dizininde benzersiz bir anlık sıralı düğüm oluşturulmasıdır. Kilit alıp almayacağınızı belirlemenin yolu basittir, sadece sıralanmış düğümde en küçük seri numarasına sahip olanı belirlemeniz yeterlidir. Kilit açıldığında, anlık düğümü silmek yeterlidir. Aynı zamanda, hizmet durdurma süresi nedeniyle serbest bırakılamayan çıkmaz kilitler sorununu da önleyebilir.
Bakalım Zookeeper daha önce bahsedilen sorunları çözebilir mi.
- Kilit açılmıyor mu? Zookeeper kullanmak, kilitlerin açılmaması sorununu etkili bir şekilde çözebilir, çünkü kilit oluşturulurken istemci ZK'da geçici bir düğüm oluşturur ve istemci kilidi alıp aniden astığında (oturum bağlantısı bozulur), geçici düğüm otomatik olarak silinir. Diğer müşteriler tekrar kilidi alabilir.
- Engelleymeyen kilitler mi? Düğüm değiştiğinde, Zookeeper istemciye haber verir ve istemci oluşturduğu düğümün tüm düğümler arasında en küçük sıralı sayı olup olmadığını kontrol edebilir.
- Tekrar giremiyor musun? İstemci bir düğüm oluşturduğunda, mevcut istemcinin ana bilgisayar bilgilerini ve iş parçacığı bilgilerini doğrudan düğüme yazar ve bir dahaki kilidi almak istediğinizde, bunu mevcut en küçük düğümdeki verilerle karşılaştırabilirsiniz. Eğer bilgi sizinkilerle aynıysa, kilidi doğrudan edinebilirsiniz ve farklıysa, kuyruğun içine katılmak için geçici bir ardışık düğüm oluşturabilirsiniz.
Yine soru ortaya çıkıyor, Zookeeper'ın kümelerde dağıtılması gerektiğini biliyoruz, Redis kümeleri gibi veri senkronizasyonu sorunları olacak mı?
Zookeeper, zayıf tutarlılığı, yani nihai tutarlılığı garanti eden dağıtık bir bileşendir.
Zookeeper, Quorum Based Protocol adı verilen bir veri senkronizasyon protokolü kullanır. Zookeeper kümesinde N Zookeeper sunucusu varsa (N genellikle tektir, 3'ü veri güvenilirliğini karşılayabilir ve yüksek okuma-yazma performansına sahip olur, 5'i ise veri güvenilirliği ile okuma-yazma performansı arasında en iyi dengeye sahiptir), kullanıcının yazma işlemi önce N/2 + 1 sunuculara senkronize edilir ve ardından kullanıcıya geri gönderilerek kullanıcıdan başarılı yazma önerilir. Quorum Tabanlı Protokole dayalı veri senkronizasyon protokolü, Zookeeper'ın destekleyebileceği güç tutarlılığını belirler.
Dağıtık bir ortamda, güçlü tutarlılık sağlayan veri depolama temelde yoktur ve bir düğümün verisi güncellenirken tüm düğümlerin eşzamanlı güncellenmesini gerektirir. Bu senkronizasyon stratejisi, master-slave senkron replikasyon veritabanında da görülür. Ancak, bu senkronizasyon stratejisi yazma performansı üzerinde çok fazla etkiye sahiptir ve pratikte nadiren görülür. Zookeeper N/2+1 düğümlerini eşzamanlı yazdığı ve N/2 düğümlerin eşzamanlı güncellenmediği için, Zookeeper güçlü bir tutarlı değildir.
Kullanıcının veri güncelleme işlemi, sonraki okumaların güncellenmiş değeri okuyacağını garanti etmez, ancak sonunda tutarlılık gösterir. Tutarlılıktan ödün vermek, verinin tutarlılığını tamamen görmezden gelmek anlamına gelmez, aksi takdirde veri kaotiktir, bu yüzden sistemin kullanılabilirliği ne kadar yüksek olursa olsun, dağılım ne kadar iyi olursa olsun, bunun hiçbir değeri yoktur. Tutarlılıktan ödün vermek, ilişkisel veritabanlarında güçlü tutarlılığın artık gerekli olmaması, ancak sistemin nihai tutarlılığı sağlayabildiği sürece kullanılmasıdır.
Tek bir soru mu? Zookeeper kullanımı tek nokta sorununu etkili bir şekilde çözebilir, ZK kümeler halinde dağıtılır; kümedeki makinelerin yarısından fazlası hayatta kalırsa, hizmet dış dünyaya sunulabilir.
Adalet sorunları mı? Zookeeper kullanımı adil kilitler sorununu çözebilir; ZK'da istemci tarafından oluşturulan geçici düğümler düzenli olur ve kilit her açıldığında ZK en küçük düğümü kilidi almak için haber vererek adaleti sağlar.
Yine soru ortaya çıkıyor, Zookeeper'ın kümelerde dağıtılması gerektiğini biliyoruz, Redis kümeleri gibi veri senkronizasyonu sorunları olacak mı?
Zookeeper, zayıf tutarlılığı, yani nihai tutarlılığı garanti eden dağıtık bir bileşendir.
Zookeeper, Quorum Based Protocol adı verilen bir veri senkronizasyon protokolü kullanır. Zookeeper kümesinde N Zookeeper sunucusu varsa (N genellikle tektir, 3'ü veri güvenilirliğini karşılayabilir ve yüksek okuma-yazma performansına sahip olur, 5'i ise veri güvenilirliği ile okuma-yazma performansı arasında en iyi dengeye sahiptir), kullanıcının yazma işlemi önce N/2 + 1 sunuculara senkronize edilir ve ardından kullanıcıya geri gönderilerek kullanıcıdan başarılı yazma önerilir. Quorum Tabanlı Protokole dayalı veri senkronizasyon protokolü, Zookeeper'ın destekleyebileceği güç tutarlılığını belirler.
Dağıtık bir ortamda, güçlü tutarlılık sağlayan veri depolama temelde yoktur ve bir düğümün verisi güncellenirken tüm düğümlerin eşzamanlı güncellenmesini gerektirir. Bu senkronizasyon stratejisi, master-slave senkron replikasyon veritabanında da görülür. Ancak, bu senkronizasyon stratejisi yazma performansı üzerinde çok fazla etkiye sahiptir ve pratikte nadiren görülür. Zookeeper N/2+1 düğümlerini eşzamanlı yazdığı ve N/2 düğümlerin eşzamanlı güncellenmediği için, Zookeeper güçlü bir tutarlı değildir.
Kullanıcının veri güncelleme işlemi, sonraki okumaların güncellenmiş değeri okuyacağını garanti etmez, ancak sonunda tutarlılık gösterir. Tutarlılıktan ödün vermek, verinin tutarlılığını tamamen görmezden gelmek anlamına gelmez, aksi takdirde veri kaotiktir, bu yüzden sistemin kullanılabilirliği ne kadar yüksek olursa olsun, dağılım ne kadar iyi olursa olsun, bunun hiçbir değeri yoktur. Tutarlılıktan ödün vermek, ilişkisel veritabanlarında güçlü tutarlılığın artık gerekli olmaması, ancak sistemin nihai tutarlılığı sağlayabildiği sürece kullanılmasıdır.
Zookeeper'ın nedensel tutarlılığı karşılayıp karşılamadığı, istemcinin nasıl programlandığına bağlıdır.
Nedensel tutarlılığı karşılamayan uygulamalar
- Süreç A, Hayvanat Bahçesi Görevlisinin /z dosyasına bir veri yazar ve başarılı şekilde geri döner.
- Süreç A, B sürecine A'nın /z'nin verilerini değiştirdiğini bildirir
- B, Hayvanat Görevlisinin /z verilerini okur
- B'ye bağlı Hayvanat Görevlisinin sunucusu A'nın yazılı verileriyle güncellenmemiş olabilir, bu yüzden B A'nın yazılı verilerini okuyamayacak
Nedensel tutarlılığı karşılayan uygulamalar
- Süreç B, Zookeeper'da /z veri değişikliklerini dinler
- Süreç A, Hayvanat Bahçesi Bekçisinin /z'sine bir veri yazar ve başarılı şekilde geri dönmeden önce, Hayvanat Görevlisi /z'de kayıtlı dinleyiciyi araması gerekir ve lider B'ye veri değişikliğini bildirir
- B sürecinin olay yanıt yöntemi yanıtlandıktan sonra, değişen veri alınır, yani B kesinlikle değişen değeri alabilir
- Burada nedensel tutarlılık, Lider ile B arasındaki nedensel tutarlılığı ifade eder; yani lider bir değişikliği veriye bildirir
İkinci olay dinleme mekanizması da Zookeeper'ı doğru şekilde programlamak için kullanılması gereken yöntemdir; böylece Zookeeper nedensel tutarlılığı karşılamalıdır
Bu nedenle, Zookeeper tabanlı dağıtık kilitler uygularken, nedensel tutarlılığı sağlama pratiğini kullanmalıyız; yani kilidi bekleyen iş parçacıkları Zookeeper'ın kilidindeki değişiklikleri dinler ve kilit açıldığında, Zookeeper adil kilit koşullarını karşılayan bekleyen iş parçacığına bildirim verir.
Zookeeper üçüncü taraf kütüphane istemcisini doğrudan kullanabilirsiniz; bu istemciyi yeniden giriş kilidi hizmetini kapsele eder.
ZK ile uygulanan dağıtık kilitler, bu makalenin başında dağıtık bir kilitten beklediğimiz şeye tam olarak uyuyor gibi görünüyor. Ancak öyle değildir ve Zookeeper tarafından uygulanan dağıtık kilidin aslında bir dezavantajı vardır; yani performans önbellek servisi kadar yüksek olmayabilir. Çünkü kilit oluşturma ve serbest bırakma sürecinde, kilit fonksiyonunu gerçekleştirmek için anında düğümler dinamik olarak oluşturulmalı ve yok edilmelidir. ZK'da düğüm oluşturma ve silme yalnızca lider sunucu üzerinden yapılabilir ve ardından veri tüm takip makineleriyle paylaşılır.
Dağıtık kilitleri uygulamak için Zookeeper kullanmanın avantajları Tek nokta sorunlarını, yeniden giriş yapmama sorunlarını, engelleme sorunlarını ve kilit açılmamasını etkili bir şekilde çözer. Uygulaması nispeten basit.
Dağıtık kilitleri uygulamak için Zookeeper kullanmanın dezavantajları Performans, dağıtık kilitleri uygulamak için önbellek kullanmak kadar iyi değildir. ZK'nın ilkelerini anlamak gereklidir.
Üç seçeneğin karşılaştırması
Anlaşılma kolaylığı açısından (düşükten yukarıya) Veritabanı > Cache > Zookeeper
Uygulama karmaşıklığı açısından (düşükten yükseğe doğru) Zookeeper > önbellek > veritabanları
Performans açısından (yüksekten aşağıya) Önbellek > Zookeeper >= veritabanı
Güvenilirlik açısından (yüksekten düşüklere) Zookeeper > önbellek > veritabanları
|