Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Mail.ru Group'ta Tarantool'umuz var - bu, Lua'da aynı zamanda veritabanı görevi de gören bir uygulama sunucusudur (veya tam tersi?). Hızlı ve harikadır ancak bir sunucunun yetenekleri hala sınırsız değildir. Dikey ölçeklendirme de her derde deva değildir, bu nedenle Tarantool'un yatay ölçeklendirme için araçları vardır - vshard modülü [1]. Verileri birkaç sunucuya ayırmanıza olanak tanır, ancak onu kurmak ve iş mantığını eklemek için üzerinde oynamalar yapmanız gerekir.

İyi haber: Bazı önemli fotoğrafları topladık (ör. [2], [3]) ve bu sorunun çözümünü önemli ölçüde kolaylaştıracak başka bir çerçeve oluşturdu.

Tarantool Kartuş karmaşık dağıtılmış sistemlerin geliştirilmesi için yeni bir çerçevedir. Altyapı sorunlarını çözmek yerine iş mantığını yazmaya odaklanmanızı sağlar. Kesimin altında size bu çerçevenin nasıl çalıştığını ve onu kullanarak dağıtılmış hizmetlerin nasıl yazılacağını anlatacağım.

Ve gerçekte sorun ne?

Bir tarantulamız var, vshard'ımız var; daha ne isteyebilirsiniz ki?

Öncelikle bu bir kolaylık meselesi. Vshard yapılandırması Lua tabloları aracılığıyla yapılandırılır. Birden çok Tarantool işleminden oluşan dağıtılmış bir sistemin doğru çalışması için yapılandırmanın her yerde aynı olması gerekir. Kimse bunu manuel olarak yapmak istemez. Bu nedenle her türlü script, Ansible ve dağıtım sistemi kullanılmaktadır.

Kartuş vshard yapılandırmasını kendisi yönetir, bunu kendi kendi dağıtılmış konfigürasyonu. Bu aslında basit bir YAML dosyasıdır ve bir kopyası her Tarantool örneğinde saklanır. Basitleştirme, çerçevenin kendisinin konfigürasyonunu izlemesi ve her yerde aynı olmasını sağlamasıdır.

İkincisi, bu yine bir kolaylık meselesidir. Vshard konfigürasyonunun iş mantığının gelişimi ile hiçbir ilgisi yoktur ve yalnızca programcının dikkatini işinden uzaklaştırır. Bir projenin mimarisini tartıştığımızda çoğunlukla bireysel bileşenlerden ve bunların etkileşiminden bahsederiz. Bir kümeyi 3 veri merkezine yaymayı düşünmek için henüz çok erken.

Bu sorunları tekrar tekrar çözdük ve bir noktada uygulamayla tüm yaşam döngüsü boyunca çalışmayı kolaylaştıran bir yaklaşım geliştirmeyi başardık: oluşturma, geliştirme, test etme, CI/CD, bakım.

Kartuş, her Tarantool işlemi için bir rol kavramını tanıtır. Roller, geliştiricinin kod yazmaya odaklanmasını sağlayan bir kavramdır. Projede mevcut tüm roller tek bir Tarantool örneğinde çalıştırılabilir ve bu, testler için yeterli olacaktır.

Tarantool Kartuşunun temel özellikleri:

  • otomatik küme orkestrasyonu;
  • yeni roller kullanarak uygulamanın işlevselliğini genişletmek;
  • geliştirme ve dağıtım için uygulama şablonu;
  • yerleşik otomatik parçalama;
  • Luatest test çerçevesiyle entegrasyon;
  • WebUI ve API kullanarak küme yönetimi;
  • paketleme ve dağıtım araçları.

Selam Dünya!

Çerçevenin kendisini göstermek için sabırsızlanıyorum, bu yüzden mimariyle ilgili hikayeyi sonraya bırakacağız ve basit bir şeyle başlayacağız. Tarantool'un zaten kurulu olduğunu varsayarsak, geriye kalan tek şey

$ tarantoolctl rocks install cartridge-cli
$ export PATH=$PWD/.rocks/bin/:$PATH

Bu iki komut, komut satırı yardımcı programlarını yükleyecek ve ilk uygulamanızı şablondan oluşturmanıza olanak tanıyacaktır:

$ cartridge create --name myapp

Ve elde ettiğimiz şey bu:

myapp/
├── .git/
├── .gitignore
├── app/roles/custom.lua
├── deps.sh
├── init.lua
├── myapp-scm-1.rockspec
├── test
│   ├── helper
│   │   ├── integration.lua
│   │   └── unit.lua
│   ├── helper.lua
│   ├── integration/api_test.lua
│   └── unit/sample_test.lua
└── tmp/

