API'de Bulk Operasyonlar: Batch Boyutu ve İşlem Süresi Optimizasyonu
Bulk operasyonlar, API'ye tek seferde çok sayıda veri göndermek demektir. Örneğin 10 bin kullanıcıyı bir kere bir kere eklemek yerine, 500'erli gruplar halinde göndermek. Buradaki anahtar soru: kaç veriyi bir seferde göndermeli?
Batch boyutu çok küçük olursa (örneğin 10 kayıt), toplam istek sayı artar ve ağ gecikmesi birikir. Çok büyük olursa (10 bin kayıt) sunucu timeout'a uğrayabilir ya da bellek tükenir. Deneyimli API tasarımcılar genelde 100 ile 1000 arasında bir başlangıç yaparlar.
İlk adım: API'nin limit'ini öğren. Dokümantasyona bakıp maksimum kaç kayıt kabul ettiğini kontrol et. Sonra kendi sunucunun kapasite testini yap. Bir batch gönderdikten sonra yanıt süresini ölç.
İkinci adım: Hata yönetimi ekle. Bir batch başarısız olursa, tüm işlemi durdurmak yerine o batch'i daha küçük parçalara böl ve tekrar gönder. Bu exponential backoff stratejisi denir.
Üçüncü adım: Parallellik. Ardışık batch göndermek yerine, 3-5 batch'i eşzamanlı gönder. Ağ bekleme süresi azalır.
Pratik örnek: 10 bin satış kaydını bir e-ticaret API'sine yükleyelim.
1import requests2import time3from typing import List45def batch_upload(records: List[dict], batch_size: int = 500, max_retries: int = 3):6base_url = "https://api.example.com/sales/bulk"7total_records = len(records)8uploaded = 0910for i in range(0, total_records, batch_size):11batch = records[i:i + batch_size]12retry_count = 01314while retry_count < max_retries:15try:16start = time.time()17response = requests.post(18base_url,19json={"records": batch},20timeout=3021)22elapsed = time.time() - start2324if response.status_code == 200:25uploaded += len(batch)26print(f"Batch {i//batch_size + 1}: {len(batch)} kayıt, {elapsed:.2f}s")27break28elif response.status_code == 429: # Rate limit29retry_count += 130wait_time = 2 ** retry_count # Exponential backoff31print(f"Rate limited. {wait_time}s bekleniyor...")32time.sleep(wait_time)33else:34print(f"Hata: {response.status_code}")35break36except requests.Timeout:37retry_count += 138print(f"Timeout. Retry {retry_count}/{max_retries}")39time.sleep(2 ** retry_count)4041print(f"\nToplam yüklenen: {uploaded}/{total_records}")42return uploaded4344# Test verileri45test_records = [{"product_id": i, "quantity": i*2, "price": 100 + i} for i in range(10000)]4647# Batch boyutu 500 ile çalıştır48batch_upload(test_records, batch_size=500)Çıktı örneği:
1Batch 1: 500 kayıt, 1.23s2Batch 2: 500 kayıt, 1.18s3Batch 3: 500 kayıt, 1.25s...4Toplam yüklenen: 10000/10000Batch boyutunu 1000'e çıkarırsan her batch daha uzun sürer ama toplam batch sayısı yarıya iner. Deneme-yanılma ile kendi API'n için optimal değeri bulursun. Genelde 500-1000 arası çoğu durumda iyi sonuç verir.
0 yorum