Cassandra. Yalnızca Oracle'ı biliyorsanız nasıl ölmezsiniz?

Merhaba Habr.

Adım Misha Butrimov, size Cassandra'dan biraz bahsetmek istiyorum. Hikayem, NoSQL veritabanlarıyla hiç karşılaşmamış olanlar için faydalı olacaktır; bilmeniz gereken birçok uygulama özelliği ve tuzakları vardır. Oracle veya başka bir ilişkisel veritabanından başka bir şey görmediyseniz bunlar hayatınızı kurtaracaktır.

Cassandra'nın nesi bu kadar iyi? Tek bir hata noktası olmadan tasarlanmış ve iyi ölçeklenen bir NoSQL veritabanıdır. Bazı veritabanı için birkaç terabayt eklemeniz gerekiyorsa, halkaya düğüm eklemeniz yeterlidir. Başka bir veri merkezine genişletilsin mi? Kümeye düğüm ekleyin. İşlenen RPS artırılsın mı? Kümeye düğüm ekleyin. Aynı zamanda ters yönde de çalışır.

Cassandra. Yalnızca Oracle'ı biliyorsanız nasıl ölmezsiniz?

Başka hangi konuda iyi? Bu, birçok isteğin karşılanmasıyla ilgilidir. Ama ne kadar çok? Saniyede 10, 20, 30, 40 bin istek çok fazla değil. Kayıt için de saniyede 100 bin istek. Saniyede 2 milyon isteği sakladığını söyleyen firmalar var. Muhtemelen buna inanmak zorunda kalacaklar.

Ve prensip olarak Cassandra'nın ilişkisel verilerden büyük bir farkı var - onlara hiç benzemiyor. Ve bunu hatırlamak çok önemlidir.

Aynı görünen her şey aynı şekilde çalışmaz

Bir keresinde bir meslektaşım bana gelip şunu sordu: "İşte bir CQL Cassandra sorgu dili ve bir select ifadesi var, nerede var, var ve. Mektup yazıyorum ama işe yaramıyor. Neden?". Cassandra'ya ilişkisel bir veri tabanı muamelesi yapmak şiddet içeren intiharın mükemmel yoludur. Ve ben bunu tanıtmıyorum, Rusya'da yasak. Yanlış bir şey tasarlayacaksınız.

Mesela bir müşterimiz bize geliyor ve şöyle diyor: “Dizilere veri tabanı oluşturalım, yemek tarifi dizinine veri tabanı oluşturalım. Orada yemeklerimiz ya da dizi ve oyuncuların listesi olacak” dedi. Sevinçle diyoruz: “Hadi gidelim!” Sadece iki bayt, birkaç işaret gönderin ve işiniz bitti, her şey çok hızlı ve güvenilir bir şekilde çalışacaktır. Ve müşteriler gelip ev hanımlarının da tam tersi sorunu çözdüklerini söyleyene kadar her şey yolunda: Ellerinde bir ürün listesi var ve hangi yemeği pişirmek istediklerini bilmek istiyorlar. Sen ölüsün.

Bunun nedeni Cassandra'nın hibrit bir veritabanı olmasıdır: Aynı anda bir anahtar değer sağlar ve verileri geniş sütunlarda saklar. Java veya Kotlin'de şu şekilde tanımlanabilir:

Map<RowKey, SortedMap<ColumnKey, ColumnValue>>

Yani, sıralanmış bir haritayı da içeren bir harita. Bu haritanın ilk anahtarı Satır anahtarı veya Bölüm anahtarıdır - bölümleme anahtarı. Zaten sıralanmış bir haritanın anahtarı olan ikinci anahtar Kümeleme anahtarıdır.

Veritabanının dağılımını göstermek için üç düğüm çizelim. Artık verileri düğümlere nasıl ayıracağınızı anlamanız gerekiyor. Çünkü her şeyi bire sıkıştırırsak (bu arada bin, iki bin, beş, istediğiniz kadar olabilir), bu aslında dağıtımla ilgili değil. Bu nedenle sayı döndürecek bir matematik fonksiyonuna ihtiyacımız var. Sadece bir sayı, belirli bir aralığa girecek bir long int. Ve bir aralıktan sorumlu bir düğümümüz olacak, ikincisi ikinciden, n'incisi n'inciden sorumlu olacak.

Cassandra. Yalnızca Oracle'ı biliyorsanız nasıl ölmezsiniz?

Bu sayı, Bölüm anahtarı dediğimiz şeye uygulanan karma işlevi kullanılarak alınır. Primary key direktifinde belirtilen sütundur ve haritanın ilk ve en temel anahtarı olacak sütundur. Hangi düğümün hangi veriyi alacağını belirler. Cassandra'da SQL'dekiyle hemen hemen aynı sözdizimine sahip bir tablo oluşturulur:

