Le 7e principe de Redis : nous optimisons pour la joie

Le 7e principe de Redis : nous optimisons pour la joie

7th principle art

Le 7e principe, tel qu’énoncé dans la Manifeste Redis, correspond vraiment à mes convictions et à mes opinions, et probablement à celles de tous les ingénieurs (quelle que soit leur expérience). Il y a peu de choses dans ce monde aussi satisfaisantes que cette poussée d’excitation que vous ressentez en concevant une manière intelligente de faire quelque chose de nouveau et/ou de mieux. Cette ruée joyeuse, à son tour, peut et conduit souvent au développement d’une grave dépendance, comme l’ont reconnu Donald Knuth (“l’optimisation prématurée est la racine de tous les maux”) et Randall Munroe (par exemple http://xkcd.com/1205/, http://xkcd.com/1445/ et http://xkcd.com/1319/) il y a longtemps.

J’ai découvert, cependant, qu’en faisant preuve de bon sens et de logique froide chaque fois que j’ai envie de me lancer dans une quête d’optimisation, je peux garder ma dépendance satisfaite et contrôlée. Ce message concerne trois de ces envies de la semaine dernière.

Optimiser en partageant les connaissances

En tant que défenseur des logiciels open source et internaute décent dans son ensemble, je m’efforce d’aider les autres dans tout ce qui concerne Redis. Bien sûr, Redis peut être utilisé comme un stockage clé-valeur stupide, mais c’est tellement plus qu’il demande pratiquement à être utilisé intelligemment.

C’est donc lors de mes patrouilles quotidiennes sur internet que je suis tombé sur ce Donc question et a commencé à y répondre. Dans ma réponse, j’ai délibérément omis les détails sur la façon dont on procéderait pour scanner une grande liste – l’OP semblait être un débutant et je ne pensais pas qu’il le croirait – mais j’ai toujours ce frisson de joie parce que je avait aidé quelqu’un à faire quelque chose de mieux. J’espère que je l’ai également encouragé à apprendre et à comprendre les commandes qu’il utilisait avant de plonger dans le codage (et peut-être que j’ai aussi économisé au monde des ressources CPU et réseau en cours de route).

Optimisation par exploration

Bien que cette question SO en elle-même ne soit pas quelque chose à écrire à la maison – ou sur un blog (bien que je l’aie fait) – cela m’a fait penser à ce manque LSCAN commande. Il y a ANALYSE pour scanner l’espace clé, HSCAN pour les hachages, SSCAN pour les ensembles et ZSCAN pour les ensembles triés mais rien pour les listes. Depuis les listes de Redis (et Listes rapides) sont des listes régulières (ou des listes chaînées de ziplists), l’accès aléatoire à leurs éléments se fait en complexité O(N). Avoir une efficacité LSCAN commande signifie implémenter les listes Redis différemment, et comme il n’y a pas de repas gratuits, il y a un prix à payer. Les listes sont bonnes (c’est-à-dire O(1)) pour les pops et les pushs, et compte tenu des principes #3 (“Structures de données fondamentales pour une API fondamentale”) et #5 (“Nous sommes contre la complexité”) du Manifeste, si vous utilisez une liste et avez besoin de la parcourir d’un bout à l’autre, vous n’auriez probablement pas dû utiliser une liste en premier lieu.

Mais, pour les besoins de la discussion et juste pour rire, pouvez-vous faire d’une manière ou d’une autre ce que LSCAN ferait (si elle avait été là en premier lieu) ? Question intéressante… eh bien, bien sûr que vous le pouvez. Pour commencer, si vous n’êtes pas préoccupé par la cohérence en raison de la concurrence, vous pouvez facilement utiliser une boucle avec RPOPLPUSH et gardez un compte pour parcourir la liste plus efficacement. Bien sûr, si la simultanéité est un problème, vous devrez probablement trouver un moyen de dupliquer la liste et de parcourir la copie en toute sécurité.

Alors comment faire pour dupliquer une liste de 10 millions d’éléments ? Commençons par créer une telle liste (tous les tests effectués dans une VM sur un ordinateur portable, donc YMMV):

Une copie rapide devra être effectuée sur le serveur, donc la façon naïve de copier la liste serait d’écrire un script Lua qui fera apparaître les éléments un par un et les repoussera vers l’original et la destination. J’ai écrit un tel script et je l’ai testé sur cette longue liste…

Il a fallu une éternité pour courir et a donné les résultats attendus “Script Lua lent détecté” message dans le journal :

23 secondes, c’est beaucoup trop long, et bien que vous puissiez grouper certains appels vers LPUSHpeut être LRANGE est une meilleure approche :

11 secondes, c’est bien mieux que 23, mais que diriez-vous TRIERle faire – serait-ce plus rapide ? Probablement, vérifions-le:

Une amélioration impressionnante – seulement 2,248 secondes et environ 10 fois plus rapide que de sauter et de pousser, mais pouvons-nous faire encore mieux ? Laissez-moi vérifier si Redis en a COPIE, DUPLIQUER ou CLONER commandes… Non, le plus proche qui existe est ÉMIGRER, mais il n’accepte qu’un seul nom de clé. Mais attendez! [lightbulb] Qu’en est-il de DÉCHARGER et sa complémentaire RESTAURER… est-ce que ça pourrait être?

copy key chart

C’est une très bonne astuce – la copie par vidage et restauration est beaucoup plus rapide car vous contournez toute la logique de gestion de la structure de données (un peu comme le bon vieux POUSSÉE en BASIC, et le plus loin possible jusqu’à ce que des pointeurs vers des valeurs soient introduits dans Redis :P). C’est presque 20 fois mieux que l’approche naïve et en théorie, cela devrait fonctionner pour n’importe quel type de données – listes, hachages, ensembles et ensembles triés. Je devrai me souvenir de ce petit hack lorsque j’aurai besoin de copier rapidement des valeurs.

Optimiser par Hacking

Mais attendez ! Il y a même quelque chose de plus méchant auquel je peux penser – que diriez-vous de faire en sorte que Redis aille plus vite que Redis ? Et si quelqu’un écrivait un morceau de code qui pourrait générer des sérialisations de valeurs compatibles avec Redis, comme DÉCHARGER Est-ce que? Avec cette fonctionnalité, vous pouvez charger des données sur Redis très très très rapidement. À moins d’essayer d’écrire directement dans l’espace mémoire du processus Redis, cette approche pourrait potentiellement surpasser n’importe quel client conventionnel basé sur RESP en déplaçant une partie de la charge de Redis vers le client lui-même. Passionnant!

Je connais au moins un de ces codes, alors maintenant je suis vraiment tenté d’y jeter un œil DÉCHARGERla mise en œuvre de [insert link] et voir si je peux l’extraire et le porter, disons pour un Hashmap. Ensuite, je pourrais tester le chargement des JSON en prétraitant et en injectant directement leurs sérialisations finales au lieu d’utiliser HMSET. Les possibilités sont vraiment infinies, mais la quantité d’efforts nécessaires pour y arriver l’est tout autant. Et même cela fonctionne et est relativement exempt de bogues (ouais, c’est vrai), je vais m’appuyer sur l’API privée interne de Redis, donc le potentiel de rupture est énorme. Et ces préoccupations mises à part, c’est juste se sent mauvais. Une meilleure direction consiste peut-être à intégrer Redis dans l’application cliente et à implémenter la réplication Master<->Master pour synchroniser les instances locales et distantes…

Je m’arrête donc ici, laissant mon train de pensée toujours sur ses rails, et la grande partie de mes fantasmes d’optimisation sauvages inassouvis. Je vous ai dit que je pouvais contrôler mon addiction à la joie, le bon sens a enfin tiré le frein d’urgence et en voici la preuve. Mais néanmoins, l’autre jour, Salvatore m’a dit (sur un tout autre sujet) que : « Casser c’est bien, la quintessence du hacking 🙂 »alors je devrais peut-être…

Des questions? Retour d’information? Ne hésitez pas à tweeter ou e-mail moi – je suis très disponible 🙂

Development Source

Related Posts

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Clés Redis dans la RAM |  Redis

Clés Redis dans la RAM | Redis

No Comment

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *