Parçalama düzeniSharding pattern

Veri deposunu bir dizi yatay bölüme veya parçaya ayırın.Divide a data store into a set of horizontal partitions or shards. Bu düzen, büyük hacimli verileri depolarken ve bu verilere erişirken ölçeklenebilirliği artırabilir.This can improve scalability when storing and accessing large volumes of data.

Bağlam ve sorunContext and problem

Tek bir sunucu tarafından barındırılan bir veri deposu aşağıdaki sınırlamalara tabi olabilir:A data store hosted by a single server might be subject to the following limitations:

  • Depolama alanı.Storage space. Büyük ölçekli bir bulut uygulaması için veri deposunun zaman içinde önemli ölçüde artırabilen çok büyük bir veri hacmi içermesi beklenir.A data store for a large-scale cloud application is expected to contain a huge volume of data that could increase significantly over time. Bir sunucu genellikle yalnızca sınırlı miktarda disk depolama alanı sağlar, ancak var olan diskleri büyük olanlarla değiştirebilir veya veri hacimleri büyüdükçe makineye daha fazla disk ekleyebilirsiniz.A server typically provides only a finite amount of disk storage, but you can replace existing disks with larger ones, or add further disks to a machine as data volumes grow. Bununla birlikte, sistem belirli bir sunucu üzerindeki depolama kapasitesini kolayca artırmanın mümkün olmadığı bir sınıra sonunda ulaşır.However, the system will eventually reach a limit where it isn't possible to easily increase the storage capacity on a given server.

  • Bilgi işlem kaynakları.Computing resources. Bir bulut uygulamasının, her biri veri deposundan bilgi alan sorgular çalıştıran çok sayıda eşzamanlı kullanıcıyı desteklemesi gerekir.A cloud application is required to support a large number of concurrent users, each of which run queries that retrieve information from the data store. Veri deposunu barındıran tek bir sunucu bu yükü desteklemeye yetecek işlem gücünü sağlayamayabilir ve kullanıcılar için yanıt sürelerinin uzamasına ve verileri depolayıp almaya çalışan uygulamalar zaman aşımına uğradıkça sık hatalara yol açar. Bellek eklemek veya işlemcileri yükseltmek mümkün olabilir, ancak bilgi işlem kaynaklarını daha fazla artırmak mümkün olmadığında sistem bir sınıra ulaşır.A single server hosting the data store might not be able to provide the necessary computing power to support this load, resulting in extended response times for users and frequent failures as applications attempting to store and retrieve data time out. It might be possible to add memory or upgrade processors, but the system will reach a limit when it isn't possible to increase the compute resources any further.

  • Ağ bant genişliği.Network bandwidth. Nihai olarak, tek bir sunucu üzerinde çalışan bir veri deposunun performansı, sunucunun istekleri alabildiği ve yanıtları gönderebildiği hıza göre yönetilir.Ultimately, the performance of a data store running on a single server is governed by the rate the server can receive requests and send replies. Trafik hacminin sunucuya bağlanmak için kullanılan ağın kapasitesini aşması ve başarısız isteklerle sonuçlanması mümkündür.It's possible that the volume of network traffic might exceed the capacity of the network used to connect to the server, resulting in failed requests.

  • Coğrafya.Geography. Belirli kullanıcılar tarafından oluşturulan verilerin yasal, uyumluluk veya performans amaçlı kullanıcılarla ya da veri erişimi gecikmesini azaltmak amacıyla aynı bölgede depolanması gerekebilir.It might be necessary to store data generated by specific users in the same region as those users for legal, compliance, or performance reasons, or to reduce latency of data access. Kullanıcılar farklı ülke veya bölgeler arasında dağılmışsa, uygulamaya ait tüm verilerin tek bir veri deposunda depolanması mümkün olmayabilir.If the users are dispersed across different countries or regions, it might not be possible to store the entire data for the application in a single data store.

Daha fazla disk kapasitesi, işleme gücü, bellek ve ağ bağlantısı ekleyerek dikey yönde ölçeklendirmek, bu sınırlamalardan bazılarının etkilerini erteleyebilir ancak yalnızca geçici bir çözüm olabilir.Scaling vertically by adding more disk capacity, processing power, memory, and network connections can postpone the effects of some of these limitations, but it's likely to only be a temporary solution. Çok sayıda kullanıcıyı ve yüksek hacimli verileri destekleyebilen ticari bir bulut uygulaması neredeyse süresiz olarak ölçekleyebilmelidir, bu nedenle ölçeklendirmenin mutlaka en iyi çözüm olması gerekmez.A commercial cloud application capable of supporting large numbers of users and high volumes of data must be able to scale almost indefinitely, so vertical scaling isn't necessarily the best solution.

ÇözümSolution

Veri deposunu yatay bölümlere veya parçalara ayırın.Divide the data store into horizontal partitions or shards. Her parça aynı şemaya sahiptir ancak kendi ayrı veri alt kümesini tutar.Each shard has the same schema, but holds its own distinct subset of the data. Parça, depolama düğümü olarak görev yapan bir sunucu üzerinde çalışan, kendi çapında bir veri deposudur (farklı türlerdeki birçok varlığın verilerini içerebilir).A shard is a data store in its own right (it can contain the data for many entities of different types), running on a server acting as a storage node.

Bu düzen aşağıdaki avantajlara sahiptir:This pattern has the following benefits:

  • Ek depolama düğümleri üzerinde çalışan daha fazla parça ekleyerek sistemin ölçeğini genişletebilirsiniz.You can scale the system out by adding further shards running on additional storage nodes.

  • Bir sistem her depolama düğümü için özelleştirilmiş ve pahalı bilgisayarlar yerine piyasada satılan donanımları kullanabilir.A system can use off-the-shelf hardware rather than specialized and expensive computers for each storage node.

  • Parçalar arasındaki iş yükünü dengeleyerek çekişmeyi azaltabilir ve performansı artırabilirsiniz.You can reduce contention and improve performance by balancing the workload across shards.

  • Bulutta parçalar, verilere erişecek kullanıcıların fiziksel olarak yakınına konumlandırılabilir.In the cloud, shards can be located physically close to the users that'll access the data.

Bir veri deposunu parçalara bölerken her bir parçaya hangi verilerin yerleştirilmesi gerektiğine karar verin.When dividing a data store up into shards, decide which data should be placed in each shard. Bir parça genellikle verilerin bir veya daha fazla özniteliği ile belirlenmiş belirli bir aralığa denk düşen öğeler içerir.A shard typically contains items that fall within a specified range determined by one or more attributes of the data. Bu öznitelikler parça anahtarını (bazı durumlarda bölüm anahtarı olarak adlandırılır) oluşturur.These attributes form the shard key (sometimes referred to as the partition key). Parça anahtarı statik olmalıdır.The shard key should be static. Değişebilecek verileri temel almamalıdır.It shouldn't be based on data that might change.

Parçalama işlemi, verileri fiziksel olarak düzenler.Sharding physically organizes the data. Bir uygulama veri depolayıp aldığında, parçala mantığı uygulamayı uygun parçaya yönlendirir.When an application stores and retrieves data, the sharding logic directs the application to the appropriate shard. Bu parçalama mantığı, uygulamadaki veri erişim kodunun bir parçası olarak uygulanabilir veya parçalamayı saydam bir şekilde destekliyorsa veri depolama sistemi tarafından uygulanabilir.This sharding logic can be implemented as part of the data access code in the application, or it could be implemented by the data storage system if it transparently supports sharding.

Parçalama mantığında verilerin fiziksel konumunun soyutlanması, parçaların hangi verileri içerdiğine dair yüksek düzeyde denetim sağlar.Abstracting the physical location of the data in the sharding logic provides a high level of control over which shards contain which data. Ayrıca, parçalardaki verilerin daha sonra yeniden dağıtılması gerekirse (örneğin, parçalar dengesiz hale gelirse), verilerin bir uygulamanın iş mantığı üzerinde yeniden çalışmadan parçalar arasında geçiş yapmasına olanak tanır.It also enables data to migrate between shards without reworking the business logic of an application if the data in the shards need to be redistributed later (for example, if the shards become unbalanced). Denge, alınan her veri öğesinin konumunu belirlerken gereken ek veri erişimi yüküdür.The tradeoff is the additional data access overhead required in determining the location of each data item as it's retrieved.

En iyi performans ve ölçeklenebilirliği sağlamak için verileri uygulamanın gerçekleştirdiği sorgu türlerine uygun bir şekilde bölmek önemlidir.To ensure optimal performance and scalability, it's important to split the data in a way that's appropriate for the types of queries that the application performs. Birçok durumda, parçalama düzeninin her sorguya ait gereksinimlerle tam olarak eşleşme olasılığı düşüktür.In many cases, it's unlikely that the sharding scheme will exactly match the requirements of every query. Örneğin, çok kiracılı bir sistemde bir uygulamanın kiracı kimliğini kullanarak kiracı verilerini alması gerekebilir, ancak aynı zamanda kiracının adı veya konumu gibi diğer özniteliklere göre bu verileri araması gerekebilir.For example, in a multi-tenant system an application might need to retrieve tenant data using the tenant ID, but it might also need to look up this data based on some other attribute such as the tenant’s name or location. Bu durumların üstesinden gelmek için, en yaygın olarak gerekleştirilen sorguları destekleyen bir parça anahtarı ile parçalama stratejisi uygulayın.To handle these situations, implement a sharding strategy with a shard key that supports the most commonly performed queries.

Sorgular öznitelik değerlerinin bir birleşimini kulanarak düzenli aralıklarla veri alıyorsa, öznitelikleri birbirine bağlayarak bileşik bir parça anahtarı tanımlayabilirsiniz.If queries regularly retrieve data using a combination of attribute values, you can likely define a composite shard key by linking attributes together. Alternatif olarak, parça anahtarı kapsamında olmayan özniteliklere göre verileri hızlı aramayı sağlayan Dizin Tablosu gibi bir düzen kullanın.Alternatively, use a pattern such as Index Table to provide fast lookup to data based on attributes that aren't covered by the shard key.

Parçalama stratejileriSharding strategies

Parça anahtarı seçerken ve parçalar arasında verilerin nasıl dağıtılacağına karar verirken yaygın olarak üç strateji kullanılır.Three strategies are commonly used when selecting the shard key and deciding how to distribute data across shards. Parçalar ile onları barındıran sunucular arasında bire bir karşılık olması zorunlu değildir—Tek bir sunucu birden çok parça barındırabilir.Note that there doesn't have to be a one-to-one correspondence between shards and the servers that host them—a single server can host multiple shards. Stratejiler şunlardır:The strategies are:

Arama stratejisi.The Lookup strategy. Bu stratejide parçalama mantığı, parça anahtarını kullanarak bir veri isteğini bu verileri içeren parçaya yönlendiren bir eşleme uygular.In this strategy the sharding logic implements a map that routes a request for data to the shard that contains that data using the shard key. Çok kiracılı bir uygulamada bir kiracının tüm verileri, parça anahtarı olarak kiracı kimliğini kullanılarak bir parçada birlikte depolanabilir.In a multi-tenant application all the data for a tenant might be stored together in a shard using the tenant ID as the shard key. Birden çok kiracı aynı parçayı paylaşabilir, ancak tek bir kiracının verileri birden fazla parça arasında yayılmaz.Multiple tenants might share the same shard, but the data for a single tenant won't be spread across multiple shards. Şekilde, kiracı kimliklerine göre parçalama kiracı verileri gösterilmektedir.The figure illustrates sharding tenant data based on tenant IDs.

