Dağıtık Sistemlerde ‘Broadcasting’, ‘Cache’, ‘Lock’

Büyük, çok modüllü ve dağıtık olarak çalışan projeleriniz varsa, zamanla servislerinizin birbirleri ile haberleşmesi, dağıtık cache vs gibi çözümlere de ihtiyacınız olacaktır. Aynı zamanda birçok işlemin de cluster (küme) bazında tekil çalışması gerekecektir. Örnek olarak aynı anda kupon kullanımı, kullanıcının sadece tek bir işlem yapabilmesi gibi cluster bazında lock gerektiren işlemler karşınıza çıkacaktır.
In memory distributed cache, lock, broadcast, distributed task execution gibi bir çok özelliğe sahip bir çözüm ile tüm bunları aşmak mümkün. Bunun için kullanabileceğiniz, kendi topraklarımızdan çıkmış bir çözüm var; Hazelcast!

Hazelcast her istemcinin birer cluster node olabilmesini sağlıyor (Hazelcast sunucusu, servislerinize gömülü oluyor), dolayısı ile sunucu-istemci modeli şeklinde kullanmak zorunda kalmıyorsunuz. Ek olarak sunucu-istemci modeli ile de çalışmak mümkün.
İkisinin de kendine özgü avantaj ve dezavantajları mevcut.

Örneğin servisinize gömülü olarak olarak kullandığınızda entegrasyonu oldukça basit ve ekstra olarak Hazelcast servis sunucularını yönetmeye gerek kalmıyor. Servisiniz çalıştığı anda ayarladığınız şekilde Hazelcast cluster’a node olarak dahil oluyor, replikasyon ve buna benzer operasyonları otomatik olarak yapıyor.
Bu yapıya ait üzerinde durulması gereken bir sorun ise yoğun bir in memory grid işlemleri kullanımı var ise bu durumda kendi servislerinizin kaynaklarını kullanmaya başlıyorsunuz ve bellek ve işlemci gibi kaynakların kullanımlarının nasıl dengesizleştiğini ve neden böyle olduğunu, servislerinizin yapması gereken birçok başka işi varken, bir de Hazelcast cluster üzerinde node rolü üstlenip tüm bu görevlerinde aksaklıklar yaşadığını görüyorsunuz.
Sunucu-istemci modeli tercih edildiğinde ise servisleriniz birer istemci olarak bağlanacağı cluster’ı arıyor olacak. Bunun için ise birkaç adet Hazelcast sunucu node instance ayarlamanız ve bunları da yönetmeniz gerekecek. Yine de ben kendi işlerini yapan sunucu instance’larını kullanmayı tercih ederim. Yönetimi biraz daha karmaşık olsa da sunucuların inmesi vs. durumları hariç sessiz sedasız çalışmaya devam ediyorlar ve yönetimi de çok zor olmuyor.
Kaynakları ayrı, işleri kendilerine özgü
İstenildiğinde uygulama servislerinizi ölçeklendirmek yerine daha küçük ve az maliyetli olan Hazelcast node instance’larınızı ölçeklendirebiliyorsunuz.
Tüm cluster’daki node’lara ve istemcilere “Hey, şöyle bir mesajım var. Lütfen aksiyon alın!” demek için tek yapmanız gereken Hazelcast ile belirli bir topic üzerinden mesaj göndermek. Servisleriniz bu topic’i dinliyor ise mesajı alacak ve istediğiniz aksiyonu yapmaya koyulacak. Cache uygulamanız gerekiyor fakat bunu tek bir yerden güncelleyebilmek ve her yerden güncel veriye ulaşabilmek istiyorsunuz, dağıtık olsun ve yük de dağılsın diyorsunuz, replikasyon da olsun, veri kaybı (cache olduğu için kısa süreli olsa da) olmasın diyorsunuz. İşte burda yine Hazelcast’in Map, Set gibi in-memory data grid özelliklerini rahatça yapılandırıp kullanabiliyorsunuz.Lock için yapabilecekleriniz
Lock mekanizması uygulamanın birkaç yolu mevcut tabii. Örneğin veritabanı lock yapılabilir fakat transaction sayısının yüksek olduğu ve performansın üst düzeyde olması gerektiği kısımlarda birbiri ile hızlı haberleşebilen çözümler düşünmek gerekiyor. Bunu yapmak için kendiniz bir sistem yazabilirsiniz fakat bu oldukça maliyetli olacaktır. Bağlanan ve lock alan kişilerin heartbeat işlemleri, deadlock gibi bir çok konuyu düşünmeniz gerekecektir.
Redis vs. gibi sistemler de kullanılabilmekte fakat “single point of failure” yaratmamak için cluster, master-slave gibi mekanizmaların kullanıldığı durumda kritik lock işlemlerinde asenkron bir replikasyon sunduğundan bu işlem tam güven sağlayamamaktadır. Bunun için Redis’in sunduğu çözüm ise Redlock.

Redlock bir algoritma ve bu algoritma farklı şekillerde uygulanabiliyor. Örneğin Java için kullanılan kütüphaneler tam istenilen performansta çalışmıyor ve bug’lar içeriyorlar. Redlock’ı merak edenler ayrıca araştırabilirler.
Hazelcast ile lock çözümü oldukça kolay!
Çok aktif bir lock sistemi kullanılmayacak ise Hazelcast’in hazır olarak sunduğu ILock mekanizmasının kullanımı oldukçta basit, kullanışlı ve iş görüyor. Fakat çok fazla lock işlemi kullanılıyor ise bu yapının bir handikapı var: Lock’lardan tek bir node sorumlu! Bu da bu node’un çok yoğun işlem yapması ve ağır yük altında kalıp cevap verememesi gibi sorunlara yol açabiliyor. Cevap verememesi durumunda ise cluster’dan düşüyor ve bu görevi bir başkası devralırken çok uzun zaman harcıyor. Ardından bu daha büyük bir kaynak kullanımına sebep olduğu için de yeni devralan servis de dayanamayıp düşüyor. Kartopu etkisi ile tüm cluster dağılabiliyor. Ayrıca bu görevden kurtulan node otomatik olarak tekrar cluster’a bağlanıp kısır döngü oluşturabiliyor.
Bu durumda imdadımıza IMap denilen key-value şeklindeki distributed in-memory cache mekanizması yetişiyor. Bu yapı, key başına lock yapabiliyor ve key’lerden sorumlu kişiler ayrı birer node olabildiği için yük dağıtılabiliyor ve ölçeklendirilebiliyor. Tabii bu durumda kullanılan map için replikasyon, yedekleme vs. gibi verilerin nasıl saklanması gerektiğin Hazelcast cluster’ınızda ayarlamayı unutmamanız lazım (quorum replica gibi).
Kodunuz keskin olsun!