1 puan yazan GN⁺ 2024-10-31 | 1 yorum | WhatsApp'ta paylaş
  • OpenZFS 2.3.0’daki Fast Dedup, önceki dedup’a göre büyük ilerleme sağlasa da, sıradan kullanıcıların varsayılan gibi açmadan önce maliyetini ve koşullarını hâlâ dikkatle değerlendirmesi gereken bir özellik
  • dedup, daha önce depolanmış blokları yeniden yazmak yerine yalnızca başvuruları artıran bir yöntem olduğundan, tüm yazma ve serbest bırakma yollarına dedup table sorgulama ve güncelleme maliyeti eklenir
  • Eski yöntem, ZAP tabanlı tablodaki read-modify-write amplifikasyonu, işlem boyunca geri kazanılamayan live entry list ve fayda sağlamayan unique entry’ler nedeniyle bellek ve IO yükünü büyütüyordu
  • Fast Dedup, live entry boyutunu 424 bayttan 216 bayta indiriyor ve dedup log, kademeli flush, zpool ddtprune, dedup_table_quota, DDT prefetch ve kstats ile yöneticilerin maliyeti daha iyi denetlemesini sağlıyor
  • Genel iş yüklerinde gerçekte yinelenen blok sayısı az olabilir ve OpenZFS 2.2’deki BRT/block cloning daha düşük maliyetle benzer tasarruf sunabildiği için, dedup ancak çok büyük miktarda yinelenen veri olduğunda ve zero-copy alternatifleri bulunmadığında dikkatle değerlendirilmeli

OpenZFS dedup’un temel çalışma biçimi

  • Yinelenen veri kaldırma (dedup), OpenZFS’nin veriyi diske yazmadan önce aynı verinin zaten mevcut olup olmadığını kontrol etmesi; varsa yeni yazmayı atlayıp mevcut kopyaya başvuru eklemesi özelliğidir
  • Zor olan kısım, “zaten diskte mi” ve “nerede” sorularını hızlıca yanıtlayabilmek için gereken bilgilerin sürekli saklanıp sorgulanmasıdır
  • Bu bilgiyi taşıyan yapı dedup table’dır
    • Kavramsal olarak, veri sağlama toplamını anahtar; disk konumu ve başvuru sayısını (refcount) değer olarak tutan bir hash tablosudur
    • Kullanıcı verisi değil, pool metadata’sının bir parçası olan yapısal pool verisidir

Yazma ve serbest bırakma yoluna eklenen maliyet

  • dedup kapalıyken OpenZFS, metaslab allocator’dan alan ayırır, dönen DVA’yı block pointer’a koyar ve veriyi yazar
  • dedup açıksa önce sağlama toplamı dedup table içinde aranır
    • Kayıt yoksa yeni alan ayrılır, veri yazılır ve refcount değeri 1 olan yeni bir dedup entry oluşturulur
    • Kayıt varsa mevcut DVA block pointer’a kopyalanır, yazma IO’su tamamlanmış sayılır ve refcount artırılır
  • dedup ile ayrılan blokların block pointer’ında D bayrağı ayarlanır
    • Serbest bırakma sırasında D bayrağı varsa dedup table yeniden sorgulanır ve refcount azaltılır
    • refcount 0 olursa dedup entry silinir ve gerçek alan serbest bırakılır
  • Tüm yazma ve serbest bırakma işlemleri dedup table sorgusu/güncellemesinden geçtiği için, dedup’un yararlı olabilmesi adına tablo yönetim maliyetinin gerçek alan ve IO tasarrufundan düşük olması gerekir

