Apache Ignite'ta veri sıkıştırma. Sber'in deneyimi

Apache Ignite'ta veri sıkıştırma. Sber'in deneyimiBüyük hacimli verilerle çalışırken bazen disk alanı eksikliği sorunu ortaya çıkabilir. Bu sorunu çözmenin bir yolu sıkıştırmadır, bu sayede aynı ekipmanla depolama hacimlerini artırmayı göze alabilirsiniz. Bu yazımızda Apache Ignite'ta veri sıkıştırmanın nasıl çalıştığına bakacağız. Bu makalede yalnızca üründe uygulanan disk sıkıştırma yöntemleri açıklanacaktır. Uygulansın veya uygulanmasın diğer veri sıkıştırma yöntemleri (ağ üzerinden, bellekte) kapsamın dışında kalacaktır.

Böylece, kalıcılık modu etkinleştirildiğinde, önbelleklerdeki verilerdeki değişikliklerin bir sonucu olarak Ignite, diske yazmaya başlar:

  1. Önbelleklerin içeriği
  2. İleri Günlüğü Yaz (bundan sonra sadece WAL olarak anılacaktır)

Bir süredir WAL sıkıştırması için WAL sıkıştırması adı verilen bir mekanizma var. Yakın zamanda piyasaya sürülen Apache Ignite 2.8, diskteki verileri sıkıştırmanıza olanak tanıyan iki mekanizma daha tanıttı: önbellek içeriğini sıkıştırmak için disk sayfası sıkıştırma ve bazı WAL girişlerini sıkıştırmak için WAL sayfası anlık görüntü sıkıştırma. Aşağıda bu mekanizmaların üçü hakkında daha fazla ayrıntı bulacaksınız.

Disk sayfası sıkıştırma

Bu nasıl çalışıyor

Öncelikle Ignite'ın verileri nasıl sakladığına çok kısa bir göz atalım. Sayfa belleği depolama için kullanılır. Sayfa boyutu düğümün başlangıcında ayarlanır ve daha sonraki aşamalarda değiştirilemez; ayrıca sayfa boyutu, dosya sistemi blok boyutunun ikinin katı ve katı olmalıdır. Sayfalar gerektiğinde diskten RAM'e yüklenir; diskteki verilerin boyutu, ayrılan RAM miktarını aşabilir. RAM'de diskten bir sayfa yüklemek için yeterli alan yoksa eski, artık kullanılmayan sayfalar RAM'den çıkarılacaktır.

Veriler diskte şu şekilde depolanır: her önbellek grubunun her bölümü için ayrı bir dosya oluşturulur; bu dosyada sayfalar artan dizin sırasına göre birbiri ardına görünür. Tam sayfa tanımlayıcısı, dosyadaki önbellek grubu tanımlayıcısını, bölüm numarasını ve sayfa dizinini içerir. Böylece, tam sayfa tanımlayıcıyı kullanarak, her sayfa için dosyayı ve dosyadaki ofseti benzersiz şekilde belirleyebiliriz. Apache Ignite Wiki makalesinde disk belleği belleği hakkında daha fazla bilgi edinebilirsiniz: Ignite Persistent Store - başlık altında.

Disk sayfası sıkıştırma mekanizması adından da anlaşılacağı gibi sayfa düzeyinde çalışır. Bu mekanizma etkinleştirildiğinde, RAM'deki veriler herhangi bir sıkıştırma olmadan olduğu gibi işlenir, ancak sayfalar RAM'den diske kaydedildiğinde sıkıştırılır.