Bu, hazır bir "Merhaba Dünya!" içeren bir git deposudur. başvuru. Bağımlılıkları önceden yükledikten sonra (çerçevenin kendisi dahil) hemen çalıştırmayı deneyelim:

$ tarantoolctl rocks make
$ ./init.lua --http-port 8080

Yani gelecekteki parçalı uygulama için çalışan bir düğümümüz var. Meraklı bir meslekten olmayan kişi, web arayüzünü hemen açabilir, fareyle bir düğüm kümesini yapılandırabilir ve sonucun tadını çıkarabilir, ancak sevinmek için henüz çok erken. Şu ana kadar uygulama işe yarar bir şey yapamadı o yüzden konuşlandırmayı daha sonra anlatacağım ama şimdi sıra kod yazmaya geldi.

Uygulama geliştirme

Düşünün, günde bir kez veri alıp, kaydedip rapor oluşturması gereken bir proje tasarlıyoruz.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Bir diyagram çizmeye başlıyoruz ve üzerine üç bileşeni yerleştiriyoruz: ağ geçidi, depolama ve zamanlayıcı. Mimari üzerinde daha fazla çalışıyoruz. Depolama olarak vshard kullandığımız için şemaya vshard-router ve vshard-storage ekliyoruz. Ne ağ geçidi ne de zamanlayıcı doğrudan depolamaya erişemez; yönlendirici bunun için yaratılmıştır, bunun için yaratılmıştır.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Bu diyagram hala projede inşa edeceğimiz şeyi tam olarak temsil etmiyor çünkü bileşenler soyut görünüyor. Bunun gerçek Tarantool'a nasıl yansıtılacağını hâlâ görmemiz gerekiyor; hadi bileşenlerimizi sürece göre gruplandıralım.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

vshard-router ve ağ geçidini ayrı örneklerde tutmanın pek bir anlamı yoktur. Bu zaten yönlendiricinin sorumluluğundaysa neden ağda bir kez daha gezinmemiz gerekiyor? Aynı süreç içerisinde çalıştırılmaları gerekir. Yani, hem ağ geçidi hem de vshard.router.cfg tek bir işlemde başlatılır ve bunların yerel olarak etkileşime girmesine izin verilir.

Tasarım aşamasında üç bileşenle çalışmak uygundu, ancak ben bir geliştirici olarak kodu yazarken Tarnatool'un üç örneğini başlatmayı düşünmek istemiyorum. Testleri çalıştırmam ve ağ geçidini doğru yazdığımı kontrol etmem gerekiyor. Ya da belki meslektaşlarıma bir özellik göstermek istiyorum. Neden üç kopyayı dağıtma zahmetine gireyim? Rol kavramı böyle doğdu. Rol, yaşam döngüsü Kartuş tarafından yönetilen normal bir luash modülüdür. Bu örnekte bunlardan dördü vardır: ağ geçidi, yönlendirici, depolama, zamanlayıcı. Başka bir projede daha fazlası olabilir. Tüm roller tek bir süreçte çalıştırılabilir ve bu yeterli olacaktır.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Aşamalandırma veya üretime dağıtım söz konusu olduğunda, donanım özelliklerine bağlı olarak her Tarantool sürecine kendi rol kümesini atayacağız:

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

topoloji yönetimi

Hangi rollerin nerede çalıştığına ilişkin bilgilerin bir yerde saklanması gerekir. Ve bu "bir yer" yukarıda bahsettiğim dağıtılmış konfigürasyondur. Bununla ilgili en önemli şey küme topolojisidir. İşte 3 Tarantool işleminin 5 çoğaltma grubu:

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Verileri kaybetmek istemiyoruz, bu nedenle yürütülen süreçlerle ilgili bilgilere dikkatli davranıyoruz. Kartuş, iki aşamalı bir taahhüt kullanarak yapılandırmayı takip eder. Yapılandırmayı güncellemek istediğimizde, ilk olarak tüm örneklerin mevcut ve yeni yapılandırmayı kabul etmeye hazır olup olmadığını kontrol eder. Bundan sonra ikinci aşama yapılandırmayı uygular. Böylece, bir kopya geçici olarak kullanılamasa bile kötü bir şey olmayacaktır. Yapılandırma uygulanmayacaktır ve önceden bir hata göreceksiniz.

Ayrıca topoloji bölümünde her çoğaltma grubunun lideri gibi önemli bir parametre belirtilir. Genellikle bu, kaydedilen kopyadır. İstisnalar olabilmesine rağmen geri kalanlar çoğunlukla salt okunurdur. Bazen cesur geliştiriciler çatışmalardan korkmazlar ve paralel olarak birkaç kopyaya veri yazabilirler, ancak ne olursa olsun iki kez gerçekleştirilmemesi gereken bazı işlemler vardır. Bunun için bir liderin işareti var.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Rollerin hayatı

