Dağıtılmış kilit ilkelerini öğrenme ve düşünme-redis dağıtılmış kilit, zookeeper dağıtılmış kilit

İlk olarak, dağıtılmış kilitler temelde genellikle bahsettiğimiz kilit ilkeleriyle aynıdır.Amaç, birden fazla iş parçacığı eşzamanlı olduğunda, aynı anda yalnızca bir iş parçacığının bu işi veya yöntemi veya değişkeni çalıştırmasını sağlamaktır.

Bir süreçte, yani bir jvm veya uygulamada kontrolü kolaylıkla halledebiliriz. Jdk java.util eşzamanlılık paketi bize senkronize anahtar kelime veya Kilit kilidi gibi kilitlemek için bu yöntemleri sağladı. uğraşmak.

Ancak mevcut uygulamamız yalnızca bir sunucu kullanıyorsa, eşzamanlılık miktarı çok düşüktür.Aynı anda on binlerce istek varsa, aşırı sunucu baskısına ve felce neden olabilir.

30'unda saat 10'da Double Eleven ve Alipay kırmızı zarflar gibi iş senaryolarını düşünün. Doğal olarak, bu hizmetleri aynı anda işlemek için birden fazla sunucuya ihtiyaç vardır, o zaman aynı anda işlenebilecek yüzlerce hizmet olabilir.

Ama lütfen bir düşünün, kırmızı zarf işini halledecek 100 sunucu varsa, şimdi varsayalım ki 100 milyon kırmızı zarf, 10 milyon ayrı nokta var ve miktar rastgele, o zaman bu iş senaryosunda bu 10 milyonu sağlamak gerekli mi? Bireyler tarafından dağıtılan toplam kırmızı zarf miktarı 100 milyona eşittir.

Eğer bunu iyi idare etmezseniz ~~ herkes 1 milyon alır, o zaman Jack Manın babası yeni yılın ilk gününde iflas ilan etmesi gerekeceğini tahmin ediyor ~~

1. Geleneksel kilitlere ne olur?

Her şeyden önce, neden bir küme kurmak istediğimizden bahsedeyim Basit anlayış, talebin (eşzamanlı taleplerin miktarı) arttığı ve bir işçinin işleme kapasitesinin sınırlı olduğudur, bu nedenle birlikte halletmek için daha fazla işçi işe alın.

10 milyon isteğin 100 sunucuya eşit olarak dağıtıldığını varsayarsak, her sunucu 10w istek alır (10w istekler aynı saniyede gelmez, belki bir veya iki saat içinde bize üç tane düşünebilirsiniz. Kırmızı zarflar on gecede açıldı ve 10.20'de başladıklarında, bazıları hemen açtı, bazıları hatırlamak için saat 12'ye kadar bekledi mi ~)

Bu durumda, saniyedeki ortalama istek sayısı 1.000'den azdır ve bu tür bir baskı, sunucular için hala kabul edilebilir.

İlk talep geldikten sonra, ona 100 milyonluk bir pay vermek gerekli midir, miktar rastgele, ilk kişinin 100 aldığı varsayılırsa, bu 100 milyondan 100 yuan çıkarmak gerekli midir, 99999900 yuan ~

İkinci kullanıcı tekrar bölecek, miktar rastgele ve bu sefer 200 yuan'a bölünecek. Kalan 9,999900 yuan'dan 200 yuan çıkarması gerekiyor mu, geriye 99999700 yuan kalıyor.

10. kullanıcı geldiğinde, hala 1000w var, o zaman bu 1000w onun.

Her sunucuda 100 milyonu bölmekle eşdeğerdir, yani 10w kullanıcı 100 milyona bölünür ve nihayet toplamda 100 sunucu vardır ki bu da 10 milyar gerektirir.

Durum böyleyse, Jack Manın babası iflas etmeyecek olsa da (son istatistiklere göre Jack Manın 230 milyar yuanı var), o zaman bonusu paylaşan geliştirme projesi ekibi ve ürün yöneticisi GG olabilir ~

Basitleştirilmiş yapı şeması aşağıdaki gibidir:

2. Dağıtılmış kilitlerle nasıl başa çıkılır?

Yani bu sorunu çözmek için 10 milyon kullanıcının 10 milyar yerine sadece 100 milyonu bölmesine izin verin Şu anda dağıtılmış kilitler işe yarıyor.