Şekil 1 - Kiracı kimliklerine göre parçalama kiracı verileri

Parça anahtarı ile fiziksel depolama alanı arasındaki eşleme, her parça anahtarının fiziksel bir bölümle eşlendiği fiziksel parçaları temel alabilir.The mapping between the shard key and the physical storage can be based on physical shards where each shard key maps to a physical partition. Alternatif olarak, parçaları yeniden dengelemeye yönelik daha esnek bir teknik ise parça anahtarlarının aynı sayıda sanal parça ile ve sonuç olarak daha az fiziksel bölümle eşlendiği sanal bölümlemedir.Alternatively, a more flexible technique for rebalancing shards is virtual partitioning, where shard keys map to the same number of virtual shards, which in turn map to fewer physical partitions. Bu yaklaşımda bir uygulama, sanal bir parçaya başvuran bir parça anahtarı kullanarak verileri bulur ve sistem, sanal parçaları fiziksel bölümlerle saydam bir şekilde eşler.In this approach, an application locates data using a shard key that refers to a virtual shard, and the system transparently maps virtual shards to physical partitions. Sanal parça ile fiziksel bölüm arasındaki eşleme, farklı bir parça anahtarları kümesi kullanmak için uygulama kodunun değiştirilmesini gerektirmeden değişebilir.The mapping between a virtual shard and a physical partition can change without requiring the application code be modified to use a different set of shard keys.

Aralık stratejisi.The Range strategy. Bu strateji, ilgili öğeleri aynı parçada gruplandırır ve parça anahtarına göre sıralar—Parça anahtarları sıralıdır.This strategy groups related items together in the same shard, and orders them by shard key—the shard keys are sequential. Aralık sorguları (belirli bir aralığa denk gelen bir parça anahtarı için bir veri öğeleri kümesi döndüren sorgular) kullanarak sıklıkla öğe kümeleri alan uygulamalar için yararlıdır.It's useful for applications that frequently retrieve sets of items using range queries (queries that return a set of data items for a shard key that falls within a given range). Örneğin, bir uygulama belirli bir ayda verilen tüm siparişleri düzenli olarak bulması gerekiyorsa, bir aya ait tüm siparişlerin aynı parçaya tarih ve saat sırasıyla depolanması durumunda bu veriler daha hızlı bir şekilde alınabilir.For example, if an application regularly needs to find all orders placed in a given month, this data can be retrieved more quickly if all orders for a month are stored in date and time order in the same shard. Her sipariş farklı bir parçada depolanmışsa, çok sayıda nokta sorgu (tek bir veri öğesi döndüren sorgular) gerçekleştirilerek siparişlerin tek tek getirilmesi gerekir.If each order was stored in a different shard, they'd have to be fetched individually by performing a large number of point queries (queries that return a single data item). Aşağıdaki şekilde, sıralı veri kümelerinin (aralıklar) parçalarda depolanması gösterilmektedir.The next figure illustrates storing sequential sets (ranges) of data in shard.

Şekil 2 - Sıralı veri kümelerinin (aralıklar) parçalarda depolanması

Bu örnekte parça anahtarı, en önemli unsur olarak siparişi, ardından sipariş günü ve saatini içeren bir bileşik anahtardır.In this example, the shard key is a composite key containing the order month as the most significant element, followed by the order day and the time. Yeni siparişler oluşturulup bir parçaya eklendiğinde sipariş verileri doğal olarak sıralanır.The data for orders is naturally sorted when new orders are created and added to a shard. Bazı veri depoları, parçayı tanımlayan bir bölüm anahtarı öğesi ve parçadaki öğeyi benzersiz şekilde tanımlayan bir satır anahtarı içeren iki kısımlı parça anahtarlarını destekler.Some data stores support two-part shard keys containing a partition key element that identifies the shard and a row key that uniquely identifies an item in the shard. Veriler genellikle parçada satır anahtarı sırasıyla tutulur.Data is usually held in row key order in the shard. Aralık sorgularına tabi olup birlikte gruplanması gereken öğeler, bölüm anahtarı için aynı ancak satır anahtarı için benzersiz bir değere sahip olan parça anahtarını kullanabilir.Items that are subject to range queries and need to be grouped together can use a shard key that has the same value for the partition key but a unique value for the row key.

Karma stratejisi.The Hash strategy. Bu stratejinin amacı etkin nokta (orantısız miktarda yük alan parçalar) olasılığını azaltmaktır.The purpose of this strategy is to reduce the chance of hotspots (shards that receive a disproportionate amount of load). Verileri her parçanın boyutu ile her parçanın karşılaşacağı ortalama yük arasında bir denge kuracak şekilde parçalar arasında dağıtır.It distributes the data across the shards in a way that achieves a balance between the size of each shard and the average load that each shard will encounter. Parçalama mantığı bir veya daha fazla veri özniteliğinin karmasına göre bir öğeyi depolayacak şekilde parçayı hesaplar.The sharding logic computes the shard to store an item in based on a hash of one or more attributes of the data. Seçilen karma işlevi, muhtemelen hesaplamaya rastgele öğeler ekleyerek verileri parçalar arasında eşit olarak dağıtmalıdır.The chosen hashing function should distribute data evenly across the shards, possibly by introducing some random element into the computation. Aşağıdaki şekilde, bir kiracı kimlikleri karmasına göre parçalama kiracı verileri gösterilmektedir.The next figure illustrates sharding tenant data based on a hash of tenant IDs.

Şekil 3 - Bir kiracı kimlikleri karmasına göre parçalama kiracı verileri