Eski dedup neden kötüydü?

  • ZAP tabanlı dedup table’ın yarattığı amplifikasyon

    • Eski dedup table, OpenZFS’nin standart disk üstü hash tablo nesnesi olan ZAP’ı kullanıyordu
    • ZAP; dizinler, özellik listeleri ve iç yönetim için de kullanılan genel amaçlı bir yapı olsa da dedup entry saklamak için pek uygun değil
    • Tipik bir dedup entry, 40 baytlık bir anahtar ve sıkıştırmadan sonra yaklaşık 64 baytlık bir değerden oluşur; tek bir 32K ZAP bloğuna yaklaşık 188 normal entry sığar
    • OpenZFS kısmi blok yazımı ve yerinde üzerine yazma yapmadığından, tek bir entry güncellense bile tüm ZAP bloğunun okunup değiştirilmesi ve yeni blok olarak yeniden yazılması gerekir
    • Sağlama toplamı anahtarlarının çakışmaya güçlü biçimde dayanıklı olması gerektiğinden, rastgele iki entry’nin aynı ZAP bloğunda yakın yerleşme olasılığı düşüktür; aynı işlem içindeki çoklu güncellemelerin de aynı blokta toplanma ihtimali azdır
    • RAM yeterliyse ARC dedup table’ı sürekli tutabilir ve okuma maliyetini azaltabilir; ancak bu yüzden dedup için çok bellek gerektiğine dair eski tavsiye ortaya çıkmıştır
    • dedup vdev class, yeterince büyük ve hızlı bir özel dedup vdev ekleyerek bellek gereksinimini bir miktar azaltabilir; ancak dedup’un anlamlı olduğu ölçeklerde tablonun tamamını barındıracak kapasite ve hız yine gerekir
  • live entry list’in bellek kullanımı

    • OpenZFS, işlem sırasında oluşturulan/değiştirilen dedup entry’leri bellekteki live entry list içinde tutar
    • Bu yapı, aynı verinin aynı anda birden çok kez yazılması durumunda her yazma iş parçacığının dedup table’da henüz kayıt yok sanıp hepsini yeniden yazmasını önlemek için vardır
    • lookup önce live entry list’e bakar
      • İlgili entry varsa refcount artırılır
      • Yoksa “in progress” durumunda bir live entry oluşturulur, gerçek entry ZAP’tan okunur ve sonra “ready” durumuna getirilir
      • Aynı anda gelen diğer yazma iş parçacıkları ready olana kadar bekler
    • İşlem sonunda live entry list üzerinde dolaşılır ve ilgili değişiklikler dedup ZAP’a yansıtılır
    • Eski live entry’lerin her biri 424 bayt idi ve bu bellek ARC değil kernel slab memory olduğu için sistem bellek baskısı altında geri kazanılamıyordu
    • live entry list her işlemde boşaltılsa da, tek bir işlem içinde çok sayıda farklı veri yazılırsa tepe kullanım büyüyebilir
  • unique entry’ler tabloyu şişiriyordu

    • dedup diskte saklanan tüm blokları izler, fakat gerçek kazanç yalnızca refcount 1’den büyük olduğunda oluşur
    • refcount değeri 1 olan unique entry, gelecekte aynı verinin tekrar yazılmasını beklemenin maliyetine daha yakındır
    • dedup, şifreleme ve sıkıştırmadan sonra blok düzeyinde uygulanır
    • Aynı kaynak veri bile aynı blok sayılabilmek için sıkıştırma yöntemi, şifreleme anahtarı ve dosya içi hizalama açısından eşleşmelidir
    • Genel amaçlı iş yüklerinde “gerçekten aynı” bloklar az olduğundan, dedup maliyeti çoğu zaman kazancı aşar

Fast Dedup’un getirdiği iyileştirmeler

  • live entry küçültme

    • Fast Dedup önce live entry list’in bellek ayak izini azaltır
    • ddt_entry_t içindeki büyük sayısal tür bayrakları bitfield’a çevrilir ve eşzamanlama alanları sadeleştirilir
    • dedup uygulanmış veri bloğu ilk kez yazılırken veya repair write gerektiğinde kullanılan 40 baytlık durum, ayrı bir IO state nesnesine taşınır
    • Eski dedup entry değeri, dört physical entry içerdiği için 256 bayttı
    • Her physical entry içinde üç adet 128 bit DVA, refcount ve birth transaction id bulunurdu
    • Dördüncü entry, eski dedupditto özelliğinin kalıntısıdır; modern OpenZFS bunu yalnızca okuyabilir, yeni yazmaz
    • Fast Dedup, copies= değiştiğinde daha fazla DVA gerekirse mevcut variant’ı ayrı bir entry gibi korumak yerine, gereken ek kopyaları ayırıp mevcut dedup entry’ye ekler
    • Yeni Fast Dedup table’daki entry değeri eski 256 bayttan 72 bayta düşer
    • live list içindeki bir entry de eski 424 bayttan 216 bayta iner
  • dedup log’un eklenmesi

    • Eski yöntem, işlem sonunda live entry list değişikliklerini doğrudan dedup ZAP’a yansıtıyordu ve entry çevresindeki diğer 187 kayıt çoğunlukla ilgisiz olsa da blok düzeyinde güncelleme maliyeti oluşuyordu
    • Fast Dedup, yakın zamanda oluşturulmuş veya yinelenmiş blokların yeniden yinelenme ya da serbest bırakılma olasılığının daha yüksek olduğu gözlemine dayanarak dedup log ekler
    • İşlem sonunda live entry değişiklikleri doğrudan ZAP’a yazılmak yerine log’a kaydedilir
      • disk üstü log, çökme güvenliği için gereklidir
      • bellek içi log ise hızlı lookup için tutulur
    • lookup sırası live entry list, bellek içi log, dedup ZAP olur
    • disk üstü log, pool import sırasında bellek içi log’u geri yüklemek için kullanılır
  • kademeli log flush

    • İlk yaklaşımdaki gibi log çok büyüdüğünde tek seferde ZAP’a flush etmek, yalnızca birkaç bin entry ile bile uzun duraklamalara yol açabiliyordu
    • Fast Dedup, her işlemde log’un bir kısmını ZAP’a yansıtan incremental flushing kullanır
    • flush miktarı, gerçek IO için harcanan süreye göre ayarlanır
      • yoğun zamanlarda daha az yazar
      • sakin zamanlarda daha fazla yazar
      • bellek içi log büyüyüp bellek baskısı oluşturursa flush hızlandırılabilir
    • disk üstü log’u append-only tutarken tüm sistemi durdurmadan boşaltabilmek için iki log kullanılır
      • biri active log olarak yeni değişiklikleri alır
      • diğeri flushing log olarak ZAP’a yansıtılır
      • flushing log boşalınca disk üstü log sıfırlanır ve iki log rol değiştirir
    • scrub veya resilver gibi pool scan işlemlerinde dedup log’da kararlı bir konum kavramı olmadığı için, scan isteğinde log flushing hızlandırılır; her şey dedup ZAP’a yansıtıldıktan sonra tarama eski yöntemle yapılır

