Gerçek dünyadan bir örnek kullanarak Azure Cosmos DB'de verileri modelleme ve bölümleme
UYGULANDıĞı YER:
SQL API
bu makalede, veri modelleme, bölümlemeve sağlanan aktarım hızı gibi çeşitli Azure Cosmos DB kavramlarıyla ilgili olarak gerçek bir veri tasarımı denemesinin nasıl üstesinden geldiğini göstermek için derleme yapılır.
Genellikle ilişkisel veritabanları ile çalışıyorsanız, büyük olasılıkla bir veri modelinin nasıl tasarlanacağını gösteren alışkanlıkları ve kavramları oluşturabilirsiniz. ayrıca, belirli kısıtlamalar nedeniyle Azure Cosmos DB benzersiz güçlerinin yanı sıra, bu en iyi uygulamalardan çoğu doğru şekilde çevrilmez ve sizi en uygun çözümlere sürükleyebilirsiniz. bu makalenin amacı, öğe modellemesinin varlık birlikte bulundurma ve kapsayıcı bölümlendirme olarak Azure Cosmos DB bir gerçek dünya kullanım örneğini modellemenin tam sürecinde size rehberlik sağlamaktır.
Bu makaledeki kavramları gösteren topluluk tarafından oluşturulan bir kaynak kodunu indirin veya görüntüleyin . bu kod örneği bir topluluk katılımcısı tarafından katkıda bulunulmuş ve Azure Cosmos DB ekibi, bakımını desteklemiyor.
Senaryo
Bu alıştırmada, kullanıcıların gönderi oluşturbilecekleri bir blog platformunun etki alanını göz önünde bulunduracağız. Kullanıcılar Ayrıca bu gönderilere yorum ekleyebilir ve bu postalara yorum ekleyebilir.
İpucu
Bazı kelimeleri italik olarak vurgulıyoruz; Bu sözcükler, modelimizin ' i işlemek zorunda olacağı "şeyleri" türünü belirler.
Belirtimize daha fazla gereksinim ekleniyor:
- Ön sayfa, son oluşturulan gönderilerin akışını görüntüler,
- Bir kullanıcının tüm gönderilerini, bir gönderiye ilişkin tüm açıklamaları ve bir gönderiye ilişkin tüm beğeni getirebilirsiniz.
- Gönderimler, yazarların Kullanıcı adı ve kaç yorum ve beğendikleri bir sayı ile döndürülür,
- Açıklamalar ve beğeni, bunları oluşturan kullanıcıların Kullanıcı adı ile de döndürülür,
- Liste olarak görüntülendiğinde, gönderilerin yalnızca içeriğinin kesilmiş bir özetini sunması gerekir.
Ana erişim desenlerini tanımla
Başlamak için çözümünüzün erişim desenlerini tanımlayarak ilk belirtimize bazı yapılara izin veririz. Azure Cosmos DB için bir veri modeli tasarlarken, modelin bu istekleri verimli bir şekilde sunacağına emin olmak için modelinizin hangi isteklerin sunacağına anlaşılması önemlidir.
Genel işlemi daha kolay hale getirmek için, bu farklı istekleri komut veya sorgu olarak sınıflandırıyoruz. Bu, CQRS 'den bazı sözlük (örneğin, sistemi güncelleştirme amaçları) ve sorguları salt okuma isteklerdir.
Platformumuzu göstermek için gereken isteklerin listesi aşağıda verilmiştir:
- [C1] Kullanıcı Oluştur/Düzenle
- [S1] Kullanıcı alma
- [C2] Gönderi Oluştur/Düzenle
- [S2] Gönderi alma
- [Q3] Kullanıcı Gönderilerini kısa biçimde listeleme
- [C3] Açıklama oluşturma
- [S4] Bir postanın açıklamalarını listeleme
- [C4] Gönderi gibi
- [Q5] Bir postanın beğeneni listeleyin
- [Q6] Kısa bir biçimde (akış) oluşturulan en son x gönderilerini listeleyin
Bu aşamada, her bir varlığın (Kullanıcı, gönderi vs.) içereceği ayrıntıları düşünmemiş. Bu adım genellikle, bu varlıkların tablolar, sütunlar, yabancı anahtarlar vb. açısından nasıl çevrileceğini anlamak zorunda olduğumuz için, ilişkisel bir mağazaya göre tasarlanırken ilk olarak, bir ilişkisel depoya göre tasarlanırken ilk olanların arasındadır. Yazma sırasında hiçbir şemayı zorlayameyen bir belge veritabanı ile ilgili bir kaygıdan çok daha azdır.
Başlangıçtan itibaren erişim modellerimizi belirlemek için önemli olmasının önemi, çünkü bu istek listesi test paketimize gidiyor. Veri modelimizi her tekrarlıyoruz, her bir isteği ele alacak ve performansını ve ölçeklenebilirliğini denetlemeye devam edeceğiz. Her modelde tüketilen istek birimlerini hesaplar ve bunları iyileştirir. Tüm bu modeller varsayılan dizin oluşturma ilkesini kullanır ve belirli özellikleri dizinleyerek geçersiz kılabilir, bu da RU tüketimini ve gecikmesini daha da iyileştirebilir.
V1: ilk sürüm
İki kapsayıcıyla başlıyoruz: users ve posts .
Kullanıcı kapsayıcısı
Bu kapsayıcı yalnızca Kullanıcı öğelerini depolar:
{
"id": "<user-id>",
"username": "<username>"
}
Bu kapsayıcıyı tarafından bölümliyoruz, yani bu kapsayıcı id içindeki her mantıksal bölüm yalnızca bir öğe içerecekse.
Gönderi kapsayıcısı
Bu kapsayıcı gönderi, yorum ve beğeni barındırır:
{
"id": "<post-id>",
"type": "post",
"postId": "<post-id>",
"userId": "<post-author-id>",
"title": "<post-title>",
"content": "<post-content>",
"creationDate": "<post-creation-date>"
}
{
"id": "<comment-id>",
"type": "comment",
"postId": "<post-id>",
"userId": "<comment-author-id>",
"content": "<comment-content>",
"creationDate": "<comment-creation-date>"
}
{
"id": "<like-id>",
"type": "like",
"postId": "<post-id>",
"userId": "<liker-id>",
"creationDate": "<like-creation-date>"
}
Bu kapsayıcıyı tarafından bölümliyoruz postId , yani bu kapsayıcı içindeki her mantıksal bölüm bir gönderi, bu gönderiyle ilgili tüm yorumlar ve bu gönderiyle ilgili tüm beğeni içerir.
Bu kapsayıcının type barındırdığı üç varlık türü arasında ayrım yapmak için bu kapsayıcıda depolanan öğelerde bir özellik sunduğumuz unutulmamalıdır.
Ayrıca, eklemek yerine ilgili verilere başvurmayı seçtik (bu kavramlarla ilgili ayrıntılar için Bu bölüme bakın):
- bir kullanıcının kaç tane posta oluştur, bir üst sınırı yoktur,
- gönderimler oldukça uzun olabilir,
- bir gönderinin kaç yorum ve beğeni olabilir,
- Post 'un kendisini güncelleştirmek zorunda kalmadan bir yorum veya bir gönderinin gibi bir yorum ekleyebilmesini istiyoruz.
Modelimiz ne kadar iyi çalışıyor?
İlk sürümümüzün performansını ve ölçeklenebilirliğini değerlendirmek artık zaman alabilir. Daha önce tanımlanan isteklerin her biri için, gecikme süresini ve tükettiği istek birimi sayısını ölçyoruz. Bu ölçüm, Kullanıcı başına 5 ile 50 arasında bir ileti ve posta başına en fazla 25 yorum ve 100 beğeni olan 100.000 kullanıcı içeren bir kukla veri kümesine karşı yapılır.
= Kullanıcı Oluştur/Düzenle
Yalnızca kapsayıcıda bir öğe oluştururken veya güncelleştirtiğimiz için bu istek basittir users . İstekler id bölüm anahtarına teşekkür ederiz.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 7 MS | 5,71 RU | ✅ |
Q1 Kullanıcı alma
Kullanıcının alınması, kapsayıcıdan karşılık gelen öğe okunarak yapılır users .
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 2 MS | 1 RU | ✅ |
Geç Gönderi Oluştur/Düzenle
[C1] benzer şekilde, kapsayıcıya yazmanız yeterlidir posts .
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 9 MS | 8,76 RU | ✅ |
Üç Gönderi alma
İlgili belgeyi kapsayıcıdan alarak başlayacağız posts . bu, belirtimizin uyarınca, bu kadar çok sayıda yorum ve bu gönderideki kaç tane beğeneni (3 ek SQL sorgusunun verilmek üzere) toplamamız gerekir.
Ek sorguların her biri, ilgili kapsayıcısının bölüm anahtarında filtreleyip performansı ve ölçeklenebilirliği en üst düzeye çıkarmak istiyoruz. Ancak sonunda, tek bir gönderi döndürmek için dört işlem gerçekleştirmemiz gerekir, bu nedenle bir sonraki yinelemede bunu iyileştireceğiz.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 9 MS | 19,54 RU | ⚠ |
S3 Kullanıcı Gönderilerini kısa biçimde listeleme
ilk olarak, belirli bir kullanıcıya karşılık gelen gönderileri getiren bir SQL sorgusuyla istenen gönderileri almamız gerekir. Ancak yazarın Kullanıcı adını ve yorumların sayısını ve beğeni toplamak için ek sorgular da vermek istiyoruz.
Bu uygulama birçok sakıncalar sunar:
- ilk sorgu tarafından döndürülen her bir gönderi için açıklama ve beğeni toplanan sorguların verilmesi gerekir,
- ana sorgu kapsayıcının bölüm anahtarına göre filtrelemez ve bu da kapsayıcı genelinde bir bölüm taraması ve bir bölüm
poststaramasına neden olur.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 130 ms | 619,41 RU | ⚠ |
[C3] Açıklama oluşturma
Kapsayıcıya karşılık gelen öğe yazarak bir açıklama posts oluşturulur.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 7 ms | 8,57 RU | ✅ |
[Q4] Bir gönderinin açıklamalarını listele
Bu gönderinin tüm açıklamalarını alan bir sorguyla başlayacağız ve bir kez daha her açıklama için kullanıcı adlarını ayrı ayrı toplamamız gerekiyor.
Ana sorgu kapsayıcının bölüm anahtarını filtrelese de, kullanıcı adlarının ayrı olarak bir şekilde toplaması genel performansı cezaya neden olur. Bunu daha sonra geliştireceğiz.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 23 ms | 27,72 RU | ⚠ |
[C4] Gönderi gibi
Aynı [C3] gibi kapsayıcıda karşılık gelen öğeyi de posts oluşturuz.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 6 ms | 7,05 RU | ✅ |
[Q5] Gönderinin like'larını listele
Aynı [Q4] gibi, o gönderi için de benzerleri sorgular ve ardından kullanıcı adlarını toplarız.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 59 ms | 58,92 RU | ⚠ |
[Q6] Kısa formda (akış) oluşturulan en son x gönderiyi listele
Kapsayıcıyı azalan oluşturma tarihine göre sıralanmış olarak sorgular, ardından gönderilerin her biri için kullanıcı adlarını ve açıklama ve like sayısını toparak en son posts gönderileri getiririz.
Bir kez daha ilk sorgumuz kapsayıcının bölüm anahtarına göre filtrelemez ve bu da yüksek maliyetli bir posts fanatiği tetikler. Çok daha büyük bir sonuç kümesi hedefle ve sonuçları bir yan tümcesi ile sırala, bu da istek birimleri açısından daha pahalı hale ORDER BY geldi.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 306 ms | 2063,54 RU | ⚠ |
V1'in performansını yansıtma
Önceki bölümde karşılaştığımız performans sorunlarına bakarak iki ana sorun sınıflarını tanımlayabiliriz:
- Bazı istekler, geri dönmemiz gereken tüm verileri toplamak için birden çok sorgu gerektirir,
- Bazı sorgular hedeflene kapsayıcıların bölüm anahtarına göre filtrelemez ve bu da ölçeklenebilirliğimizi önemli kıldı.
İlk sorundan başlayarak bu sorunların her birini çözeceğiz.
V2: Okuma sorgularını iyileştirmek için normalleştirmeden çıkarmak tanıtımı
Bazı durumlarda ek istekler uygulamanın nedeni, ilk isteğin sonuçlarının geri dönmemiz gereken tüm verileri içermesidir. Azure Cosmos DB gibi ilişkisel olmayan bir veri deposuyla çalışırken bu tür bir sorun genellikle veri kümemizde verilerin normalleştirmeden çıkararak çözülür.
Bizim örneğimizde gönderi öğelerini değiştirerek gönderi yazarının kullanıcı adını, açıklama sayısını ve like sayısını ekleyebilirsiniz:
{
"id": "<post-id>",
"type": "post",
"postId": "<post-id>",
"userId": "<post-author-id>",
"userUsername": "<post-author-username>",
"title": "<post-title>",
"content": "<post-content>",
"commentCount": <count-of-comments>,
"likeCount": <count-of-likes>,
"creationDate": "<post-creation-date>"
}
Ayrıca açıklamayı ve like öğelerini değiştirerek bunları oluşturan kullanıcının kullanıcı adını ekleyebilirsiniz:
{
"id": "<comment-id>",
"type": "comment",
"postId": "<post-id>",
"userId": "<comment-author-id>",
"userUsername": "<comment-author-username>",
"content": "<comment-content>",
"creationDate": "<comment-creation-date>"
}
{
"id": "<like-id>",
"type": "like",
"postId": "<post-id>",
"userId": "<liker-id>",
"userUsername": "<liker-username>",
"creationDate": "<like-creation-date>"
}
Açıklama ve like sayılarını normalleştirmeden alma
Elde etmek istediğiniz şey, bir açıklama veya benzer eklemede karşılık gelen gönderide veya değerini commentCount likeCount de artırmamızdır. Kapsayıcımız tarafından bölümlenmiş olduğundan, yeni öğe (açıklama veya gibi) ve buna karşılık gelen posts gönderi aynı mantıksal bölümde yer postId alar. Sonuç olarak, bu işlemi gerçekleştirmek için saklı yordam kullanabiliriz.
Şimdi kapsayıcıya yeni bir öğe eklemek yerine bir açıklama ([C3]) oluştururken posts bu kapsayıcıda aşağıdaki saklı yordamı çağırabilirsiniz:
function createComment(postId, comment) {
var collection = getContext().getCollection();
collection.readDocument(
`${collection.getAltLink()}/docs/${postId}`,
function (err, post) {
if (err) throw err;
post.commentCount++;
collection.replaceDocument(
post._self,
post,
function (err) {
if (err) throw err;
comment.postId = postId;
collection.createDocument(
collection.getSelfLink(),
comment
);
}
);
})
}
Bu saklı yordam, post kimliğini ve yeni açıklamanın gövdelerini parametre olarak alır, sonra:
- gönderiyi alır
- değerini artırır
commentCount - gönderiyi değiştirir
- yeni açıklamayı ekler
Saklı yordamlar atomik işlemler olarak yürütülürken, değeri ve gerçek açıklama commentCount sayısı her zaman eşit kalır.
değerini artıran yeni like'lar eklerken de benzer bir saklı yordam likeCount çağrılır.
Kullanıcı adlarını normalleştirmeden
Kullanıcılar yalnızca farklı bölümlere değil farklı bir kapsayıcıda yer alan kullanıcılara farklı bir yaklaşım gerektirir. Bölümler ve kapsayıcılar arasında verileri normalleştirmeden çıkarmak zorundayken kaynak kapsayıcının değişiklik beslemesini kullanabiliriz.
Bizim örneğimizde, kullanıcılar kullanıcı adlarını güncelleştiren her zaman tepki users vermek için kapsayıcının değişiklik akışı kullanılır. Bu durumda, kapsayıcıda başka bir saklı yordam çağırarak değişikliği posts yalıtabilirsiniz:
function updateUsernames(userId, username) {
var collection = getContext().getCollection();
collection.queryDocuments(
collection.getSelfLink(),
`SELECT * FROM p WHERE p.userId = '${userId}'`,
function (err, results) {
if (err) throw err;
for (var i in results) {
var doc = results[i];
doc.userUsername = username;
collection.upsertDocument(
collection.getSelfLink(),
doc);
}
});
}
Bu saklı yordam, kullanıcının kimliğini ve kullanıcının yeni kullanıcı adını parametre olarak alır, sonra:
- ile eşleşen tüm öğeleri
userIdgetirir (gönderiler, yorumlar veya like'lar olabilir) - bu öğelerin her biri için
- ,
userUsername - öğesini değiştirir
- ,
Önemli
Kapsayıcının her bir bölümü üzerinde bu saklı yordamın yürütültülür gerektirdiği için bu işlem posts maliyetlidir. Çoğu kullanıcının kayıt sırasında uygun bir kullanıcı adı seçeceklerini ve hiçbir zaman değiştirmeyeceklerini, dolayısıyla bu güncelleştirmenin çok nadir çalıştırılamayacaklarını varsayalım.
V2'nin performans kazancı nedir?
[Q2] Gönderi alma
Normalleştirmeden çıkarmak için tek bir öğe getirmemiz gerekiyor.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 2 ms | 1 RU | ✅ |
[Q4] Bir gönderinin açıklamalarını listele
Burada da kullanıcı adlarını alan ek istekleri ayırarak bölüm anahtarına filtre uygulamanın tek bir sorgusunu kullanabiliriz.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 4 ms | 7,72 RU | ✅ |
[Q5] Bir postanın beğeneni listeleyin
Beğeni listelenirken aynı durum kesin.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 4 MS | 8,92 RU | ✅ |
V3: tüm isteklerin ölçeklenebilir olduğundan emin olma
Genel performans geliştirmelerimize baktığınızda, tam olarak iyileştirildiğimiz iki istek vardır: [Q3] ve [Q6]. Bunlar, hedefleytikleri kapsayıcıların bölüm anahtarını filtrelememe sorguları içeren isteklerdir.
S3 Kullanıcı Gönderilerini kısa biçimde listeleme
Bu istek, ek sorguları kapsayan v2 sürümünde tanıtılan geliştirmelerden zaten faydalanır.
Ancak kalan sorgu hala kapsayıcının bölüm anahtarında filtrelenemiyor posts .
Bu durumu göz önünde bulundurmanız, aslında basittir:
userIdBelirli bir kullanıcı için tüm gönderileri getirmek istiyoruz, bu isteğin üzerine filtre uygulamak istiyorpostsŞu şekilde bölümlenmemiş çünkü kapsayıcıya göre bölümlenmemişuserId- Belirgin bir şekilde, bu isteği tarafından bölümlenen bir kapsayıcıya karşı yürüterek performans sorunumuzu çözeceğiz.
userId - Zaten bu tür bir kapsayıcınıza sahip olduğumuz
usersbir kapsayıcıdır.
Bu nedenle, tüm gönderileri kapsayıcıyla çoğaltarak ikinci bir kat düzeyi sunuyoruz users . Bunu yaparak, gönderilerimizin bir kopyasını, yalnızca farklı boyutlarda bölümleyerek, bu sayede daha verimli bir şekilde elde eteceğiz userId .
usersKapsayıcıda artık 2 tür öğe var:
{
"id": "<user-id>",
"type": "user",
"userId": "<user-id>",
"username": "<username>"
}
{
"id": "<post-id>",
"type": "post",
"postId": "<post-id>",
"userId": "<post-author-id>",
"userUsername": "<post-author-username>",
"title": "<post-title>",
"content": "<post-content>",
"commentCount": <count-of-comments>,
"likeCount": <count-of-likes>,
"creationDate": "<post-creation-date>"
}
Şunlara dikkat edin:
typekullanıcıları gönderimler arasında ayrım yapmak için Kullanıcı öğesinde bir alan ekledik,- Ayrıca,
userIdalan ile yedekli olanidancakuserskapsayıcı artıkuserId(iddaha önce değil) tarafından bölümlenerek gerekli olan Kullanıcı öğesine bir alan ekledik.
Bu eğilimi başarmak için, değişiklik akışını yeniden kullanırız. Bu kez, kapsayıcıya posts Yeni veya güncelleştirilmiş bir gönderi göndermek için kapsayıcının değişiklik akışına tepki veririz users . Ve liste gönderilerinin tam içeriğini döndürmesi gerekli olmadığı için, bu işlemleri işlemden kesebiliriz.
Şimdi sorgumuzu users kapsayıcıya yönlendirebilir ve kapsayıcının bölüm anahtarında filtre uygulayabilirsiniz.
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 4 MS | 6,46 RU | ✅ |
[Q6] Kısa bir biçimde (akış) oluşturulan en son x gönderilerini listeleyin
Burada benzer bir durumla uğraşmanız gerekir: Sparing ' de sunulan ek sorgular gereksiz hale gelse bile, kalan sorgu kapsayıcının bölüm anahtarında filtrelemez:
Aynı yaklaşımdan sonra, bu isteğin performansını ve ölçeklenebilirliğini en üst düzeye çıkarmak, yalnızca bir bölüme ait olması gerekir. Yalnızca sınırlı sayıda öğe döndürtiğimiz için bu Conceivable. Blog platformumuzu giriş sayfamızı doldurmak için, tüm veri kümesi üzerinde ilerlemeden yalnızca en son 100 gönderi almanız gerekir.
Bu son isteği iyileştirmek için tasarımımız için üçüncü bir kapsayıcı sunuyoruz ve bu isteğin sunulması için tamamen ayrıldık. Gönderilerimizi bu yeni kapsayıcıya uzlaştırdık feed :
{
"id": "<post-id>",
"type": "post",
"postId": "<post-id>",
"userId": "<post-author-id>",
"userUsername": "<post-author-username>",
"title": "<post-title>",
"content": "<post-content>",
"commentCount": <count-of-comments>,
"likeCount": <count-of-likes>,
"creationDate": "<post-creation-date>"
}
Bu kapsayıcı type , her zaman post öğelerimizde olacak şekilde bölümlenmiş. Bunun yapılması, bu kapsayıcıdaki tüm öğelerin aynı bölümde yer almasını sağlar.
Daha fazla işlem yapmak için, daha önce bu yeni kapsayıcıya gönderdiğimiz değişiklik akışı ardışık düzenine ulaşmanız gerekir. Göz önünde bulundurmanız gereken önemli bir şey; yalnızca en son 100 gönderi depolıyoruz. Aksi takdirde, kapsayıcının içeriği bir bölümün en büyük boyutunun ötesine çıkabilir. Bu işlem, kapsayıcıya bir belge eklendiğinde bir son tetikleyici çağırarak yapılır:
Koleksiyonu kesen tetiklemenin gövdesi aşağıda verilmiştir:
function truncateFeed() {
const maxDocs = 100;
var context = getContext();
var collection = context.getCollection();
collection.queryDocuments(
collection.getSelfLink(),
"SELECT VALUE COUNT(1) FROM f",
function (err, results) {
if (err) throw err;
processCountResults(results);
});
function processCountResults(results) {
// + 1 because the query didn't count the newly inserted doc
if ((results[0] + 1) > maxDocs) {
var docsToRemove = results[0] + 1 - maxDocs;
collection.queryDocuments(
collection.getSelfLink(),
`SELECT TOP ${docsToRemove} * FROM f ORDER BY f.creationDate`,
function (err, results) {
if (err) throw err;
processDocsToRemove(results, 0);
});
}
}
function processDocsToRemove(results, index) {
var doc = results[index];
if (doc) {
collection.deleteDocument(
doc._self,
function (err) {
if (err) throw err;
processDocsToRemove(results, index + 1);
});
}
}
}
Son adım sorgumuzu yeni kapsayıcımızda yeniden yönlendirimdir feed :
| Gecikme süresi | RU ücreti | Performans |
|---|---|---|
| 9 MS | 16,97 RU | ✅ |
Sonuç
Tasarımımızın farklı sürümlerine tanıtıldığımız genel performans ve ölçeklenebilirlik iyileştirmeleri göz atalım.
| V1 | V2 | Yüklemesinde | |
|---|---|---|---|
| = | 7 MS/5,71 RU | 7 MS/5,71 RU | 7 MS/5,71 RU |
| Q1 | 2 ms/1 RU | 2 ms/1 RU | 2 ms/1 RU |
| Geç | 9 MS/8,76 RU | 9 MS/8,76 RU | 9 MS/8,76 RU |
| Üç | 9 MS/19,54 RU | 2 ms/1 RU | 2 ms/1 RU |
| S3 | 130 MS/619,41 RU | 28 MS/201,54 RU | 4 MS/6,46 RU |
| C3 | 7 MS/8,57 RU | 7 MS/15,27 RU | 7 MS/15,27 RU |
| Ç | 23 MS/27,72 RU | 4 MS/7,72 RU | 4 MS/7,72 RU |
| C4 | 6 MS/7,05 RU | 7 MS/14,67 RU | 7 MS/14,67 RU |
| [Q5] | 59 MS/58,92 RU | 4 MS/8,92 RU | 4 MS/8,92 RU |
| [Q6] | 306 ms / 2063,54 RU | 83 ms / 532,33 RU | 9 ms / 16,97 RU |
Yoğun okuma olan bir senaryoyu en iyi duruma getirilmişiz
Yazma isteklerinin (komutlar) masrafı ile okuma isteklerinin (sorguların) performansını artırmaya yönelik çalışmalarımızı yoğun bir şekilde sürdürüyoruz. Çoğu durumda, yazma işlemleri artık değişiklik akışları aracılığıyla sonraki normalleştirmeden kaldırıcıyı tetikler ve bu da işlem olarak daha pahalı ve daha uzun bir işlem gücü sağlar.
Bu durum, bir platform platformunun (çoğu sosyal uygulama gibi) okumanın yoğun olduğu, yani hizmet vermek zorunda olduğu okuma isteği miktarının genellikle yazma isteği miktarından daha yüksek olan siparişler olduğu anlamına gelir. Bu nedenle okuma isteklerinin daha ucuz ve daha iyi performansa sahip olması için yazma isteklerinin yürütülmek daha pahalı olması mantıklıdır.
Yapmış olduğu en aşırı iyileştirmeye bakarak [Q6] 2000'den fazla RU'dan yalnızca 17 RU'ya çıktı; Bunu, gönderileri öğe başına yaklaşık 10 RU maliyetle normalleştirmeden çıkarmakla elde ettik. Gönderi oluşturma veya güncelleştirmeden çok daha fazla akış isteğine hizmet verecek olsak da, genel tasarruf göz önünde bulundurarak bu normalleştirmeden çıkarılma maliyeti göz ardı edilebilir.
Normalleştirmeden çıkarmak artımlı olarak uygulanabilir
Bu makalede inceledik ölçeklenebilirlik geliştirmeleri, verilerin normalleştirmeden kaldırılması ve veri kümesi genelinde çoğaltılması içerir. Bu iyileştirmelerin 1. günde yerine koymak zorunda olmadığını lütfen not alın. Bölüm anahtarlarını filtre eden sorgular büyük ölçekte daha iyi performans sergilese de, nadiren veya sınırlı bir veri kümesine karşı çağrılsa bölümler arası sorgular tamamen kabul edilebilir. Yalnızca bir prototipi inşa ediyorsanız veya küçük ve denetimli bir kullanıcı tabanına sahip bir ürün başlatıyorsanız, bu geliştirmeleri muhtemelen daha sonra için ayırabilirsiniz; Bundan sonra önemli olan, modelinizin performansını izlemektir. Bu nedenle bunları getirmenin zamanı ve zamanı geldiğinde karar vesersiniz.
Güncelleştirmeleri diğer kapsayıcılara dağıtmak için kullanabileceğimiz değişiklik akışı, tüm bu güncelleştirmeleri kalıcı olarak depolar. Bu, kapsayıcı ve normalleştirilmiş olmayan görünümlerin oluşturulmasından bu yana, sisteminiz zaten çok fazla veriye sahip olsa bile tek kullanımlık bir yakalama işlemi olarak tüm güncelleştirmeleri talep etmek mümkün hale getirir.
Sonraki adımlar
Bu pratik veri modelleme ve bölümleme tanıtımının ardından, ele alınan kavramları gözden geçirmek için aşağıdaki makaleleri gözden geçirmek iyi olabilir:
- Veritabanları, kapsayıcılar ve öğelerle çalışma
- Azure Cosmos DB'de bölümleme
- Azure Cosmos DB'de değişiklik akışı
Azure Cosmos DB'ye geçiş için kapasite planlaması yapmaya mı çalışıyorsunuz? Kapasite planlaması için mevcut veritabanı kümeniz hakkında bilgi kullanabilirsiniz.
- Mevcut veritabanı kümenizin sanal çekirdek ve sunucu sayısıyla ilgili tüm bilginiz varsa, sanal çekirdek veya vCPUS kullanarak istek birimlerini tahmin hakkında bilgi edinebilirsiniz
- Geçerli veritabanı iş yükünüz için tipik istek oranlarını biliyorsanız Azure Cosmos DB kapasite planlayıcısı kullanarak istek birimlerini tahmin hakkında bilgi edinin