GCP Bigtable Kurulum ve Kullanımı

Büyük veri projelerinde en zorlu kararlardan biri doğru veritabanı teknolojisini seçmektir. Milyarlarca satır veriyi milisaniyeler içinde sorgulamanız gerekiyorsa, geleneksel ilişkisel veritabanları yetersiz kalacaktır. Google Cloud Bigtable tam bu noktada devreye giriyor. Google’ın kendi arama altyapısında yıllardır kullandığı bu NoSQL veritabanı servisi, IoT verileri, finansal işlem kayıtları ve analitik iş yükleri için mükemmel bir çözüm sunuyor. Bu yazıda Bigtable’ı sıfırdan kurup production ortamında nasıl kullanacağınızı adım adım ele alacağız.

Bigtable Nedir ve Ne Zaman Kullanılır?

Bigtable, Google tarafından geliştirilen ve 2015 yılında herkese açılan tamamen yönetilen bir NoSQL veritabanı servisidir. Temel olarak geniş sütunlu (wide-column) bir veri modeli kullanır. İlişkisel veritabanlarından en önemli farkı, şema esnekliği ve yatay ölçeklenebilirlik konusundaki üstünlüğüdür.

Bigtable şu senaryolarda mükemmel performans gösterir:

  • IoT veri toplama: Milyonlarca cihazdan saniyede binlerce yazma işlemi
  • Zaman serisi verileri: Sensor ölçümleri, sistem metrikleri, finansal fiyat verileri
  • Makine öğrenmesi pipeline: Büyük feature store’ları yönetmek
  • Reklam teknolojisi: Kullanıcı davranış verileri ve tıklama akışları
  • Oyun analitiği: Oyuncu aksiyonları ve skor tabloları

Bigtable’ın kullanılmaması gereken durumlar da var. ACID uyumluluk gerektiren işlemsel veriler, karmaşık JOIN sorguları veya küçük ölçekli uygulamalar için Bigtable aşırıya kaçmak olur. Bu durumlarda Cloud SQL veya Firestore daha mantıklı seçimlerdir.

Ön Gereksinimler ve Kurulum Hazırlığı

Bigtable kurulumuna başlamadan önce birkaç şeyi hazır etmeniz gerekiyor.

gcloud CLI kurulumu için önce Google Cloud SDK’yı yüklüyoruz:

# Google Cloud SDK kurulumu (Ubuntu/Debian)
curl https://sdk.cloud.google.com | bash
exec -l $SHELL
gcloud init

# SDK versiyonunu kontrol et
gcloud --version

# Bigtable için gerekli component'i ekle
gcloud components install cbt

Ardından projenizi ve bölgenizi ayarlayın:

# Proje ayarla
gcloud config set project YOUR_PROJECT_ID

# Varsayılan bölge ve zone belirle
gcloud config set compute/region europe-west1
gcloud config set compute/zone europe-west1-b

# Bigtable API'yi etkinleştir
gcloud services enable bigtable.googleapis.com
gcloud services enable bigtableadmin.googleapis.com

Instance Oluşturma

Bigtable’da her şey bir instance ile başlar. Instance, cluster’larınızı barındıran mantıksal bir konteynerdir. Instance oluştururken iki önemli tip var:

PRODUCTION: Yüksek erişilebilirlik için en az 3 node, SLA garantisi olan tip DEVELOPMENT: Tek node, düşük maliyet, test amaçlı

# Production instance oluşturma
gcloud bigtable instances create my-prod-instance 
    --display-name="Production Bigtable" 
    --cluster=my-prod-cluster 
    --cluster-zone=europe-west1-b 
    --cluster-num-nodes=3 
    --cluster-storage-type=SSD 
    --instance-type=PRODUCTION

# Development instance oluşturma (test için)
gcloud bigtable instances create my-dev-instance 
    --display-name="Dev Bigtable" 
    --cluster=my-dev-cluster 
    --cluster-zone=europe-west1-b 
    --instance-type=DEVELOPMENT