Karma stratejisinin diğer parçalama stratejilerine göre avantajını anlamak için, sırayla yeni kiracılar kaydeden çok kiracılı bir uygulamanın kiracıları veri deposundaki parçalara nasıl atayabileceğini düşünün.To understand the advantage of the Hash strategy over other sharding strategies, consider how a multi-tenant application that enrolls new tenants sequentially might assign the tenants to shards in the data store. Aralık stratejisini kullanırken, 1 ile n arasındaki kiracı verilerinin tümü A parçasında, n+1 kiracı verilerinin tümü B parçasında vb. depolanır.When using the Range strategy, the data for tenants 1 to n will all be stored in shard A, the data for tenants n+1 to m will all be stored in shard B, and so on. En son kaydedilen kiracılar aynı zamanda en etkin kiracılar değilse, veri etkinliklerinin çoğunluğu az sayıda parça içinde oluşur ve etkin noktalar oluşur.If the most recently registered tenants are also the most active, most data activity will occur in a small number of shards, which could cause hotspots. Buna karşılık, Karma stratejisi kiracıları kendi kiracı kimliklerinin karmasına göre parçalara ayırır.In contrast, the Hash strategy allocates tenants to shards based on a hash of their tenant ID. Diğer bir deyişle, sıralı kiracılar büyük olasılıkla farklı parçalara ayrılır ve yük bunlar arasında dağıtılır.This means that sequential tenants are most likely to be allocated to different shards, which will distribute the load across them. Yukarıdaki şekilde 55. ve 56. kiracılar için bu durum gösterilmiştir.The previous figure shows this for tenants 55 and 56.

Üç parçalama stratejisi aşağıdaki avantajları ve dikkat edilmesi gereken noktaları içerir:The three sharding strategies have the following advantages and considerations:

  • Arama.Lookup. Parçaların yapılandırılma ve kullanılma şekli üzerinde daha fazla denetim sağlar.This offers more control over the way that shards are configured and used. İş yükünü dengelemek üzere yeni fiziksel bölümler eklenebildiği için sanal parçaların kullanılması, veriler yeniden dengelenirken oluşan etkiyi azaltır.Using virtual shards reduces the impact when rebalancing data because new physical partitions can be added to even out the workload. Bir sanal parça ile parçayı uygulayan fiziksel bölümler arasındaki eşleme, veri depolayıp almak için parça anahtarı kullanan uygulama kodunu etkilemeden değiştirilebilir.The mapping between a virtual shard and the physical partitions that implement the shard can be modified without affecting application code that uses a shard key to store and retrieve data. Parça konumlarını aramak ek bir yük oluşturabilir.Looking up shard locations can impose an additional overhead.

  • Aralık.Range. Bunun uygulanması kolaydır ve genellikle tek bir işlemde tek bir parçadan birden fazla öğe getirebildiği için aralık sorgularıyla iyi çalışır.This is easy to implement and works well with range queries because they can often fetch multiple data items from a single shard in a single operation. Bu strateji daha kolay veri yönetimi sunar.This strategy offers easier data management. Örneğin, aynı bölgedeki kullanıcılar aynı parça içindeyse, yerel yüke ve talep desenine göre her saat diliminde güncelleştirmeler zamanlanabilir.For example, if users in the same region are in the same shard, updates can be scheduled in each time zone based on the local load and demand pattern. Ancak, bu strateji parçalar arasında en iyi dengelemeyi sağlamaz.However, this strategy doesn't provide optimal balancing between shards. Parçaların yeniden dengelenmesi zordur ve etkinliğin büyük bölümü bitişik parça anahtarlarına yönelikse eşit olmayan yük sorununu çözemeyebilir.Rebalancing shards is difficult and might not resolve the problem of uneven load if the majority of activity is for adjacent shard keys.

  • Karma.Hash. Bu strateji daha eşit veri ve yük dağılımı olasılığını artırır.This strategy offers a better chance of more even data and load distribution. İstek, karma işlevi kullanılarak doğrudan yönlendirilebilir.Request routing can be accomplished directly by using the hash function. Bir eşleme yapmak gerekmez.There's no need to maintain a map. Karma hesaplamanın ek yük oluşturabileceğini unutmayın.Note that computing the hash might impose an additional overhead. Ayrıca, parçaların yeniden dengelenmesi zordur.Also, rebalancing shards is difficult.

Birçok yaygın parçalama sistemi yukarıda açıklanan yaklaşımlardan birini uygular, ancak uygulamalarınızın iş gereksinimlerini ve veri kullanımı düzenlerini de dikkate almanız gerekir.Most common sharding systems implement one of the approaches described above, but you should also consider the business requirements of your applications and their patterns of data usage. Örneğin, çok kiracılı bir uygulamada:For example, in a multi-tenant application:

  • Verileri iş yüküne göre parçalayabilirsiniz.You can shard data based on workload. Ayrı parçalardaki yüksek oranda geçici kiracılar için verileri ayırabilirsiniz.You could segregate the data for highly volatile tenants in separate shards. Sonuç olarak diğer kiracılar için veri erişiminin hızı iyileştirilebilir.The speed of data access for other tenants might be improved as a result.

  • Verileri kiracıların konumuna göre parçalayabilirsiniz.You can shard data based on the location of tenants. Diğer bölgelerdeki kiracıların verileri kendi iş saatleri sırasında çevrimiçi ve erişilebilir durumda kalırken belirli bir coğrafi bölgedeki kiracıların verilerini o bölgenin yoğun olmayan saatlerinde yedekleme ve bakım için çevrimdışı yapabilirsiniz.You can take the data for tenants in a specific geographic region offline for backup and maintenance during off-peak hours in that region, while the data for tenants in other regions remains online and accessible during their business hours.

  • Yüksek değerli kiracılar kendi özel, yüksek performanslı, hafif yüklü parçalarına atanabilirken, düşük değerli kiracıların daha yoğun ve meşgul parçaları paylaşması beklenebilir.High-value tenants could be assigned their own private, high performing, lightly loaded shards, whereas lower-value tenants might be expected to share more densely-packed, busy shards.

  • Yüksek derecede veri yalıtımı ve gizliliğe gereksinim duyan kiracıların verileri tamamen ayrı bir sunucuda depolanabilir.The data for tenants that need a high degree of data isolation and privacy can be stored on a completely separate server.