unique entry yönetimi ve operasyon araçları

  • zpool ddtprune, pool içindeki dedup table’dan bazı unique entry’leri kaldırır
    • yaş veya yüzde ölçütüne göre belirtilebilir
    • yaş temelli ölçüt, yakın dönemde kullanılan verinin yeniden yinelenme olasılığının yüksek olduğu iş yüklerine özellikle uygundur
  • pruning ile dedup entry’si kaldırılmış bir blok daha sonra kopyalanırsa, mevcut blokla dedup yapılmaz ve yeni blok olarak ayrılır
    • Ancak eski bir unique block bir anda birçok kez kopyalanırsa, yeni tek bir blok üzerinde çok sayıda başvuru oluşabilir
  • dedup_table_quota pool property, dedup table’ın azami boyutunu sınırlar
    • Yeni entry oluşturulması sınırı aşarsa entry yaratılmaz ve işlem normal non-dedup write olarak yürütülür
    • Bu özellik, özel dedup aygıtı dolduğunda ana aygıta taşmayı önlemek için birlikte kullanılabilir
  • zpool prefetch -t ddt, dedup table’ı önceden ARC’ye yükler
    • pool import sonrasında performansa yardımcı olabilir
    • Fast Dedup’ta da log’da olmayan entry sorguları ve flush sırasında ZAP erişimi gerektiği için hâlâ etkilidir
  • Yeni kstats ve tuneable’lar da eklenmiştir
    • Linux: /proc/spl/kstat/zfs/<pool>/ddt_stats_<checksum>
    • FreeBSD: kstat.zfs.<pool>.misc.ddt_stats_<checksum>
    • Linux tuneable: /sys/modules/zfs/parameters/zfs_dedup_log_*
    • FreeBSD tuneable: vfs.zfs.dedup.log_*
  • zpool status -D, zdb -D, zdb -S gibi mevcut dedup-aware araçlar da yeni yapıyı anlayacak şekilde güncellendi

Eski dedup table ile uyumluluk

  • Fast Dedup’un büyük bölümü on-disk format değişikliği gerektirdiğinden mevcut dedup table’a olduğu gibi uygulanamaz
  • Mevcut tabloda da disk üstü biçim değişikliği gerektirmeyen özellikler çalışabilir
    • dedup_table_quota
    • zpool prefetch -t ddt
    • ddt_stats_* lookup ve hit count
    • ZAP shrink
  • dedup log’un geleneksel table üzerinde de çalışmasını sağlamak görece straightforward bir iş olarak duruyor
    • Ancak daha küçük live/log entry avantajı kazanılamaz
  • zpool ddtprune için eski table’da yalnızca “percentage of uniques” modu eklemek daha kolaydır
    • age modu, yeni entry formatındaki verilere ihtiyaç duyduğu için eski formatta mümkün değildir
  • Eski table’ı yeni formatta dönüştürmeye yönelik bir özellik şu an yok
    • copies= hiç değişmemiş basit durumlarda, yeni bir ZAP oluşturup eski entry’leri dönüştürerek kopyalama mümkün olabilir
    • online dönüşüm, old/new ZAP’a aynı anda bakma veya yazma gerektirdiği için karmaşıktır
    • offline dönüşüm daha kolaydır ama pool’un offline alınmasını gerektirir
    • copies= değişikliği nedeniyle birden çok variant’ın refcount taşıdığı durumlarda tam dönüşüm mümkün olmayabilir
  • deduplicated dataset’i dedup destekleyen başka bir yeni pool’a göndermek işe yarar