Ancak her sayfayı ayrı ayrı sıkıştırmak soruna çözüm değildir; ortaya çıkan veri dosyalarının boyutunu bir şekilde azaltmanız gerekir. Sayfa boyutu artık sabit değilse, artık dosyaya sayfaları arka arkaya yazamayız, çünkü bu bir dizi sorun yaratabilir:

  • Sayfa dizinini kullanarak dosyada bulunduğu uzaklığı hesaplayamayız.
  • Dosyanın sonunda olmayan ve boyutu değişen sayfalarla ne yapılacağı belli değil. Sayfa boyutu küçülürse açtığı alan kaybolur. Sayfa boyutu artarsa ​​dosyada bunun için yeni bir yer aramanız gerekir.
  • Bir sayfa, dosya sistemi blok boyutunun katı olmayan bir bayt sayısı kadar hareket ederse, bu durumda sayfayı okumak veya yazmak, bir dosya sistemi bloğuna daha dokunulmasını gerektirecektir ve bu da performansın düşmesine neden olabilir.

Bu sorunları kendi düzeyinde çözmekten kaçınmak için Apache Ignite'taki disk sayfası sıkıştırması, seyrek dosyalar adı verilen bir dosya sistemi mekanizması kullanır. Seyrek dosya, bazı sıfır doldurulmuş bölgelerin "delik" olarak işaretlenebildiği dosyadır. Bu durumda, bu delikleri depolamak için hiçbir dosya sistemi bloğu tahsis edilmeyecektir, bu da disk alanından tasarruf edilmesini sağlayacaktır.

Bir dosya sistemi bloğunu serbest bırakmak için deliğin boyutunun dosya sistemi bloğundan büyük veya ona eşit olması mantıklıdır; bu da sayfa boyutuna ve Apache Ignite'a ek bir sınırlama getirir: sıkıştırmanın herhangi bir etkiye sahip olması için, sayfa boyutu dosya sistemi bloğunun boyutundan kesinlikle büyük olmalıdır. Sayfa boyutu blok boyutuna eşitse, tek bir bloğu boşaltmak için sıkıştırılmış sayfanın 0 bayt kaplaması gerektiğinden hiçbir zaman tek bir bloğu serbest bırakamayız. Sayfa boyutu 2 veya 4 bloğun boyutuna eşitse, sayfamız sırasıyla en az %50 veya %75 oranında sıkıştırılmışsa zaten en az bir blokta yer açabileceğiz.

Böylece mekanizmanın nasıl çalıştığına dair son açıklama: Diske bir sayfa yazılırken sayfa sıkıştırılmaya çalışılır. Sıkıştırılmış sayfanın boyutu bir veya daha fazla dosya sistemi bloğunun serbest bırakılmasına izin veriyorsa, sayfa sıkıştırılmış biçimde yazılır ve serbest bırakılan blokların yerine bir "delik" açılır (bir sistem çağrısı yürütülür) fallocate() delik bayrağıyla birlikte). Sıkıştırılmış sayfanın boyutu blokların serbest bırakılmasına izin vermiyorsa, sayfa sıkıştırılmamış olarak olduğu gibi kaydedilir. Tüm sayfa ofsetleri, sıkıştırmasız yöntemle aynı şekilde, sayfa dizininin sayfa boyutuyla çarpılmasıyla hesaplanır. Kendi başınıza sayfaların yeniden konumlandırılmasına gerek yoktur. Sayfa ofsetleri, tıpkı sıkıştırma olmadan olduğu gibi, dosya sistemi bloklarının sınırlarına düşer.

Apache Ignite'ta veri sıkıştırma. Sber'in deneyimi

Mevcut uygulamada, Ignite yalnızca Linux işletim sistemi altındaki seyrek dosyalarla çalışabilir; buna göre, disk sayfası sıkıştırma yalnızca bu işletim sisteminde Ignite kullanıldığında etkinleştirilebilir.

Disk sayfası sıkıştırma için kullanılabilecek sıkıştırma algoritmaları: ZSTD, LZ4, Snappy. Ek olarak, kalan verilere sıkıştırma uygulanmadan sayfada yalnızca kullanılmayan alanın atıldığı, daha önce listelenen algoritmalara kıyasla CPU üzerindeki yükü azaltan bir çalışma modu (SKIP_GARBAGE) bulunmaktadır.

Performans Etkisi

Maalesef bu mekanizmayı üretimde kullanmayı planladığımız için gerçek tribünlerde gerçek performans ölçümleri yapmadım ancak teorik olarak nerede kaybedeceğimizi ve nerede kazanacağımızı tahmin edebiliriz.