Böyle bir mimaride soyut bir rolün var olabilmesi için çerçevenin bunları bir şekilde yönetmesi gerekir. Doğal olarak kontrol, Tarantool sürecini yeniden başlatmadan gerçekleşir. Rolleri yönetmek için 4 geri arama vardır. Kartuşun kendisi, dağıtılmış konfigürasyonunda yazılanlara bağlı olarak bunları arayacak ve böylece konfigürasyonu belirli rollere uygulayacaktır.

function init()
function validate_config()
function apply_config()
function stop()

Her rolün bir işlevi vardır init. Rol etkinleştirildiğinde veya Tarantool yeniden başlatıldığında bir kez çağrılır. Örneğin, box.space.create'i başlatmak uygundur veya zamanlayıcı, belirli zaman aralıklarında iş gerçekleştirecek bazı arka plan fiberlerini başlatabilir.

Tek işlev init yeterli olmayabilir. Kartuş, rollerin topolojiyi depolamak için kullandığı dağıtılmış yapılandırmadan yararlanmasına olanak tanır. Aynı konfigürasyonda yeni bir bölüm ilan edebilir ve iş konfigürasyonunun bir parçasını burada saklayabiliriz. Örneğimde bu, zamanlayıcı rolü için bir veri şeması veya zamanlama ayarları olabilir.

Küme çağrıları validate_config и apply_config dağıtılmış konfigürasyon her değiştiğinde. Bir konfigürasyon iki aşamalı bir taahhütle uygulandığında, küme her rolün bu yeni konfigürasyonu kabul etmeye hazır olup olmadığını kontrol eder ve gerekirse kullanıcıya bir hata bildirir. Herkes konfigürasyonun normal olduğu konusunda hemfikir olduğunda, o zaman apply_config.

Ayrıca rollerin de bir yöntemi vardır stop, rolün çıktısını temizlemek için gereklidir. Bu sunucuda zamanlayıcıya artık ihtiyaç duyulmadığını söylersek, başladığı fiberleri durdurabilir. init.

Roller birbirleriyle etkileşime girebilir. Lua'da işlev çağrıları yazmaya alışkınız, ancak belirli bir sürecin ihtiyacımız olan role sahip olmaması da mümkündür. Ağ üzerinden aramaları kolaylaştırmak için Tarantool'da yerleşik standart netbox temel alınarak oluşturulan rpc (uzaktan prosedür çağrısı) yardımcı modülünü kullanıyoruz. Bu, örneğin ağ geçidinizin bir gün beklemek yerine doğrudan zamanlayıcıdan işi hemen şimdi yapmasını istemesi durumunda faydalı olabilir.

Bir diğer önemli nokta ise hata toleransının sağlanmasıdır. Kartuş, sağlığı izlemek için SWIM protokolünü kullanır [4]. Kısacası, süreçler UDP üzerinden birbirleriyle "söylentiler" alışverişinde bulunur; her süreç komşularına en son haberleri söyler ve onlar da yanıt verir. Aniden cevap gelmezse Tarantool bir şeylerin ters gittiğinden şüphelenmeye başlar ve bir süre sonra ölüm okuyarak bu haberi etrafındaki herkese anlatmaya başlar.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Bu protokole dayanarak Kartuş, otomatik arıza işlemeyi düzenler. Her süreç kendi ortamını izler ve lider aniden yanıt vermeyi bırakırsa replika onun rolünü devralabilir ve Cartridge çalışan rolleri buna göre yapılandırır.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Burada dikkatli olmanız gerekir çünkü sık sık ileri geri geçiş yapmak, çoğaltma sırasında veri çakışmalarına yol açabilir. Elbette otomatik yük devretmeyi rastgele etkinleştirmemelisiniz. Neler olduğunu net bir şekilde anlamalı ve lider geri getirilip tacın kendisine iade edilmesinden sonra kopyanın bozulmayacağından emin olmalıyız.

Tüm bunlardan rollerin mikro hizmetlere benzer olduğu hissine kapılabilirsiniz. Bir bakıma Tarantool süreçlerinin içindeki modüller olarak tam da böyledirler. Ama aynı zamanda bir takım temel farklılıklar da var. Öncelikle tüm proje rollerinin aynı kod tabanında yaşaması gerekir. Ve tüm Tarantool işlemlerinin aynı kod tabanından başlatılması gerekir, böylece zamanlayıcıyı başlatmaya çalıştığımızda olduğu gibi sürprizlerle karşılaşmayız, ancak aslında mevcut değildir. Ayrıca kod sürümlerindeki farklılıklara izin vermemelisiniz çünkü böyle bir durumda sistemin davranışını tahmin etmek ve hata ayıklamak çok zordur.

