İçeriğe geç
Muslu Yüksektepe

CemirCol-Go

CemirCol sütunlu veri formatının Go kütüphanesi. Rust çekirdeğini C-ABI üzerinden, ek kopya yapmadan kullanır.

CemirCol-Go, sütun tabanlı CemirCol veri biçimini Go dilinden kullanmak için hazırladığım kütüphane. CemirCol'un Rust ile yazılmış çekirdeğini C uyumlu bir arayüz üzerinden Go'ya bağlıyor. Böylece Python sürümündeki mmap ve sıfır kopya okuma yaklaşımını Go ile yazılan uygulamalarda da kullanabilirim.

Amaç

CemirCol'u ilk olarak Python için geliştirmiştim. Ancak arka uç servislerimin ve veri işleme hatlarımın önemli bir kısmını Go ile yazarım. Aynı dosya biçimini Go tarafında da okuyup yazabilmek istedim. Biçimi Go ile sıfırdan yeniden yazmak yerine, zaten çalışan ve test edilmiş Rust çekirdeğini ortak kullanmayı tercih ettim.

Bu yaklaşımın amacı, bellek yönetimini ve eşzamanlılığı Go'ya bırakırken ağır sıkıştırma ve açma işlerini Rust tarafında yapmak. Go'nun goroutine yapısı, yani hafif iş parçacıklarıyla çok sayıda işi aynı anda yürütebilme yeteneği, okunan veriyi paralel işlemek için iyi bir zemin sağlıyor.

Nasıl çalışır

Rust çekirdeği hem statik hem de paylaşımlı kütüphane olarak derleniyor. Çekirdek, C ABI (farklı dillerin birbirinin fonksiyonlarını çağırabilmesi için kullanılan ortak ikili arayüz) üzerinden dışarıya birkaç fonksiyon açıyor. Bu fonksiyonlar okuyucu açmayı ve kapatmayı, satır sayısını sorgulamayı, float64 veya int64 sütun okumayı ve tek sütunlu dosya yazmayı sağlıyor.

Go tarafında cgo kullanırım. cgo, Go kodunun C fonksiyonlarını doğrudan çağırmasını sağlayan araç. NewReader fonksiyonu dosyayı Rust tarafında mmap ile açıyor ve bir okuyucu döndürüyor. QueryFloat64 veya QueryInt64 çağrıldığında Rust, ilgili sütunun sıkıştırılmış bölümünü açıyor ve sonucu bir bellek bloğu olarak Go'ya veriyor. Go bu bloğu kendi dilimine (slice) kopyaladıktan sonra Rust tarafındaki belleği serbest bırakıyor. Böylece Go'nun çöp toplayıcısı yalnızca Go'ya ait belleği yönetiyor ve iki dil arasında bellek sahipliği karışmıyor.

Close metodu okuyucuyu kapatıyor ve dosyanın bellek eşlemesini kaldırıyor. Yazma tarafında WriteFloat64 ve WriteInt64 fonksiyonları verilen sütunu zstd ile sıkıştırıp .cemir dosyasına yazıyor.

Öne çıkan özellikler

  • Python sürümüyle aynı Rust çekirdeğini ve aynı .cemir dosya biçimini kullanıyor.
  • Dosyalar mmap ile açıldığı için yalnızca istenen sütunun verisine erişiliyor.
  • float64 ve int64 sütunları için hem okuma hem yazma fonksiyonları sunuyor.
  • Rust tarafında ayrılan bellek, veri Go'ya kopyalandıktan hemen sonra serbest bırakılıyor.
  • Okuyucu kapatıldıktan sonra yapılan çağrılar çökme yerine açık bir hata döndürüyor.
  • setup.sh betiği Rust ve Go kurulumunu kontrol ediyor, Rust çekirdeğini derliyor ve Go modüllerini düzenliyor.

Teknik altyapı

Kütüphanenin Go tarafı cgo ile yazıldı, Rust tarafında ise ek olarak libc kütüphanesiyle C uyumlu bir API katmanı bulunuyor. Çekirdekte Python sürümündeki gibi memmap2, zstd, flate2, rayon, serde ve serde_json kullanılıyor. Rust kütüphanesi en yüksek optimizasyon düzeyi ve LTO ile derleniyor.

Depoda ayrıca sensör, finans, web logu ve uygulama logu gibi farklı veri türleri için hazırlanmış örnek ve karşılaştırma programları var. Parquet ile karşılaştırma yapmak için xitongsys/parquet-go kütüphanesini kullandım. README'deki ölçümde 1 milyon float64 satırı CemirCol-Go ile yaklaşık 22 ms'de yazılıp 12 ms'de okunurken, aynı işlemler parquet-go ile yaklaşık 75 ms ve 130 ms sürdü. Dosya boyutu CemirCol'da yaklaşık 1 MB, Parquet'te yaklaşık 3,9 MB oldu. Bu ölçümler belirli bir makinede ve belirli bir veriyle yapıldı; başka koşullarda sonuçlar değişebilir.

Kütüphaneyi kullanmadan önce Rust çekirdeğinin derlenmesi gerekiyor. Bu nedenle sistemde Rust araç zincirinin ve Go'nun kurulu olması şart.

Kullanım alanları

  • Go ile yazılmış arka uç servislerinde büyük sayısal veri kümelerini sıkıştırılmış ve hızlı okunabilir biçimde saklamak için kullanılabilir.
  • Log, sensör veya finans verilerini işleyen veri hatlarında, Python ile üretilmiş .cemir dosyalarını Go tarafında okumayı sağlar.
  • Python ve Go'nun birlikte kullanıldığı projelerde iki dil arasında ortak bir veri biçimi sunar.
  • Rust ile yazılmış bir kütüphanenin Go'ya nasıl bağlanacağını gösteren bir örnek olarak da incelenebilir.

Durum

Kütüphane şu anda tek sütunlu yazma ile float64 ve int64 okuma işlemlerini destekliyor. Python sürümündeki çok sütunlu yazma ve dönüştürücüler Go tarafında henüz yok.

Kategori
Veri ve veritabanı
Yıl
2026

Teknolojiler

  • Go
  • Rust
  • C-ABI
  • Open Source

Bağlantılar

  • GitHub https://github.com/muslu/cemircol-go

Tüm projelere dön