Ölçeklendirme ve veri taşıma işlemleriScaling and data movement operations

Parçalama stratejilerinin her biri ölçek azaltma, ölçeği genişletme, veri taşıma ve durum koruma amacıyla farklı özellikler ve karmaşıklık düzeyleri uygular.Each of the sharding strategies implies different capabilities and levels of complexity for managing scale in, scale out, data movement, and maintaining state.

Arama stratejisi, kullanıcı düzeyinde çevrimiçi veya çevrimdışı olarak ölçeklendirme ve veri taşıma işlemlerinin gerçekleştirilmesine izin verir.The Lookup strategy permits scaling and data movement operations to be carried out at the user level, either online or offline. Kullanıcı etkinliğinin bir kısmını veya tamamını (belki de yoğun olmayan dönemlerde) askıya alma, verileri yeni sanal bölüme veya fiziksel parçaya taşıma, eşlemeleri değiştirme, bu verileri tutan tüm önbellekleri geçersiz kılma ya da yenileme ve sonra kullanıcı etkinliğinin devam etmesine izin verme tekniği kullanılır.The technique is to suspend some or all user activity (perhaps during off-peak periods), move the data to the new virtual partition or physical shard, change the mappings, invalidate or refresh any caches that hold this data, and then allow user activity to resume. Bu işlem türü genellikle merkezi olarak yönetilebilir.Often this type of operation can be centrally managed. Arama stratejisi, durumun yüksek oranda önbelleğe alınabilir ve çoğaltmaya uygun olmasını gerektirir.The Lookup strategy requires state to be highly cacheable and replica friendly.

Aralık stratejisi, ölçeklendirme ve veri taşıma işlemlerine bazı sınırlamalar getirir. Verilerin parçalar arasında bölünmesi ve birleştirilmesi gerektiğinden, bu işlemlerin genellikle veri deposu kısmen ya da tamamen çevrimdışı olduğunda gerçekleştirilmesi gerekir.The Range strategy imposes some limitations on scaling and data movement operations, which must typically be carried out when a part or all of the data store is offline because the data must be split and merged across the shards. Etkinliğin büyük bölümü bitişik parça anahtarlarına veya aynı aralıktaki veri tanımlayıcılara yönelikse, parçaları yeniden dengelemek üzere verilerin taşınması eşit olmayan yük sorununu çözemeyebilir.Moving the data to rebalance shards might not resolve the problem of uneven load if the majority of activity is for adjacent shard keys or data identifiers that are within the same range. Aralık stratejisi ayrıca aralıkları fiziksel bölümlere eşlemek için bazı durumların sürdürülmesini gerektirebilir.The Range strategy might also require some state to be maintained in order to map ranges to the physical partitions.

Bölüm anahtarları parça anahtarlarının veya veri tanımlayıcıların karmaları olduğundan karma stratejisi, ölçeklendirme ve veri taşıma işlemlerini daha karmaşık hale getirir.The Hash strategy makes scaling and data movement operations more complex because the partition keys are hashes of the shard keys or data identifiers. Her parçanın yeni konumu karma işlevinden belirlenmeli veya işlev doğru eşlemeleri sağlayacak şekilde değiştirilmelidir.The new location of each shard must be determined from the hash function, or the function modified to provide the correct mappings. Ancak, Karma stratejisi durumun sürdürülmesini gerektirmez.However, the Hash strategy doesn't require maintenance of state.

Sorunlar ve dikkat edilmesi gerekenlerIssues and considerations