Docker'dan farklı olarak, bir rol "imajı" alıp onu başka bir makineye alıp orada çalıştıramayız. Rollerimiz Docker konteynerleri kadar izole değil. Ayrıca tek bir örnekte iki özdeş rolü çalıştıramayız. Bir rol ya vardır ya da yoktur; bir bakıma tekildir. Üçüncüsü, rollerin tüm çoğaltma grubu içinde aynı olması gerekir, çünkü aksi takdirde bu saçma olurdu; veriler aynıdır, ancak yapılandırma farklıdır.

Dağıtım araçları

Kartuş'un uygulamaların dağıtımına nasıl yardımcı olduğunu göstereceğime söz verdim. Başkalarının hayatını kolaylaştırmak için çerçeve, RPM paketlerini paketler:

$ cartridge pack rpm myapp -- упакует для нас ./myapp-0.1.0-1.rpm
$ sudo yum install ./myapp-0.1.0-1.rpm

Kurulu paket ihtiyacınız olan hemen hemen her şeyi içerir: hem uygulama hem de kurulu bağımlılıklar. Tarantool ayrıca RPM paketinin bağımlılığı olarak sunucuya ulaşacak ve hizmetimiz başlatılmaya hazır. Bu, systemd aracılığıyla yapılır, ancak önce küçük bir yapılandırma yazmanız gerekir. En azından her işlemin URI'sini belirtin. Örneğin üç tanesi yeterli.

$ sudo tee /etc/tarantool/conf.d/demo.yml <<CONFIG
myapp.router: {"advertise_uri": "localhost:3301", "http_port": 8080}
myapp.storage_A: {"advertise_uri": "localhost:3302", "http_enabled": False}
myapp.storage_B: {"advertise_uri": "localhost:3303", "http_enabled": False}
CONFIG

Burada ilginç bir nüans var. Yalnızca ikili protokol bağlantı noktasını belirtmek yerine, ana bilgisayar adı da dahil olmak üzere sürecin tüm genel adresini belirtiriz. Bu, küme düğümlerinin birbirine nasıl bağlanacağını bilmesi için gereklidir. Advertise_uri adresi olarak 0.0.0.0 kullanmak kötü bir fikirdir; bu bir soket bağlantısı değil, harici bir IP adresi olmalıdır. Bu olmadan hiçbir şey işe yaramaz, bu nedenle Kartuş, yanlış reklam_uri'ye sahip bir düğüm başlatmanıza izin vermez.

Artık konfigürasyon hazır olduğuna göre işlemlere başlayabilirsiniz. Normal bir systemd ünitesi birden fazla prosesin başlamasına izin vermediğinden Kartuş üzerindeki uygulamalar sözde kurulmaktadır. şu şekilde çalışan somutlaştırılmış birimler:

$ sudo systemctl start myapp@router
$ sudo systemctl start myapp@storage_A
$ sudo systemctl start myapp@storage_B

Yapılandırmada, Kartuş'un web arayüzüne hizmet verdiği HTTP bağlantı noktasını (8080) belirttik. Hadi ona gidip bir göz atalım:

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

Süreçlerin çalışıyor olmasına rağmen henüz yapılandırılmadığını görüyoruz. Kartuş henüz kimin kiminle çoğalması gerektiğini bilmiyor ve kendi başına karar veremiyor, bu yüzden bizim eylemlerimizi bekliyor. Ancak fazla seçeneğimiz yok: Yeni bir kümenin ömrü, ilk düğümün yapılandırılmasıyla başlar. Daha sonra diğerlerini de kümeye ekleyeceğiz, onlara rol atayacağız ve bu noktada dağıtım başarıyla tamamlanmış sayılabilir.

Uzun bir çalışma haftasının ardından en sevdiğiniz içkiden bir bardak içelim ve rahatlayalım. Uygulama kullanılabilir.

Tarantool Kartuş: Üç satırda Lua arka uç parçalama

sonuçlar

Sonuçlar nelerdir? Deneyin, kullanın, geri bildirim bırakın, Github'da destek talepleri oluşturun.

referanslar

[1] Tarantool » 2.2 » Referans » Rocks referansı » Modül vshard

[2] Alfa-Bank'ın yatırım işinin temelini Tarantool'a dayalı olarak nasıl uyguladık?

[3] Yeni nesil faturalandırma mimarisi: Tarantool'a geçişle dönüşüm

[4] SWIM - küme oluşturma protokolü

[5] GitHub - tarantool/kartuş-cli

[6] GitHub - tarantool/kartuş

Kaynak: habr.com

Yorum ekle