Geçen hafta bir üretim sorununu gideriyordum. Sorun, birden çok kez paylaşılmış olmalarına rağmen bazı paylaşılan dosyaların uygulamamızda görünmediğini belirtti.
Triyaj için yeterince basit bir hata gibi görünüyor.
Dosyaları paylaşmaktan sorumlu olan lambda günlüklerine göz atmak için CloudWatch'a gittim. Ama hiçbir hata yoktu. Her şey sorunsuz başarılı görünüyordu.
Bu yüzden DynamoDB'de "eksik" olan bazı dosyalara tuhaf bir durumda olup olmadıklarını görmek için baktım. Bir kez daha her şey yerli yerinde görünüyordu. Günlüklerde neden herhangi bir hata olmadığı mantıklıydı, veriler doğru görünüyordu.
Kendim çoğaltmaya çalıştım. Sıfırdan başladım, ama her şey tekrar iyi görünüyordu. Her şey bana iyi göründü. Bu yüzden hatada bildirilen alana gittim ve kesinlikle dosyalar eksikti.
Neler oluyordu?
O lambda dosyasındaki aynı 100 satır koda bakmak için çok zaman harcadım. Sadece bakıyorum. Nerede yanlış gidebileceğini anlamaya çalışırken kafamın içinde dolaşıyorum.
Sonra bir dönüm noktasına ulaştım. Bildirilen sorunla alanı, yeniden üretmeye çalıştığım ve bana bir şey yapışmış olanla karşılaştırdım. Sadece 7 veya 8 dosya paylaşmıştım, ancak sorunda bildirilen 2.000'i paylaşmıştı. Bu bir veri boyutu sorunu olmalıydı .
Kodun içinde, verileri sorgularken her şeyi yüklediğimizi görüyorum . Tüm dosyalar, ilgili varlıklar, işler. Ama sayfa açmıyoruz. DynamoDB, tek bir sorguda maksimum 1 MB veri alabilir . Bu benim sorunumdu.
DynamoDB'nin 1 MB sınırından daha fazla sonucu olduğunda,
LastEvaluatedKeyyanıtta a döndürür, böylece kaldığı yerden başlayarak sonraki sorguları çalıştırabilirsiniz.
Kod bunu görmezden geliyordu. Bir kullanıcının üretimde bu kadar çok veriye sahip olacağı hiç aklıma gelmemişti. Bu yüzden ne inşa ettiğimizi ve nerede yanlış gittiğini düşünmek için bir adım geri attım.
Her şey zayıf REST API tasarımına ve kötü NoSQL veri modellemesine bağlıydı.
REST'in harika bir yönü, varlıklarınızı sezgisel olarak incelemeye izin vermesidir. Bir varlığın çocukları varsa, varlığı yüklemek için bir uç noktanız ve çocukları yüklemek için bir uç noktanız olmalıdır. Çocukların çocukları varsa, çocukların çocuklarını (vb.) yüklemek için bir uç noktanız olur. Diyelim ki aşağıda açıklanan varlık modeline sahibiz:
Bu görünüm, varlıkların 4 seviyeli bir hiyerarşisini gösterir, burada en üsttedir ve
neighborhoodiki alt varlık özelliği ve HOA (Ev Sahipleri Birliği) vardır . RESTful API tasarımı söz konusu olduğunda, uç noktalar şu şekilde yapılandırılacaktır:
/neighborhoods/{neighborhoodId} /neighborhoods/{neighborhoodId}/properties /neighborhoods/{neighborhoodId}/hoa
Bir sonraki katmanımızda,
propertyvarlığın iki alt varlığı vardır
treesve
buildings. Bunları şu şekilde yapılandırırız:
/neighborhoods/{neighborhoodId}/properties/{propertyId}/trees /neighborhoods/{neighborhoodId}/properties/{propertyId}/buildings
/neighborhoods/{neighborhoodId}/properties/{propertyId}/buildings/{buildingId}/rooms /neighborhoods/{neighborhoodId}/properties/{propertyId}/buildings/{buildingId}/rooms/{roomId}
/neighborhoods/{neighboorhoodId}
neighborhoodvarlık hakkında veri döndürür
/neighborhoods/{neighborhoodId}/properties/{propertyId}
propertybelirli bir varlık hakkında veri döndürür
/neighborhoods/{neighborhoodId}/properties/{propertyId}/buildings/{buildingId}/roomsbelirli bir alandaki tüm odaların bir listesini döndürür
building
, , , , ve
/neighborhoods/{neighborhoodId}üzerinde uç nokta dönüş ayrıntılarını yaptıysanız , verileri aşırı derecede fazla getiren ve DynamoDB'ye veritabanı çağrıları yapmak için çok fazla para isteyen büyük bir API çağrınız olur.
neighborhood
properties
HOA
trees
buildings
rooms
REST standartlarına bağlı kalırsanız, varlıkların bir listesini almanın ve kimliğe göre tek bir varlık almanın her zaman kolay bir yoluna sahip olmalısınız.
DynamoDB ile bileşik tuşlarla detaya inme yaklaşımını benimseyebilirsiniz . Bu, listelerinizi sorgulamak veya tek bir varlık elde etmek için karma ve aralık anahtarlarınızı birden çok varlık içerecek şekilde yapılandırabileceğiniz anlamına gelir.
Örneğin, bir özellik için karma ve aralık anahtarımı şu şekilde yapılandırabilirim:
pk: `${neighborhoodId}#${propertyId}`, sk: `metadata`
pk: `${neighborhoodId}#${propertyId}`, sk: `building#${buildingId}`
Kaçınmak istediğiniz şey, istediğiniz verileri bulmak için FilterExpression gerektiren bir yapı oluşturmaktır . Sorgudan sonra A
FilterExpressionuygulanır, yani tüm Okuma Kapasitesi Birimleri (RCU'lar) için ücretlendirilirsiniz .
Sunucusuz, kullandığınız şey için ödeme yapmakla ilgilidir ve asla kullanmayacağınız okumalar için gereksiz yere ödeme yapmak istemezsiniz. Kendinizi aşırı kullandığınız bir durumda bulursanız
FilterExpression, bir adım geri atın ve veri modelinize farklı bir şekilde yaklaşıp yaklaşamayacağınıza bakın.
Üzerinde çalıştığım böcek bununla karşılaştı.
FilterExpressionsPaylaşılan dosyalar etrafında, sorgu sonrası ve sorgu sonrası filtrelemenin bir kombinasyonunu yapmamıza neden olan yanlış tasarlanmış bir veri modelimiz vardı . Getirmek biraz ciddiydi!
LastEvaluatedKeyBu nedenle, DynamoDB'nin yüklenecek daha fazla veri olduğunu bize bildirmek için döndürdüğü (uzun süredir gözden kaçan) bir sorunla hızla karşılaştık .
Ancak bu büyüklükteki verileri tahmin etmediğimiz için kodumuz yanıtta bunu kontrol etmiyordu. Bu, tüm varlıkları işlemememize ve dosyaların eksik olduğu görünümünü vermemize neden oldu.
Veri modelini doğru tasarlamış olsaydık, bunların hepsi önlenebilirdi.
Uygun REST tasarımı ile uç noktalarınız bir isim dizisi olmalıdır. Bir öğe hiyerarşisine ulaşmanın kolay bir yolunu sunarlar. Ancak uygulamanızın aynı anda yüzlerce (veya binlerce) varlığı güncelleyeceği senaryolar ne olacak?
Her varlık güncellemesi için tek bir API çağrısı gerektirebilir. Sunucusuz API'ler, talebi karşılamak için kesinlikle ölçeklenebilir. Ama olmalı mı? Tek bir kullanıcı 1000 API çağrısıyla sonuçlanan bir işlem yapıyorsa, bunu aynı anda 10 kullanıcı yapıyorsa ne olur? 100 kullanıcı ne olacak?
Eşzamanlı lambda yürütmeleriyle hızlı bir şekilde bazı hizmet sınırlarıyla karşılaşacaksınız. Bu sınırları her zaman artırabilirsiniz, ancak yine de, yapmalı mısınız ?
Bazen kuralları çiğnemek iyidir. Köktenci olmayın.
Tek bir kullanıcının aynı anda yüzlerce veya binlerce varlığı güncellemeye çalıştığı bunun gibi senaryolarda, toplu işlem bitiş noktası zamanı gelebilir . Toplu eylem bitiş noktası RESTful olup olmadığı tartışılabilir, ancak bazı durumlarda kesinlikle gereklidir.
1000 varlığı güncellemeye çalışıyorsak, 1'lik 1000 arama yerine 100'lük 10 arama yapmak daha iyi olabilir.
Yüksek verimli uç noktaları için başka bir alternatif, toplu iş boyutlarını kontrol edebilmeniz ve kuyruktan okuyan lambda işlevinin eşzamanlı yürütmelerini sınırlayabilmeniz için doğrudan API Ağ Geçidi'nden SQS'ye entegre etmektir.
Projenize başladığınızda erişim modellerini veya yüksek trafikli uç noktalarını bilmediğinizi fark ederseniz, sorun değil! Bildiklerinizle ve birincil kullanım durumu olmasını beklediğiniz şeylerle çalışın.
İşiniz bitmeden fikir edinmenin yolları var. Alberto Savoia'nın “Doğru O” kitabı , riski azaltmak ve tasarımınızı önceden yapmak için uygulayabileceğiniz stratejilerden bahsediyor.
Yazılımınızı zaten oluşturmuşsanız ve benim gibi sorunlarla karşılaşmaya başladıysanız, sorunu çözmek için asla geç değildir . Yeni uç noktalar oluşturabilir, mevcut olanları değiştirebilir veya artık kullanılmaması gereken bazılarını kullanımdan kaldırabilirsiniz. Uygulamanız üretimdeyse, önemli değişiklikler oluşturmadığınızdan emin olun .
Bir veri modelini yeniden tasarlayabilirsiniz. Sunucusuz veri modelleri arasında geçiş beş adımda gerçekleşir:
En çok aranan uç noktalarınızı belirlemek için metrikleri kullanın. Diğerlerinden önemli ölçüde daha fazla eşzamanlı yürütme ile çalışan var mı? Önemli miktarda arama yapan aynı kullanıcı mı? Bir toplu işlem için aykırı değerleri ve adayları seçmenize olanak tanıyan lambda işlevleriniz için inanılmaz derecede değerli bilgiler elde edebilirsiniz .
Yazılım, özellikle sunucusuz yazılım, sürekli yeniden düzenleme durumunda olmalıdır . Uygulamanızın her gün nasıl kullanıldığına dair fikir edinirsiniz, özellikler eklersiniz, sorunları giderirsiniz. Bunların her biri, uygulamanızı geliştirmek için bir öğrenme fırsatıdır.
Asla şu anda olduğundan daha azını bilemeyeceksin.
Veri modellerinizi geliştirmek, performans ve maliyet için optimize etmek ve kullanıcılarınıza keyifli bir deneyim sunmak için içgörüleri alın .
Mutlu kodlama!
Bilinç nedir? Yüzyıllardır filozofların ve bilim adamlarının kafasını karıştıran bir sorudur. Bazıları bunun bedenlerimizden bağımsız olarak gerçekten anlayamadığımız geçici bir şey olduğunu söylüyor.
Yıllık ortalama 154 bin dolar maaş ve istikrarlı iş büyümesi ile şimdi blok zinciri geliştirmeyi öğrenmek için ideal zaman. Blok zinciri teknolojilerini oluşturmak ve geliştirmek için blok zinciri geliştiricileri, bilgisayar ağı, kriptografi, algoritmalar ve veri yapıları dahil olmak üzere çeşitli beceriler kullanır.
En yakın arkadaşlarım ve ben, gaz lambası, kapı bekçisi ve kız patronu gibi şüpheli üç rolü birbirine atamak zorunda kalsaydık, kapı bekçisi karakterinin sahipliğini büyük olasılıkla benim alacağım konusunda hemfikirdik. Görünüşte bir 'yeraltı' indie albümü, 2000'lerin yenilenme filmi ya da gelecek vadeden podcast dizisi olduğunu düşündüğüm şeyi, dehşet içinde, yaygın olarak bilindiğini belirlemeden önce 'keşfettiğim' biliniyor. Aylar sonra ve gerçekten de bir zamanlar olduğuma inandığım popüler kültür mücevherlerini senden daha kutsal keşfeden ben değilim.
Bioscout, çiftçileri sürücü koltuğuna oturtma görevinde ve Artesian(GrainInnovate) ve Uniseed ile birlikte en son tohum turlarında ekibe destek vermekten heyecan duyuyoruz. Sorun Mantar hastalığından kaynaklanan önemli mahsul kaybı, çiftçiler için bir çile olduğunu kanıtladı.
Telesağlık, pandemi sonrası dönemde yeni veya modası geçmiş bir sektör değil. Ancak sektöre daha yakından baktığımızda, talep ve arzda güçlü bir sürdürülebilirlik ve ABD'de sürekli bir devrim olacak güçlü bir potansiyel büyüme eğrisi gösteriyor.
Hesaplama iştahımız ile Moore Yasasının sunabilecekleri arasında katlanarak büyüyen bir boşluk var. Uygarlığımız hesaplamaya dayanmaktadır - mimarinin ve hayal gücünün mevcut sınırlarını aşan teknolojiler bulmalıyız.