Bunu yapmak için sayfalara erişildiğinde sayfaların nasıl okunduğunu ve yazıldığını hatırlamamız gerekir:

  • Okuma işlemi yapılırken öncelikle RAM'de arama yapılır; arama başarısız olursa sayfa, okumayı gerçekleştiren aynı iş parçacığı tarafından diskten RAM'e yüklenir.
  • Bir yazma işlemi gerçekleştirildiğinde, RAM'deki sayfa kirli olarak işaretlenir, ancak sayfa, yazmayı gerçekleştiren iş parçacığı tarafından fiziksel olarak hemen diske kaydedilmez. Tüm kirli sayfalar daha sonra kontrol noktası işleminde ayrı iş parçacıkları halinde diske kaydedilir.

Yani okuma işlemleri üzerindeki etkisi:

  • Okunan dosya sistemi bloklarının sayısındaki azalma nedeniyle pozitif (disk GÇ).
  • Negatif (CPU), işletim sisteminin seyrek dosyalarla çalışması için gerektirdiği ek yük nedeniyle. Daha karmaşık bir seyrek dosya yapısını kaydetmek için ek GÇ işlemlerinin burada dolaylı olarak görünmesi de mümkündür (maalesef seyrek dosyaların nasıl çalıştığına ilişkin tüm ayrıntılara aşina değilim).
  • Sayfaların sıkıştırmasını açma ihtiyacı nedeniyle negatif (CPU).
  • Yazma işlemleri üzerinde hiçbir etkisi yoktur.
  • Denetim noktası sürecine etkisi (buradaki her şey okuma işlemlerine benzer):
  • Pozitif (disk GÇ), yazılı dosya sistemi bloklarının sayısındaki azalma nedeniyle.
  • Seyrek dosyalarla çalışma nedeniyle negatif (CPU, muhtemelen disk IO).
  • Sayfa sıkıştırma ihtiyacı nedeniyle negatif (CPU).

Terazinin hangi tarafı teraziyi çevirecek? Bunların hepsi büyük ölçüde ortama bağlıdır, ancak disk sayfası sıkıştırmanın büyük olasılıkla çoğu sistemde performans düşüşüne yol açacağına inanma eğilimindeyim. Ayrıca, seyrek dosyalarla benzer bir yaklaşım kullanan diğer DBMS'ler üzerinde yapılan testler, sıkıştırma etkinleştirildiğinde performansta bir düşüş olduğunu göstermektedir.

Nasıl etkinleştirilir ve yapılandırılır

Yukarıda belirtildiği gibi Apache Ignite'ın disk sayfası sıkıştırmayı destekleyen minimum sürümü 2.8'dir ve yalnızca Linux işletim sistemi desteklenmektedir. Aşağıdaki gibi etkinleştirin ve yapılandırın:

  • Sınıf yolunda bir tutuşturma sıkıştırma modülü bulunmalıdır. Varsayılan olarak Apache Ignite dağıtımında libs/isteğe bağlı dizinde bulunur ve sınıf yoluna dahil edilmez. Dizini basitçe bir seviye yukarı libs'e taşıyabilirsiniz ve ardından onu ignite.sh aracılığıyla çalıştırdığınızda otomatik olarak etkinleştirilecektir.
  • Kalıcılık etkinleştirilmelidir (Şununla etkinleştirildi: DataRegionConfiguration.setPersistenceEnabled(true)).
  • Sayfa boyutu, dosya sistemi blok boyutundan daha büyük olmalıdır (bunu kullanarak ayarlayabilirsiniz). DataStorageConfiguration.setPageSize() ).
  • Verilerinin sıkıştırılması gereken her önbellek için sıkıştırma yöntemini ve (isteğe bağlı olarak) sıkıştırma düzeyini (yöntemler) yapılandırmanız gerekir. CacheConfiguration.setDiskPageCompression() , CacheConfiguration.setDiskPageCompressionLevel()).