“Daha iyi olduysa neden yine de açılmamalı?”

  • Fast Dedup, eskiye göre overhead’i azaltarak daha fazla sınır durumunda yararlı olabilir
  • Ancak dedup hâlâ IO throughput, bellek kullanımı ve dedup table boyutu arasında bir denge problemidir
  • Genel amaçlı workload’larda yinelenebilir bloklar son derece az olabilir
  • Örnek bir laptop pool’unda zdb -S ile yapılan simüle DDT sonucu, dedup kazancının neredeyse yok denecek kadar az olduğunu gösteriyordu
    • 11.7M entry’nin büyük bölümü refcount değeri 1 olan unique entry’ydi
    • Gerçekte dedup yapılabilecek entry sayısı, toplam içinde yuvarlama hatası seviyesindeydi
    • Sonuç dedup = 1.00 olarak görünüyordu
  • Bu gibi durumlarda dedup’u açmak, neredeyse hiçbir şey kazandırmadan yalnızca IO ve bellek baskısı ekler

BRT/block cloning’in daha iyi olduğu durumlar

  • OpenZFS 2.2’den beri BRT, yani block cloning veya reflinks mevcut
  • dedup table, “bu veri zaten diskte var mı” sorusunu bağlamdan bağımsız yanıtlamak için kullanılan bir yapıdır
  • Modern sistemlerde kopyalama işlemi olduğunun storage stack’e aktarılabildiği durumlar vardır
    • Linux ve FreeBSD dosya sistemlerinde copy_file_range()
    • macOS’ta copyfile()
    • Windows’ta FSCTL_SRV_COPYCHUNK
    • NFS, CIFS, OS block device driver, SCSI EXTENDED COPY, NVMe Copy gibi katmanlarda da benzer yetenekler bulunur
  • İstemci programlar ve ara katmanlar copy offload sinyalini iletebilirse OpenZFS, BRT üzerinde yalnızca refcount artırabilir
  • BRT, blok clone edilmemişse hiçbir maliyet yaratmaz; clone edilmişse entry boyutu yalnızca 16 bayttır
  • Örnek pool’da BRT, used 292M; saved 309M; ratio 2.05x sonucu veriyordu
  • Ham tasarruf, dedup simülasyonundan biraz daha düşük ama benzer düzeydeydi; buna karşılık clone edilmemiş tüm blokları izleme gibi büyük bir maliyet yoktu

Pratik değerlendirme ölçütleri

  • Fast Dedup, geleneksel dedup’un üç ana ekseni olan IO throughput, memory usage ve dedup table size alanlarının hepsini iyileştiriyor
  • Başarısız olduğunda ortaya çıkan yıkıcı maliyet de azaldı ve yöneticilere tabloyu sınırlayıp temizleyebilecek araçlar verildi
  • Yine de fayda sağlanabilmesi için koşullar nettir
    • Veri ölçeği çok büyük olmalı
    • Aynı veri çok sayıda kez kopyalanmalı
    • block cloning veya snapshot clone gibi OpenZFS’nin diğer zero-copy seçenekleri kullanılamıyor olmalı
  • İstemcinin “kopyala” şeklinde açık sinyal verebildiği iş yüklerinde, block cloning çok daha düşük maliyetle büyük fayda sağlayabilir