Bu düzenin nasıl uygulanacağına karar verirken aşağıdaki noktaları göz önünde bulundurun:Consider the following points when deciding how to implement this pattern:

  • Parçalama, dikey bölümleme ve işlevsel bölümleme gibi diğer bölümleme biçimlerini tamamlayıcı niteliktedir.Sharding is complementary to other forms of partitioning, such as vertical partitioning and functional partitioning. Örneğin, tek bir parça dikey olarak bölümlenmiş varlıklar içerebilir ve bir işlevsel bölüm, birden çok parça halinde uygulanabilir.For example, a single shard can contain entities that have been partitioned vertically, and a functional partition can be implemented as multiple shards. Bölümleme hakkında daha fazla bilgi için bkz. Veri Bölümleme Kılavuzu.For more information about partitioning, see the Data Partitioning Guidance.

  • Parçaları tümü benzer bir G/Ç hacmini işleyecek şekilde dengede tutun.Keep shards balanced so they all handle a similar volume of I/O. Veriler eklenip silindikçe parçaların eşit bir dağılımı garanti edecek ve etkin nokta olasılığını azaltacak şekilde düzenli aralıklarla yeniden dengelenmesi gerekir.As data is inserted and deleted, it's necessary to periodically rebalance the shards to guarantee an even distribution and to reduce the chance of hotspots. Yeniden dengeleme, pahalı bir işlem olabilir.Rebalancing can be an expensive operation. Yeniden dengeleme gereksinimini azaltmak için, her parçanın beklenen değişiklik hacmini işleyecek yeterlilikte boş alan içerdiğinden emin olarak büyümeyi planlayın.To reduce the necessity of rebalancing, plan for growth by ensuring that each shard contains sufficient free space to handle the expected volume of changes. Ayrıca, gerekli hale gelirse parçaları hızlıca yeniden dengelemek için kullanabileceğiniz stratejiler ve betikler geliştirmeniz gerekir.You should also develop strategies and scripts you can use to quickly rebalance shards if this becomes necessary.

  • Parça anahtarı için kararlı veriler kullanın.Use stable data for the shard key. Parça anahtarı değişirse, karşılık gelen veri öğesinin parçalar arasında taşınması gerekebilir ve güncelleştirme işlemleri tarafından gerçekleştirilen iş miktarını artırabilir.If the shard key changes, the corresponding data item might have to move between shards, increasing the amount of work performed by update operations. Bu nedenle, parça anahtarını geçici olabilecek bilgilere dayandırmamaya özen gösterin.For this reason, avoid basing the shard key on potentially volatile information. Bunun yerine, sabit olan veya doğal olarak bir anahtar oluşturan öznitelikleri arayın.Instead, look for attributes that are invariant or that naturally form a key.

  • Parça anahtarlarının benzersiz olduğundan emin olun.Ensure that shard keys are unique. Örneğin, parça anahtarı olarak otomatik artan alanlar kullanmaktan kaçının.For example, avoid using autoincrementing fields as the shard key. Bazı sistemlerde otomatik artırılan alanlar parçalar arasında koordine edilemez ve farklı parçalardaki öğelerin aynı parça anahtarına sahip olmasına neden olabilir.Is some systems, autoincremented fields can't be coordinated across shards, possibly resulting in items in different shards having the same shard key.

    Parça anahtarı olmayan diğer alanlardaki otomatik artırılan değerler de sorunlara yol açabilir.Autoincremented values in other fields that are not shard keys can also cause problems. Örneğin, benzersiz kimlikler oluşturmak için otomatik artırılan alanlar kullanırsanız, farklı parçalarda bulunan iki farklı öğeye aynı kimlik atanabilir.For example, if you use autoincremented fields to generate unique IDs, then two different items located in different shards might be assigned the same ID.

  • Verilere yönelik her olası sorgunun gereksinimleriyle eşleşen bir parça anahtarı tasarlamak mümkün olmayabilir.It might not be possible to design a shard key that matches the requirements of every possible query against the data. En sık gerçekleştirilen sorguları desteklemek üzere verileri parçalayın ve gerekirse, parça anahtarına ait olmayan öznitelikleri temel alan ölçütleri kullanarak veri alan sorguları desteklemek amacıyla ikincil dizin tabloları oluşturun.Shard the data to support the most frequently performed queries, and if necessary create secondary index tables to support queries that retrieve data using criteria based on attributes that aren't part of the shard key. Daha fazla bilgi için bkz. Dizin Tablosu düzeni.For more information, see the Index Table pattern.

  • Yalnızca tek bir parçaya erişimi olan sorgular, birden fazla parçadan veri alan sorgulardan daha verimlidir; bu nedenle, uygulamaların farklı parçalarda tutulan verileri birleştiren çok sayıda sorgu gerçekleştirmesi ile sonuçlanan bir parçalama sistemi uygulamaktan kaçının.Queries that access only a single shard are more efficient than those that retrieve data from multiple shards, so avoid implementing a sharding system that results in applications performing large numbers of queries that join data held in different shards. Tek bir parçanın birden fazla varlık türü için veri içerebildiğini unutmayın.Remember that a single shard can contain the data for multiple types of entities. Bir uygulamanın gerçekleştirdiği ayrı okuma işlemlerinin sayısını azaltmak üzere aynı parçada yaygın olarak sorgulanan ilgili varlıkları (örneğin, müşterilerin ayrıntıları ve verdikleri siparişler) bir arada tutmak için verilerinizi normal durumdan çıkarmayı düşünün.Consider denormalizing your data to keep related entities that are commonly queried together (such as the details of customers and the orders that they have placed) in the same shard to reduce the number of separate reads that an application performs.

    Bir parça içindeki varlık başka bir parça içinde depolanmış varlığa başvuruyorsa, ikinci varlığın parça anahtarını birinci varlığın şemasına dahil edin.If an entity in one shard references an entity stored in another shard, include the shard key for the second entity as part of the schema for the first entity. Bunun yapılması, parçalar arasında ilgili verilere başvuran sorguların performansını artırmaya yardımcı olabilir.This can help to improve the performance of queries that reference related data across shards.

  • Bir uygulamanın birden çok parçadan veri alan sorgular gerçekleştirmesi gerekiyorsa, bu verileri paralel görevler kullanarak getirmek mümkün olabilir.If an application must perform queries that retrieve data from multiple shards, it might be possible to fetch this data by using parallel tasks. Birden fazla parçadan verilerin paralel olarak alındıktan sonra tek bir sonuçta toplandığı yaygın sorgular bunun örneklerindendir.Examples include fan-out queries, where data from multiple shards is retrieved in parallel and then aggregated into a single result. Ancak, bu yaklaşım bir çözümün veri erişim mantığına kaçınılmaz olarak biraz karmaşıklık ekler.However, this approach inevitably adds some complexity to the data access logic of a solution.

  • Küçük parçalar yük dengeleme için daha fazla fırsat sunduğundan, birçok uygulama için çok sayıda küçük parça oluşturmak az sayıda büyük parçaya sahip olmaktan daha verimlidir.For many applications, creating a larger number of small shards can be more efficient than having a small number of large shards because they can offer increased opportunities for load balancing. Bunun yapılması, parçaları bir fiziksel konumdan diğerine geçirmeyi öngörüyorsanız da yararlı olabilir.This can also be useful if you anticipate the need to migrate shards from one physical location to another. Küçük bir parça, büyük bir parçadan daha hızlı taşınabilir.Moving a small shard is quicker than moving a large one.

  • Her parça depolama düğümünün kullanabildiği kaynakların veri boyutu ve aktarım hızı açılarından ölçeklenebilirlik gereksinimlerini karşılamak için yeterli olduğundan emin olun.Make sure the resources available to each shard storage node are sufficient to handle the scalability requirements in terms of data size and throughput. Daha fazla bilgi için Veri Bölümlendirme Kılavuzu’nun “Bölümleri Ölçeklenebilirlik için Tasarlama” bölümüne bakın.For more information, see the section “Designing Partitions for Scalability” in the Data Partitioning Guidance.

  • Başvuru verilerini tüm parçalara çoğaltmayı düşünün.Consider replicating reference data to all shards. Bir parçadan veri alan bir işlem aynı sorgu kapsamında statik veya yavaş hareket eden verilere de başvuruyorsa, bu verileri parçaya ekleyin.If an operation that retrieves data from a shard also references static or slow-moving data as part of the same query, add this data to the shard. Bundan sonra uygulama, ayrı bir veri deposuna ilave bir gidiş dönüş yapmak zorunda kalmadan sorgunun tüm verilerini kolayca getirebilir.The application can then fetch all of the data for the query easily, without having to make an additional round trip to a separate data store.

    Birden fazla parçada tutulan başvuru verileri değişirse, sistem bu değişiklikleri tüm parçalarda eşitlemelidir.If reference data held in multiple shards changes, the system must synchronize these changes across all shards. Bu eşitleme gerçekleşirken sistem bir miktar tutarsızlık yaşayabilir.The system can experience a degree of inconsistency while this synchronization occurs. Bunu yaparsanız uygulamalarınızı bu tutarsızlığı giderecek şekilde tasarlamanız gerekir.If you do this, you should design your applications to be able to handle it.

  • Parçalar arasında bilgi tutarlılığının sürdürülmesi zor olabilir; bu nedenle, birden fazla parçadaki verileri etkileyen işlemleri en aza indirmeniz gerekir.It can be difficult to maintain referential integrity and consistency between shards, so you should minimize operations that affect data in multiple shards. Bir uygulamanın parçalar arasındaki verileri değiştirmesi gerekirse, tam veri tutarlılığının gerçekten gerekli olup olmadığını değerlendirin.If an application must modify data across shards, evaluate whether complete data consistency is actually required. Bunun yerine, bulutta yaygın bir yaklaşım son tutarlılığı gerçekleştirmektir.Instead, a common approach in the cloud is to implement eventual consistency. Her bölümdeki veriler ayrı ayrı güncelleştirilir ve uygulama mantığı tüm güncelleştirmelerin başarıyla tamamlandığından emin olmanın yanı sıra sonunda tutarlı bir işlem çalışırken verileri sorgulamaktan kaynaklanabilecek tutarsızlıkları gidermenin sorumluluğunu üstlenmelidir.The data in each partition is updated separately, and the application logic must take responsibility for ensuring that the updates all complete successfully, as well as handling the inconsistencies that can arise from querying data while an eventually consistent operation is running. Son tutarlılık uygulama hakkında daha fazla bilgi için bkz. Veri tutarlılığı Temel Bilgileri.For more information about implementing eventual consistency, see the Data Consistency Primer.

  • Çok sayıda parçayı yapılandırmak ve yönetmek zor olabilir.Configuring and managing a large number of shards can be a challenge. İzleme, yedekleme, tutarlılık denetimi ve günlüğe kaydetme veya denetim gibi görevler, muhtemelen birden fazla konumda tutulan birden çok parça ve sunucuda gerçekleştirilmelidir.Tasks such as monitoring, backing up, checking for consistency, and logging or auditing must be accomplished on multiple shards and servers, possibly held in multiple locations. Bu görevler betikler veya diğer otomasyon çözümleri kullanılarak uygulanabilir, ancak ek yönetim gereksinimlerini tamamen ortadan kaldıramayabilir.These tasks are likely to be implemented using scripts or other automation solutions, but that might not completely eliminate the additional administrative requirements.

  • Parçalar, içerdikleri verilerin veriyi kullanan bir uygulamaya ait örneklere yakın olması için coğrafi olarak konumlandırılabilir.Shards can be geolocated so that the data that they contain is close to the instances of an application that use it. Bu yaklaşım, performansı önemli ölçüde artırabilir ancak farklı konumlardaki birden fazla parçaya erişmesi gereken görevler için daha fazla değerlendirme gerektirir.This approach can considerably improve performance, but requires additional consideration for tasks that must access multiple shards in different locations.