WAL sıkıştırma

Bu nasıl çalışıyor

WAL nedir ve neden gereklidir? Çok kısaca: Bu, sonuçta sayfa depolama alanını değiştiren tüm olayları içeren bir günlüktür. Düşme durumunda toparlanabilmek için öncelikle gereklidir. Herhangi bir işlem, kontrolü kullanıcıya vermeden önce, ilk önce WAL'e bir olay kaydetmelidir; böylece başarısızlık durumunda, günlükte oynatılabilir ve kullanıcının başarılı bir yanıt aldığı tüm işlemler, bu işlemler olsa bile geri yüklenebilir. diskteki sayfa deposuna yansıtılacak zamanı yoktu (zaten yukarıda Sayfa deposuna gerçek yazma işleminin, ayrı iş parçacıkları tarafından biraz gecikmeyle "kontrol noktası oluşturma" adı verilen bir işlemle yapıldığı açıklanmıştı).

WAL'deki girişler mantıksal ve fiziksel olarak ayrılmıştır. Boolean olanlar anahtarların ve değerlerin kendisidir. Fiziksel - sayfa deposundaki sayfalarda yapılan değişiklikleri yansıtır. Mantıksal kayıtlar diğer bazı durumlar için yararlı olabilirken, fiziksel kayıtlara yalnızca bir çökme durumunda kurtarma için ihtiyaç duyulur ve kayıtlara yalnızca son başarılı kontrol noktasından bu yana ihtiyaç duyulur. Burada ayrıntılara girmeyeceğiz ve neden bu şekilde çalıştığını açıklamayacağız, ancak ilgilenenler Apache Ignite Wiki'de daha önce bahsedilen makaleye başvurabilirler: Ignite Persistent Store - başlık altında.

Mantıksal kayıt başına genellikle birden fazla fiziksel kayıt bulunur. Yani, örneğin, önbelleğe yapılan bir yerleştirme işlemi, sayfa belleğindeki birkaç sayfayı etkiler (verilerin bulunduğu sayfa, indeksli sayfalar, serbest listeli sayfalar). Bazı sentetik testlerde fiziksel kayıtların WAL dosyasının %90'ını kapladığını gördüm. Ancak çok kısa bir süre için bunlara ihtiyaç duyulur (varsayılan olarak kontrol noktaları arasındaki aralık 3 dakikadır). Bu verilerden alaka düzeyini kaybettikten sonra kurtulmak mantıklı olacaktır. Bu tam olarak WAL sıkıştırma mekanizmasının yaptığı şeydir: fiziksel kayıtlardan kurtulur ve kalan mantıksal kayıtları zip kullanarak sıkıştırırken, dosya boyutu çok önemli ölçüde (bazen onlarca kez) azaltılır.

Fiziksel olarak WAL, üzerine dairesel bir şekilde yazılan sabit boyutta (varsayılan olarak 10 MB) birkaç bölümden (varsayılan olarak 64) oluşur. Geçerli bölüm doldurulur doldurulmaz bir sonraki bölüm geçerli olarak atanır ve doldurulan bölüm ayrı bir iş parçacığı aracılığıyla arşive kopyalanır. WAL sıkıştırması zaten arşiv bölümleriyle çalışıyor. Ayrıca ayrı bir iş parçacığı olarak kontrol noktasının yürütülmesini izler ve artık fiziksel kayıtlara ihtiyaç duyulmayan arşiv bölümlerinde sıkıştırmayı başlatır.

Apache Ignite'ta veri sıkıştırma. Sber'in deneyimi

Performans Etkisi

WAL sıkıştırması ayrı bir iş parçacığı olarak çalıştığından, gerçekleştirilen işlemler üzerinde doğrudan bir etki olmamalıdır. Ancak yine de CPU'ya (sıkıştırma) ve diske (arşivden her WAL bölümünü okuma ve sıkıştırılmış bölümleri yazma) ek arka plan yükü koyar, dolayısıyla sistem maksimum kapasitesinde çalışıyorsa, performansın düşmesine de yol açacaktır.