Dağıtılmış kilitler tüm kümeyi bir uygulama olarak ele alabilir, bu nedenle bu kilit, hizmetten değil her hizmetten bağımsız olarak da gereklidir.

İlk sunucunun 1. kullanıcının talebini aldıktan sonra, şu anda kendi uygulamasında ne kadar para kaldığına karar veremeyeceğini, 100 milyon kırmızı zarfı yönetmekten sorumlu kişiden istemek için dışarı çıkması gerektiğini varsayalım. (Hizmet), ona sorun: Hey, burada 100 yuan'ı bölmek ve bana 100 vermek istiyorum.

Kırmızı zarfı (hizmet) yöneten kız hala 100 milyon olduğunu gördü, bu iyi, sana 100 vereceğim ve sonra 999999900 kaldı.

İkinci istek geldikten sonra sunucu 2 tarafından alındı ve sorgulamaya devam ettim.Kırmızı zarfı yöneten kız için 10 parçaya bölmem gerekiyor.Kırmızı zarfı yöneten kız önce kontrol etti ve 99999900 var, sonra dedi ki: Tamam, sana 10 ver Parça. Sonra 99998890 yuan kaldı

1000'inci istek geldikten sonra, sunucu 100 isteği alır ve sorgulamaya devam eder.Kırmızı zarfı yöneten kız, sen 100 istiyorsun. Kız gözlerini deviriyor ve sana sadece 1 yuan kaldığını söylüyor. Sevmek istiyorsan, o zaman bu sefer Size sadece 1 yuan verebilirim (1 yuan aynı zamanda paradır ve kök yaban turpu satın almak hala uygundur).

Bu 1, 2 numaralı talep, yürütme sırasını temsil etmez.Resmi bir senaryoda, 100 sunucu olmalıdır.Her sunucu, kırmızı zarfı yönetmekten sorumlu kıza (hizmete) erişim talebinde bulunur.Kırmızı zarfı yöneten kız da 100 istek alındı Bu sefer kırmızı zarftan sorumlu kıza bir kilit eklemeniz gerekiyor (ortancayı fırlatmak). 100 sunucunuzdan her kim kilidi alırsa (ortancayı kaparak), gelin ve benimle konuşun, vereceğim Sen bölüyorsun, diğerleri gitmeyi bekliyor

Yukarıdaki dağıtılmış kilit işleminden sonra, Jack Ma'nın babası nihayet rahatladı ve kırmızı zarf ekibinin her birine bir tavuk budu eklemeye karar verdi.

Basitleştirilmiş yapı şeması aşağıdaki gibidir:

3. Dağıtılmış kilitlerin uygulamaları nelerdir?

Dağıtılmış kilitlerin gerçekleştirilmesi söz konusu olduğunda, hala çok sayıda veritabanı yöntemi vardır, dağıtılmış kilitleri redis, zookeeper dağıtılmış kilitleri vb.

Redis'i dağıtılmış bir kilit olarak kullanırsak, yukarıdaki resimdeki "kırmızı zarftan (hizmet) sorumlu olan kız" redis ile değiştirilebilir. Lütfen kendi kararınızı verin.

3.1 Neden yeniden dağıtılmış kilitleri uygulayabilir?

Her şeyden önce, redis tek iş parçacıklıdır.Buradaki tek iş parçacığı, bir iş parçacığı kullanan ağ istek modülünü ifade eder (bu nedenle eşzamanlılık güvenliğini dikkate almaya gerek yoktur), yani, bir iş parçacığı tüm ağ isteklerini ele alır ve diğer modüller hala birden çok iş parçacığı kullanır.

Gerçek operasyonda süreç kabaca şu şekildedir:

Sunucu 1, redis olan kırmızı zarfı gönderen kızı ziyaret edecek, daha sonra "setnx anahtar değeri" işlemi ile redis'de bir anahtar ayarlayacak ve değer önemli değil, önemli olan bir anahtara, yani bir işarete sahip olmak. , Ve bu anahtar, tüm sunucular aynı anahtara sahip olduğu sürece istediğiniz şeydir.

Aşağıda gösterildiği gibi bir tane ayarladığımızı varsayalım

O zaman 1'in döndüğünü görebiliriz, bu da başarı anlamına gelir.

Aynı anahtarı ayarlamak için aşağıda gösterildiği gibi başka bir istek varsa:

Şu anda 0 döndürecektir, bu da başarısızlık anlamına gelir.

Daha sonra kilidin mevcut olup olmadığını belirlemek veya "kırmızı zarf göndermekten sorumlu kızı" ziyaret etmek için bu işlemi kullanabiliriz, eğer 1 döndürürse, 0 döndürürse aşağıdaki mantığı çalıştırmaya başlayacağım, sonra Bu işgal edildiği anlamına geliyor ve ben beklemeye devam edeceğim.

Sunucu 1 kilidi aldıktan sonra, iş sürecini gerçekleştirir. Tamamlandıktan sonra, aşağıdaki şekilde gösterildiği gibi kilidi de bırakması gerekir:

Silme başarılı olursa ve 1 döndürürse, diğer sunucular kilidi alma amacına ulaşmak için bu anahtarı ayarlamak için yukarıdaki adımları tekrarlamaya devam edebilir.

Tabii ki yukarıdaki işlemler direkt olarak redis istemcisi üzerinde gerçekleştirilir.Bir program üzerinden çağırırsanız kesinlikle böyle yazamazsınız.Örneğin java'nın jedis üzerinden çağrılması gerekir ama tüm işlem mantığı temelde aynıdır.

Yukarıdaki yöntemle, dağıtılmış kilit sorununu çözmüş gibiyiz, ancak herhangi bir sorun var mı? ?

Evet, hala sorunlar var Kilitlenme meydana gelebilir Örneğin, sunucu 1 kurulduktan sonra, kilidi aldıktan sonra aniden çöküyor.

Daha sonra sonraki silme tuşu işlemi yürütülemez. Bu anahtar her zaman redis içinde olacaktır.Diğer sunucular her kontrol ettiğinde, 0 döndürür. Birisinin kilidi kullandığını düşünecekler. Beklemem gerekiyor.

Bu kilitlenme problemini çözmek için, anahtarın geçerlilik süresini ayarlamamız gerekiyor.

Ayarlamanın 2 yolu vardır

1. Birincisi, anahtar ayarlandıktan sonra "anahtar zaman aşımının sona ermesi" anahtarının sona erme süresini doğrudan ayarlamak ve anahtar için saniye cinsinden bir zaman aşımı süresi ayarlamaktır Kilit, kilitlenmeyi önlemek için bu süreden sonra otomatik olarak serbest bırakılacaktır.

Bu yöntem, kilidin geçerlilik süresini kontrole redis'e devretmeye eşdeğerdir. Süre dolduysa ve anahtarı benim için silmediyseniz, redis onu sizin için doğrudan siler ve diğer sunucular kilidi almak için setnx'e devam edebilir.

2. İkinci yol, anahtarı diğer sunuculara silme hakkı vermektir, bu durumda değer değerine bu sefer ihtiyaç duyulur.

Örneğin, sunucu 1 değeri, yani zaman aşımını geçerli zaman + 1 saniyeye ayarlar Bu zamanda, sunucu 2 get yoluyla, zamanın geçerli sistem zamanını aştığını bulur, bu, sunucu 1'in kilidi serbest bırakmadığı ve sunucu 1'in bir sorun yaşayabileceği anlamına gelir.

Sunucu 2, tuş işlemini silmeye başlar ve setnx işlemini yürütmeye devam eder.

Ancak bununla ilgili bir sorun var, yani sadece sunucunuz 2 sunucu 1'in zaman aşımına uğradığını bulmayabilir, aynı zamanda sunucu 3 de bu olursa sunucu 2, setnx işlemi tamamlanır, sunucu 3 silinir, sunucu 3 de silinir Setnx başarılı olabilir mi?

Bu, hem Sunucu 2 hem de Sunucu 3'ün kilidi almasına eşdeğerdir ki bu büyük bir problemdir. Şu anda ne yapmalı?

Şu anda, "GETSET anahtar değeri" komutu gereklidir. Bu komutun anlamı, mevcut anahtarın değerini almak ve yeni bir değer belirlemektir.

Sunucu 2'nin anahtarın süresinin dolduğunu bulduğunu varsayarsak, getset komutunu çağırmaya başlar ve elde edilen süreyi süresinin dolup dolmadığını belirlemek için kullanır.Eğer elde edilen süre hala dolmuşsa kilidin alındığı anlamına gelir.