1 yorum

 
GN⁺ 2024-10-31
Hacker News yorumları
  • çevrimdışı tekilleştirme ya da havuzu tamamen kapatmayı gerektirmeyen ama anında da çalışmayan gecikmeli tekilleştirme olsa iyi olurdu
    Tekilleştirmeyi açınca her yazma ve serbest bırakma işleminde tekilleştirme tablosu araması ve yazması gerekmesi, çoğu durumda yanlış bir yaklaşım gibi görünüyor. Veri yazarken disk alanı biraz daha fazla kullanılsa bile işin olabildiğince hızlı bitmesini istersiniz; bu yüzden üzerinde çalıştığınız dosyaları 7zip arşivinin içine kaydetmezsiniz. Sistem daha sonra boşta olduğunda ZFS'nin yinelenen verileri bulup BRT benzeri bir şeyle alanı geri kazanması güzel olurdu; hatta bu, normal scrub işleminin bir parçası da olabilir gibi görünüyor

    • Gecikmeli/çevrimdışı tekilleştirme için Block Pointer Rewrite gerekir, ama ZFS gerçek bir CAS sistemi olmadığından düzgün BP rewrite desteğini gelecekte de alması zor görünüyor
      Fiziksel konum Merkle hash ağacına hash'lenerek girdiği için, fiziksel konumu taşımak istiyorsanız değiştirilecek düğüme kadar olan tüm iç düğümleri yeniden yazmanız gerekir ve bunun maliyeti çok yüksektir. Daha iyi bir tasarım, block pointer içeren tüm düğümleri yalnızca mantıksal block pointer içeren ve ağaca hash'lenen bir bölüm ile, o mantıksal pointer'a karşılık gelen fiziksel konumu yalnızca cache gibi tutan ama Merkle ağacına hash'lenmeyen bir bölüme ayırmak olurdu. Böylece BP rewrite için yalnızca Merkle ağacının parçası olmayan blokları yeniden yazmak yeterli olurdu. Mevcut yapıda istenen işlevi ZFS'de elde etmek zor, ama okuma sırasında hash uyuşmazlığı çıkarsa pointer'ın hash'iyle tekilleştirme tablosunda bloğu bulup tekilleştirilmiş bloğu yeniden atamak gibi bir dolaylı çözüm mümkün olabilir. Bedeli de bir adet gereksiz okuma civarında olur; çok da kötü sayılmaz. Ama BP rewrite mümkün olmayınca genelde böyle yamalar ortaya çıkar
    • Bu yaklaşım Windows tekilleştirme yöntemiyle aynı. Oldukça fazla kullandım ve donanım yeterliyse genel olarak memnun kaldım
      Çok RAM ve I/O tüketiyor ama “groveler” zamanlanabiliyor ve sınırlandırılabiliyor. Yalnız Windows 2012 R2 dönemindeki bir bug yüzünden veriyi yiyen bir bozulma yaşamıştım
    • Bu, çevrimdışı yinelenen dosya tespit araçlarıyla da yapılabilir
      Örneğin jdupes ya da duperemove var. Gerekli sistem çağrılarını desteklemek için hem ZFS tarafına hem de duperemove tarafına PR gönderdim. ZFS tarafındaki inceleme uzun sürdü; işi tamamlamayı tamamen unuttuğumu fark ettim, tekrar takip etmem gerek
    • ZFS'de mevcut snapshot'ları değiştirebilme yeteneği, veri tamamen korunacak şekilde yapılsa bile son derece sınırlı. O yüzden böyle bir özellik güzel olurdu ama Block Pointer Rewrite bekliyorsanız muhtemelen çoktan ölmüş olurdunuz
    • Satır içi tekilleştirmenin güzel yanı, blok hash'i zaten varsa o bloğu gerçekten yazmaya gerek kalmaması
      Birçok durumda yazma I/O'sunu ciddi ölçüde azaltabilir. Tekilleştirmeli bir depolama dizisinde iki VM arasında dosya kopyalarsanız, gerçek veriyi kopyalamak yerine sadece orijinal bloğun referans sayacı artırılabilir. İşletim sistemine saçma düzeyde TB/s yazma hızı varmış gibi görünür; oldukça havalıdır
  • “Geleneksel tekilleştirmenin temel sorunu, bu overhead'in çok yüksek olması ve nadir, belirli iş yükleri dışında kendini amorti etmesinin zor olmasıdır” iddiası kulağa epey tuhaf geliyor
    Pure ve Dell/EMC dizileriyle çalıştım; VMWare iş yüklerinde genelde tekilleştirme/sıkıştırma ile en az 3:1 tasarruf görürdük. Temel VM imajının yalnızca tek bir kopyasını saklama yaklaşımı çok iyi çalışır. syslog sunucularında da tekilleştirme/sıkıştırma iyi sonuç veriyordu; 6:1 tasarruf gördüğüm oldu. Tekilleştirmenin etkisi, hash'lenen blok boyutuna çok bağlıdır; ne kadar küçükse o kadar iyidir. Blok küçüldükçe eşleşen blok çıkma olasılığı hızla artar ve deneyimlerime göre tercih edilen blok boyutu 4KB

    • VM imajları, Windows Server imajlarının C sürücülerinin neredeyse aynı olması gibi çok yüksek düzeyde yinelenen bilgi içerir; oysa asıl yazı dizüstü bilgisayarındaki verileri örnek veriyordu
      Ayrıca sıkıştırma ile tekilleştirme gibi iki farklı işlevi karıştırıyor gibi görünüyor. ZFS'de havuz için sıkıştırmayı açabilirsiniz ve bu neredeyse her zaman değerlidir; ama tekilleştirme kapalı bırakılabilir
    • Temel VM imajları nadir ve belirli iş yüklerine girer; tekilleştirmenin anlamlı olduğu az sayıdaki durumlardan biridir
      Yine de ZFS dosya sistemi üzerinde VM barındırıyorsanız, muhtemelen blok ya da dosya sistemi klonları gibi daha iyi stratejiler kullanıyor olmanız beklenir. Bunu yapmamak, o ortamda ZFS'nin temel farklılaştırıcı özelliklerinden birini boşa harcamak olur. Genel amaçlı dosya sunucularında ya da kişisel masaüstü/dizüstü kullanımlarında genelde yinelenen blok sayısı çok düşüktür; dolayısıyla overhead buna değmez. Yedekler ise uygulama şekline ve dosya sistemi katmanından önce şifrelenip şifrelenmediğine göre bazen uygun olabilir, bazen olmayabilir. Sıkıştırma ise bambaşka bir konu; güncel ZFS en iyi uygulaması, neredeyse tüm iş yüklerinde varsayılan olarak açık olması yönünde. Günümüzde CPU maliyeti söz etmeye bile değmeyecek kadar küçük ve alan tasarrufundan bağımsız olarak I/O azaltımı da ciddi olabilir. Tipik log depolamasında deneyimlerime göre 6:1'den çok daha iyi oranlar bile görülebilir
    • Bizzat denemedim ama eski ZFS tekilleştirmesi için sık alıntılanan rakam, 1 TB disk başına 5 GB RAM gerektiği yönünde
      Bugün 1 TB diskin yaklaşık 15 dolar, 5 GB sunucu RAM'inin ise yaklaşık 25 dolar olduğunu varsayarsanız, başa baş noktaya gelmek için bile 3:1 tekilleştirme oranı gerekir. Veriniz çok uygunsa TB başına 1 GB ile de idare edebilirsiniz; ama şanssızsanız 5 GB bile yetmeyebilir. Yazıda da ZFS tekilleştirmenin verinin tam uygun olduğu dar bir sweet spot'u olduğu söyleniyordu; çoğu insanın ilgilenmemesinin nedeni de bu. Diğer dosya sistemleri genelde ekonomik olarak daha mantıklı olan çevrimdışı tekilleştirmeyi tercih ediyor
    • VM'lerde tekilleştirmenin faydası zaten iyi biliniyor; bu yüzden orada işe yarayabilir. Ama ZFS sadece kurumsal SAN için değil, aynı zamanda genel amaçlı bir dosya sistemi; dolayısıyla birçok ZFS kullanıcısı VM çalıştırmıyor
      syslog için tekilleştirme/sıkıştırma iyi çalışıyor demek de ayrıntıya inince yanıltıcı olabilir; çünkü tekilleştirme ile sıkıştırma aynı şey değildir. Kurumsal depolama dünyasında ikisi sık sık birlikte anılır ama loglar muhtemelen tekilleştirmeden değil, sıkıştırmadan fayda görüyordur; ZFS'de de sıkıştırma zaten en başından beri vardı
    • Temel VM imajlarını derin kopya olarak çoğaltmamak elbette mantıklı, ancak ZFS'de tekilleştirme bunun için doğru yöntem değil
      Bunun yerine temel imajı klonlarsanız, değişiklik yapılana kadar neredeyse hiç yer kaplamaz. Bu, ZFS'nin copy-on-write özelliği sayesinde olur. ZFS tekilleştirme ise bir volume'a yazılan verinin mevcut bir kopyasını bulmaya çalışır. Container imaj deposu gibi bazı kullanım alanlarında oldukça mantıklı olabilir; ancak bir veri kümesinin zaten en baştan başka bir şeyin klonu olduğunu biliyorsanız son derece verimsiz kalır
  • Eskiden ZFS tekilleştirmeyi yaygın biçimde kullanıyordum ve büyük fayda görüyordum. Somut kullanım alanı VMWare kümesi için depolamaydı ve içerikleri büyük ölçüde aynı olan yüzlerce Linux ve Windows VM vardı. Docker öncesi dönemden bahsediyorum

    • Burada VM'lerde tekilleştirme kullanan birkaç örnek görünüyor; bunun dosya sisteminden ziyade hypervisor tarafında uygulanması çok daha verimli olmaz mı diye düşünüyorum
    • Katılıyorum. Kısa süre önce Ubuntu'nun “experimental” zfs içeren yeni iş dizüstü bilgisayarını aldım ve nix store üzerinde tekilleştirme kullanmak gerçekten çok yardımcı oldu
  • Hızlı tekilleştirme çok heyecan verici görünüyor. Yıllardır ArchiveBox verisinde ZFS tekilleştirme kullanmak istiyordum; hızlı tekilleştirme sayesinde milyonlarca URL'yi tek bir koleksiyonda arşivleyip dosya sisteminin tüm sıkıştırmayı üstlendiği bir yaklaşım nihayet mümkün olabilir
    Arşiv verilerinde jquery.min.js, bootstrap.min.css, logo görselleri gibi şeyler binlerce snapshot içinde tekrar tekrar yer alıyor. Diğer araçlar tek bir crawl içinde sıkıştırma yapıp wacz veya warc.gz dosyaları oluşturuyor, ancak şu ana kadar çekilmiş tüm snapshot'ların tüm veritabanı boyunca sıkıştırma yapmayı deneyen bir araç görmedim. Acaba tüm tekilleştirme hash tablosunu olduğu gibi saklamamak için Bloom filter benzeri bir olasılıksal tekilleştirme yaklaşımını deneyen oldu mu diye de merak ediyorum. Yaklaşık 100 blok hash'ini kovalar hâlinde gruplayıp Bloom filter içinde aşırı sıkıştırılmış bir gösterim saklamak gibi. Yazma sırasında kullanılacak bloğun hash'i Bloom filter'da sorgulanır; olası bir tekilleştirme isabeti tespit edilirse ilgili kovadaki 100 blok doğrudan taranarak aynı hash aranır. Teorik olarak farklı çözünürlüklere sahip Bloom filter katmanları kurulabilir ve bellek baskısı yükseldiğinde yüksek çözünürlüklü filtre dinamik olarak diske indirilebilir. Bloom filter doğruluğu ayarlanabilir bir parametre olursa CPU süresi/ek yük ile tasarruf edilen bayt oranı arasındaki tercih de seçilebilir

    • Bu değişiklikle birlikte bile ZFS tekilleştirme hâlâ blok hizalamasına dayalı olduğu için, tekrar eden web varlıkları WARC arşivi içinde her zaman aynı ofsette değilse pek iyi sonuç vermeyecektir
      dm-vdo da aynı şekilde çalışır. Bunun yerine uzun aralıkları gören solid sıkıştırma kullanmak, WARC dosyalarını dizin benzeri bir yapıya açmak ya da içerik tanımlı chunking kullanan bir FUSE sistemi varsa ona yönelmek daha iyi olabilir. Belki Seafile buna uygundur
    • Kullanım amacını anlıyorum ama çoğu durumda, özellikle de bu durumda, bunun istemci tarafında uygulanması çok daha iyi olur gibi geliyor
      WARC standardına bakarsanız zaten hash tabanlı tekilleştirme yapıp ilk kayıttan sonra pointer kullanan bir yöntem var. Bu yüzden dosya sistemi katmanındaki tekilleştirme için tam olarak iyi olmayan bir örnek
    • Kullanım alanı biraz farklı ama zbackup'ı bilmiyorsan hoşuna gidebilir
  • RAM kullanımını azalttıktan sonra bunun düzgün çalıştırılmasının neden bu kadar zor olduğunu merak ediyorum. Ticari depolama appliance'ları, bağlı disk kapasitesine kıyasla RAM'i “az” olan sistemlerde bile bunu en az 10 yıl önce başarabiliyordu
    Sadece parmak izlerini bir veritabanında saklayıp gece tarayarak blok pointer'larını düzeltmek yeterli olmaz mı diye düşünüyorum

    • Sebep tam olarak “blok pointer'larını düzeltmek”. ZFS'nin çeşitli nedenlerle blok pointer yeniden yazma yeteneği yok
      Bu uzun zamandır istenen bir özellik ve mümkün olursa birleştirme/defragmentation da yapılabilir. Sanal bellek gibi blok pointer dolaylılama kullanılarak bir miktar hız maliyetiyle çözülebilir mi diye düşündüm, ama ben ZFS geliştiricisi değilim; kesin gözden kaçırdığım bir şey vardır. http://eworldproblems.mbaynton.com/posts/2014/zfs-block-poin... / https://github.com/openzfs/zfs/issues/3582
    • Blok pointer'larını düzeltmek tam da ZFS'nin yapmaktan kaçınmak istediği şeydi
    • DragonFlyBSD ve Hammer2 kullanmak da bir seçenek. Hammer2 hem çevrimiçi hem çevrimdışı tekilleştirmeyi destekliyor ve birçok açıdan ZFS'ye çok benziyor
      Büyük dezavantajı, RDMA kullanan bir dosya aktarım protokolünün olmaması. Hammer2'yi FreeBSD üzerinde çalıştırmayı hedefleyen deneysel bir dal olduğunu da duydum. Ama FreeBSD'nin de RDMA desteği yok. FreeBSD 15'te Chelsio, NVMe-oF target ve initiator desteğine sponsor oldu, fakat görünen o ki bu yalnızca TCP için geçerli
  • cp --reflink=auto kullanın
    Dosya düzeyinde tekilleştirme elde edebilirsiniz. Bu komut hafif bir kopyalama yapar ve dosya düzeyindeki ZFS clone'ları gibi veri blokları yalnızca değiştirildiklerinde kopyalanır. Hard link değil, bir kopyadır. Reflink destekleyen diğer copy-on-write transactional dosya sistemlerinde de aynı yaklaşım çalışacaktır

  • ZFS'yi gerçekten kullanmak istiyordum ama bütün verilerin doğal olarak şifreli olması gerekiyordu. Fakat kullanım beklediğimden çok daha karmaşık hâle geliyor ve işler karışınca pek çok kişinin veriyi hiç şifrelememeyi seçmesi beni şaşırttı
    Proxmox'un sitesinde bile “Enterprise” yazdığı için varsayılan kurulumda şifrelemeyi desteklediğini sanmıştım, ama şifrelemeyle birlikte kullanmaya kalkınca önemli özellikleri kaybediyorsunuz. Issue tracker'a da mutlaka bakmak gerekiyor. Çalışan bir dosya sisteminde olmasını beklemeyeceğiniz bazı şaşırtıcı eksikler var

    • ZFS'yi şifrelemenin en iyi yolu, şifreli olmayan ZFS'yi LUKS volume gibi şifreli bir volume üzerine kurmaktır. ZFS “şifreleme”, düz metin olarak çok fazla şeyi bıraktığı için rahatsız edici
  • Keşke dosya sistemi olarak tamamen farklı bir API olsaydı. Tüm işletim sistemlerindeki dosya sistemi API yüzeyi, geriye dönük uyumluluk yüzünden kilitlenmiş tam bir karmaşa

    • ZFS dahili olarak esasen bir nesne deposu. Bunu nesne deposu API'si olarak açığa çıkarmaya yönelik çalışmalar olmuştu ama ne yazık ki bir yere varmamış gibi görünüyor
      Sunumu bulmaya çalıştım ama bulamadım. Bunu Developer Summit'te gördüğümü sanıyordum ama demek ki değilmiş
    • Neden karmaşa ve bunun yerine ne gelebilir? AWS S3 tarzı bir API daha iyi olur mu?
  • Tekilleştirmeyi unutup ZFS sıkıştırma kullanmak çok daha iyi bir maliyet/fayda dengesi sunuyor

    • Verisetiniz zaten güçlü biçimde sıkıştırılmış medya dosyalarından oluşuyorsa bu bir istisna
      Genel olarak rsync işleri sırasında büyük video dosyalarında sıkıştırmayı kapatırım. Çünkü sıkıştırma depolama ya da aktarım açısından pek fayda sağlamaz, bazen hiç sağlamaz; buna karşılık RAM ve CPU tüketir. Tekilleştirme ise Virtual Machine OS imajları için iyidir. Çünkü depolama maliyetinin büyük kısmı tekrar eden temel imajlardan gelir
  • Genel amaçlı veri tekilleştirme teoride iyi görünse de pratikte çoğu zaman beklendiği gibi işlemez. IPFS, verileri rsync gibi tekilleştirmeye çalışmak için değişken boyutlu parçalar ve rolling hash kullanıyor, ancak pratikte bir fark yaratamıyor ve boş yere sadece karmaşıklığı artırıyor.