Nasıl etkinleştirilir ve yapılandırılır

Özelliği kullanarak WAL sıkıştırmasını etkinleştirebilirsiniz WalCompactionEnabled в DataStorageConfiguration (DataStorageConfiguration.setWalCompactionEnabled(true)). Ayrıca DataStorageConfiguration.setWalCompactionLevel() yöntemini kullanarak, varsayılan değerden (BEST_SPEED) memnun değilseniz sıkıştırma düzeyini ayarlayabilirsiniz.

WAL sayfası anlık görüntü sıkıştırması

Bu nasıl çalışıyor

WAL'de kayıtların mantıksal ve fiziksel olarak ikiye ayrıldığını zaten öğrendik. Her sayfada yapılan her değişiklik için sayfa belleğinde fiziksel bir WAL kaydı oluşturulur. Fiziksel kayıtlar da 2 alt türe ayrılır: sayfa anlık görüntü kaydı ve delta kaydı. Bir sayfada bir şeyi değiştirdiğimizde ve onu temiz durumdan kirli duruma aktardığımızda, bu sayfanın tam bir kopyası WAL'de (sayfa anlık görüntü kaydı) saklanır. WAL'da yalnızca bir bayt değiştirsek bile kayıt sayfa boyutundan biraz daha büyük olacaktır. Zaten kirli olan bir sayfada bir şeyi değiştirirsek, WAL'de, sayfanın tamamını değil, yalnızca sayfanın önceki durumuna göre değişiklikleri yansıtan bir delta kaydı oluşturulur. Sayfaların durumunun kirliden temize sıfırlanması, kontrol noktası işlemi sırasında, kontrol noktasının başlamasından hemen sonra gerçekleştirildiğinden, neredeyse tüm fiziksel kayıtlar yalnızca sayfaların anlık görüntülerinden oluşacaktır (çünkü kontrol noktasının başlangıcından hemen sonraki tüm sayfalar temizdir) , ardından bir sonraki kontrol noktasına yaklaştığımızda delta kaydı fraksiyonu büyümeye başlar ve bir sonraki kontrol noktasının başlangıcında yeniden sıfırlanır. Bazı sentetik testlerde yapılan ölçümler, sayfa anlık görüntülerinin toplam fiziksel kayıt hacmi içindeki payının %90'a ulaştığını gösterdi.

WAL sayfa anlık görüntü sıkıştırmasının amacı, hazır bir sayfa sıkıştırma aracı kullanarak sayfa anlık görüntülerini sıkıştırmaktır (bkz. disk sayfası sıkıştırma). Aynı zamanda, WAL'de kayıtlar salt ekleme modunda sırayla kaydedilir ve kayıtları dosya sistemi bloklarının sınırlarına bağlamaya gerek yoktur, dolayısıyla burada, disk sayfası sıkıştırma mekanizmasının aksine, aynı anda seyrek dosyalara ihtiyacımız yoktur. hepsi; buna göre, bu mekanizma yalnızca OS Linux'ta çalışmayacaktır. Ayrıca sayfayı ne kadar sıkıştırabildiğimiz artık bizim için önemli değil. 1 bayt serbest bıraksak bile, bu zaten olumlu bir sonuçtur ve sıkıştırılmış sayfayı yalnızca 1'den fazla dosya sistemi bloğunu serbest bıraktığımızda kaydettiğimiz disk sayfası sıkıştırmanın aksine, sıkıştırılmış verileri WAL'de kaydedebiliriz.

Sayfalar oldukça sıkıştırılabilir verilerdir, toplam WAL hacmi içindeki payları çok yüksektir, bu nedenle WAL dosya formatını değiştirmeden boyutunda önemli bir azalma elde edebiliriz. Mantıksal kayıtlar da dahil olmak üzere sıkıştırma, örneğin mantıksal kayıtlarla ilgilenebilecek harici tüketiciler için formatta bir değişiklik ve uyumluluk kaybı gerektirebilir, ancak dosya boyutunda önemli bir azalmaya yol açmaz.