# Instance listesini kontrol et
gcloud bigtable instances list

Instance oluşturduktan sonra cbt aracını yapılandırmamız gerekiyor. Ev dizininizdeki .cbtrc dosyasını düzenleyin:

# .cbtrc dosyasını oluştur
cat > ~/.cbtrc << EOF
project = YOUR_PROJECT_ID
instance = my-dev-instance
EOF

# Bağlantıyı test et
cbt ls

Tablo ve Column Family Yapısını Anlama

Bigtable veri modeli birkaç temel kavram üzerine kuruludur:

  • Row Key: Her satırı benzersiz şekilde tanımlayan anahtar, lexicografik sırayla saklanır
  • Column Family: İlgili sütunları gruplayan yapı, tablo oluşturulurken tanımlanır
  • Column Qualifier: Column family içindeki bireysel sütun adı
  • Cell: Belirli bir row key, column family ve qualifier kombinasyonundaki değer
  • Timestamp: Her hücrenin zaman damgası, versiyonlama için kullanılır

İyi bir row key tasarımı Bigtable performansı için kritiktir. Hotspot oluşturmamak için row key’lerinizi dikkatli tasarlayın.

# Tablo oluşturma
cbt createtable user-events

# Column family ekleme
cbt createfamily user-events events
cbt createfamily user-events metadata

# Garbage collection policy ayarla (son 10 versiyonu tut)
cbt setgcpolicy user-events events maxversions=10

# Tabloları listele
cbt ls

# Tablo yapısını görüntüle
cbt ls user-events

Veri Yazma ve Okuma İşlemleri

Şimdi gerçek veri işlemlerine geçelim. cbt CLI ile temel operasyonları gösterelim:

# Tek satır yazma
cbt set user-events "user123#2024-01-15T10:30:00" events:action=click events:page=/home metadata:ip=192.168.1.1

# Satırı okuma
cbt read user-events prefix=user123

# Belirli bir row key aralığını okuma
cbt read user-events start=user123#2024-01-01 end=user123#2024-01-31

# Sınırlı sayıda satır okuma
cbt read user-events count=10

# Belirli column family'yi okuma
cbt read user-events columns=events:action

# Satır silme
cbt deleterow user-events user123#2024-01-15T10:30:00

Python ile Bigtable Kullanımı

Production ortamında CLI yeterli olmayacak. Python istemci kütüphanesiyle daha kapsamlı bir örnek yapalım. Önce bağımlılıkları kurun:

pip install google-cloud-bigtable
pip install google-auth

Şimdi gerçek dünya senaryosuna benzer bir Python örneği yazalım. IoT sensör verilerini kaydettiğimizi düşünelim:

from google.cloud import bigtable
from google.cloud.bigtable import column_family, row_filters
from datetime import datetime, timedelta
import struct

# Client oluştur
project_id = "your-project-id"
instance_id = "my-dev-instance"
table_id = "sensor-readings"

client = bigtable.Client(project=project_id, admin=True)
instance = client.instance(instance_id)

# Tablo ve column family oluştur
table = instance.table(table_id)

# Tablo yoksa oluştur
if not table.exists():
    max_versions_rule = column_family.MaxVersionsGCRule(2)
    column_families = {
        "readings": max_versions_rule,
        "meta": column_family.MaxVersionsGCRule(1)
    }
    table.create(column_families=column_families)
    print(f"Tablo olusturuldu: {table_id}")

def write_sensor_data(device_id, temperature, humidity, timestamp=None):
    """Sensör verisini Bigtable'a yaz"""
    if timestamp is None:
        timestamp = datetime.utcnow()
    
    # Row key: device_id#ters_timestamp (yeni veriler önce gelsin)
    reverse_ts = str(9999999999 - int(timestamp.timestamp())).zfill(10)
    row_key = f"{device_id}#{reverse_ts}".encode()
    
    row = table.direct_row(row_key)
    
    # Değerleri yaz
    row.set_cell(
        "readings", "temperature",
        str(temperature).encode(),
        timestamp=timestamp
    )
    row.set_cell(
        "readings", "humidity",
        str(humidity).encode(),
        timestamp=timestamp
    )
    row.set_cell(
        "meta", "device_id",
        device_id.encode(),
        timestamp=timestamp
    )
    
    row.commit()
    return row_key