Aksi takdirde, sunucu 2 getset'i yürütmeden önce, sunucu 3'ün kilidin sona erdiğini de bulabileceği ve sunucu 2'nin sona erme süresini sıfırlamak için sunucu 2'den önce getset işlemini yürüteceği anlamına gelir.

Ardından, sunucu 2'nin sonraki işlemleri bırakması ve sunucu 3'ün kilidi açmasını veya anahtarın geçerlilik süresinin dolup dolmadığını izlemesi için beklemeye devam etmesi gerekir.

Aslında bu alanda küçük bir problem var Sunucu 3 geçerlilik süresini değiştirdi.Kilidi aldıktan sonra sunucu 2 de geçerlilik süresini değiştirdi ancak kilidi alamadı ancak geçerlilik süresi sunucu 3'e göre değiştirildi. Biraz artırın, ancak bu etki aslında hala çok küçük, neredeyse ihmal edilebilir.

3.2 Zookeeper neden dağıtılmış kilitleri uygulayabilir?

Baidu Ansiklopedisi böyle tanıtıldı: ZooKeeper, dağıtılmış, açık kaynak kodlu dağıtılmış bir uygulama koordinasyon hizmeti, Google'ın Chubby'sinin açık kaynaklı bir uygulaması ve önemli bir Hadoop ve Hbase bileşenidir.

İlk defa tanıdığımız insanlar için, ZooKeeper'ın bilgisayar dosya sistemimiz gibi olduğu anlaşılabilir.D sürücüsünde a klasörü oluşturabilir ve a klasöründe a1, a2 klasörleri oluşturmaya devam edebiliriz.

Dosya sistemimizin özellikleri nelerdir? ? Yani, aynı dizindeki dosya adları tekrar edilemez, aynı durum ZooKeeper için de geçerlidir.

ZooKeeper'daki tüm düğümler, yani klasör Znode olarak adlandırılır ve bu Znode düğümü verileri depolayabilir.

"Create / zkjjj nice" ile bir düğüm oluşturabiliriz Bu komut, güzel değeriyle kök dizinde bir zkjjj düğümü oluşturmak anlamına gelir. Buradaki aynı değer daha önce bahsettiğim redis ile aynı, anlamı yok, istediğinizi verebilirsiniz.

Ek olarak, ZooKeeper 4 tür düğüm oluşturabilir, yani:

1. Kalıcı düğüm

2. Kalıcılık dizisi düğümü

3. Geçici düğümler

4. Geçici sıralı düğümler

Önce kalıcı bir düğüm ile geçici bir düğüm arasındaki farktan bahsedeyim Kalıcı düğüm, ZooKeeper istemcinizin bağlantısı kesilmiş olsun veya olmasın, bu düğümü yarattığınız sürece, ZooKeeper sunucusunun bu düğümü kaydedeceği anlamına gelir.

Geçici düğümler tam tersidir ZooKeeper istemcinizin bağlantısı kesildiğinde, ZooKeeper sunucusu artık bu düğümü kaydetmeyecektir.

Sıralı düğümlerden bahsedelim Sıralı düğümler, düğümler oluştururken ZooKeeper'ın 0000001 ve 0000002 gibi düğümleri otomatik olarak numaralandıracağı anlamına gelir.

Son olarak, zookeeper bir izleme mekanizmasına sahiptir. İstemci, ilgilendiği dizin düğümlerini kaydeder ve dinler. Dizin düğümü değiştiğinde (veri değişir, silinir, alt dizin düğümleri eklenir veya silinir) vb., Zookeeper istemciyi bilgilendirir.

Zookeeper'da nasıl kilitleneceğinizi açıklamak için yukarıdaki bonus senaryomuzu birleştirmeye devam edelim.

Sunucu 1'in bir düğüm / zkjjj oluşturduğunu ve başarılı olduğunu, ardından sunucu 1'in kilidi aldığını ve sunucu 2'nin aynı kilidi tekrar oluşturduğunu ve bu durumda başarısız olacağını varsayalım.Şu anda yalnızca bu düğümün değişikliklerini izleyebilir.

Sunucu 1, işi işlemeyi bitirip düğümü silinceye kadar bekleyin, kendisine bildirim gönderilecek ve ardından aynı düğümü oluşturacak, işi yürütmek için kilidi alacak ve ardından düğümü silecektir. Sonraki 100 sunucu benzerdir