Bu düzenin kullanılacağı durumlarWhen to use this pattern

Bir veri deposunu tek bir depolama düğümünde mevcut olan kaynakların dışında ölçeklendirme gereksinimi yüksek bir olasılık ise veya bir veri deposunda çekişmeyi azaltarak performansı iyileştirmek amacıyla bu düzeni kullanın.Use this pattern when a data store is likely to need to scale beyond the resources available to a single storage node, or to improve performance by reducing contention in a data store.

Not

Parçalamanın birincil odak noktası, sistemin performansını ve ölçeklenebilirliğini artırmaktır; ancak bir yan ürün olarak, verilerin ayrı bölümlere bölünme şeklinden dolayı kullanılabilirliği de artırabilir.The primary focus of sharding is to improve the performance and scalability of a system, but as a by-product it can also improve availability due to how the data is divided into separate partitions. Bir bölümdeki hata mutlaka uygulamanın diğer bölümlerde tutulan verilere erişmesini önlemez ve bir operatör, uygulamanın tüm verilerini erişilemez hale getirmeden bir ya da daha fazla bölümün bakım ya da kurtarma işlemini gerçekleştirebilir.A failure in one partition doesn't necessarily prevent an application from accessing data held in other partitions, and an operator can perform maintenance or recovery of one or more partitions without making the entire data for an application inaccessible. Daha fazla bilgi için bkz. Veri Bölümleme Kılavuzu.For more information, see the Data Partitioning Guidance.

ÖrnekExample

Aşağıdaki C# örneği, parça olarak görev yapan bir SQL Server veritabanları kümesi kullanır.The following example in C# uses a set of SQL Server databases acting as shards. Her veritabanı, bir uygulama tarafından kullanılan verilerin alt kümesini içerir.Each database holds a subset of the data used by an application. Uygulama, kendi parçalama mantığını kullanarak parçalar arasında dağıtılmış verileri alır (bu bir yaygın sorgu örneğidir).The application retrieves data that's distributed across the shards using its own sharding logic (this is an example of a fan-out query). Her bir parçada bulunan verilerin ayrıntıları GetShards adlı bir yöntemle döndürülür.The details of the data that's located in each shard is returned by a method called GetShards. Bu yöntem, ShardInformation nesnelerinin numaralı bir listesini döndürür; burada ShardInformation türü, her parça için ve bir uygulamanın parçaya bağlanmak üzere kullanması gereken SQL Server bağlantı dizesi için bir tanımlayıcı içerir (bağlantı dizeleri kod örneğinde gösterilmemiştir).This method returns an enumerable list of ShardInformation objects, where the ShardInformation type contains an identifier for each shard and the SQL Server connection string that an application should use to connect to the shard (the connection strings aren't shown in the code example).

private IEnumerable<ShardInformation> GetShards()
{
  // This retrieves the connection information from a shard store
  // (commonly a root database).
  return new[]
  {
    new ShardInformation
    {
      Id = 1,
      ConnectionString = ...
    },
    new ShardInformation
    {
      Id = 2,
      ConnectionString = ...
    }
  };
}

Aşağıdaki kod, uygulamanın her parçadan paralel olarak verileri getiren bir sorgu gerçekleştirmek üzere ShardInformation nesneleri listesini nasıl kullandığını gösterir.The code below shows how the application uses the list of ShardInformation objects to perform a query that fetches data from each shard in parallel. Sorgunun ayrıntıları gösterilmemiştir, ancak bu örnekte alınan veriler, parçalar müşteri ayrıntılarını içeriyorsa müşterinin adı gibi bilgileri tutabilen bir dize içerir.The details of the query aren't shown, but in this example the data that's retrieved contains a string that could hold information such as the name of a customer if the shards contain the details of customers. Sonuçlar uygulama tarafından işlenmek üzere bir ConcurrentBag koleksiyonunda toplanır.The results are aggregated into a ConcurrentBag collection for processing by the application.

// Retrieve the shards as a ShardInformation[] instance.
var shards = GetShards();

var results = new ConcurrentBag<string>();

// Execute the query against each shard in the shard list.
// This list would typically be retrieved from configuration
// or from a root/master shard store.
Parallel.ForEach(shards, shard =>
{
  // NOTE: Transient fault handling isn't included,
  // but should be incorporated when used in a real world application.
  using (var con = new SqlConnection(shard.ConnectionString))
  {
    con.Open();
    var cmd = new SqlCommand("SELECT ... FROM ...", con);

    Trace.TraceInformation("Executing command against shard: {0}", shard.Id);

    var reader = cmd.ExecuteReader();
    // Read the results in to a thread-safe data structure.
    while (reader.Read())
    {
      results.Add(reader.GetString(0));
    }
  }
});

Trace.TraceInformation("Fanout query complete - Record Count: {0}",
                        results.Count);

Bu düzen uygulanırken aşağıdaki düzenler ve yönergeler de yararlı olabilir:The following patterns and guidance might also be relevant when implementing this pattern:

  • Veri Tutarlılığı Temel Bilgileri.Data Consistency Primer. Farklı parçalara dağıtılan veriler için tutarlılığın sürdürülmesi gerekli olabilir.It might be necessary to maintain consistency for data distributed across different shards. Dağıtılmış veriler üzerinde tutarlılık sağlama konusundaki sorunları özetlemesinin yanı sıra farklı tutarlılık modellerinin avantajlarını ve dezavantajlarını açıklar.Summarizes the issues surrounding maintaining consistency over distributed data, and describes the benefits and tradeoffs of different consistency models.
  • Veri Bölümleme Kılavuzu.Data Partitioning Guidance. Bir veri deposunun parçalanması bir dizi ek sorunu ortaya çıkarabilir.Sharding a data store can introduce a range of additional issues. Ölçeklenebilirliği artırmak, çekişmeyi azaltmak ve performansı iyileştirmek üzere bu sorunları buluttaki veri depolarını bölümlemeyle ilgili olarak açıklar.Describes these issues in relation to partitioning data stores in the cloud to improve scalability, reduce contention, and optimize performance.
  • Dizin Tablosu deseni.Index Table pattern. Bazı durumlarda sorguların yalnızca parça anahtarı tasarımıyla tamamen desteklenmesi mümkün değildir.Sometimes it isn't possible to completely support queries just through the design of the shard key. Bir uygulamanın, parça anahtarı dışında bir anahtar belirterek büyük bir veri deposundan verileri hızlıca almasını sağlar.Enables an application to quickly retrieve data from a large data store by specifying a key other than the shard key.
  • Gerçekleştirilmiş Görünüm düzeni.Materialized View pattern. Bazı sorgu işlemlerinin performansını korumak için, özellikle bu özet veriler parçalar arasında dağıtılan bilgileri temel alıyorsa, verileri toplayıp özetleyen gerçekleştirilmiş görünümler oluşturmak yararlıdır.To maintain the performance of some query operations, it's useful to create materialized views that aggregate and summarize data, especially if this summary data is based on information that's distributed across shards. Bu görünümlerin nasıl oluşturulup doldurulacağını açıklar.Describes how to generate and populate these views.