CREATE TABLE users (
	user_id uu id,
	name text,
	year int,
	salary float,
	PRIMARY KEY(user_id)

)

Bu durumda Birincil anahtar bir sütundan oluşur ve aynı zamanda bölümleme anahtarıdır.

Kullanıcılarımız nasıl performans gösterecek? Bazıları bir düğüme, bazıları diğerine, bazıları da üçte birine gidecek. Sonuç, harita olarak da bilinen, Python'da sözlük olarak da bilinen sıradan bir karma tablosu veya tüm değerleri okuyabileceğimiz, anahtarla okuyup yazabileceğimiz basit bir Anahtar değer yapısıdır.

Cassandra. Yalnızca Oracle'ı biliyorsanız nasıl ölmezsiniz?

Seçin: filtrelemeye izin verme tam taramaya dönüştüğünde veya ne yapılmayacağını seçin

Biraz select ifadesi yazalım: select * from users where, userid = . Oracle'da olduğu gibi çıkıyor: seç yazıyoruz, koşulları belirliyoruz ve her şey çalışıyor, kullanıcılar bunu alıyor. Ancak örneğin belirli bir doğum yılına sahip bir kullanıcıyı seçerseniz Cassandra, isteği yerine getiremediğinden şikayet ediyor. Çünkü doğum yılıyla ilgili verileri nasıl dağıttığımız hakkında hiçbir şey bilmiyor; anahtar olarak gösterilen yalnızca bir sütunu var. Sonra şöyle diyor: “Tamam, yine de bu isteği yerine getirebilirim. Ekle filtrelemeye izin ver." Direktifi ekliyoruz, her şey çalışıyor. Ve şu anda korkunç bir şey oluyor.

Test verileri üzerinde çalıştığımızda her şey yolundadır. Ve örneğin 4 milyon kaydımızın olduğu üretimde bir sorgu çalıştırdığınızda, o zaman her şey bizim için pek iyi olmuyor. Çünkü izin verme filtreleme, Cassandra'nın bu tablodaki tüm verileri tüm düğümlerden, tüm veri merkezlerinden (bu kümede çok sayıda varsa) toplamasına ve ancak o zaman filtrelemesine olanak tanıyan bir yönergedir. Bu, Tam Taramanın bir benzeridir ve neredeyse hiç kimse bundan memnun değildir.

Kullanıcılara yalnızca kimliğe göre ihtiyacımız olsaydı, bu bizim için sorun olmazdı. Ancak bazen başka sorgular yazmamız ve seçime başka kısıtlamalar getirmemiz gerekir. Bu nedenle hatırlıyoruz: bunların hepsi bölümleme anahtarı olan bir harita, ancak içinde sıralanmış bir harita var.

Ayrıca Kümeleme Anahtarı adını verdiğimiz bir anahtarı da var. Bu anahtar, Cassandra'nın yardımıyla verilerinin fiziksel olarak nasıl sıralandığını ve her düğümde bulunacağını anladığı, seçtiğimiz sütunlardan oluşur. Yani, bazı Bölümleme anahtarları için Kümeleme anahtarı, verileri bu ağaca nasıl aktaracağınızı, orada hangi yeri alacağını size tam olarak söyleyecektir.

Bu gerçekten bir ağaçtır, orada basitçe bir nesne biçiminde belirli bir sütun kümesini ilettiğimiz bir karşılaştırıcı denir ve aynı zamanda bir sütun listesi olarak da belirtilir.