Buradaki 100 sunucunun yukarıdaki düğüm oluşturma işlemini tek tek değil, aynı anda yürüttüğünü unutmayın. Sunucu 1 başarıyla oluşturulduğunda, kalan 99 sunucu bu düğümü kaydedecek ve dinleyecek, bildirimi bekleyecek vb.

Ama burada hala bir sorun olduğunu fark ettiniz mi, yoksa yine de kilitlenmeler olacak, değil mi?

Sunucu 1 bir düğüm oluşturduktan sonra telefonu kapattığında ve onu silemediğinde, diğer 99 sunucu bildirimleri beklemeye devam edecek ve sona erecektir. . .

Şu anda, geçici düğümler kullanmanız gerekiyor, daha önce de söylediğimiz gibi, geçici düğümlerin özelliği, istemci bağlantısı kesildiğinde, yani sunucu 1 düğüm oluşturduğunda, kilitlenirse kaybolacak olmasıdır.

Ardından bu düğüm otomatik olarak silinecek, böylece sonraki diğer sunucular düğümler oluşturmaya ve kilitler almaya devam edebilecek.

Ancak sürü etkisine de dikkat etmemiz gerekebilir: çok basit bir örnek vermek gerekirse, bir güvercin grubunun ortasına bir parça yiyecek attığınızda, sonunda yiyeceği sadece bir güvercin kapsa da, tüm güvercinler yarışmak için alarma geçecektir. Kapmak...

Yani, sunucu 1 düğümünde bir değişiklik olduğunda, kalan 99 sunucuya haber verilecek, ancak sonunda yalnızca 1 sunucu başarıyla oluşturulacak, bu nedenle 98'in hala izleme için beklemesi gerekiyor, bu nedenle bu durumla başa çıkmak için geçici sıralı düğümler kullanmanız gerekiyor

Bunun kaba anlamı, 99 sunucunun tümü bir düğümü dinlemeden önce, şimdi her sunucunun kendi önündeki bir düğümü dinlemesidir.

100 sunucunun aynı anda istek gönderdiğini varsayarsak, şu anda 100 geçici sıralı düğüm / zkjjj / 000000001, / zkjjj / 000000002, / zkjjj düğümü altında oluşturulacak ve / zkjjj / 000000100'e kadar bu sayı onlar için ayarlanmış olmaya eşdeğerdir Kilitlerin alındığı sıra.

001 düğümü işlendiğinde ve düğüm silindiğinde, 002 bir bildirim alır, kilidi alır, yürütmeyi başlatır, yürütmeyi bitirir, düğümü siler ve 003 ~ bildirir vb.

Transfer: https://www.cnblogs.com/JJJ1990/p/10496850.html

Pingxiang, Hebei: "Buğday Tarlası Kontrolü" gelirin artmasına yardımcı oluyor
önceki
İlkokul oluşumu, Halk Donanmasına haraç vermek için "Deniz Geçidi" düzenledi
Sonraki
"Like You Me Too" da kabin atmosferi donma noktasına geldi .. Erkek konuk neden öfkeyle ayrılıyor?
Saf kuru ürünler | Şimdiye kadar gördüğüm daha kapsamlı BERT ürünleri, şiddetle tavsiye edilir
Hızlı yaşlanmana şaşmamalı! Ama çoğu insan sık sık ...
Transformer ve BERT Üzerine Kısa Bir Konuşma
Ne dağınıklık! Havaalanının camı hayranlar tarafından parçalandı ve Kamu Güvenliği Bakanlığı yardım edemedi ama konuştu
Saf kuru ürünler | Boosting ailesinin Adaboost algoritması
Akşam saat 2'de Zhejiang'lı bir kadın 120'yi aradı, ama ambulanstan çıkan kocasıydı! orijinal
Öneri algoritması yeterince doğru değil mi? Bilgi grafiği çözsün
Kar düştü! Bu yıldız şirkete ne oldu
Borsa birçok iyi hafta sonunun ardından neden düştü?
Qingdao, Shandong: İlkokul öğrencileri Dünya Kitap Gününü kutlamak için "Dört Bahar" etkinliği düzenlediler.
Kırsal canlanma için yetenek desteği sağlayın! Shantou "Binlerce, Yüzlerce ve Onlarca" yerel yetenek geliştirme projesini başlattı
To Top