def read_device_readings(device_id, hours=24):
    """Son N saatin verilerini oku"""
    now = datetime.utcnow()
    past = now - timedelta(hours=hours)
    
    reverse_now = str(9999999999 - int(now.timestamp())).zfill(10)
    reverse_past = str(9999999999 - int(past.timestamp())).zfill(10)
    
    start_key = f"{device_id}#{reverse_now}".encode()
    end_key = f"{device_id}#{reverse_past}".encode()
    
    rows = table.read_rows(start_key=start_key, end_key=end_key)
    
    results = []
    for row in rows:
        reading = {}
        for family, columns in row.cells.items():
            for qualifier, cells in columns.items():
                reading[qualifier.decode()] = cells[0].value.decode()
        results.append(reading)
    
    return results

# Test verisi yaz
print("Sensör verileri yazılıyor...")
for i in range(10):
    ts = datetime.utcnow() - timedelta(minutes=i*30)
    write_sensor_data(
        device_id="sensor-001",
        temperature=22.5 + i * 0.3,
        humidity=65.0 - i * 0.5,
        timestamp=ts
    )

# Verileri oku
readings = read_device_readings("sensor-001", hours=6)
print(f"Son 6 saatte {len(readings)} okuma bulundu")
for r in readings[:3]:
    print(f"  Sicaklik: {r.get('temperature')}°C, Nem: {r.get('humidity')}%")

Batch Yazma ile Performansı Artırma

Büyük veri yüklerinde tekil yazma işlemleri yerine batch kullanmak çok daha verimlidir:

from google.cloud.bigtable.row import DirectRow
import random

def batch_write_sensor_data(device_readings_list):
    """Toplu sensör verisi yazma"""
    rows = []
    
    for reading in device_readings_list:
        device_id = reading["device_id"]
        timestamp = reading["timestamp"]
        
        reverse_ts = str(9999999999 - int(timestamp.timestamp())).zfill(10)
        row_key = f"{device_id}#{reverse_ts}".encode()
        
        row = table.direct_row(row_key)
        row.set_cell("readings", "temperature",
                     str(reading["temperature"]).encode(),
                     timestamp=timestamp)
        row.set_cell("readings", "humidity",
                     str(reading["humidity"]).encode(),
                     timestamp=timestamp)
        row.set_cell("meta", "location",
                     reading.get("location", "unknown").encode(),
                     timestamp=timestamp)
        rows.append(row)
    
    # Batch commit - 1000 satırlık chunk'lar halinde gönder
    chunk_size = 1000
    for i in range(0, len(rows), chunk_size):
        chunk = rows[i:i+chunk_size]
        errors = table.mutate_rows(chunk)
        if errors:
            for error in errors:
                print(f"Batch yazma hatasi: {error}")
        else:
            print(f"Chunk {i//chunk_size + 1}: {len(chunk)} satir yazildi")

# 5000 kayıt oluştur ve batch yaz
test_data = []
devices = ["sensor-001", "sensor-002", "sensor-003"]
locations = ["istanbul", "ankara", "izmir"]

for i in range(5000):
    device = random.choice(devices)
    test_data.append({
        "device_id": device,
        "timestamp": datetime.utcnow() - timedelta(minutes=i),
        "temperature": round(random.uniform(18.0, 35.0), 2),
        "humidity": round(random.uniform(40.0, 90.0), 2),
        "location": random.choice(locations)
    })

batch_write_sensor_data(test_data)
print("Toplu yazma tamamlandi!")

Row Filter Kullanımı

Bigtable’da karmaşık sorgular için row filter’lar kullanılır. Bu filtreler sunucu tarafında uygulandığından network trafiğini azaltır:

from google.cloud.bigtable import row_filters

def read_with_filters(device_id, column_qualifier=None):
    """Filter kullanarak veri okuma"""
    
    # Sadece belirli bir column'u getir
    if column_qualifier:
        col_filter = row_filters.ColumnQualifierRegexFilter(
            column_qualifier.encode()
        )
    else:
        col_filter = row_filters.PassAllFilter(True)
    
    # Son 1 versiyonu getir
    version_filter = row_filters.CellsColumnLimitFilter(1)
    
    # Filtreleri birleştir (AND mantığı)
    combined_filter = row_filters.RowFilterChain(
        filters=[col_filter, version_filter]
    )
    
    prefix = f"{device_id}#".encode()
    
    rows = table.read_rows(
        row_set=None,
        filter_=combined_filter,
        start_key=prefix,
        end_key=prefix + b'xff'
    )
    
    results = []
    for row in rows:
        for family, columns in row.cells.items():
            for qualifier, cells in columns.items():
                results.append({
                    "row_key": row.row_key.decode(),
                    "qualifier": qualifier.decode(),
                    "value": cells[0].value.decode()
                })
    
    return results

# Sadece sıcaklık değerlerini getir
temps = read_with_filters("sensor-001", "temperature")
print(f"Toplam {len(temps)} sicaklik kaydi bulundu")

Monitoring ve Performans İzleme

Production Bigtable instance’ınızı izlemek için Cloud Monitoring entegrasyonunu kullanabilirsiniz:

# Instance metriklerini görüntüle
gcloud monitoring dashboards list

# CPU kullanımını kontrol et
gcloud bigtable clusters describe my-prod-cluster 
    --instance=my-prod-instance

# Node sayısını güncelle (ölçeklendirme)
gcloud bigtable clusters update my-prod-cluster 
    --instance=my-prod-instance 
    --num-nodes=5

# Mevcut konfigürasyonu listele
gcloud bigtable instances describe my-prod-instance

Otomatik ölçeklendirme için autoscaling özelliğini etkinleştirebilirsiniz. Bu özellik CPU kullanımına göre node sayısını otomatik ayarlar:

# Autoscaling ile cluster güncelleme
gcloud bigtable clusters update my-prod-cluster 
    --instance=my-prod-instance 
    --autoscaling-min-nodes=3 
    --autoscaling-max-nodes=10 
    --autoscaling-cpu-target=60 
    --autoscaling-storage-target=70

Key Visualizer ile Hotspot Analizi

Key Visualizer, Bigtable’ın en güçlü debugging araçlarından biridir. Row key dağılımınızdaki hotspot’ları tespit etmenizi sağlar:

# Key Visualizer'ı etkinleştir (tablonun en az 1 TB verisi veya 
# son 24 saatte 10.000+ okuma/yazma olması gerekir)
# Cloud Console üzerinden Tables > Key Visualizer menüsünden erişilir

# Alternatif olarak profiling için örnek okuma yük testi
for i in $(seq 1 100); do
    cbt read sensor-readings prefix=sensor-001 count=100 > /dev/null
    echo "Okuma $i tamamlandi"
done

Hotspot’lardan kaçınmak için row key tasarımında dikkat edilecekler:

  • Monoton artan değerler kullanmayın: Timestamp’i direkt row key olarak kullanmak hotspot yaratır
  • Hash prefix ekleyin: sha256(device_id)[:4] + "#" + device_id formatı dağılımı iyileştirir
  • Ters timestamp kullanın: En yeni verileri önce listelemek için MAX_INT - timestamp kullanın
  • Bölgesel prefix ekleyin: TR#user123 gibi önekler coğrafi dağılım sağlar

Yedekleme ve Geri Yükleme

Bigtable managed backup özelliği ile verilerinizi koruyabilirsiniz:

# Manuel backup oluştur
gcloud bigtable backups create sensor-backup-20240115 
    --instance=my-prod-instance 
    --cluster=my-prod-cluster 
    --table=sensor-readings 
    --expiration-date=2024-02-15

# Backup listesini görüntüle
gcloud bigtable backups list 
    --instance=my-prod-instance 
    --cluster=my-prod-cluster

# Backup'tan geri yükleme
gcloud bigtable instances tables restore 
    --source-instance=my-prod-instance 
    --source-cluster=my-prod-cluster 
    --source=sensor-backup-20240115 
    --destination=sensor-readings-restored 
    --destination-instance=my-prod-instance

# Backup silme
gcloud bigtable backups delete sensor-backup-20240115 
    --instance=my-prod-instance 
    --cluster=my-prod-cluster

Güvenlik ve IAM Yapılandırması

Production ortamında erişim kontrolünü IAM ile yönetmek kritik önem taşır:

# Servis hesabı oluştur
gcloud iam service-accounts create bigtable-reader 
    --display-name="Bigtable Reader Service Account"

# Sadece okuma yetkisi ver
gcloud bigtable instances add-iam-policy-binding my-prod-instance 
    --member="serviceAccount:bigtable-reader@YOUR_PROJECT.iam.gserviceaccount.com" 
    --role="roles/bigtable.reader"

# Okuma+yazma yetkisi ver
gcloud bigtable instances add-iam-policy-binding my-prod-instance 
    --member="serviceAccount:bigtable-writer@YOUR_PROJECT.iam.gserviceaccount.com" 
    --role="roles/bigtable.user"

# Mevcut IAM politikasını görüntüle
gcloud bigtable instances get-iam-policy my-prod-instance

# Servis hesabı için key oluştur
gcloud iam service-accounts keys create ./bigtable-key.json 
    --iam-account=bigtable-reader@YOUR_PROJECT.iam.gserviceaccount.com

# Key'i ortam değişkeni olarak ayarla
export GOOGLE_APPLICATION_CREDENTIALS="./bigtable-key.json"

Maliyet Optimizasyonu

Bigtable maliyeti temelde üç kalemden oluşur:

  • Node saati: Her çalışan node için saatlik ücret (region’a göre değişir)
  • Depolama: SSD veya HDD seçimine göre GB başına ücret
  • Network çıkışı: GCP dışına çıkan veri için ücret

Maliyeti düşürmek için şu adımları uygulayabilirsiniz:

  • Development ve test ortamları için her zaman DEVELOPMENT instance tipi kullanın
  • Kullanılmayan dev instance’larını durdurun veya silin
  • HDD storage, cold data için SSD’ye göre çok daha ucuzdur
  • Autoscaling’i etkinleştirerek düşük trafik dönemlerinde node sayısını azaltın
  • Sık erişilmeyen verileri Cloud Storage’a export edin

Sonuç

Google Cloud Bigtable, doğru kullanım senaryolarında gerçekten etkileyici sonuçlar veren güçlü bir veritabanı servisidir. Bu yazıda ele aldığımız konuları özetlemek gerekirse; instance kurulumu, tablo ve column family yönetimi, Python ile batch yazma işlemleri, row filter kullanımı, monitoring ve hotspot analizi ile güvenlik yapılandırmasını işledik.

Bigtable’ı başarıyla kullanmanın sırrı büyük ölçüde row key tasarımında saklıdır. Hotspot oluşturmadan yüksek yazma hızı elde etmek, verileri mantıklı aralıklarda okuyabilmek için row key şemanızı iyi düşünün. İlk kurulumda DEVELOPMENT instance tipiyle başlayıp performans testlerinizi yapın, sonra production’a geçin.

IoT platformları, gerçek zamanlı analitik ve yüksek hacimli yazma iş yükleri için Bigtable rakipsiz bir seçenektir. Ancak küçük ölçekli projeler veya karmaşık ilişkisel sorgular için overkill olduğunu unutmayın. Doğru araç, doğru iş prensibiyle hareket ettiğiniz sürece Bigtable büyük veri altyapınızın en sağlam temeli olabilir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir