Κάθε database system έχει τις ιδιαιτερότητες του και καλό είναι να γνωρίζουμε όσα περισσότερα για αυτές καθώς έτσι θα είμαστε σε θέση να σχεδιάζουμε καλύτερες λύσεις.
Έτσι και στην Cosmos DB υπάρχουν κάποιες που πρέπει να γνωρίζουμε για αυτό ας δούμε κάποιες που είναι κυρίαρχες.
Request Units
Η Cosmos DB έχει τα Request Units ανά δευτερόλεπτο (RU/s) τα οποία εφαρμόζονται σε επίπεδο collection και με τα οποία ορίζονται οι πόροι ( CPU, Memory, I/O of network activity) και με βάση αυτά γίνεται και η ωριαία χρέωση χρήσης.
Ένα RU σύμφωνα με την Microsoft είναι ισοδύναμο με το διάβασμα ενός document μεγέθους 1 ΚΒ με 10 properties.
Αν έχουμε εκτιμήσει χαμηλότερα από ότι χρειάζεται και έχουμε request που ξεπερνάνε την εκτίμηση τότε μπαίνουμε σε performance throttling που σημαίνει ότι ζητάτε από τα request να προσπαθήσουν αργότερα μέχρι να υπάρχουν οι πόροι που χρειάζονται για να εξυπηρετηθούν. Φυσικά αν ο αριθμός των requests είναι τόσο μεγάλος ή έχουμε μεγάλο αριθμό προσπαθειών τότε αυτά γίνονται abort.
Η σωστή εκτίμηση των RU/s όσο περισσότερο γίνει με ακρίβεια πέρα από το κόστος θα μας δώσει και το performance που επιθυμούμε, για αυτό το λόγο υπάρχει ο αντίστοιχος calculator.
Να επισημανθεί ότι μπορώ να αλλάζω κατά βούληση τα RU/s όποτε χρειάζεται να γίνεται πχ όταν κάνω import.
Είναι προφανές ότι στην επιλογή των RU/s θα πρέπει να λάβουμε υπόψη τα writes, complex queries, large documents όμως δεν είναι μόνο αυτά. Θα πρέπει να ληφθούν υπόψη:
- το consistency level που θα επιλέξουμε καθώς το Strong και Bounded Staleness απαιτούν περισσότερα reads για να την επίτευξη του επιθυμητού consistency level
- ο αριθμός των indexes που δημιουργούνται αυτόματα καθώς απαιτούν πολλά writes και μια πρακτική είναι να μειώνουμε τον αριθμό τους για το λόγο αυτό με βάση βέβαια και την απόδοση που θέλουμε.
- το τρόπο με το οποίο γράφουμε stored procedures και triggers καθώς δεν θέλουμε μέσα σε αυτές να έχουμε αχρείαστα reads/writes.
Partitioning
Στην Cosmos DB έχουμε τρία container types (collections, tables, graphs) που είναι logical resources που αποτελούνται από ένα ή περισσότερα physical partitions.
Κάθε physical partition αποτελείται από ένα αριθμό από SSD storage που γίνεται local replicated για high availability και δεν υπάρχει περιορισμός στο μέγεθος και στην κλιμάκωση του και συνδυάζεται με CPU και memory resources αν έχουμε επιλέξει unlimited scaling. Φυσικά υπάρχει και το Fixed scaling model στο οποίο εξ αρχής έχω ορίσει το μέγεθος.
Δεν χρειάζεται να κάνουμε κάτι για αυτό καθώς γίνεται αυτόματα και με τον ίδιο τρόπο ανεξαρτήτως το τύπο του container σε συνάρτηση πάντα με τον αριθμό των RU/s που έχουμε επιλέξει.
Για να καταλάβουμε πως λειτουργεί η όλη διαδικασία ας υποθέσουμε ότι έχουμε ένα collection container που έχει documents και έχω αποφασίσει να έχω σαν partition key το userid.
Αυτό σημαίνει ότι για κάθε userid έχω ένα logical partition το οποίο με βάση μια διαδικασία η οποία ονομάζεται consistent hashing σπάει σε ένα ή περισσότερα physical partitions.
Το πόσα physical partitions θα έχω είναι ο λόγος των επιλεγμένων RU/s διά το Maximum throughput per partition. Κάθε φορά που ένα partition φτάνει να γεμίσει τότε αυτόματα αυτό σπάει σε δύο νέα (50-50) κ.ο.κ
Partition Key
Στην Cosmos DB το partitioning είναι ο βασικός παράγοντας απόδοσης και κλιμάκωσης και ο μόνος τρόπος για επηρεάσουμε θετικά είναι η σοφή επιλογή του partition key.
Αρκετοί λένε και όχι άδικα ότι είναι «the top-most design decision in Cosmos DB».
Αν έχουμε κάνει λάθος επιλογή ο μόνος τρόπος για να το διορθώσουμε είναι να ξαναδημιουργηθεί ο container. Βέβαια πρέπει να επισημάνω ότι το σύνηθες είναι να μην μπορούμε να καλύψουμε όλες τις περιπτώσεις με το επιλεγμένο partition key για αυτό και επιλέγουμε αυτό που καλύπτει τις περισσότερες περιπτώσεις.
Το partition key μπορεί να είναι κάποιο από τα document properties αν είμαστε σίγουροι ότι σε όλα τα documents αυτό θα υπάρχει ή κάποιο generic που θα φτιάχνουμε για να καλύψουμε την ανάγκη αυτή.
Εδώ θα πρέπει να λάβουμε υπόψη ότι μπορεί να μην έχω περιορισμό στο μέγεθος των physical partitions αλλά έχω περιορισμό στο μέγεθος του κάθε logical partition και αυτός είναι τα 10GB.
Ακόμα θα πρέπει να υπολογίσουμε τα transactions στην επιλογή του partition key καθώς η Cosmos DB υποστηρίζει ACID transactions αλλά μόνο στα όρια ενός single partition.
Φυσικά ακόμα μια παράμετρος είναι το querying καθώς δεν θέλουμε να δημιουργούμε hot sports στο partitioning (odd distribution vs even distribution).
Η Microsoft προτείνει ότι το partition key πρέπει να πολλές διακριτές τιμές (100-1000 το ελάχιστο).
Επίσης έχει διαπιστωθεί ότι collections που είναι κάτω από 1GB η επιλογή partition key μπορεί να γίνει «αυθαίρετα», αν και θα συνιστούσα να μην γίνει.
When to denormalize data
Σε προηγούμενο άρθρο μου ανέφερα ότι στην Cosmo DB τα δεδομένα είναι κυρίως denormalized, όμως πάντα υπάρχει το σαιξπηρικό ερώτημα που πρέπει να απαντηθεί.
Επιλέγουμε να κάνουμε denormalization όταν:
- έχουμε λογικές οντότητες που περιέχονται σε άλλες πχ μαθήματα / μαθητής.
- οι λογικές οντότητες έχουν 1:Μ σχέσεις πχ τηλέφωνα / πρόσωπο
- τα denormalized records αλλάζουν σπάνια πχ μαθήματα
- ο αριθμός των denormalized records είσαι συγκεκριμένος και μικρός.
Αντίθετα επιλέγουμε το normalization όταν:
- Οι λογικές οντότητες αλλάζουν συχνά πχ αλλαγές τιμών στα προϊόντα.
- Όταν οι λογικές οντότητες έχουν N:M σχέσεις.
- Όταν δεν υπάρχει συγκεκριμένος αριθμός από records πχ σχόλια σε κοινωνικά δίκτυα.
Επίσης πρέπει να επισημανθεί ότι στην Cosmos DB όταν κάνω update ένα συγκεκριμένο σημείο ενός document θα πρέπει να κάνω update όλο το document καθώς δεν υποστηρίζει partial update και αυτό σαν διαδικασία είναι ακριβή σε πόρους ιδιαίτερα όταν έχω να κάνω συχνά αυτή.
//antonch