Ölçeklenebilirlik¶
Genel Bakış¶
Ölçeklenebilirlik, bir sistemin artan yükü karşılayabilme ve kaynakları verimli kullanabilme yeteneğidir. Sistemlerin dikey (vertical) ve yatay (horizontal) olarak ölçeklendirilmesi, yük dengeleme stratejileri ve önbellekleme mekanizmaları ölçeklenebilirliği sağlamak için kullanılan temel yaklaşımlardır.
Temel Kavramlar¶
1. Dikey Ölçeklendirme (Vertical Scaling)¶
public class VerticalScalingExample
{
private readonly ILogger<VerticalScalingExample> _logger;
private readonly SemaphoreSlim _semaphore;
private readonly int _maxConcurrentOperations;
public VerticalScalingExample(
ILogger<VerticalScalingExample> logger,
IConfiguration configuration)
{
_logger = logger;
_maxConcurrentOperations = configuration.GetValue<int>("MaxConcurrentOperations", 100);
_semaphore = new SemaphoreSlim(_maxConcurrentOperations);
}
public async Task ProcessRequestAsync(Request request)
{
await _semaphore.WaitAsync();
try
{
// CPU yoğun işlem
await Task.Run(() => ProcessCpuIntensiveOperation(request));
// Bellek yoğun işlem
await ProcessMemoryIntensiveOperation(request);
}
finally
{
_semaphore.Release();
}
}
private void ProcessCpuIntensiveOperation(Request request)
{
// CPU kaynaklarını verimli kullan
Parallel.For(0, request.Items.Count, new ParallelOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount
}, i =>
{
ProcessItem(request.Items[i]);
});
}
private async Task ProcessMemoryIntensiveOperation(Request request)
{
// Bellek kullanımını optimize et
using var memoryStream = new MemoryStream();
await JsonSerializer.SerializeAsync(memoryStream, request);
// Büyük nesneleri temizle
GC.Collect();
}
}
2. Yatay Ölçeklendirme (Horizontal Scaling)¶
public class HorizontalScalingExample
{
private readonly ILogger<HorizontalScalingExample> _logger;
private readonly ILoadBalancer _loadBalancer;
private readonly IRedisCache _cache;
public HorizontalScalingExample(
ILogger<HorizontalScalingExample> logger,
ILoadBalancer loadBalancer,
IRedisCache cache)
{
_logger = logger;
_loadBalancer = loadBalancer;
_cache = cache;
}
public async Task<Response> HandleRequestAsync(Request request)
{
// Önbellekten kontrol et
var cachedResponse = await _cache.GetAsync<Response>(request.Id);
if (cachedResponse != null)
{
return cachedResponse;
}
// Yük dengeleyici üzerinden isteği yönlendir
var server = await _loadBalancer.GetNextServerAsync();
var response = await server.ProcessRequestAsync(request);
// Yanıtı önbelleğe al
await _cache.SetAsync(request.Id, response, TimeSpan.FromMinutes(30));
return response;
}
}
public interface ILoadBalancer
{
Task<Server> GetNextServerAsync();
}
public class RoundRobinLoadBalancer : ILoadBalancer
{
private readonly List<Server> _servers;
private int _currentIndex;
public RoundRobinLoadBalancer(List<Server> servers)
{
_servers = servers;
_currentIndex = 0;
}
public Task<Server> GetNextServerAsync()
{
var server = _servers[_currentIndex];
_currentIndex = (_currentIndex + 1) % _servers.Count;
return Task.FromResult(server);
}
}
3. Veritabanı Ölçeklendirme¶
public class DatabaseScalingExample
{
private readonly ILogger<DatabaseScalingExample> _logger;
private readonly IDatabaseShardingStrategy _shardingStrategy;
private readonly IReadWriteSplittingStrategy _splittingStrategy;
public DatabaseScalingExample(
ILogger<DatabaseScalingExample> logger,
IDatabaseShardingStrategy shardingStrategy,
IReadWriteSplittingStrategy splittingStrategy)
{
_logger = logger;
_shardingStrategy = shardingStrategy;
_splittingStrategy = splittingStrategy;
}
public async Task SaveDataAsync(Data data)
{
// Sharding stratejisine göre veritabanı seç
var shard = _shardingStrategy.GetShard(data.Id);
// Write işlemi için primary veritabanını kullan
var writeConnection = await _splittingStrategy.GetWriteConnectionAsync();
await writeConnection.SaveAsync(data);
// Replikasyon gecikmesini bekle
await Task.Delay(TimeSpan.FromMilliseconds(100));
}
public async Task<Data> GetDataAsync(string id)
{
// Sharding stratejisine göre veritabanı seç
var shard = _shardingStrategy.GetShard(id);
// Read işlemi için replica veritabanını kullan
var readConnection = await _splittingStrategy.GetReadConnectionAsync();
return await readConnection.GetAsync(id);
}
}
Best Practices¶
1. Ölçeklendirme Stratejileri¶
- Sistem yükünü sürekli izle
- Otomatik ölçeklendirme politikaları belirle
- Stateless tasarım prensiplerini uygula
- Servis keşfi (service discovery) kullan
- Circuit breaker pattern uygula
2. Performans Optimizasyonu¶
- Önbellekleme stratejileri uygula
- Asenkron işleme kullan
- Batch işlemleri optimize et
- Veritabanı sorgularını iyileştir
- CDN kullan
3. Monitoring ve Alerting¶
- Performans metriklerini topla
- Kaynak kullanımını izle
- Hata oranlarını takip et
- Otomatik alarmlar kur
- Kapasite planlaması yap
Sık Sorulan Sorular¶
1. Dikey ve yatay ölçeklendirme arasındaki farklar nelerdir?¶
- Dikey: Tek sunucu kapasitesini artırma
- Yatay: Sunucu sayısını artırma
- Dikey: Sınırlı ölçeklenebilirlik
- Yatay: Teorik olarak sınırsız ölçeklenebilirlik
- Dikey: Daha basit yönetim
- Yatay: Daha karmaşık yönetim
2. Yatay ölçeklendirmede hangi zorluklarla karşılaşılır?¶
- Veri tutarlılığı
- Oturum yönetimi
- Servis keşfi
- Yük dengeleme
- Monitoring ve logging
3. Veritabanı ölçeklendirme stratejileri nelerdir?¶
- Read/Write splitting
- Database sharding
- Replication
- Partitioning
- Caching