Disk sayfası sıkıştırmasında olduğu gibi, WAL sayfası anlık görüntü sıkıştırması da ZSTD, LZ4, Snappy sıkıştırma algoritmalarının yanı sıra SKIP_GARBAGE modunu kullanabilir.

Performans Etkisi

WAL sayfa anlık görüntü sıkıştırmasının doğrudan etkinleştirilmesinin yalnızca sayfa belleğine veri yazan iş parçacıklarını, yani önbelleklerdeki verileri değiştiren iş parçacıklarını etkilediğini fark etmek zor değildir. WAL'den fiziksel kayıtların okunması yalnızca bir kez gerçekleşir; düğüm bir düşüşten sonra kaldırıldığı anda (ve yalnızca bir kontrol noktası sırasında düştüğünde).

Bu, verileri değiştiren iş parçacıklarını şu şekilde etkiler: diske yazmadan önce her seferinde sayfayı sıkıştırma ihtiyacı nedeniyle olumsuz bir etki (CPU) ve miktarındaki azalma nedeniyle olumlu bir etki (disk IO) elde ederiz. veriler yazılmıştır. Buna göre burada her şey basit: Sistem performansı CPU ile sınırlıysa hafif bir bozulma, disk I/O ile sınırlıysa artış elde ederiz.

Dolaylı olarak, WAL boyutunun azaltılması aynı zamanda WAL bölümlerini arşive ve WAL sıkıştırma akışlarına aktaran akışları da (olumlu olarak) etkiler.

Ortamımızda sentetik veriler kullanılarak yapılan gerçek performans testleri hafif bir artış gösterdi (iş hacmi %10 - %15 arttı, gecikme %10 - %15 azaldı).

Nasıl etkinleştirilir ve yapılandırılır

Minimum Apache Ignite sürümü: 2.8. Aşağıdaki gibi etkinleştirin ve yapılandırın:

  • Sınıf yolunda bir tutuşturma sıkıştırma modülü bulunmalıdır. Varsayılan olarak Apache Ignite dağıtımında libs/isteğe bağlı dizinde bulunur ve sınıf yoluna dahil edilmez. Dizini basitçe bir seviye yukarı libs'e taşıyabilirsiniz ve ardından onu ignite.sh aracılığıyla çalıştırdığınızda otomatik olarak etkinleştirilecektir.
  • Kalıcılık etkinleştirilmelidir (Şununla etkinleştirildi: DataRegionConfiguration.setPersistenceEnabled(true)).
  • Sıkıştırma modu, yöntem kullanılarak ayarlanmalıdır. DataStorageConfiguration.setWalPageCompression(), sıkıştırma varsayılan olarak devre dışıdır (DEVRE DIŞI mod).
  • İsteğe bağlı olarak, yöntemi kullanarak sıkıştırma düzeyini ayarlayabilirsiniz. DataStorageConfiguration.setWalPageCompression(), her modun geçerli değerleri için yöntem için javadoc'a bakın.

Sonuç

Apache Ignite'ta dikkate alınan veri sıkıştırma mekanizmaları birbirinden bağımsız olarak kullanılabilir, ancak bunların herhangi bir kombinasyonu da kabul edilebilir. Nasıl çalıştıklarını anlamak, ortamınızdaki görevlerinize ne kadar uygun olduklarını ve bunları kullanırken neleri feda etmeniz gerektiğini belirlemenize olanak tanır. Disk sayfası sıkıştırma, ana depolamayı sıkıştırmak için tasarlanmıştır ve orta düzeyde bir sıkıştırma oranı verebilir. WAL sayfası anlık görüntü sıkıştırması, WAL dosyaları için ortalama bir sıkıştırma derecesi sağlayacak ve büyük olasılıkla performansı artıracaktır. WAL sıkıştırmanın performans üzerinde olumlu bir etkisi olmayacaktır ancak fiziksel kayıtları kaldırarak WAL dosyalarının boyutunu mümkün olduğunca azaltacaktır.

Kaynak: habr.com

Yorum ekle