Sharding or Data Partitioning(Parçalama yada Veri Bölümleme)

Veri bölümleme (parçalama olarakta bilinir) büyük bir veri tabanını (DB) küçük parçalara ayırma tekniğidir. Bir uygulamanın yönetilebilirliğini, performansını, erişilebilirliğini ve yük dengesini iyileştirmek için, veri tabanını/tabloyu çok sayıda makineye ayırma işlemidir. Belirli bir veri büyüklüğünden sonra daha güçlü sunucular ekleyerek sistemi dikey olarak büyütmek yerine daha fazla bilgisayar ekleyerek yatay olarak ölçeklemek daha kolay ve makuldür.Veri parçalama yatay olarak ölçekleme avantajı sağlar.

Buradaki ana sorun ise parçalama için kullanılan değer aralığı doğru seçilmezse bölümleme şeması sunucularda dengesizlik yaratabilir. Bir önceki örnekte, zip kodlarına göre konum ayırmak konumların farklı zip kodlarına eşit dağıtılmasını öngörmektedir. Bu, küçük bir il ile kıyaslandığında İstanbul gibi yoğun nüfuslu bir şehirde çok fazla konum olacağı için geçersiz bir öngörüdür.

Dikey bölümlemenin uygulaması kolaydır ayrıca uygulama üzerinde düşük bir etkiye sahiptir. Bu yöntemin dezavantajı ise eğer uygulama büyürse, bir özelliğe yönelik veri tabanını farklı sunucular içerisinde daha fazla bölümlemek gerekebilir. (Tek bir sunucunun 140 milyon kullanıcı tarafından paylaşılan 10 milyar fotoğraf için tüm metaveri sorgusunu yapması mümkün olmayabilir.)

Yukarıda sözü edilen şemalardaki sorunları çözmek için bağımsız bir yaklaşım olarak güncel bölümleme şemanızı bilen ve bunu veri tabanı erişim kodundan soyutlayan bir lookup servisi oluşturulabilir. Dolayısıyla belirli bir veri ögesinin nerede olduğunu bulmak için, her bir demet anahtarı(tuple key) bir veri tabanına eşlenmiş dizin sunucusunda(directory server ) sorgulama yapabiliriz. Bu yaklaşımla, DB havuzuna sunucu eklemek gibi görevleri yerine getirebilir veya uygulamayı etkilemeden bölümleme şemasını değiştirebiliriz.

Bu şemada, depolanan verinin anahtar özniteliklerinden birine hash fonksiyonu uyguluyabilir ve böylelikle bölümleme sayısını arttırırabiliriz. Örneğin, eğer 100 tane DB sunucumuz var ve ID’miz her yeni kayıtta +1 arttırılan sayısal bir değer. Bu örnekte, hash fonksiyonu ‘ID %100’ olsun. Bu bize kaydı depoladığımız ve okuyabileceğimiz sunucuyu verir. Bu yaklaşım sunucular arasında veri paylaşımının tek bir şekilde olmasını sağlar. Dezavatantajı ise yeni sunucular eklemek, verinin yeniden dağıtılmasını gerektirdiğinden ve hash fonksiyonunun değiştirilmesi serviste aksamaya neden olduğu için DB sunucularını total sayısını efektif bir biçimde sabitlemesidir. Bu sorun, Tutarlı Hashing(Consistent Hashing ) kullanılarak aşılabilir.

Bu şemada, her bir bölüme bir değerler listesi atanır ve her yeni kayıt eklemek istediğimizde hangi bölümün anahtarı bulundurduğunu görebilir ve orada depolayabiliriz. Örneğin, İzlanda, Norveç, İsveç, Finlandiya veya Danimarka’da yaşayan tüm kullanıcıları Nordik ülkeler için bir bölümde depolayabiliriz.

Verilerin tek bir şekilde dağıtılmasını sağlayan basit bir yöntemdir. ‘n’ bölümleme ile, ‘i’ demeti bölümlemeye atanır. (i mod n)

Bu şemada, yeni bir şema oluşturmak için yukarıdaki bölümleme şemalarından herhangi ikisini birleştiriyoruz. Örnek olarak, önce bir liste bölümleme sonra da hash tabanlı bölümleme uygulanabilir. Tutarlu hashing, hash ve liste bölümlemenin bir bileşiği olarak düşünülebilir. Hash, anahtar boşluğu listelenebilecek bir boyuta küçültür.

Parçalanmış bir veri tabanı üzerinde, yapılabilecek işlemlere dair belirli kısıtlamalar vardır. Bu kısıtlamalar, çok sayıda tablo ile veya aynı tablo içerisindeki çok fazla satırdaki işlemler için gerekli tablo ve satırların aynı sunucuda bulunmamasından kaynaklanır. Parçalamadan dolayı ortaya çıkan kısıtlamalar veya karmaşıklıklardan bazıları şunlardır:

Bölümlenmiş bir veri tabanı üzerinde shard’lar arasın sorgu yapmak kolay olmadığından, benzer şekilde parçalanmış veri tabanına yabancı anahtarlar(foreign keys) gibi veri bütünlüğü kısıtlamalarını zorlamak oldukça zor olabilir. Çoğu RDMBS( İlişkisel Veritabanı Yönetim Sistemleri) farklı veri tabanı serverları üzerinde veri tabanlarında yabancı anahtar(foreign keys) zorlamalarını desteklemez. Bu da parçalanmış veri tabanları üzerinde veri tutarlılığı gerektiren uygulamaların bu zorlamayı uygulama kodunda yapması anlamına gelir. Böyle durumlarda uygulamalar genellikle boşta duran başvuruları(references) temizlemek için düzenli olarak SQL işleri çalıştırır.

Parçalama şemasının değiştirilmesi için birçok neden olabilir.

  1. Veri dağıtımı tek bir formatta gerçekleşmemiştir. Örneğin, bir veri tabanının parçalaması için uyumlu olmayacak şekilde bir ZIP kodu çok sayıda farklı yere kayıt atılmış olabilir.

  2. Bir shard üzerinde çok fazla yük olabilir. Örneğin, kullanıcı fotoğraflarına ait bir DB shard’ı fazla sayıda isteği yanıtlamak zorunda kalmış olabilir.

Böyle durumlarda, ya daha fazla DB shardı oluştururuz ya da var olan shardları yeniden dengeler,parçalama şeması değiştirilir ve var olan tüm veri yeni konumlara taşınır. Herhangi bir kesinti olmadan bunu yapmak oldukça zordur. Dizin tabanlı parçalama(directory based partitioning) gibi bir şema kullanmak, sistem daha komplike hale getirme ve yeni bir tek arıza noktası (lookup servisi/veri tabanı gibi) oluşturma riskini doğurmasına rağmen yeniden dengelemeyi daha kolay hale getirmektedir.