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

Πριν από πέντε χρόνια προσπάθησα να δουλέψω με τον Tarantool, αλλά μετά δεν μου λειτούργησε. Αλλά πρόσφατα διοργάνωσα ένα διαδικτυακό σεμινάριο όπου μίλησα για το Hadoop και πώς λειτουργεί το MapReduce. Εκεί μου έκαναν μια ερώτηση: "Γιατί να μην χρησιμοποιήσω το Tarantool για αυτήν την εργασία;"

Από περιέργεια, αποφάσισα να επιστρέψω σε αυτό, να δοκιμάσω την τελευταία έκδοση - και αυτή τη φορά μου άρεσε πολύ το έργο. Τώρα θα σας δείξω πώς να γράψετε μια απλή εφαρμογή στο Tarantool, να τη φορτώσετε και να ελέγξετε την απόδοσή της και θα δείτε πόσο εύκολα και ωραία είναι όλα.

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

Τι είναι το Tarantool

Το Tarantool τοποθετείται ως μια εξαιρετικά γρήγορη βάση δεδομένων. Μπορείτε να βάλετε όποια δεδομένα θέλετε εκεί. Επιπλέον, αντιγράψτε τα, θραύσματα - δηλαδή, διαχωρίστε μια τεράστια ποσότητα δεδομένων σε πολλούς διακομιστές και συνδυάστε τα αποτελέσματα από αυτούς - κάντε συνδέσεις master-master με ανοχή σφαλμάτων.

Δεύτερον, αυτός είναι ένας διακομιστής εφαρμογών. Μπορείτε να γράψετε τις εφαρμογές σας σε αυτό, να εργαστείτε με δεδομένα, για παράδειγμα, να διαγράψετε παλιές εγγραφές στο παρασκήνιο σύμφωνα με ορισμένους κανόνες. Μπορείτε να γράψετε έναν διακομιστή Http απευθείας στο Tarantula που θα λειτουργεί με δεδομένα: δώστε την ποσότητα τους, γράψτε νέα δεδομένα εκεί και μειώστε τα όλα στον κύριο.

Διάβασα ένα άρθρο για το πώς οι τύποι έκαναν μια ουρά μηνυμάτων 300 γραμμών, η οποία απλά ξεσπά και βιάζεται - έχουν ελάχιστη απόδοση 20 μηνυμάτων ανά δευτερόλεπτο. Εδώ μπορείτε πραγματικά να γυρίσετε και να γράψετε μια πολύ μεγάλη εφαρμογή, και δεν θα είναι αποθήκευση, όπως στο PostgreS.

Θα προσπαθήσω να περιγράψω κάτι σαν αυτόν τον διακομιστή, μόνο απλό, σε αυτό το άρθρο.

Εγκατάσταση

Για τη δοκιμή, ξεκίνησα τρεις τυπικές εικονικές μηχανές - έναν σκληρό δίσκο 20 GB, το Ubuntu 18.04. 2 εικονικές CPU και 4 gig μνήμης.

Εγκαθιστούμε το Tarantool - τρέχουμε το σενάριο bash ή προσθέτουμε ένα αποθετήριο και κάνουμε apt να εγκαταστήσουμε το Tarantool. Σύνδεσμος στο σενάριο - (curl -L https://tarantool.io/installer.sh | VER=2.4 sudo -E bash). Έχουμε εντολές όπως:

tarantoolctl — η κύρια εντολή για τη διαχείριση περιπτώσεων Tarantula.
/etc/tarantool - εδώ είναι ολόκληρη η διαμόρφωση.
var/log/tarantool - εδώ είναι τα κούτσουρα.
var/lib/tarantool — τα δεδομένα βρίσκονται εδώ και στη συνέχεια χωρίζονται σε περιπτώσεις.

Υπάρχουν φάκελοι instance-available και instance-enable - περιέχει αυτό που θα εκκινηθεί - ένα αρχείο διαμόρφωσης instance με κωδικό lua, το οποίο περιγράφει ποιες θύρες ακούει, ποια μνήμη είναι διαθέσιμη σε αυτό, ρυθμίσεις κινητήρα Vinyl, κώδικας που εκτελείται κατά την εκκίνηση διακομιστές, διαμοιρασμός, ουρές, διαγραφή απαρχαιωμένων δεδομένων και ούτω καθεξής.

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

Διαχείριση περιπτώσεων

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

Μπορείτε να δείτε την κατάσταση της παρουσίας - παράδειγμα κατάστασης tarantoolctl. Με τον ίδιο τρόπο μπορείτε να κάνετε start, stop, restart.

Μόλις εκτελείται η παρουσία, μπορείτε να συνδεθείτε σε αυτήν με δύο τρόπους.

1. Διοικητική κονσόλα

Από προεπιλογή, το Tarantool ανοίγει μια υποδοχή και κανονικό κείμενο ASCII αποστέλλεται εκεί για έλεγχο του Tarantool. Η σύνδεση με την κονσόλα πραγματοποιείται πάντα υπό τον χρήστη διαχειριστή, δεν υπάρχει έλεγχος ταυτότητας, επομένως δεν χρειάζεται να εξωτερικεύσετε τη θύρα της κονσόλας για τη διαχείριση του Tarantula.

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

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

2. Χρήση δυαδικού πρωτοκόλλου για σύνδεση σε συγκεκριμένη θύρα

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

Για αυτή τη σύνδεση, χρησιμοποιείται το tarantoolctl connect to port number. Χρησιμοποιώντας το, μπορείτε να συνδεθείτε σε απομακρυσμένους διακομιστές, να χρησιμοποιήσετε έλεγχο ταυτότητας και να δώσετε διάφορα δικαιώματα πρόσβασης.

Ενότητα καταγραφής δεδομένων και πλαισίου

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

Ρεκόρ

Για παράδειγμα, μπαίνουμε στη μονάδα box και καλούμε τη συνάρτηση box.once. Αυτό θα αναγκάσει το Tarantool να εκτελέσει τον κώδικά μας κατά την προετοιμασία του διακομιστή. Δημιουργούμε έναν χώρο στον οποίο θα αποθηκεύονται τα δεδομένα μας.

local function bootstrap()
    local space = box.schema.create_space('example')
    space:create_index('primary')
    box.schema.user.grant('guest', 'read,write,execute', 'universe')

    -- Keep things safe by default
    --  box.schema.user.create('example', { password = 'secret' })
    --  box.schema.user.grant('example', 'replication')
    --  box.schema.user.grant('example', 'read,write,execute', 'space', 'example')
end

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

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

Σε σύγκριση με τις συμβατικές βάσεις δεδομένων, όλα εδώ είναι αρκετά απλά. Έχουμε χώρο - μια περιοχή στην οποία απλά αποθηκεύονται τα δεδομένα μας. Κάθε εγγραφή ονομάζεται πλειάδα. Είναι συσκευασμένο σε MessagePack. Αυτή είναι μια πολύ ωραία μορφή - είναι δυαδική και καταλαμβάνει λιγότερο χώρο - 18 byte έναντι 27.

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

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

Μπορούμε να προβάλουμε όλα τα κενά χρησιμοποιώντας την εντολή Box.space. Για να επιλέξετε ένα συγκεκριμένο παράδειγμα, γράψτε παράδειγμα box.space και λάβετε πλήρεις πληροφορίες σχετικά με αυτό.

Το Tarantool έχει δύο ενσωματωμένους κινητήρες: Memory και Vinyl. Η μνήμη αποθηκεύει όλα τα δεδομένα στη μνήμη. Επομένως, όλα λειτουργούν απλά και γρήγορα. Τα δεδομένα απορρίπτονται στο δίσκο και υπάρχει επίσης ένας μηχανισμός καταγραφής εγγραφής πριν, οπότε δεν θα χάσουμε τίποτα εάν ο διακομιστής διακοπεί.

Το βινύλιο αποθηκεύει δεδομένα στο δίσκο με μια μορφή πιο οικεία σε εμάς - δηλαδή, μπορείτε να αποθηκεύσετε περισσότερα δεδομένα από όσα έχουμε μνήμη και ο Tarantula θα τα διαβάσει από το δίσκο.

Προς το παρόν θα χρησιμοποιήσουμε τη Μνήμη.

unix/:/var/run/tarantool/example.control> box.space.example
---
- engine: memtx
  before_replace: 'function: 0x41eb02c8'
  on_replace: 'function: 0x41eb0568'
  ck_constraint: []
  field_count: 0
  temporary: false
  index:
    0: &0
      unique: true
      parts:
      - type: unsigned
        is_nullable: false
        fieldno: 1
      id: 0
      space_id: 512
      type: TREE
      name: primary
    primary: *0
  is_local: false
  enabled: true
  name: example
  id: 512
...

unix/:/var/run/tarantool/example.control>

Δείκτης:

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

Μέρη:

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

Στη συνέχεια μπορούμε να εισάγουμε δεδομένα χρησιμοποιώντας την εντολή insert.

unix/:/var/run/tarantool/example.control> box.space.example:insert{1, 'test1', 'test2'}
---
- [1, 'test1', 'test2']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{2, 'test2', 'test3', 'test4'}
---
- [2, 'test2', 'test3', 'test4']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{3, 'test3'}
---
- [3, 'test3']
...

unix/:/var/run/tarantool/example.control> box.space.example:insert{4, 'test4'}
---
- [4, 'test4']
...

unix/:/var/run/tarantool/example.control>

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

Έξοδος δεδομένων

Στη συνέχεια μπορούμε να εμφανίσουμε τα δεδομένα χρησιμοποιώντας την εντολή Select.

Το Box.example.select με το πλήκτρο {1} θα εμφανίσει την επιθυμητή καταχώρηση. Αν χαμηλώσουμε το κλειδί, θα δούμε όλες τις εγγραφές που έχουμε. Όλα διαφέρουν ως προς τον αριθμό των στηλών, αλλά εδώ, κατ 'αρχήν, δεν υπάρχει η έννοια των στηλών - υπάρχουν αριθμοί πεδίων.

Μπορεί να υπάρχει απολύτως οποιαδήποτε ποσότητα δεδομένων. Και για παράδειγμα, πρέπει να τα αναζητήσουμε από το δεύτερο πεδίο. Για να γίνει αυτό, δημιουργούμε ένα νέο δευτερεύον ευρετήριο.


box.space.example:create_index( ‘secondary’, { type = ‘TREE’, unique = false, parts = {{field = 2, type =’string’} }}) 

Χρησιμοποιούμε την εντολή Create_index.
Ας το πούμε Δευτερεύον.

Μετά από αυτό πρέπει να καθορίσετε τις παραμέτρους. Ο τύπος ευρετηρίου είναι ΔΕΝΤΡΟ. Μπορεί να μην είναι μοναδικό, οπότε πληκτρολογήστε Unique = false.

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

unix/:/var/run/tarantool/example.control> box.space.example:create_index('secondary', { type = 'TREE', unique = false, parts = {{field = 2, type = 'string'}}})
---
- unique: false
  parts:
  - type: string
    is_nullable: false
    fieldno: 2
  id: 1
  space_id: 512
  type: TREE
  name: secondary
...

unix/:/var/run/tarantool/example.control>

Τώρα μπορούμε να το ονομάσουμε έτσι:

unix/:/var/run/tarantool/example.control> box.space.example.index.secondary:select('test1')
---
- - [1, 'test1', 'test2']
...

Αποθήκευση

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

Δεν θα λειτουργήσει ούτε να αποθηκεύετε κάθε δευτερόλεπτο, επειδή η συνεχής απόρριψη 20 GB στο δίσκο δεν είναι καλή ιδέα.

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

Κάθε καταχώρηση μέχρι το σημείο ελέγχου αποθηκεύεται σε αυτά. Για αυτά τα αρχεία ορίζουμε το μέγεθος - για παράδειγμα, 64 MB. Όταν γεμίσει, η εγγραφή αρχίζει να πηγαίνει στο δεύτερο αρχείο. Και μετά την επανεκκίνηση, το Tarantool αποκαθίσταται από το τελευταίο σημείο ελέγχου και στη συνέχεια μεταφέρει όλες τις μεταγενέστερες συναλλαγές μέχρι να σταματήσει.

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

Για να πραγματοποιήσετε μια τέτοια εγγραφή, πρέπει να καθορίσετε την επιλογή στις ρυθμίσεις box.cfg (στο αρχείο example.lua):

wal_mode = “write”;

χρήση δεδομένων

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

Σύνταξη αίτησης

Για παράδειγμα, ας γράψουμε την παρακάτω εφαρμογή για Tarantula

Δείτε την εφαρμογή κάτω από το spoiler

box.cfg {
    listen = '0.0.0.0:3301';
    io_collect_interval = nil;
    readahead = 16320;
    memtx_memory = 128 * 1024 * 1024; -- 128Mb
    memtx_min_tuple_size = 16;
    memtx_max_tuple_size = 128 * 1024 * 1024; -- 128Mb
    vinyl_memory = 128 * 1024 * 1024; -- 128Mb
    vinyl_cache = 128 * 1024 * 1024; -- 128Mb
    vinyl_max_tuple_size = 128 * 1024 * 1024; -- 128Mb
    vinyl_write_threads = 2;
    wal_mode = "write";
    wal_max_size = 256 * 1024 * 1024;
    checkpoint_interval = 60 * 60; -- one hour
    checkpoint_count = 6;
    force_recovery = true;
    log_level = 5;
    log_nonblock = false;
    too_long_threshold = 0.5;
    read_only   = false
}

local function bootstrap()
    local space = box.schema.create_space('example')
    space:create_index('primary')

    box.schema.user.create('example', { password = 'secret' })
    box.schema.user.grant('example', 'read,write,execute', 'space', 'example')

    box.schema.user.create('repl', { password = 'replication' })
    box.schema.user.grant('repl', 'replication')
end

-- for first run create a space and add set up grants
box.once('replica', bootstrap)

-- enabling console access
console = require('console')
console.listen('127.0.0.1:3302')

-- http config
local charset = {}  do -- [0-9a-zA-Z]
    for c = 48, 57  do table.insert(charset, string.char(c)) end
    for c = 65, 90  do table.insert(charset, string.char(c)) end
    for c = 97, 122 do table.insert(charset, string.char(c)) end
end

local function randomString(length)
    if not length or length <= 0 then return '' end
    math.randomseed(os.clock()^5)
    return randomString(length - 1) .. charset[math.random(1, #charset)]
end

local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')

local httpd = http_server.new('0.0.0.0', 8080, {
    log_requests = true,
    log_errors = true
})

local router = http_router.new()

local function get_count()
 local cnt = box.space.example:len()
 return cnt
end

router:route({method = 'GET', path = '/count'}, function()
    return {status = 200, body = json.encode({count = get_count()})}
end)

router:route({method = 'GET', path = '/token'}, function()
    local token = randomString(32)
    local last = box.space.example:len()
    box.space.example:insert{ last + 1, token }
    return {status = 200, body = json.encode({token = token})}
end)

prometheus = require('prometheus')

fiber = require('fiber')
tokens_count = prometheus.gauge("tarantool_tokens_count",
                              "API Tokens Count")

function monitor_tokens_count()
  while true do
    tokens_count:set(get_count())
    fiber.sleep(5)
  end
end
fiber.create(monitor_tokens_count)

router:route( { method = 'GET', path = '/metrics' }, prometheus.collect_http)

httpd:set_router(router)
httpd:start()

Δηλώνουμε έναν πίνακα σε lua που ορίζει τους χαρακτήρες. Αυτή η πλάκα χρειάζεται για τη δημιουργία μιας τυχαίας συμβολοσειράς.

local charset = {}  do -- [0-9a-zA-Z]
    for c = 48, 57  do table.insert(charset, string.char(c)) end
    for c = 65, 90  do table.insert(charset, string.char(c)) end
    for c = 97, 122 do table.insert(charset, string.char(c)) end
end

Μετά από αυτό, δηλώνουμε τη συνάρτηση - randomString και δίνουμε την τιμή του μήκους σε παρένθεση.

local function randomString(length)
    if not length or length <= 0 then return '' end
    math.randomseed(os.clock()^5)
    return randomString(length - 1) .. charset[math.random(1, #charset)]
end

Στη συνέχεια συνδέουμε τον δρομολογητή http και τον διακομιστή http στον διακομιστή Tarantula, JSON, τον οποίο θα στείλουμε στον πελάτη.

local http_router = require('http.router')
local http_server = require('http.server')
local json = require('json')

Μετά από αυτό, ξεκινάμε από τη θύρα 8080 σε όλες τις διεπαφές διακομιστή http, οι οποίες θα καταγράφουν όλα τα αιτήματα και τα σφάλματα.

local httpd = http_server.new('0.0.0.0', 8080, {
    log_requests = true,
    log_errors = true
})

Στη συνέχεια, δηλώνουμε διαδρομή, έτσι ώστε αν φτάσει ένα αίτημα με τη μέθοδο GET στη θύρα 8080 /count, τότε καλούμε τη συνάρτηση από μία γραμμή. Επιστρέφει την κατάσταση - 200, 404, 403 ή οποιαδήποτε άλλη καθορίζουμε.

router:route({method = 'GET', path = '/count'}, function()
    return {status = 200, body = json.encode({count = get_count()})}
end)

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

Η δεύτερη μέθοδος

router:route({method = 'GET', path = '/token'}, function() 
    local token = randomString(32) 
    local last = box.space.example:len() 
    box.space.example:insert{ last + 1, token } 
    return {status = 200, body = json.encode({token = token})}
end)

Πού στη γραμμή router:route({method = 'GET', path = '/token'}, function() καλούμε τη συνάρτηση και δημιουργούμε ένα διακριτικό.

Σειρά τοπικό διακριτικό = randomString(32) είναι μια τυχαία συμβολοσειρά 32 χαρακτήρων.
Στη γραμμή local last = box.space.example:len() βγάζουμε το τελευταίο στοιχείο.
Και στη γραμμή box.space.example:insert{ last + 1, token } γράφουμε τα δεδομένα στη βάση δεδομένων μας, δηλαδή απλώς αυξάνουμε το αναγνωριστικό κατά 1. Αυτό μπορεί να γίνει, παρεμπιπτόντως, όχι μόνο με αυτόν τον αδέξιο τρόπο. Υπάρχουν ακολουθίες για αυτό στον Ταραντούλα.

Εκεί γράφουμε το διακριτικό.

Έτσι, γράψαμε την αίτηση σε ένα αρχείο. Μπορείτε να χειριστείτε απευθείας τα δεδομένα εκεί και η μονάδα κουτιού θα κάνει όλη τη βρώμικη δουλειά για εσάς.

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

Για να ξεκινήσουμε, εγκαθιστούμε την ενότητα http:

Πώς το κάνουμε αυτό, κοιτάξτε κάτω από το σπόιλερ

root@test2:/# tarantoolctl rocks install http
Installing http://rocks.tarantool.org/http-scm-1.src.rock
Missing dependencies for http scm-1:
   checks >= 3.0.1 (not installed)

http scm-1 depends on checks >= 3.0.1 (not installed)
Installing http://rocks.tarantool.org/checks-3.0.1-1.rockspec

Cloning into 'checks'...
remote: Enumerating objects: 28, done.
remote: Counting objects: 100% (28/28), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 28 (delta 1), reused 16 (delta 1), pack-reused 0
Receiving objects: 100% (28/28), 12.69 KiB | 12.69 MiB/s, done.
Resolving deltas: 100% (1/1), done.
Note: checking out '580388773ef11085015b5a06fe52d61acf16b201'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

No existing manifest. Attempting to rebuild...
checks 3.0.1-1 is now installed in /.rocks (license: BSD)

-- The C compiler identification is GNU 7.5.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Found TARANTOOL: /usr/include (found version "2.4.2-80-g18f2bc82d")
-- Tarantool LUADIR is /.rocks/share/tarantool/rocks/http/scm-1/lua
-- Tarantool LIBDIR is /.rocks/share/tarantool/rocks/http/scm-1/lib
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:

    version


-- Build files have been written to: /tmp/luarocks_http-scm-1-V4P9SM/http/build.luarocks
Scanning dependencies of target httpd
[ 50%] Building C object http/CMakeFiles/httpd.dir/lib.c.o
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:32:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c: In function ‘tpl_term’:
/usr/include/tarantool/lauxlib.h:144:15: warning: this statement may fall through [-Wimplicit-fallthrough=]
    (*(B)->p++ = (char)(c)))
    ~~~~~~~~~~~^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:62:7: note: in expansion of macro ‘luaL_addchar’
       luaL_addchar(b, '\');
       ^~~~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:63:6: note: here
      default:
      ^~~~~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:39:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h: In function ‘tpe_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:147:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
    type = TPE_TEXT;
    ~~~~~^~~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/tpleval.h:149:3: note: here
   case TPE_LINECODE:
   ^~~~
In file included from /tmp/luarocks_http-scm-1-V4P9SM/http/http/lib.c:40:0:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h: In function ‘httpfast_parse’:
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:372:22: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 code = 0;
                 ~~~~~^~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:374:13: note: here
             case status:
             ^~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:393:23: warning: this statement may fall through [-Wimplicit-fallthrough=]
                 state = message;
                 ~~~~~~^~~~~~~~~
/tmp/luarocks_http-scm-1-V4P9SM/http/http/httpfast.h:395:13: note: here
             case message:
             ^~~~
[100%] Linking C shared library lib.so
[100%] Built target httpd
[100%] Built target httpd
Install the project...
-- Install configuration: "Debug"
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/VERSION.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lib/http/lib.so
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/server/tsgi_adapter.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/nginx_server/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/init.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/fs.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/matching.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/middleware.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/request.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/router/response.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/tsgi.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/utils.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/mime_types.lua
-- Installing: /.rocks/share/tarantool/rocks/http/scm-1/lua/http/codes.lua
http scm-1 is now installed in /.rocks (license: BSD)

root@test2:/#

Χρειαζόμαστε επίσης τον Προμηθέα για να τρέξουμε:

root@test2:/# tarantoolctl rocks install prometheus
Installing http://rocks.tarantool.org/prometheus-scm-1.rockspec

Cloning into 'prometheus'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (19/19), done.
remote: Total 19 (delta 2), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (19/19), 10.73 KiB | 10.73 MiB/s, done.
Resolving deltas: 100% (2/2), done.
prometheus scm-1 is now installed in /.rocks (license: BSD)

root@test2:/#

Εκκινούμε και μπορούμε να έχουμε πρόσβαση στις ενότητες

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"e2tPq9l5Z3QZrewRf6uuoJUl3lJgSLOI"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/token
HTTP/1.1 200 Ok
Content-length: 44
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"token":"fR5aCA84gj9eZI3gJcV0LEDl9XZAG2Iu"}

root@test2:/# curl -D - -s http://127.0.0.1:8080/count
HTTP/1.1 200 Ok
Content-length: 11
Server: Tarantool http (tarantool v2.4.2-80-g18f2bc82d)
Connection: keep-alive

{"count":2}root@test2:/#

Το /count μας δίνει την κατάσταση 200.
Το /token εκδίδει ένα διακριτικό και εγγράφει αυτό το διακριτικό στη βάση δεδομένων.

Δοκιμή της ταχύτητας

Ας εκτελέσουμε ένα σημείο αναφοράς για 50 αιτήματα. Θα υπάρξουν 000 ανταγωνιστικά αιτήματα.

root@test2:/# ab -c 500 -n 50000 http://127.0.0.1:8080/token
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 127.0.0.1 (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Completed 25000 requests
Completed 30000 requests
Completed 35000 requests
Completed 40000 requests
Completed 45000 requests
Completed 50000 requests
Finished 50000 requests


Server Software:        Tarantool
Server Hostname:        127.0.0.1
Server Port:            8080

Document Path:          /token
Document Length:        44 bytes

Concurrency Level:      500
Time taken for tests:   14.578 seconds
Complete requests:      50000
Failed requests:        0
Total transferred:      7950000 bytes
HTML transferred:       2200000 bytes
Requests per second:    3429.87 [#/sec] (mean)
Time per request:       145.778 [ms] (mean)
Time per request:       0.292 [ms] (mean, across all concurrent requests)
Transfer rate:          532.57 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   10 103.2      0    3048
Processing:    12   69 685.1     15   13538
Waiting:       12   69 685.1     15   13538
Total:         12   78 768.2     15   14573

Percentage of the requests served within a certain time (ms)
  50%     15
  66%     15
  75%     16
  80%     16
  90%     16
  95%     16
  98%     21
  99%     42
 100%  14573 (longest request)
root@test2:/#

Εκδίδονται μάρκες. Και καταγράφουμε συνεχώς δεδομένα. Το 99% των αιτημάτων διεκπεραιώθηκε σε 42 χιλιοστά του δευτερολέπτου. Αντίστοιχα, έχουμε περίπου 3500 αιτήματα ανά δευτερόλεπτο σε ένα μικρό μηχάνημα με 2 πυρήνες και 4 gigabyte μνήμης.

Μπορείτε επίσης να επιλέξετε περίπου 50000 διακριτικά και να δείτε την αξία του.

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

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

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

Ο Tarantula θα το κάνει αυτό μόνος του και δεν θα χρειαστεί να γράψετε ξεχωριστή αίτηση.

Εν κατακλείδι

Αυτό είναι μόνο το πρώτο μέρος μιας μεγάλης δουλειάς. Το δεύτερο θα δημοσιευτεί πολύ σύντομα στο ιστολόγιο του Ομίλου Mail.ru και σίγουρα θα προσθέσουμε έναν σύνδεσμο σε αυτό σε αυτό το υλικό.

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

Εάν πρέπει να μεταβείτε στο cloud ή έχετε ερωτήσεις σχετικά με την υποδομή σας, μη διστάσετε να αφήσετε ένα αίτημα.

Υ.Γ. Έχουμε 2 δωρεάν ελέγχους το μήνα, ίσως το έργο σας να είναι ένας από αυτούς.

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο