portaldacalheta.pt
  • Κύριος
  • Επιστήμη Δεδομένων Και Βάσεις Δεδομένων
  • Κερδοφορία & Αποδοτικότητα
  • Σχεδιασμός Ux
  • Κινητό
Πίσω Μέρος

Ακυρώσεις προσωρινής μνήμης Rails σε επίπεδο πεδίου: Λύση DSL



Στη σύγχρονη ανάπτυξη ιστού, η προσωρινή αποθήκευση είναι ένας γρήγορος και ισχυρός τρόπος για να επιταχύνετε τα πράγματα. Όταν γίνει σωστά, η προσωρινή αποθήκευση μπορεί να επιφέρει σημαντικές βελτιώσεις στη συνολική απόδοση της εφαρμογής σας. Όταν γίνει λάθος, σίγουρα θα καταλήξει σε καταστροφή.

Η ακύρωση της προσωρινής μνήμης, όπως ίσως γνωρίζετε, είναι ένα από τα τρία πιο δύσκολα προβλήματα στην επιστήμη των υπολογιστών - τα άλλα δύο είναι η ονομασία πραγμάτων και τα λάθη off-by-one. Ένας εύκολος τρόπος είναι να ακυρώσετε τα πάντα, αριστερά και δεξιά, όποτε κάτι αλλάζει. Αλλά αυτό χάνει τον σκοπό της προσωρινής αποθήκευσης. Θέλετε να ακυρώσετε την προσωρινή μνήμη μόνο όταν είναι απολύτως απαραίτητο.



Εάν θέλετε να αξιοποιήσετε στο έπακρο την προσωρινή αποθήκευση, πρέπει να είστε πολύ συγκεκριμένοι σχετικά με το τι ακυρώνετε και να αποθηκεύσετε την αίτησή σας από σπατάλη πολύτιμων πόρων σε επαναλαμβανόμενες εργασίες.



Ακύρωση προσωρινής μνήμης Rails σε επίπεδο πεδίου



Σε αυτήν την ανάρτηση ιστολογίου, θα μάθετε μια τεχνική για τον καλύτερο έλεγχο του τρόπου με τον οποίο συμπεριφέρονται οι κρυφές μνήμες Rails: συγκεκριμένα, εφαρμογή ακύρωσης προσωρινής μνήμης σε επίπεδο πεδίου. Αυτή η τεχνική βασίζεται Rails ActiveRecord και ActiveSupport::Concern καθώς και χειραγώγηση του touch συμπεριφορά μεθόδου.

Αυτή η ανάρτηση ιστολογίου βασίζεται στις πρόσφατες εμπειρίες μου σε ένα έργο όπου είδαμε σημαντική βελτίωση στην απόδοση μετά την εφαρμογή ακύρωσης προσωρινής μνήμης σε επίπεδο πεδίου. Βοήθησε στη μείωση των περιττών ακυρώσεων της προσωρινής μνήμης και της επαναλαμβανόμενης απόδοσης προτύπων.



Rails, Ruby και Performance

Το Ruby δεν είναι η πιο γρήγορη γλώσσα, αλλά συνολικά, είναι μια κατάλληλη επιλογή για την ταχύτητα ανάπτυξης. Επιπλέον, είναι μεταπρογραμματισμός και οι ενσωματωμένες δυνατότητες γλώσσας για συγκεκριμένους τομείς (DSL) προσφέρουν στον προγραμματιστή τεράστια ευελιξία.

Υπάρχουν μελέτες εκεί έξω Η μελέτη του Jakob Nielsen που μας δείχνουν ότι εάν μια εργασία διαρκεί περισσότερο από 10 δευτερόλεπτα, θα χάσουμε την εστίασή μας. Και η ανάκτηση της εστίασης απαιτεί χρόνο. Αυτό μπορεί να είναι απροσδόκητα δαπανηρό.



Δυστυχώς, στο Ruby on Rails, είναι εξαιρετικά εύκολο να ξεπεράσετε αυτό το όριο των 10 δευτερολέπτων με τη δημιουργία προτύπων. Δεν θα δείτε ότι συμβαίνει σε καμία εφαρμογή «γειά σου κόσμου» ή μικρού μεγέθους έργου κατοικίδιων ζώων, αλλά σε έργα πραγματικού κόσμου όπου πολλά πράγματα φορτώνονται σε μία σελίδα, πιστέψτε με, η δημιουργία προτύπων μπορεί πολύ εύκολα να αρχίσει να μεταφέρεται.

Και αυτό ακριβώς έπρεπε να λύσω στο έργο μου.



Απλές βελτιστοποιήσεις

Αλλά πώς ακριβώς επιταχύνετε τα πράγματα;

Η απάντηση: Συγκριτική αξιολόγηση και βελτιστοποίηση.



Στο έργο μου, δύο πολύ αποτελεσματικά βήματα βελτιστοποίησης ήταν:

  • Εξάλειψη ερωτημάτων N + 1
  • Παρουσιάζοντας μια καλή τεχνική προσωρινής αποθήκευσης για πρότυπα

N + 1 ερωτήματα

Διόρθωση N + 1 ερωτήματα είναι εύκολο. Αυτό που μπορείτε να κάνετε είναι να ελέγξετε τα αρχεία καταγραφής σας — όποτε βλέπετε πολλά ερωτήματα SQL όπως αυτά παρακάτω στα αρχεία καταγραφής σας, εξαλείψτε τα αντικαθιστώντας τα με πρόθυμη φόρτωση:



Learning Load (0.4ms) SELECT 'learnings'.* FROM 'learnings' WHERE 'project'.'id' = ? Learning Load (0.3ms) SELECT 'learnings'.* FROM 'learnings' WHERE 'project'.'id' = ? Learning Load (0.4ms) SELECT 'learnings'.* FROM 'learnings' WHERE 'project'.'id' = ?

Υπάρχει ένα στολίδι για αυτό που ονομάζεται σφαίρα για να βοηθήσουμε στον εντοπισμό αυτής της αναποτελεσματικότητας. Μπορείτε επίσης να δείτε όλες τις περιπτώσεις χρήσης και, εν τω μεταξύ, να ελέγξετε τα αρχεία καταγραφής ελέγχοντάς τα με το παραπάνω μοτίβο. Καταργώντας όλες τις ανεπάρκειες N + 1, μπορείτε να είστε αρκετά σίγουροι ότι δεν θα υπερφορτώσετε τη βάση δεδομένων σας και ο χρόνος που αφιερώνετε στο ActiveRecord θα μειωθεί σημαντικά.

Αφού κάνατε αυτές τις αλλαγές, το πρόγραμμά μου έτρεχε ήδη πιο γρήγορα. Αλλά αποφάσισα να το πάω στο επόμενο επίπεδο και να δω αν μπορούσα να μειώσω ακόμη περισσότερο τον χρόνο φόρτωσης. Υπήρχε ακόμη ένα άσκοπο κομμάτι που δεν συνέβαινε στα πρότυπα, και τελικά, εκεί βοήθησε η κρυφή μνήμη θραυσμάτων.

Αποθήκευση κλασμάτων

Το Fragment caching γενικά βοηθά στη σημαντική μείωση του χρόνου δημιουργίας προτύπων. Αλλά η προεπιλεγμένη συμπεριφορά προσωρινής αποθήκευσης Rails δεν την έκοψε για το έργο μου.

Η ιδέα πίσω από το Rails fragment caching είναι εξαιρετική. Παρέχει έναν εξαιρετικά απλό και αποτελεσματικό μηχανισμό προσωρινής αποθήκευσης.

Οι συγγραφείς του Ruby On Rails έχουν γράψει ένα πολύ καλό άρθρο στο Signal v. Noise για το πώς έργα αποθήκευσης κλασμάτων .

Ας υποθέσουμε ότι έχετε λίγο περιβάλλον εργασίας χρήστη που δείχνει ορισμένα πεδία μιας οντότητας.

  • Κατά τη φόρτωση της σελίδας, το Rails υπολογίζει το cache_key με βάση την κλάση της οντότητας και updated_at πεδίο.
  • Χρησιμοποιώντας αυτό cache_key, ελέγχει αν υπάρχει κάτι στην κρυφή μνήμη που σχετίζεται με αυτό το κλειδί.
  • Εάν δεν υπάρχει τίποτα στην κρυφή μνήμη, τότε ο κώδικας HTML για αυτό το τμήμα αποδίδεται για την προβολή (και το περιεχόμενο που προσφέρθηκε πρόσφατα αποθηκεύεται στην κρυφή μνήμη).
  • Εάν υπάρχει υπάρχον περιεχόμενο στην προσωρινή μνήμη με αυτό το κλειδί, τότε η προβολή αποδίδεται με τα περιεχόμενα της προσωρινής μνήμης.

Αυτό σημαίνει ότι η προσωρινή μνήμη δεν χρειάζεται ποτέ να ακυρωθεί ρητά. Κάθε φορά που αλλάζουμε την οντότητα και φορτώνουμε ξανά τη σελίδα, αποδίδεται νέο περιεχόμενο προσωρινής μνήμης για την οντότητα.

Οι ράγες, από προεπιλογή, προσφέρουν επίσης τη δυνατότητα ακύρωσης της προσωρινής μνήμης των γονικών οντοτήτων σε περίπτωση αλλαγής του παιδιού:

belongs_to :parent_entity, touch: true

Αυτό, όταν περιλαμβάνεται σε ένα μοντέλο, αυτόματα αφή ο γονέας όταν είναι το παιδί συγκενημένος . Μπορείτε να μάθετε περισσότερα για το touch εδώ . Με αυτό, η Rails μας παρέχει έναν απλό και αποτελεσματικό τρόπο ακύρωσης της προσωρινής μνήμης για τις γονικές οντότητες μας ταυτόχρονα με την προσωρινή μνήμη για τις θυγατρικές οντότητες.

Προσωρινή αποθήκευση σε ράγες

Ωστόσο, η προσωρινή αποθήκευση στο Rails δημιουργείται για την εξυπηρέτηση διεπαφών χρήστη, όπου το τμήμα HTML που αντιπροσωπεύει τη μητρική οντότητα περιέχει τμήματα HTML που αντιπροσωπεύουν αποκλειστικά τις θυγατρικές οντότητες του γονέα. Με άλλα λόγια, το τμήμα HTML που αντιπροσωπεύει τις θυγατρικές οντότητες σε αυτό το παράδειγμα δεν μπορεί να περιέχει πεδία από τη γονική οντότητα.

Αλλά αυτό δεν συμβαίνει στον πραγματικό κόσμο. Ίσως χρειαστεί να κάνετε πράγματα στην εφαρμογή Rails που παραβιάζουν αυτήν την προϋπόθεση.

Πώς θα χειρίζεστε μια κατάσταση όπου η διεπαφή χρήστη εμφανίζει πεδία μιας γονικής οντότητας μέσα στο τμήμα HTML που αντιπροσωπεύει την θυγατρική οντότητα;

Θραύσματα για θυγατρικές οντότητες που αναφέρονται σε πεδία μητρικών οντοτήτων

Εάν το παιδί περιέχει πεδία από τη γονική οντότητα, τότε αντιμετωπίζετε προβλήματα με την προεπιλεγμένη συμπεριφορά ακύρωσης της προσωρινής μνήμης Rails.

Κάθε φορά που τροποποιούνται αυτά τα πεδία από τη μητρική οντότητα, θα πρέπει να αγγίξετε όλες τις θυγατρικές οντότητες που ανήκουν σε αυτόν τον γονέα. Για παράδειγμα, εάν Parent1 έχει τροποποιηθεί, θα πρέπει να βεβαιωθείτε ότι η προσωρινή μνήμη για το Child1 και Child2 και οι δύο προβολές είναι άκυρες.

Προφανώς, αυτό μπορεί να προκαλέσει τεράστια συμφόρηση απόδοσης. Το άγγιγμα κάθε θυγατρικής οντότητας όποτε ένας γονέας έχει αλλάξει θα είχε ως αποτέλεσμα πολλά ερωτήματα βάσης δεδομένων χωρίς κανένα καλό λόγο.

Ένα άλλο παρόμοιο σενάριο είναι όταν οι οντότητες που σχετίζονται με το has_and_belongs_to Η συσχέτιση παρουσιάστηκε στη λίστα και η τροποποίηση αυτών των οντοτήτων ξεκίνησε έναν καταρράκτη ακύρωσης της προσωρινής μνήμης μέσω της αλυσίδας συσχέτισης.

class Event

Επομένως, για την παραπάνω διεπαφή χρήστη, θα ήταν παράλογο να αγγίξετε τον συμμετέχοντα ή το συμβάν όταν αλλάζει η τοποθεσία του χρήστη. Αλλά πρέπει να αγγίξουμε τόσο την εκδήλωση όσο και τον συμμετέχοντα όταν αλλάξει το όνομα του χρήστη, έτσι δεν είναι;

Έτσι, οι τεχνικές στο άρθρο Signal v. Noise είναι αναποτελεσματικές για ορισμένες περιπτώσεις UI / UX, όπως περιγράφεται παραπάνω.

Αν και το Rails είναι εξαιρετικά αποτελεσματικό για απλά πράγματα, τα πραγματικά έργα έχουν τις δικές τους επιπλοκές.

Μη έγκυρη προσωρινή μνήμη ράγας επιπέδου πεδίου

Στα έργα μου, χρησιμοποίησα ένα μικρό Ruby DSL για χειρισμό καταστάσεων όπως τα παραπάνω. Σας επιτρέπει να καθορίσετε δηλωτικά τα πεδία που θα προκαλέσουν ακύρωση της προσωρινής μνήμης μέσω των συσχετίσεων.

Ας ρίξουμε μια ματιά σε μερικά παραδείγματα για το πού πραγματικά βοηθά:

Android που τρέχει σε νήμα φόντου

Παράδειγμα 1:

class Event

Αυτό το απόσπασμα αξιοποιεί τις ικανότητες μετα-προγραμματισμού και το εσωτερικό Δυνατότητες DSL του Ruby .

Για να είμαστε πιο συγκεκριμένοι, μόνο μια αλλαγή ονόματος στο συμβάν θα ακυρώσει την κρυφή μνήμη των σχετικών εργασιών. Η αλλαγή άλλων πεδίων του συμβάντος - όπως ο σκοπός ή η τοποθεσία - δεν θα ακυρώσει την κρυφή μνήμη της εργασίας. Θα το αποκαλούσα Έλεγχος ακύρωσης κρυφής μνήμης σε επίπεδο πεδίου .

Θραύσμα για οντότητα συμβάντος με μόνο το πεδίο ονόματος

Παράδειγμα 2:

Ας ρίξουμε μια ματιά σε ένα παράδειγμα που δείχνει την ακύρωση της προσωρινής μνήμης μέσω του has_many αλυσίδα σύνδεσης.

Το τμήμα διεπαφής χρήστη που εμφανίζεται παρακάτω δείχνει μια εργασία και τον κάτοχό της:

Θραύσμα για οντότητα συμβάντος με τον κάτοχο του συμβάντος

Για αυτήν τη διεπαφή χρήστη, το τμήμα HTML που αντιπροσωπεύει την εργασία θα πρέπει να ακυρώνεται μόνο όταν αλλάζει η εργασία ή όταν αλλάζει το όνομα του κατόχου. Εάν αλλάξουν όλα τα άλλα πεδία του κατόχου (όπως η ζώνη ώρας ή οι προτιμήσεις), τότε η προσωρινή μνήμη εργασίας πρέπει να παραμείνει ανέπαφη.

Αυτό επιτυγχάνεται χρησιμοποιώντας το DSL που εμφανίζεται εδώ:

class User

Εφαρμογή του DSL

Η κύρια ουσία του DSL είναι το touch μέθοδος. Το πρώτο όρισμα είναι μια συσχέτιση και το επόμενο όρισμα είναι μια λίστα πεδίων που ενεργοποιεί το touch σε αυτήν την ένωση:

touch :tasks, in_case_of_modified_fields: [:first_name, :last_name]

Αυτή η μέθοδος παρέχεται από το Touchable μονάδα μέτρησης:

module Touchable extend ActiveSupport::Concern included do before_save :check_touchable_entities after_save :touch_marked_entities end module ClassMethods def touch association, options @touchable_associations ||= {} @touchable_associations[association] = options end end end

Σε αυτόν τον κώδικα, το κύριο σημείο είναι ότι αποθηκεύουμε τα ορίσματα του touch κλήση. Στη συνέχεια, πριν από την αποθήκευση της οντότητας, επισημαίνουμε ότι ο συσχετισμός είναι βρώμικος εάν τροποποιήθηκε το καθορισμένο πεδίο. Αγγίζουμε τις οντότητες σε αυτόν τον συσχετισμό αφού αποθηκεύσουμε εάν ο συσχετισμός ήταν βρώμικος.

Στη συνέχεια, το ιδιωτικό μέρος της ανησυχίας είναι:

... private def klass_level_meta_info self.class.instance_variable_get('@touchable_associations') end def meta_info @meta_info ||= {} end def check_touchable_entities return unless klass_level_meta_info.present? klass_level_meta_info.each_pair do |association, change_triggering_fields| if any_of_the_declared_field_changed?(change_triggering_fields) meta_info[association] = true end end end def any_of_the_declared_field_changed?(options) (options[:in_case_of_modified_fields] & changes.keys.map).present? end …

Στο check_touchable_entities μέθοδος, ελέγχουμε εάν το δηλωμένο πεδίο άλλαξε . Εάν ναι, επισημαίνουμε τον συσχετισμό ως βρώμικο ρυθμίζοντας το meta_info[association] έως true.

Στη συνέχεια, αφού σώσουμε την οντότητα, ελέγξουμε το δικό μας βρώμικοι σύλλογοι και αγγίξτε τις οντότητες σε αυτό εάν είναι απαραίτητο:

… def touch_marked_entities return unless klass_level_meta_info.present? klass_level_meta_info.each_key do |association_key| if meta_info[association_key] association = send(association_key) association.update_all(updated_at: Time.zone.now) meta_info[association_key] = false end end end …

Και αυτό είναι! Τώρα μπορείτε να εκτελέσετε ακύρωση προσωρινής μνήμης σε επίπεδο πεδίου στο Rails με ένα απλό DSL.

συμπέρασμα

Η αποθήκευση ράγας υπόσχεται βελτιώσεις απόδοσης στην εφαρμογή σας με σχετική ευκολία. Ωστόσο, οι πραγματικές εφαρμογές μπορεί να είναι περίπλοκες και συχνά δημιουργούν μοναδικές προκλήσεις. Η προεπιλεγμένη συμπεριφορά προσωρινής μνήμης Rails λειτουργεί καλά για τα περισσότερα σενάρια, αλλά υπάρχουν ορισμένα σενάρια όπου η βελτιστοποίηση στην ακύρωση της προσωρινής μνήμης μπορεί να προχωρήσει πολύ.

Τώρα που γνωρίζετε πώς να εφαρμόσετε την ακύρωση προσωρινής μνήμης σε επίπεδο πεδίου στο Rails, μπορείτε να αποτρέψετε περιττές ακυρώσεις προσωρινής αποθήκευσης στην εφαρμογή σας.

Κατανόηση των βασικών

Τι σημαίνει το DSL;

Το DSL σημαίνει «γλώσσα για συγκεκριμένο τομέα».

Τι κάνει η μέθοδος αφής ActiveRecord;

Η μέθοδος αφής ορίζει το πεδίο updated_at / on στην τρέχουσα ώρα και αποθηκεύει την εγγραφή.

ApeeScape Design Blog Χρώμα της Χρονιάς 2020

Σχεδιασμός Ux

ApeeScape Design Blog Χρώμα της Χρονιάς 2020
Πώς η μηχανική εκμάθηση μπορεί να βελτιώσει την ασφάλεια στον κυβερνοχώρο για αυτόνομα αυτοκίνητα

Πώς η μηχανική εκμάθηση μπορεί να βελτιώσει την ασφάλεια στον κυβερνοχώρο για αυτόνομα αυτοκίνητα

Καινοτομία

Δημοφιλείς Αναρτήσεις
Senior Full-stack Engineer, Talent Post-hire Team
Senior Full-stack Engineer, Talent Post-hire Team
Εισαγωγή στην επεξεργασία εικόνων Python στην Υπολογιστική Φωτογραφία
Εισαγωγή στην επεξεργασία εικόνων Python στην Υπολογιστική Φωτογραφία
Λειτουργίες παραθύρου εισαγωγής στο SQL
Λειτουργίες παραθύρου εισαγωγής στο SQL
Εγκατάσταση του Django στο IIS: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Εγκατάσταση του Django στο IIS: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Φαίνεται ενθουσιασμό - Μέσα στην αναπτυσσόμενη βιομηχανία ομορφιάς
Φαίνεται ενθουσιασμό - Μέσα στην αναπτυσσόμενη βιομηχανία ομορφιάς
 
Αρχιτεκτονική προσανατολισμένη στην υπηρεσία με AWS Lambda: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Αρχιτεκτονική προσανατολισμένη στην υπηρεσία με AWS Lambda: Ένα βήμα προς βήμα εκπαιδευτικό πρόγραμμα
Σχεδιασμός παρουσίασης και τέχνη της οπτικής αφήγησης
Σχεδιασμός παρουσίασης και τέχνη της οπτικής αφήγησης
Μια βαθιά ματιά στο JSON εναντίον XML, Μέρος 3: XML και το μέλλον του JSON
Μια βαθιά ματιά στο JSON εναντίον XML, Μέρος 3: XML και το μέλλον του JSON
5 Ερωτήσεις που πρέπει να υποβάλει ένα Master Scrum πριν εγγραφείτε σε μια εκκίνηση
5 Ερωτήσεις που πρέπει να υποβάλει ένα Master Scrum πριν εγγραφείτε σε μια εκκίνηση
Τρεις αρχές ανάπτυξης δεδομένων αποθήκης
Τρεις αρχές ανάπτυξης δεδομένων αποθήκης
Δημοφιλείς Αναρτήσεις
  • στοιχείο και αρχές σχεδιασμού
  • power pivot για το excel 2016
  • εάν η ελαστικότητα της ζήτησης μετρηθεί 2, αυτό σημαίνει ότι οι καταναλωτές θα το έκαναν
  • vr/ar/mr
  • elixir (γλώσσα προγραμματισμού)
  • πώς να γράψετε μια προδιαγραφή λογισμικού
Κατηγορίες
  • Επιστήμη Δεδομένων Και Βάσεις Δεδομένων
  • Κερδοφορία & Αποδοτικότητα
  • Σχεδιασμός Ux
  • Κινητό
  • © 2022 | Ολα Τα Δικαιώματα Διατηρούνται

    portaldacalheta.pt