CREATE TABLE users_by_year_salary_id (
	user_id uuid,
	name text,
	year int,
	salary float,
	PRIMARY KEY((year), salary, user_id)

Birincil anahtar yönergesine dikkat edin; ilk argümanı (bizim durumumuzda yıl) her zaman Bölüm anahtarıdır. Bir veya daha fazla sütundan oluşabilir, fark etmez. Birkaç sütun varsa, dil ön işlemcisinin bunun Birincil anahtar olduğunu ve onun arkasında diğer tüm sütunların Kümeleme anahtarı olduğunu anlaması için bunun tekrar parantez içinde kaldırılması gerekir. Bu durumda karşılaştırıcıda göründükleri sıraya göre iletileceklerdir. Yani, ilk sütun daha anlamlıdır, ikincisi daha az önemlidir vb. Örneğin, nasıl yazdığımız, veri sınıfları için alanlara eşittir: alanları listeleriz ve onlar için hangilerinin daha büyük, hangilerinin daha küçük olduğunu yazarız. Cassandra'da bunlar, nispeten konuşursak, kendisi için yazılan eşitlerin uygulanacağı veri sınıfının alanlarıdır.

Sıralamayı belirliyoruz ve kısıtlamalar getiriyoruz

Sıralama düzeninin (azalan, artan vb.) anahtar oluşturulduğunda aynı anda ayarlandığını ve daha sonra değiştirilemeyeceğini hatırlamanız gerekir. Verilerin nasıl sıralanacağını ve nasıl saklanacağını fiziksel olarak belirler. Kümeleme anahtarını veya sıralama düzenini değiştirmeniz gerekirse, yeni bir tablo oluşturmanız ve verileri bu tabloya aktarmanız gerekecektir. Bu mevcut olanla çalışmaz.

Cassandra. Yalnızca Oracle'ı biliyorsanız nasıl ölmezsiniz?

Tablomuzu kullanıcılarla doldurduk ve onların önce doğum yılına göre, ardından her düğümde maaş ve kullanıcı kimliğine göre bir halkaya düştüklerini gördük. Artık kısıtlamalar uygulayarak seçim yapabiliriz.

Çalışanımız yeniden ortaya çıkıyor where, andve kullanıcılar alıyoruz ve her şey yine yolunda. Ancak Kümeleme anahtarının yalnızca bir kısmını ve daha az önemli olanını kullanmaya çalışırsak Cassandra, boş karşılaştırıcı için bu alanlara sahip olan bu nesnenin haritamızda bulunduğu yeri bulamadığından hemen şikayet edecektir. yattığı yer yeni ayarlandı. Bu düğümdeki tüm verileri tekrar alıp filtrelemem gerekecek. Ve bu, bir düğüm içindeki Tam Taramanın bir benzeridir, bu kötüdür.

Belirsiz bir durumda yeni bir tablo oluşturun

Kullanıcıları kimliğe, yaşa veya maaşa göre hedefleyebilmek istiyorsak ne yapmalıyız? Hiç bir şey. Sadece iki tablo kullanın. Kullanıcılara üç farklı şekilde ulaşmanız gerekiyorsa üç tablo olacaktır. Vidada yerden tasarruf ettiğimiz günler geride kaldı. Bu en ucuz kaynaktır. Kullanıcıya zarar verebilecek yanıt süresinden çok daha az maliyetlidir. Kullanıcının bir şeyi 10 dakikada almaktansa bir saniyede alması çok daha keyifli.

İyi ölçeklendirme ve güvenilir bir şekilde çalışma yeteneği için gereksiz alan ve denormalize edilmiş verileri takas ediyoruz. Sonuçta, aslında, her biri beş düğüme sahip, kabul edilebilir düzeyde veri korumasına sahip (hiçbir şey kaybolmadığında) üç veri merkezinden oluşan bir küme, bir veri merkezinin ölümünden tamamen kurtulabilir. Ve kalan ikisinin her birinde iki düğüm daha var. Ve ancak bundan sonra sorunlar başlıyor. Bu oldukça iyi bir yedekliliktir, birkaç ekstra SSD sürücüsüne ve işlemciye değer. Bu nedenle asla SQL olmayan, hiçbir ilişkinin, yabancı anahtarların olmadığı Cassandra'yı kullanabilmek için basit kuralları bilmeniz gerekir.

Her şeyi isteğinize göre tasarlıyoruz. Önemli olan veri değil, uygulamanın onunla nasıl çalışacağıdır. Eğer farklı verileri farklı yollardan alması gerekiyorsa ya da aynı veriyi farklı yollardan alması gerekiyorsa bunu uygulamaya uygun bir şekilde koymalıyız. Aksi takdirde Tam Taramada başarısız olacağız ve Cassandra bize herhangi bir avantaj sağlamayacak.

Verilerin normalleştirilmesi normaldir. Normal formları unutuyoruz, artık ilişkisel veritabanlarımız yok. Bir şeyi 100 kere yere koyarsak 100 kere yatar. Hala durmaktan daha ucuz.

Bölümleme anahtarlarını normal şekilde dağıtılacak şekilde seçiyoruz. Anahtarlarımızın karma değerinin tek bir dar aralığa düşmesini istemiyoruz. Yani yukarıdaki örnekte doğum yılı kötü bir örnektir. Daha doğrusu, kullanıcılarımızın doğum yıllarına göre normal bir şekilde dağılması iyi, 5. sınıf öğrencilerinden bahsediyorsak kötü, oradaki bölümleme pek iyi olmayacak.

Kümeleme Anahtarı oluşturma aşamasında sıralama bir kez seçilir. Eğer değişmesi gerekiyorsa tablomuzu farklı bir anahtarla güncellememiz gerekecek.

Ve en önemlisi, eğer aynı veriyi 100 farklı yoldan almamız gerekiyorsa, o zaman 100 farklı tablomuz olur.

Kaynak: habr.com

Yorum ekle