{"id":56365,"date":"2020-02-11T00:00:00","date_gmt":"2020-02-10T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike"},"modified":"2020-02-18T14:04:37","modified_gmt":"2020-02-18T11:04:37","slug":"highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","title":{"rendered":"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>La prochaine conf\u00e9rence HighLoad++ se d\u00e9roulera les 6 et 7 avril 2020 \u00e0 Saint-P\u00e9tersbourg. <br \/>\nD\u00e9tails et billets <noindex><a rel=\"nofollow\" href=\"http:\/\/bit.ly\/2sSxgBx\">via le lien<\/a><\/noindex>. HighLoad++ Sib\u00e9rie 2019. Salle \u00ab Krasno\u00efarsk \u00bb. 25 juin, 12:00. R\u00e9sum\u00e9s et <noindex><a rel=\"nofollow\" href=\"https:\/\/www.highload.ru\/siberia\/2019\/abstracts\/5253\">pr\u00e9sentation<\/a><\/noindex>.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/cded9c5434d670db7295aadf5da0a9f1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIl arrive que les exigences pratiques soient en conflit avec la th\u00e9orie, o\u00f9 des aspects importants pour un produit commercial ne sont pas pris en compte. Dans cette pr\u00e9sentation, nous pr\u00e9senterons le processus de s\u00e9lection et de combinaison de diff\u00e9rentes approches pour cr\u00e9er des composants de coh\u00e9rence causale, bas\u00e9s sur des recherches acad\u00e9miques en fonction des exigences du produit commercial. Les auditeurs d\u00e9couvriront les approches th\u00e9oriques existantes en mati\u00e8re d'horloges logiques, de suivi des d\u00e9pendances, de s\u00e9curit\u00e9 des syst\u00e8mes, de synchronisation des horloges, et pourquoi MongoDB a opt\u00e9 pour certaines solutions.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p><b>Mikhail Tyulenev (ci-apr\u00e8s \u2013 MT) :<\/b> \u2013 Je vais parler de la coh\u00e9rence causale \u2013 c'est une fonctionnalit\u00e9 sur laquelle nous avons travaill\u00e9 chez MongoDB. Je fais partie du groupe des syst\u00e8mes distribu\u00e9s, nous l'avons d\u00e9velopp\u00e9e il y a environ deux ans.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/b8d0a5b64e715f53b033fa8c398e2eb4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAu cours du processus, j'ai d\u00fb me familiariser avec un grand nombre de recherches acad\u00e9miques, car cette fonctionnalit\u00e9 a \u00e9t\u00e9 bien \u00e9tudi\u00e9e. Il s'est av\u00e9r\u00e9 qu'aucun article ne correspond \u00e0 ce qui est n\u00e9cessaire en production, une base de donn\u00e9es en raison de ses exigences tr\u00e8s sp\u00e9cifiques, qui existent probablement dans n'importe quelle application de production.<\/p>\n<p>Je vais expliquer comment nous, en tant que consommateurs de la recherche acad\u00e9mique, pr\u00e9parons quelque chose que nous pouvons ensuite pr\u00e9senter \u00e0 nos utilisateurs comme un plat pr\u00eat \u00e0 l'emploi, facile et s\u00fbr \u00e0 utiliser.<\/p>\n<h3>Coh\u00e9rence causale. D\u00e9finissons les termes<\/h3>\n<p>\nPour commencer, je veux d\u00e9crire bri\u00e8vement ce qu'est la coh\u00e9rence causale. Il y a deux personnages \u2013 Leonard et Penny (s\u00e9rie \u00ab The Big Bang Theory \u00bb) :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/ee0835b604ae5d5d6c0fa1bc369e6b18.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nSupposons que Penny soit en Europe, et Leonard veuille lui faire une surprise, une f\u00eate. Et il ne trouve rien de mieux que de l\u2019enlever de sa liste d\u2019amis, d\u2019envoyer une mise \u00e0 jour \u00e0 tous ses amis dans le flux : \u00ab Faisons plaisir \u00e0 Penny ! \u00bb (elle est en Europe, elle dort pour l'instant, ne voit rien et ne peut pas le voir, car elle n'est pas l\u00e0). \u00c0 un moment donn\u00e9, il supprime ce post, l\u2019efface du \u00ab Fil \u00bb et r\u00e9tablit l'acc\u00e8s pour qu'elle ne remarque rien et qu'il n'y ait pas de scandale.<br \/>\nC'est tout \u00e0 fait magnifique, mais supposons que le syst\u00e8me soit distribu\u00e9 et que les \u00e9v\u00e9nements ne se d\u00e9roulent pas tout \u00e0 fait comme pr\u00e9vu. Par exemple, il pourrait arriver que la restriction d'acc\u00e8s de Penny se soit produite apr\u00e8s la publication de ce post, si les \u00e9v\u00e9nements ne sont pas li\u00e9s par des relations de cause \u00e0 effet. En fait, c'est un exemple de la n\u00e9cessit\u00e9 d'une coh\u00e9rence causale pour r\u00e9aliser une fonction d'affaires (dans ce cas).<\/p>\n<p>En r\u00e9alit\u00e9, ce sont des propri\u00e9t\u00e9s plut\u00f4t non triviales des bases de donn\u00e9es \u2013 tr\u00e8s peu d'entre elles les prennent en charge. Passons aux mod\u00e8les.<\/p>\n<h3>Mod\u00e8les de coh\u00e9rence (Consistency Models)<\/h3>\n<p>\nQu'est-ce qu'un mod\u00e8le de coh\u00e9rence dans les bases de donn\u00e9es ? Ce sont certaines garanties que le syst\u00e8me distribu\u00e9 fournit concernant les donn\u00e9es et leur s\u00e9quence dans laquelle le client peut les obtenir.<\/p>\n<p>En principe, tous les mod\u00e8les de coh\u00e9rence se r\u00e9sument \u00e0 la fa\u00e7on dont un syst\u00e8me distribu\u00e9 ressemble \u00e0 un syst\u00e8me fonctionnant, par exemple, sur un seul n\u0153ud sur un ordinateur portable. Et \u00e0 quel point un syst\u00e8me fonctionnant sur des milliers de n\u0153uds g\u00e9ographiquement dispers\u00e9s ressemble \u00e0 cet ordinateur portable, o\u00f9 toutes ces propri\u00e9t\u00e9s sont g\u00e9n\u00e9ralement r\u00e9alis\u00e9es automatiquement.<\/p>\n<p>C'est pourquoi les mod\u00e8les de coh\u00e9rence ne s'appliquent qu'aux syst\u00e8mes distribu\u00e9s. Tous les syst\u00e8mes qui ont exist\u00e9 auparavant et qui fonctionnaient sur une mise \u00e0 l'\u00e9chelle verticale n'avaient pas ce genre de probl\u00e8mes. Il y avait un seul Buffer Cache, et tout \u00e9tait constamment lu \u00e0 partir de celui-ci.<\/p>\n<h3>Mod\u00e8le Fort (Strong)<\/h3>\n<p>\nLa toute premi\u00e8re mod\u00e9lisation est le mod\u00e8le Fort (ou rise ability, comme il est souvent appel\u00e9). C'est un mod\u00e8le de coh\u00e9rence qui garantit qu'\u00e0 chaque fois qu'un changement est confirm\u00e9 comme ayant \u00e9t\u00e9 effectu\u00e9, celui-ci devient visible pour tous les utilisateurs du syst\u00e8me.<\/p>\n<p>Cela cr\u00e9e un ordre global de tous les \u00e9v\u00e9nements dans la base de donn\u00e9es. C'est une propri\u00e9t\u00e9 de coh\u00e9rence tr\u00e8s forte et elle est g\u00e9n\u00e9ralement tr\u00e8s co\u00fbteuse. N\u00e9anmoins, elle est bien prise en charge. Elle est juste tr\u00e8s co\u00fbteuse et lente \u2013 elle est donc rarement utilis\u00e9e. Cela s'appelle la rise ability.<\/p>\n<p>Il existe une autre propri\u00e9t\u00e9 encore plus forte qui est prise en charge dans \u00ab Spanner \u00bb \u2013 appel\u00e9e Coh\u00e9rence Externe. Nous en parlerons un peu plus tard.<\/p>\n<h3>Causale<\/h3>\n<p>\nCe qui suit est Causal, exactement ce dont je parlais. Entre Strong et Causal, il y a encore plusieurs sous-niveaux que je ne vais pas aborder, mais ils se r\u00e9sument tous \u00e0 Causal. C'est un mod\u00e8le important, car c'est le plus fort de tous les mod\u00e8les, avec la plus forte consistance en cas de r\u00e9seau ou de partitions.<\/p>\n<p>Les Causals sont en fait la situation dans laquelle les \u00e9v\u00e9nements sont li\u00e9s par une relation de cause \u00e0 effet. Ils sont souvent per\u00e7us comme Read your on rights du point de vue du client. Si un client a observ\u00e9 certaines valeurs, il ne peut pas voir les valeurs qui \u00e9taient dans le pass\u00e9. Il commence d\u00e9j\u00e0 \u00e0 voir des lectures pr\u00e9fix\u00e9es. Tout cela se r\u00e9sume \u00e0 la m\u00eame chose.<br \/>\nLes Causals en tant que mod\u00e8le de consistance repr\u00e9sentent un ordonnancement partiel des \u00e9v\u00e9nements sur le serveur, o\u00f9 les \u00e9v\u00e9nements de tous les clients sont observ\u00e9s dans le m\u00eame ordre. Dans ce cas, ce sont Leonard et Penny.<\/p>\n<h3>Eventual<\/h3>\n<p>\nLe troisi\u00e8me mod\u00e8le est la Consistance Eventuelle. C'est ce que tous les syst\u00e8mes distribu\u00e9s supportent, le mod\u00e8le minimum qui a un sens. Cela signifie que lorsque nous avons des modifications dans les donn\u00e9es, elles deviennent coh\u00e9rentes \u00e0 un certain moment.<\/p>\n<p>\u00c0 ce moment-l\u00e0, cela n'indique rien, sinon cela deviendrait une Consistance Externe \u2013 ce serait une tout autre histoire. Pourtant, c'est un mod\u00e8le tr\u00e8s populaire, le plus r\u00e9pandu. Par d\u00e9faut, tous les utilisateurs de syst\u00e8mes distribu\u00e9s utilisent la Consistance Eventuelle.<\/p>\n<p>Je veux donner quelques exemples comparatifs :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/c23e59b30d96de6ec456aaa76c67ad61.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nQue signifient ces fl\u00e8ches ?<\/p>\n<ul>\n<li><b>Latence.<\/b> Avec l'augmentation de la force de consistance, elle devient plus grande pour des raisons \u00e9videntes : il faut effectuer plus d'\u00e9critures, recevoir la confirmation de tous les h\u00f4tes et n\u0153uds impliqu\u00e9s dans le cluster que les donn\u00e9es y sont d\u00e9j\u00e0. Par cons\u00e9quent, dans la Consistance Eventuelle, la r\u00e9ponse est la plus rapide, car g\u00e9n\u00e9ralement, il est m\u00eame possible de faire un commit en m\u00e9moire et cela devrait \u00eatre suffisamment.<\/li>\n<li><b>Disponibilit\u00e9.<\/b> Si l'on comprend cela comme la capacit\u00e9 du syst\u00e8me \u00e0 r\u00e9pondre en cas de coupures r\u00e9seau, de partitions, ou de pannes \u2013 la tol\u00e9rance aux pannes augmente avec la r\u00e9duction du mod\u00e8le de consistance, car il suffit qu'un h\u00f4te soit actif et qu'il fournisse certaines donn\u00e9es. La Consistance Eventuelle ne garantit absolument rien concernant les donn\u00e9es \u2013 cela peut \u00eatre n'importe quoi.<\/li>\n<li><b>Anomalies.<\/b> Cependant, cela entra\u00eene bien s\u00fbr une augmentation du nombre d'anomalies. Avec la Consistance Forte, elles ne devraient pratiquement pas exister, alors qu'avec la Consistance \u00c9ventuelle, elles peuvent \u00eatre de toutes sortes. La question se pose : pourquoi les gens choisissent-ils la Consistance \u00c9ventuelle, si elle contient des anomalies ? La r\u00e9ponse est que les mod\u00e8les de Consistance \u00c9ventuelle sont applicables, et que les anomalies existent, par exemple, sur de courtes p\u00e9riodes ; il est possible d'utiliser un master pour lire et obtenir des donn\u00e9es relativement coh\u00e9rentes ; il y a souvent la possibilit\u00e9 d'utiliser des mod\u00e8les de consistance forte. En pratique, cela fonctionne, et souvent le nombre d'anomalies est limit\u00e9 dans le temps.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Th\u00e9or\u00e8me CAP<\/h3>\n<p>\nQuand vous entendez les mots consistance, disponibilit\u00e9 \u2013 qu'est-ce qui vous vient \u00e0 l'esprit ? Exactement \u2013 le th\u00e9or\u00e8me CAP ! Je veux maintenant dissiper un mythe... Ce n'est pas moi \u2013 c'est Martin Kleppmann, qui a \u00e9crit un excellent article, un excellent livre.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/02a9b84585218c4e85afd65f7e88aa26.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLe th\u00e9or\u00e8me CAP est un principe formul\u00e9 dans les ann\u00e9es 2000, qui traite de la Consistance, de la Disponibilit\u00e9, des Partitions : prenez-en deux, vous ne pouvez pas choisir les trois. C'\u00e9tait un certain principe. Il a \u00e9t\u00e9 prouv\u00e9 comme th\u00e9or\u00e8me quelques ann\u00e9es plus tard, cela a \u00e9t\u00e9 fait par Gilbert et Lynch. Ensuite, cela a \u00e9t\u00e9 utilis\u00e9 comme un mantra \u2013 les syst\u00e8mes ont \u00e9t\u00e9 class\u00e9s en CA, CP, AP, etc.<\/p>\n<p>Ce th\u00e9or\u00e8me a \u00e9t\u00e9 prouv\u00e9 pour les cas suivants\u2026 Premi\u00e8rement, la Disponibilit\u00e9 n'\u00e9tait pas consid\u00e9r\u00e9e comme une valeur continue allant de z\u00e9ro \u00e0 cent (0 \u2013 syst\u00e8me \u00ab mort \u00bb, 100 \u2013 r\u00e9pond rapidement ; c'est ainsi que nous avons l'habitude de le consid\u00e9rer), mais comme une propri\u00e9t\u00e9 de l'algorithme qui garantit que, lors de toutes ses ex\u00e9cutions, il retourne des donn\u00e9es.<\/p>\n<p>Il n'est absolument pas question de temps de r\u00e9ponse ici ! Il existe un algorithme qui retourne des donn\u00e9es dans 100 ans \u2013 un algorithme disponible tout \u00e0 fait remarquable, qui fait partie du th\u00e9or\u00e8me CAP.<br \/>\nDeuxi\u00e8mement : le th\u00e9or\u00e8me a \u00e9t\u00e9 prouv\u00e9 pour des modifications des valeurs d'une m\u00eame cl\u00e9, alors que ces modifications sont de type resizeable. Cela signifie qu'ils ne sont pratiquement pas utilis\u00e9s, car les mod\u00e8les de Consistance \u00c9ventuelle, de Consistance Forte (peut-\u00eatre) diff\u00e8rent.<\/p>\n<p>\u00c0 quoi cela sert-il ? Au fait que le th\u00e9or\u00e8me CAP, dans la forme dans laquelle il a \u00e9t\u00e9 prouv\u00e9, est pratiquement inapplicable, rarement utilis\u00e9. Dans sa forme th\u00e9orique, il limite d'une certaine mani\u00e8re tout. Cela donne un principe qui est intuitivement vrai, mais qui n'est pas vraiment prouv\u00e9.<\/p>\n<h3>La consistance causale est le mod\u00e8le le plus fort<\/h3>\n<p>\nCe qui se passe actuellement permet d'obtenir les trois \u00e9l\u00e9ments suivants : la coh\u00e9rence, la disponibilit\u00e9, que l'on peut r\u00e9aliser avec les partitions. En particulier, la coh\u00e9rence causale est le mod\u00e8le de coh\u00e9rence le plus puissant, qui fonctionne m\u00eame en pr\u00e9sence de partitions (coupures dans le r\u00e9seau). C'est pourquoi elle suscite un si grand int\u00e9r\u00eat, et c'est pourquoi nous nous y engageons.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/c4320294320261858a6d22faa97b9e23.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nElle simplifie, tout d'abord, le travail des d\u00e9veloppeurs d'applications. En particulier, la pr\u00e9sence d'un large soutien c\u00f4t\u00e9 serveur : lorsque toutes les op\u00e9rations qui se produisent pour un m\u00eame client arrivent de mani\u00e8re garantie dans la m\u00eame s\u00e9quence sur un autre client. Deuxi\u00e8mement, elle r\u00e9siste aux partitions.<\/p>\n<h3>La cuisine interne de MongoDB<\/h3>\n<p>\nEn gardant \u00e0 l'esprit que c'est l'heure du d\u00e9jeuner, nous nous dirigeons vers la cuisine. Je vais vous parler du mod\u00e8le syst\u00e8me, en particulier de ce qu'est MongoDB pour ceux qui entendent parler de cette base de donn\u00e9es pour la premi\u00e8re fois.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/a1784442ff1c44403b5347f4f43a1197.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/a1f9bcb4daebb43e4fc848a5f5f07c60.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMongoDB (ci-apr\u00e8s 'MongoDB') est un syst\u00e8me distribu\u00e9 qui prend en charge le scalabilit\u00e9 horizontale, c'est-\u00e0-dire le sharding ; et \u00e0 l'int\u00e9rieur de chaque shard, il prend \u00e9galement en charge la redondance des donn\u00e9es, c'est-\u00e0-dire la r\u00e9plication.<\/p>\n<p>Le sharding dans MongoDB (une base de donn\u00e9es non relationnelle) effectue un \u00e9quilibrage automatique, c'est-\u00e0-dire que chaque collection de documents (ou 'table' en termes de donn\u00e9es relationnelles) est divis\u00e9e en morceaux, et le serveur les d\u00e9place automatiquement entre les shards.<\/p>\n<p>Le routeur de requ\u00eates, qui r\u00e9partit les demandes, est pour le client un certain client \u00e0 travers lequel il travaille. Il sait d\u00e9j\u00e0 o\u00f9 se trouvent les donn\u00e9es et quelles sont ces donn\u00e9es, et dirige toutes les requ\u00eates vers le bon shard.<\/p>\n<p>Un autre point important : MongoDB est un unique master. Il y a un Primary - il peut prendre des enregistrements soutenant les cl\u00e9s qu'il contient. Il est impossible d'effectuer une \u00e9criture multi-master.<\/p>\n<p>Nous avons sorti la version 4.2 - elle a introduit de nouvelles choses int\u00e9ressantes. En particulier, nous avons int\u00e9gr\u00e9 Lucene - la recherche - c'est-\u00e0-dire Java ex\u00e9cutable directement dans 'Mongo', et il est d\u00e9sormais possible d'effectuer des recherches avec Lucene, tout comme dans 'Elasticsearch'.<\/p>\n<p>Et nous avons d\u00e9velopp\u00e9 un nouveau produit - Charts, qui est \u00e9galement disponible sur 'Atlas' (le Cloud propre \u00e0 Mongo). Ils ont une option Free Tier - vous pouvez jouer avec \u00e7a. J'ai beaucoup aim\u00e9 Charts - la visualisation des donn\u00e9es est tr\u00e8s intuitive.<\/p>\n<h3>Les ingr\u00e9dients de la coh\u00e9rence causale<\/h3>\n<p>\nJ'ai compt\u00e9 environ 230 articles publi\u00e9s sur ce sujet - de Leslie Lamport. Maintenant, de ma m\u00e9moire, je vais vous transmettre certaines parties de ces documents.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/e88b34b7a724e94837b944a4ddd21a04.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTout a commenc\u00e9 avec un article de Leslie Lampert, \u00e9crit dans les ann\u00e9es 1970. Comme vous pouvez le voir, des recherches dans ce domaine se poursuivent encore aujourd'hui. Actuellement, la coh\u00e9rence causale suscite de l'int\u00e9r\u00eat en raison de l'\u00e9volution des syst\u00e8mes distribu\u00e9s.<\/p>\n<h3>Restrictions<\/h3>\n<p>\nQuelles sont les limitations ? C'est en r\u00e9alit\u00e9 l'un des principaux points, car les contraintes impos\u00e9es par les syst\u00e8mes de production diff\u00e8rent fortement de celles qui existent dans les articles acad\u00e9miques. Souvent, elles sont assez artificielles.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/9583ba9ff870e4ddc7aad4ba4c59ecc1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Tout d'abord, \u00ab MongoDB \u00bb est un ma\u00eetre unique, comme je l'ai d\u00e9j\u00e0 mentionn\u00e9 (ce qui simplifie beaucoup les choses).<\/li>\n<li>Nous estimons que le syst\u00e8me devrait supporter environ 10 000 shards. Nous ne pouvons pas prendre des d\u00e9cisions architecturales qui limiteraient clairement cette valeur.<\/li>\n<li>Nous avons un cloud, mais nous supposons que l'utilisateur doit avoir la possibilit\u00e9, lorsqu'il t\u00e9l\u00e9charge un binaire, de l'ex\u00e9cuter sur son ordinateur portable, et que tout fonctionne parfaitement.<\/li>\n<li>Nous pensons que dans la recherche, il est rarement utilis\u00e9 : les clients externes peuvent faire ce qu'ils veulent. \u00ab MongoDB \u00bb est open source. Par cons\u00e9quent, les clients peuvent \u00eatre intelligents, malveillants \u2013 ils peuvent vouloir tout casser. Nous supposons que des \u00e9checs byzantins peuvent se produire.<\/li>\n<li>Pour les clients externes, qui se trouvent en dehors du p\u00e9rim\u00e8tre \u2013 une limitation importante : si cette fonctionnalit\u00e9 est d\u00e9sactiv\u00e9e, il ne devrait y avoir aucune d\u00e9gradation des performances.<\/li>\n<li>Un autre point \u2013 totalement anti-acad\u00e9mique : la compatibilit\u00e9 des versions pr\u00e9c\u00e9dentes et futures. Les anciens pilotes doivent prendre en charge les nouvelles mises \u00e0 jour, et la base de donn\u00e9es doit supporter les anciens pilotes.<\/li>\n<\/ul>\n<p>\nEn g\u00e9n\u00e9ral, tout cela impose des contraintes.<\/p>\n<h3>Composants de la coh\u00e9rence causale<\/h3>\n<p>\nJe vais maintenant parler de certains composants. En consid\u00e9rant la coh\u00e9rence causale, on peut distinguer des blocs. Nous avons s\u00e9lectionn\u00e9 dans des travaux qui se rapportent \u00e0 un certain bloc : le suivi des d\u00e9pendances, le choix des horloges, comment ces horloges peuvent \u00eatre synchronis\u00e9es entre elles, et comment nous assurons la s\u00e9curit\u00e9 \u2013 voici un plan approximatif de ce que je vais aborder :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/10c2631d6e61a280139b448628db763e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Suivi complet des d\u00e9pendances (Full Dependency Tracking)<\/h3>\n<p>\nPourquoi est-ce n\u00e9cessaire ? Pour que, lorsque les donn\u00e9es sont r\u00e9pliqu\u00e9es, chaque enregistrement, chaque modification des donn\u00e9es contienne des informations sur les changements dont il d\u00e9pend. La premi\u00e8re et la plus na\u00efve des modifications est celle o\u00f9 chaque message contenant un enregistrement inclut des informations sur les messages pr\u00e9c\u00e9dents :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/fa5d0086c3c77e33631d8a2cd5c217fa.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDans cet exemple, le num\u00e9ro entre accolades repr\u00e9sente ces enregistrements. Parfois, ces enregistrements avec des valeurs sont m\u00eame transmis int\u00e9gralement, parfois certaines versions sont transmises. L'essentiel est que chaque changement contient des informations sur le pr\u00e9c\u00e9dent (il porte cela en lui).<\/p>\n<p>Pourquoi avons-nous d\u00e9cid\u00e9 de ne pas utiliser cette approche (le suivi complet) ? \u00c9videmment, parce que cette m\u00e9thode est peu pratique : chaque modification dans un r\u00e9seau social d\u00e9pend de toutes les modifications pr\u00e9c\u00e9dentes dans ce r\u00e9seau, impliquant par exemple 'Facebook' ou 'VKontakte' \u00e0 chaque mise \u00e0 jour. N\u00e9anmoins, il existe de nombreuses recherches sur le Full Dependency Tracking \u2013 ce sont des pr\u00e9-r\u00e9seaux sociaux, et pour certaines situations, cela fonctionne r\u00e9ellement.<\/p>\n<h3>Suivi explicite des d\u00e9pendances (Explicit Dependency Tracking)<\/h3>\n<p>\nLe suivant est plus limit\u00e9. Ici, l'information transmise est consid\u00e9r\u00e9e, mais seulement celle qui d\u00e9pend explicitement. Ce dont d\u00e9pend quoi est g\u00e9n\u00e9ralement d\u00e9fini par l'Application. Lorsque les donn\u00e9es sont r\u00e9pliqu\u00e9es, seules les r\u00e9ponses sont fournies lorsque les d\u00e9pendances pr\u00e9c\u00e9dentes ont \u00e9t\u00e9 satisfaites, c'est-\u00e0-dire montr\u00e9es. C'est l\u00e0 que r\u00e9side le principe du fonctionnement de la coh\u00e9rence causale.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/7fe101b998c1a0c922788d8d36a5243f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nElle voit que l'enregistrement 5 d\u00e9pend des enregistrements 1, 2, 3, 4 - en cons\u00e9quence, elle attend avant que le client ait acc\u00e8s aux modifications apport\u00e9es par la d\u00e9cision d'acc\u00e8s de Penny, lorsque tous les changements pr\u00e9c\u00e9dents ont d\u00e9j\u00e0 \u00e9t\u00e9 int\u00e9gr\u00e9s dans la base de donn\u00e9es.<\/p>\n<p>Cela ne nous convient pas non plus, car il y a encore trop d'informations, et cela va ralentir. Il existe une autre approche\u2026<\/p>\n<h3>Horloge de Lamport (Lamport Clock)<\/h3>\n<p>\nElles sont tr\u00e8s anciennes. L'Horloge de Lamport suppose que ces d\u00e9pendances se plient en une fonction scalaire, qui s'appelle Lamport Clock.<\/p>\n<p>Une fonction scalaire est un nombre abstrait. On parle souvent de temps logique. \u00c0 chaque \u00e9v\u00e9nement, ce compteur augmente. Le compteur, qui est actuellement connu du processus, envoie chaque message. Il est clair que les processus peuvent \u00eatre d\u00e9synchronis\u00e9s, et qu'ils peuvent avoir des temps compl\u00e8tement diff\u00e9rents. N\u00e9anmoins, ce type d'\u00e9change de messages permet au syst\u00e8me d'\u00e9quilibrer d'une mani\u00e8re ou d'une autre les horloges. Que se passe-t-il dans ce cas ?<\/p>\n<p>J'ai divis\u00e9 ce grand shard en deux pour clarifier : les Friends peuvent vivre dans un n\u0153ud qui contient une partie de la collection, tandis que le Feed peut se trouver dans un autre n\u0153ud, qui contient un autre morceau de cette collection. Comment peuvent-ils ne pas \u00eatre en file d'attente ? D'abord, le Feed dira : \u00ab R\u00e9pliqu\u00e9 \u00bb, puis ce sera au tour de Friends. Si le syst\u00e8me ne garantit pas que le Feed ne sera pas affich\u00e9 tant que les d\u00e9pendances de Friends dans la collection Friends ne seront pas \u00e9galement livr\u00e9es, alors nous nous retrouvons pr\u00e9cis\u00e9ment dans la situation que j'ai mentionn\u00e9e.<\/p>\n<p>Vous voyez comment le temps logique du compteur sur le Feed augmente :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/bae152d1890b53804f2cb28122983df6.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAinsi, la propri\u00e9t\u00e9 principale de cette horloge de Lamport et de la coh\u00e9rence causale (expliqu\u00e9e \u00e0 travers l'horloge de Lamport) est la suivante : si nous avons des \u00e9v\u00e9nements A et B, et que l'\u00e9v\u00e9nement B d\u00e9pend de l'\u00e9v\u00e9nement A *, alors il en d\u00e9coule que le LogicalTime de l'\u00e9v\u00e9nement A est inf\u00e9rieur au LogicalTime de l'\u00e9v\u00e9nement B.<\/p>\n<p><i>* Parfois on dit aussi que A est arriv\u00e9 avant B, c'est-\u00e0-dire A a eu lieu avant B \u2013 c'est une sorte de relation qui ordonne partiellement l'ensemble des \u00e9v\u00e9nements qui se sont r\u00e9ellement produits.<\/i><\/p>\n<p>Dans l'autre sens, ce n'est pas vrai. C'est en fait l'un des principaux inconv\u00e9nients de l'horloge de Lamport \u2013 l'ordre partiel. Il existe un concept d'\u00e9v\u00e9nements simultan\u00e9s, c'est-\u00e0-dire d'\u00e9v\u00e9nements o\u00f9 ni (A est arriv\u00e9 avant B), ni (B est arriv\u00e9 avant A). Un exemple pourrait \u00eatre l'ajout parall\u00e8le de Leonard en tant qu'ami de quelqu'un d'autre (m\u00eame pas Leonard, mais Sheldon, par exemple).<br \/>\nC'est la propri\u00e9t\u00e9 qu'on utilise souvent lors du travail avec les horloges de Lamport : on regarde pr\u00e9cis\u00e9ment la fonction et on en d\u00e9duit \u2013 peut-\u00eatre que ces \u00e9v\u00e9nements sont d\u00e9pendants. Car dans un sens c'est vrai : si le LogicalTime A est inf\u00e9rieur au LogicalTime B, alors B ne peut pas \u00eatre arriv\u00e9 avant A ; et si c'est plus, alors cela peut \u00eatre le cas.<\/p>\n<h3>Horloges vectorielles (Vector Clock)<\/h3>\n<p>\nLe d\u00e9veloppement logique des horloges de Lamport est l'horloge vectorielle. Elles se distinguent par le fait que chaque n\u0153ud, pr\u00e9sent ici, contient ses propres horloges distinctes, et celles-ci sont transmises sous forme de vecteur.<br \/>\nDans ce cas, vous voyez que l'index z\u00e9ro du vecteur correspond \u00e0 Feed, et le premier index du vecteur correspond \u00e0 Friends (chacun de ces n\u0153uds). Et maintenant, ils vont commencer \u00e0 augmenter : l'index z\u00e9ro de \u00ab Feed \u00bb augmente lorsque l'on \u00e9crit - 1, 2, 3 :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/d89292686ed8dd41aef06090f16db1c0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPourquoi les horloges vectorielles sont-elles meilleures ? Parce qu'elles permettent de comprendre quels \u00e9v\u00e9nements sont simultan\u00e9s et quand ils se produisent sur diff\u00e9rents n\u0153uds. C'est tr\u00e8s important pour un syst\u00e8me de shard comme \u00ab MongoDB \u00bb. Cependant, nous ne l'avons pas choisi, bien que ce soit une tr\u00e8s bonne chose, et cela fonctionne exceptionnellement bien, et cela nous aurait probablement convenu\u2026<\/p>\n<p>Si nous avons 10 000 shards, nous ne pouvons pas transmettre 10 000 composants, m\u00eame si nous les compressons ou trouvons d'autres solutions - le payload sera toujours de plusieurs ordres de grandeur inf\u00e9rieur au volume total de ce vecteur. Par cons\u00e9quent, \u00e0 contrec\u0153ur, nous avons abandonn\u00e9 cette approche et sommes pass\u00e9s \u00e0 une autre.<\/p>\n<h3>Spanner TrueTime. Horloges atomiques<\/h3>\n<p>\nJ'ai dit qu'il y aurait un expos\u00e9 sur \u00ab Spanner \u00bb. C'est une chose g\u00e9niale, vraiment du XXIe si\u00e8cle : horloges atomiques, synchronisation GPS.<\/p>\n<p>Quelle est l'id\u00e9e ? \u00ab Spanner \u00bb est le syst\u00e8me de Google qui est r\u00e9cemment devenu accessible au public (ils lui ont ajout\u00e9 SQL). Chaque transaction a un certain timestamp. Comme le temps est synchronis\u00e9*, chaque \u00e9v\u00e9nement peut se voir attribuer un certain temps - les horloges atomiques ont un temps d'attente, apr\u00e8s lequel un autre temps se produit d\u00e9j\u00e0.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/707b5998fbb500d201aafffccc666f0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAinsi, en enregistrant simplement dans la base de donn\u00e9es et en attendant une certaine p\u00e9riode, la s\u00e9rialisation des \u00e9v\u00e9nements est automatiquement garantie. Ils ont le mod\u00e8le de consistance le plus robuste que l'on puisse imaginer - il s'agit de Consistance Externe.<\/p>\n<p>* C'est le principal probl\u00e8me des horloges de Lamport - elles ne sont jamais synchronis\u00e9es dans des syst\u00e8mes distribu\u00e9s. Elles peuvent diverger, m\u00eame avec NTP, elles ne fonctionnent toujours pas tr\u00e8s bien. \u00ab Spanner \u00bb poss\u00e8de des horloges atomiques et une synchronisation, semble-t-il, jusqu'\u00e0 la microseconde.<\/p>\n<p>Pourquoi ne l'avons-nous pas choisi ? Nous ne supposons pas que nos utilisateurs aient d'horloges atomiques int\u00e9gr\u00e9es. Quand elles seront int\u00e9gr\u00e9es \u00e0 chaque ordinateur portable, avec une super synchronisation GPS - alors oui\u2026 Mais pour l'instant, le meilleur que nous pouvons faire - ce sont les \u00ab Amazon \u00bb, Stations de base - pour les passionn\u00e9s\u2026 C'est pourquoi nous avons utilis\u00e9 d'autres horloges.<\/p>\n<h3>Horloges hybrides (Hybrid Clock)<\/h3>\n<p>\nC'est en fait ce qui fonctionne dans \u00abMongoDB\u00bb pour assurer la coh\u00e9rence causale. En quoi sont-ils hybrides ? Un hybride est une valeur scalaire, mais elle se compose de deux composants :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/dab03a87d9f6ee2e716f75baff1736bc.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<ul>\n<li>Le premier est l'\u00e9poque Unix (le nombre de secondes \u00e9coul\u00e9es depuis le \u00abd\u00e9but du monde informatique\u00bb).<\/li>\n<li>Le second est un certain incr\u00e9ment, \u00e9galement un entier non sign\u00e9 de 32 bits.<\/li>\n<\/ul>\n<p>\nVoil\u00e0, c'est tout. Il existe une approche : la partie qui g\u00e8re le temps se synchronise en permanence avec l'horloge ; chaque fois qu'une mise \u00e0 jour se produit, cette partie est synchronis\u00e9e avec l'horloge, et il en r\u00e9sulte que le temps est toujours relativement correct, alors que l'incr\u00e9ment permet de distinguer les \u00e9v\u00e9nements survenus au m\u00eame moment.<\/p>\n<p>Pourquoi est-ce important pour \u00abMongoDB\u00bb ? Parce que cela permet de faire des backups-restaurations \u00e0 un moment donn\u00e9, c'est-\u00e0-dire que l'\u00e9v\u00e9nement est index\u00e9 par le temps. C'est crucial lorsque certains \u00e9v\u00e9nements sont n\u00e9cessaires ; pour les bases de donn\u00e9es, les \u00e9v\u00e9nements sont des modifications dans la base de donn\u00e9es qui se sont produites \u00e0 des moments pr\u00e9cis.<\/p>\n<p>Je ne vais vous dire que la principale raison (s'il vous pla\u00eet, ne le dites \u00e0 personne) ! Nous l'avons fait parce que c'est ainsi que les donn\u00e9es ordonn\u00e9es et index\u00e9es apparaissent dans le MongoDB OpLog. L'OpLog est une structure de donn\u00e9es qui contient toutes les modifications dans la base : elles d'abord entrent dans l'OpLog, puis sont appliqu\u00e9es au stockage lorsque les donn\u00e9es sont r\u00e9pliqu\u00e9es ou shard\u00e9es.<\/p>\n<p>C'\u00e9tait la raison principale. N\u00e9anmoins, il existe \u00e9galement des exigences pratiques pour le d\u00e9veloppement de la base, ce qui signifie que cela doit \u00eatre simple - peu de code, le moins de choses cass\u00e9es \u00e0 r\u00e9\u00e9crire et \u00e0 tester. Le fait que nos oplogs ont \u00e9t\u00e9 index\u00e9s avec des horloges hybrides a beaucoup aid\u00e9 et a permis de faire le bon choix. Cela a vraiment port\u00e9 ses fruits et a fonctionn\u00e9 de mani\u00e8re presque magique, d\u00e8s le premier prototype. C'\u00e9tait vraiment g\u00e9nial !<\/p>\n<h3>Synchronisation des horloges<\/h3>\n<p>\nIl existe plusieurs m\u00e9thodes de synchronisation d\u00e9crites dans la litt\u00e9rature scientifique. Je parle de synchronisation lorsque nous avons deux shards diff\u00e9rents. Si nous avons un replica set, alors aucune synchronisation n'est n\u00e9cessaire : c'est un \u00ab single-master \u00bb ; nous avons un OpLog dans lequel toutes les modifications sont enregistr\u00e9es - dans ce cas, tout est d\u00e9j\u00e0 ordonn\u00e9 s\u00e9quentiellement dans l' \u00ab OpLog \u00bb. Mais s'il y a deux shards diff\u00e9rents, ici la synchronisation du temps devient importante. C'est l\u00e0 que les horloges vectorielles aident davantage ! Mais nous ne les avons pas.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/7d3306747490ac044b7f8130defea0c9.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLe deuxi\u00e8me moyen est les \u00ab Heartbeats \u00bb. Nous pouvons \u00e9changer certains signaux qui se produisent \u00e0 chaque unit\u00e9 de temps. Mais les \u00ab Heartbeats \u00bb sont trop lents, nous ne pouvons pas garantir la latence \u00e0 notre client.<\/p>\n<p>Le temps v\u00e9ritable \u2013 c'est \u00e9videmment une belle chose. Mais, encore une fois, c'est probablement l'avenir\u2026 Bien que dans \u00ab Atlas \u00bb il est d\u00e9j\u00e0 possible de le faire, il existe d\u00e9j\u00e0 des synchroniseurs de temps rapides \u00ab \u00e0 la mode d'Amazon \u00bb. Mais cela ne sera pas accessible \u00e0 tout le monde.<\/p>\n<p>Le Gossiping \u2013 c'est lorsque tous les messages incluent le temps. C'est \u00e0 peu pr\u00e8s ce que nous utilisons. Chaque message entre les n\u0153uds, le pilote, le routeur de n\u0153uds de donn\u00e9es, absolument tout pour \u00ab MongoDB \u00bb \u2013 ce sont des \u00e9l\u00e9ments, des composants de la base de donn\u00e9es qui contiennent des horloges qui coulent. Ils ont tous une valeur de temps hybride, elle est transmise. 64 bits ? Cela permet, c'est possible.<\/p>\n<h3>Comment tout cela fonctionne-t-il ensemble ?<\/h3>\n<p>\nIci, j'examine un replica set pour que ce soit un peu plus simple. Il y a un Primary et un Secondary. Le Secondary effectue la r\u00e9plication et n'est pas toujours compl\u00e8tement synchronis\u00e9 avec le Primary.<\/p>\n<p>Une insertion (insert) est effectu\u00e9e dans le \u00ab Primary \u00bb avec une certaine valeur de temps. Cette insertion augmente le compteur interne de 11, si c'est le maximum. Sinon, il v\u00e9rifiera les valeurs de l'horloge et se synchronisera si les valeurs de l'horloge sont plus \u00e9lev\u00e9es. Cela permet d'ordonner par temps.<\/p>\n<p>Apr\u00e8s qu'il ait effectu\u00e9 l'\u00e9criture, un moment important se produit. Les horloges dans \u00ab MongoDB \u00bb s'incr\u00e9mentent uniquement lors d'une \u00e9criture dans l'\u00ab OpLog \u00bb. C'est cela qui constitue un \u00e9v\u00e9nement qui change l'\u00e9tat du syst\u00e8me. Absolument dans tous les articles classiques, un \u00e9v\u00e9nement est consid\u00e9r\u00e9 comme l'arriv\u00e9e d'un message dans un n\u0153ud : un message est arriv\u00e9 \u2013 cela signifie que le syst\u00e8me a chang\u00e9 son \u00e9tat.<\/p>\n<p>Cela est d\u00fb \u00e0 la difficult\u00e9 d'interpr\u00e9ter comment ce message sera compris lors de l'exploration. Nous savons exactement que s'il n'est pas refl\u00e9t\u00e9 dans le \u00ab Oplog \u00bb, alors il ne sera pas interpr\u00e9t\u00e9 du tout, et le seul changement d'\u00e9tat du syst\u00e8me est l'enregistrement dans l'\u00ab Oplog \u00bb. Cela nous simplifie tout : le mod\u00e8le est simplifi\u00e9 et permet d'organiser les choses au sein d'un m\u00eame replica set, avec beaucoup d'autres avantages.<\/p>\n<p>La valeur qui a d\u00e9j\u00e0 \u00e9t\u00e9 enregistr\u00e9e dans l'\u00ab Oplog \u00bb est retourn\u00e9e \u2013 nous savons que cette valeur se trouve d\u00e9j\u00e0 dans l'\u00ab Oplog \u00bb, et son temps est 12. Maintenant, disons qu'une lecture commence \u00e0 partir d'un autre n\u0153ud (Secondary), et il transmet d\u00e9j\u00e0 afterClusterTime dans le message lui-m\u00eame. Il dit : \u00ab J'ai besoin de tout ce qui s'est pass\u00e9 au moins apr\u00e8s 12 ou \u00e0 12 heures \u00bb (voir illustration ci-dessus).<\/p>\n<p>C'est ce qu'on appelle Causal a consistent (CAT). Il existe un concept en th\u00e9orie qui d\u00e9signe une tranche de temps qui est coh\u00e9rente en soi. Dans ce cas, on peut dire que c'est l'\u00e9tat du syst\u00e8me observ\u00e9 au moment 12.<\/p>\n<p>Actuellement, il n'y a rien ici, car cela simule une situation o\u00f9 le Secondary doit r\u00e9pliquer des donn\u00e9es du Primary. Il attend\u2026 Et maintenant les donn\u00e9es sont arriv\u00e9es \u2013 elles retournent ces valeurs.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/54d9de3e2696c1e5d19f4da206be090b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nVoil\u00e0 comment tout cela fonctionne. \u00c0 peu pr\u00e8s.<\/p>\n<p>Que signifie \u00ab \u00e0 peu pr\u00e8s \u00bb ? Supposons qu'il y a une personne qui a lu et compris comment tout cela fonctionne. Elle a compris qu'\u00e0 chaque fois, un ClusterTime se produit, il met \u00e0 jour ses horloges logiques internes, et ensuite, le prochain enregistrement augmente de un. Cette fonction occupe 20 lignes. Supposons que cette personne transmet un nombre 64 bits maximum, moins un.<\/p>\n<p>Pourquoi \u00ab moins un \u00bb ? Parce que les horloges internes seront ins\u00e9r\u00e9es dans cette valeur (\u00e9videmment, c'est le plus grand possible et plus grand que le temps actuel), ensuite une \u00e9criture se produira dans l'\u00ab Oplog \u00bb, et les horloges seront incr\u00e9ment\u00e9es d'un autre \u2013 et ce sera d\u00e9j\u00e0 la valeur maximale (il n'y a que des unit\u00e9s l\u00e0-dedans, il n'y a pas d'autre place, unsaint int's).<\/p>\n<p>Il est \u00e9vident qu'apr\u00e8s cela, le syst\u00e8me devient compl\u00e8tement inaccessible pour quoi que ce soit. On ne peut que le d\u00e9charger, le nettoyer \u2013 c'est beaucoup de travail manuel. Disponibilit\u00e9 totale :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/634b25fe0ef1e0af39181cd59c7b522f.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn effet, si cela est r\u00e9pliqu\u00e9 ailleurs, cela fait s'effondrer tout le cluster. C'est une situation absolument inacceptable, que n'importe qui peut organiser tr\u00e8s rapidement et facilement ! C'est pourquoi nous consid\u00e9rons ce point comme l'un des plus importants. Comment le pr\u00e9venir ?<\/p>\n<h3>Notre m\u00e9thode consiste \u00e0 signer clusterTime<\/h3>\n<p>\nAinsi, cela est transmis dans le message (avant le texte en bleu). Mais nous avons \u00e9galement commenc\u00e9 \u00e0 g\u00e9n\u00e9rer une signature (texte en bleu) :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/c16e985f9610e01a61293e0d6dde459b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLa signature est g\u00e9n\u00e9r\u00e9e par une cl\u00e9, qui est stock\u00e9e dans la base de donn\u00e9es, \u00e0 l'int\u00e9rieur d'un p\u00e9rim\u00e8tre s\u00e9curis\u00e9 ; elle est g\u00e9n\u00e9r\u00e9e, mise \u00e0 jour (les utilisateurs ne voient rien de cela). Un hash est g\u00e9n\u00e9r\u00e9, et chaque message est sign\u00e9 \u00e0 sa cr\u00e9ation et valid\u00e9 \u00e0 sa r\u00e9ception.<br \/>\nLes gens se posent probablement la question : \u00ab Est-ce que cela ralentit tout \u00e7a ? \u00bb J'ai dit que cela devait fonctionner rapidement, surtout en l'absence de cette fonctionnalit\u00e9.<\/p>\n<p>Que signifie utiliser la coh\u00e9rence causale dans ce cas ? Cela consiste \u00e0 afficher le param\u00e8tre afterClusterTime. Sinon, il transmettra simplement les valeurs quoi qu'il arrive. Le Gossiping, \u00e0 partir de la version 3.6, fonctionne toujours.<\/p>\n<p>Si nous maintenons une g\u00e9n\u00e9ration constante de signatures, cela ralentira le syst\u00e8me m\u00eame en l'absence de cette fonctionnalit\u00e9, ce qui ne correspond pas \u00e0 nos approches et exigences. Et que avons-nous fait ?<\/p>\n<h3>Fais-le rapidement !<\/h3>\n<p>\nC'est une chose assez simple, mais le truc est int\u00e9ressant - je vais partager, peut-\u00eatre que cela int\u00e9ressera quelqu'un.<br \/>\nNous avons un hash dans lequel sont stock\u00e9es les donn\u00e9es sign\u00e9es. Toutes les donn\u00e9es passent par un cache. Le cache ne signe pas un temps sp\u00e9cifique, mais un Range. Lorsqu'une certaine valeur arrive, nous g\u00e9n\u00e9rons un Range, masquons les 16 derniers bits, et cette valeur est sign\u00e9e :<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/f4810456f08ba1cc69730ac0079d4206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nEn obtenant une telle signature, nous acc\u00e9l\u00e9rons le syst\u00e8me (en condition) de 65 000 fois. Cela fonctionne tr\u00e8s bien : lorsque nous avons r\u00e9alis\u00e9 des exp\u00e9riences - le temps s'est r\u00e9ellement r\u00e9duit de 10 000 fois lors de nos mises \u00e0 jour successives. \u00c9videmment, cela ne fonctionne pas lorsque les mises \u00e0 jour sont d\u00e9synchronis\u00e9es. Mais dans la plupart des cas pratiques, cela fonctionne. La combinaison de la signature du Range avec la signature a permis de r\u00e9soudre le probl\u00e8me de s\u00e9curit\u00e9.<\/p>\n<h3>Qu'avons-nous appris ?<\/h3>\n<p>\nLes le\u00e7ons que nous en avons tir\u00e9es :<\/p>\n<ul>\n<li>Il est n\u00e9cessaire de lire des documents, des histoires, des articles, car nous avons beaucoup de choses int\u00e9ressantes \u00e0 partager. Lorsque nous travaillons sur une fonctionnalit\u00e9 (surtout maintenant, quand nous avons fait des transactions, etc.), il est important de lire et de comprendre. Cela prend du temps, mais c'est en r\u00e9alit\u00e9 tr\u00e8s utile, car cela nous permet de comprendre o\u00f9 nous en sommes. Nous n'avons pas vraiment invent\u00e9 quelque chose de nouveau \u2013 nous avons simplement pris des ingr\u00e9dients.\n<p>Il existe en effet une certaine diff\u00e9rence de pens\u00e9e lorsqu'une conf\u00e9rence acad\u00e9mique a lieu (comme celle de \u00ab Sigmon \u00bb, par exemple) \u2013 l\u00e0-bas, tout le monde se concentre sur de nouvelles id\u00e9es. Quelle est l'innovation de notre algorithme ? Il n'y a pas vraiment de nouveaut\u00e9 ici. L'innovation r\u00e9side plut\u00f4t dans la fa\u00e7on dont nous avons m\u00e9lang\u00e9 ensemble des approches existantes. Donc, la premi\u00e8re chose \u00e0 faire est de lire les classiques, en commen\u00e7ant par Lamport.<\/li>\n<li>En production, les exigences sont compl\u00e8tement diff\u00e9rentes. Je suis s\u00fbr que beaucoup d'entre vous ne rencontrent pas des bases de donn\u00e9es \u00ab sph\u00e9riques \u00bb dans un vide abstrait, mais des choses normales et r\u00e9elles, qui ont des probl\u00e8mes de disponibilit\u00e9, de latence et de tol\u00e9rance aux pannes.<\/li>\n<li>Enfin, nous avons d\u00fb examiner diff\u00e9rentes id\u00e9es et combiner plusieurs articles tr\u00e8s diff\u00e9rents en une seule approche. L'id\u00e9e de la signature, par exemple, vient d'un article qui examinait le protocole Paxos, qui s'applique aux failles non byzantines \u00e0 l'int\u00e9rieur du protocole d'autorisation, et pour les byzantines \u2013 en dehors du protocole d'autorisation\u2026 En gros, c'est exactement ce que nous avons fini par faire.\n<p>Il n'y a absolument rien de nouveau ici ! Mais une fois que nous avons tout m\u00e9lang\u00e9\u2026 C'est comme dire que la recette de la salade Olivier est une absurdit\u00e9, parce que les \u0153ufs, la mayonnaise et les cornichons existent d\u00e9j\u00e0\u2026 C'est \u00e0 peu pr\u00e8s la m\u00eame histoire.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/2f9e5cb77079f9a0f7bdf76430c3386e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nJe vais conclure ici. Merci !<\/p>\n<h3>Questions<\/h3>\n<p>\n<b>Question du public (Q) :<\/b> \u2013 Merci, Mikha\u00efl, pour votre pr\u00e9sentation ! Le sujet du temps est int\u00e9ressant. Vous utilisez le Gossiping. Vous avez dit que tout le monde a son propre temps, chacun conna\u00eet son temps local. J'ai compris qu'il existe un driver \u2013 il peut y avoir beaucoup de clients avec des drivers, il y a aussi beaucoup de query-planners et de shards\u2026 Que se passe-t-il dans le syst\u00e8me si une divergence appara\u00eet : quelqu'un d\u00e9cide qu'il est une minute en avance, quelqu'un d'autre \u2013 une minute en retard ? O\u00f9 nous retrouverons-nous ?<\/p>\n<p><b>MT :<\/b> \u2013 C'est en fait une excellente question ! Je voulais justement parler des shards. Si je comprends bien la question, nous avons la situation suivante : il y a le shard 1 et le shard 2, la lecture se fait \u00e0 partir de ces deux shards \u2013 ils ont des divergences, ils n'interagissent pas entre eux car le temps qu'ils connaissent est diff\u00e9rent, surtout le temps qu'ils ont dans les oplogs.<br \/>\nDisons que le shard 1 a fait un million d'enregistrements, le shard 2 \u2013 absolument rien, et une requ\u00eate est arriv\u00e9e aux deux shards. Et le premier a un afterClusterTime de plus d'un million. Dans cette situation, comme je l'ai expliqu\u00e9, le shard 2 ne r\u00e9pondra jamais.<\/p>\n<p><b>Q :<\/b> \u2013 Je voulais savoir comment ils se synchronisent et choisissent un temps logique unique ?<\/p>\n<p><b>MT :<\/b> \u2013 Ils se synchronisent tr\u00e8s simplement. Quand un shard re\u00e7oit un afterClusterTime et qu'il ne trouve pas le temps dans l'Oplog \u2013 il initie un no approved. C'est-\u00e0-dire qu'il \u00e9l\u00e8ve manuellement son temps \u00e0 cette valeur. Cela signifie qu'il n'a pas d'\u00e9v\u00e9nements r\u00e9pondant \u00e0 cette requ\u00eate. Il cr\u00e9e cet \u00e9v\u00e9nement artificiellement et devient ainsi Causal Consistent.<\/p>\n<p><b>Q :<\/b> \u2013 Et si apr\u00e8s cela, d'autres \u00e9v\u00e9nements arrivent, qui se seraient perdus dans le r\u00e9seau ?<\/p>\n<p><b>MT :<\/b> \u2013 Le shard est con\u00e7u de telle sorte qu'ils n'arriveront plus, car il s'agit d'un single master. S'il a d\u00e9j\u00e0 enregistr\u00e9, ils n'arriveront plus, mais cela sera apr\u00e8s. Il ne peut pas arriver que quelque chose soit bloqu\u00e9 quelque part, puis il fasse un no write, puis ces \u00e9v\u00e9nements arrivent \u2013 et que la Causal consistency soit viol\u00e9e. Quand il fait un no write, ils doivent tous arriver apr\u00e8s (il les attend).<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/dbbc7c5c653f0c9fa449cceb88ed62ef.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Q :<\/b> \u2013 J'ai plusieurs questions concernant les files d'attente. La Causal consistency suppose qu'il y a une certaine file d'actions \u00e0 effectuer. Que se passe-t-il si un paquet dispara\u00eet ? Par exemple, le 10\u00e8me, 11\u00e8me\u2026 Le 12\u00e8me a disparu, et tous les autres attendent qu'il soit ex\u00e9cut\u00e9. Et soudain, notre machine est tomb\u00e9e en panne, nous ne pouvons rien faire. Y a-t-il une longueur maximale de la file qui peut s'accumuler avant d'\u00eatre ex\u00e9cut\u00e9e ? Quelle d\u00e9faillance fatale se produit lors de la perte d'un seul \u00e9tat ? D'autant plus que si nous enregistrons qu'il y a un \u00e9tat pr\u00e9c\u00e9dent, nous devons nous y r\u00e9f\u00e9rer d'une certaine mani\u00e8re ? Mais nous n'avons pas pu nous y r\u00e9f\u00e9rer !<\/p>\n<p><b>MT :<\/b> \u2013 C'est aussi une excellente question ! Que faisons-nous ? Dans MongoDB, il y a le concept d'\u00e9critures de quorum, de lectures de quorum. Dans quels cas un message peut-il dispara\u00eetre ? Quand l'\u00e9criture n'est pas de quorum ou quand la lecture n'est pas de quorum (cela peut aussi introduire des d\u00e9chets).<br \/>\nConcernant la coh\u00e9rence causale, nous avons r\u00e9alis\u00e9 une vaste \u00e9valuation exp\u00e9rimentale dont le r\u00e9sultat montre que lorsque les \u00e9critures et les lectures sont non quorum, des violations de la coh\u00e9rence causale surviennent. Exactement ce que vous dites !<\/p>\n<p>Notre conseil : utiliser au moins une lecture de quorum lors de l'utilisation de la coh\u00e9rence causale. Dans ce cas, rien ne sera perdu, m\u00eame si l'\u00e9criture de quorum est perdue\u2026 C'est une situation orthogonale : si l'utilisateur ne veut pas que des donn\u00e9es soient perdues, il doit utiliser une \u00e9criture de quorum. La coh\u00e9rence causale ne garantit pas la durabilit\u00e9. La durabilit\u00e9 est garantie par la r\u00e9plication et le m\u00e9canisme associ\u00e9 \u00e0 la r\u00e9plication.<\/p>\n<p><b>Q :<\/b> \u2013 Quand nous cr\u00e9ons une instance qui ex\u00e9cute le sharding (pas le ma\u00eetre, mais l'esclave, respectivement), elle s'appuie sur l'heure UNIX de sa propre machine ou sur l'heure du 'ma\u00eetre' ; est-elle synchronis\u00e9e une premi\u00e8re fois ou p\u00e9riodiquement ?<\/p>\n<p><b>MT :<\/b> \u2013 Laissez-moi clarifier. Un shard (c'est-\u00e0-dire une partition horizontale) a toujours un primaire. Et dans un shard, il peut y avoir un 'ma\u00eetre' et des r\u00e9pliques. Mais le shard re\u00e7oit toujours des \u00e9critures, car il doit maintenir un certain domaine (un primaire est pr\u00e9sent dans le shard).<\/p>\n<p><b>Q :<\/b> \u2013 Donc tout d\u00e9pend strictement du 'ma\u00eetre' ? L'heure du 'ma\u00eetre' est toujours utilis\u00e9e ?<\/p>\n<p><b>MT :<\/b> \u2013 Oui. On peut dire de mani\u00e8re figur\u00e9e : les horloges tournent lorsque l'\u00e9criture se produit dans le 'ma\u00eetre', dans l'OpLog.<\/p>\n<p><b>Q :<\/b> \u2013 Nous avons un client qui se connecte, et il n'a pas besoin de rien savoir sur l'heure ?<\/p>\n<p><b>MT :<\/b> \u2013 Il n'a absolument besoin de rien savoir ! Si l'on parle de la fa\u00e7on dont cela fonctionne pour le client : quand le client souhaite utiliser la coh\u00e9rence causale, il doit ouvrir une session. Actuellement, tout est l\u00e0 : les transactions dans la session et les droits \u00e0 r\u00e9cup\u00e9rer\u2026 Une session est un ordre des \u00e9v\u00e9nements logiques se produisant avec le client.<\/p>\n<p>S'il ouvre cette session et indique qu'il souhaite la coh\u00e9rence causale (si par d\u00e9faut la session supporte la coh\u00e9rence causale), tout fonctionne automatiquement. Le pilote se rappelle de cette heure et l'augmente lorsqu'il re\u00e7oit un nouveau message. Il m\u00e9morise quelle r\u00e9ponse a \u00e9t\u00e9 retourn\u00e9e par le pr\u00e9c\u00e9dent serveur qui a renvoy\u00e9 des donn\u00e9es. La prochaine demande contiendra afterCluster ('temps sup\u00e9rieur \u00e0 cela').<\/p>\n<p>Le client n'a absolument rien \u00e0 savoir ! C'est totalement opaque pour lui. Si des personnes utilisent ces fonctionnalit\u00e9s, que permet-on de faire ? Tout d'abord, on peut lire en toute s\u00e9curit\u00e9 depuis des secundaires : on peut \u00e9crire sur le Primary et lire \u00e0 partir de secundaires g\u00e9ographiquement r\u00e9pliqu\u00e9s en s'assurant que cela fonctionne. De plus, les sessions enregistr\u00e9es sur le Primary peuvent m\u00eame \u00eatre transf\u00e9r\u00e9es sur le Secondary, c'est-\u00e0-dire qu'il est possible d'utiliser non pas une session, mais plusieurs.<\/p>\n<p><b>Q :<\/b> \u2013 Le th\u00e8me de la coh\u00e9rence \u00e9ventuelle est \u00e9troitement li\u00e9 \u00e0 une nouvelle branche de l'informatique \u2013 les types de donn\u00e9es CRDT (Conflict-free Replicated Data Types). Avez-vous envisag\u00e9 l'int\u00e9gration de ces types de donn\u00e9es dans votre base et que pouvez-vous en dire ?<\/p>\n<p><b>MT :<\/b> \u2013 Bonne question ! Les CRDT ont du sens pour les conflits d'\u00e9criture : dans MongoDB, il y a un ma\u00eetre unique.<\/p>\n<p><b>Q :<\/b> \u2013 J'ai une question de la part des devops. Dans le monde actuel, on rencontre des situations de type j\u00e9suite, o\u00f9 des \u00e9checs byzantins se produisent, et o\u00f9 de mauvaises personnes \u00e0 l'int\u00e9rieur du p\u00e9rim\u00e8tre prot\u00e9g\u00e9 commencent \u00e0 trifouiller le protocole, en envoyant des paquets sp\u00e9cialement con\u00e7us ?<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/99a521d04b416e6978aa68ce7c4a4c46.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>MT :<\/b> \u2013 De mauvaises personnes \u00e0 l'int\u00e9rieur du p\u00e9rim\u00e8tre, c'est comme un cheval de Troie ! Ces personnes peuvent faire beaucoup de mauvaises choses.<\/p>\n<p><b>Q :<\/b> \u2013 Il est \u00e9vident que laisser sur le serveur, pour le dire simplement, une petite ouverture par laquelle on peut faire passer un zoo d'\u00e9l\u00e9phants et faire s'effondrer tout le cluster pour toujours\u2026 Cela prendra du temps pour une restauration manuelle\u2026 C'est, pour le dire l\u00e9g\u00e8rement, incorrect. D'un autre c\u00f4t\u00e9, il est int\u00e9ressant de se demander : dans la vie r\u00e9elle, rencontre-t-on des situations o\u00f9 de telles attaques internes se produisent ?<\/p>\n<p><b>MT :<\/b> \u2013 \u00c9tant donn\u00e9 que je fais rarement face \u00e0 des violations de la s\u00e9curit\u00e9 dans la vie r\u00e9elle, je ne peux pas dire \u2013 peut-\u00eatre qu'elles se produisent. Mais si l'on parle de philosophie de d\u00e9veloppement, nous pensons ceci : nous avons un p\u00e9rim\u00e8tre qui s\u00e9curise les personnes en charge de la s\u00e9curit\u00e9 \u2013 c'est la serrure, le mur ; et \u00e0 l'int\u00e9rieur du p\u00e9rim\u00e8tre, on peut faire tout ce qu'on veut. \u00c9videmment, il y a des utilisateurs qui ont seulement la possibilit\u00e9 de consulter, et d'autres qui peuvent supprimer des r\u00e9pertoires.<\/p>\n<p>Selon les droits, les dommages que les utilisateurs peuvent causer peuvent \u00eatre ceux d'une souris ou d'un \u00e9l\u00e9phant. Il est clair qu'un utilisateur ayant des droits complets peut faire absolument ce qu'il veut. Un utilisateur avec des droits restreints peut causer beaucoup moins de d\u00e9g\u00e2ts. En particulier, il ne peut pas briser le syst\u00e8me.<\/p>\n<p><b>Q :<\/b> \u2013 Dans un p\u00e9rim\u00e8tre s\u00e9curis\u00e9, quelqu'un a r\u00e9ussi \u00e0 \u00e9tablir des protocoles inattendus pour le serveur, afin de l'attaquer, et si tout va bien, peut-\u00eatre m\u00eame tout le cluster... Est-ce que cela peut aller jusqu'\u00e0 \u00eatre si \"bien\" ?<\/p>\n<p><b>MT :<\/b> \u2013 Je n'ai jamais entendu parler de telles choses. Que l'on puisse mettre un serveur \u00e0 genoux de cette mani\u00e8re n'est un secret pour personne. \u00c0 l'int\u00e9rieur, en utilisant le protocole, en \u00e9tant un utilisateur authentifi\u00e9 qui peut \u00e9crire quelque chose dans le message... En r\u00e9alit\u00e9, ce n'est pas possible, car cela sera quand m\u00eame v\u00e9rifi\u00e9. Il est possible de d\u00e9sactiver cette authentification pour les utilisateurs qui ne le souhaitent pas \u2013 c'est alors leur probl\u00e8me ; en gros, ils ont eux-m\u00eames d\u00e9truit les murs et on peut y introduire un \u00e9l\u00e9phant qui \u00e9crasera tout... En fait, on peut se d\u00e9guiser en r\u00e9parateur, entrer et le retirer !<\/p>\n<p><b>Q :<\/b> \u2013 Merci pour la pr\u00e9sentation. Sergey (\"Yandex\"). Dans \"Mongo\", il y a une constante qui limite le nombre de membres votants dans le Replica Set, et cette constante est \u00e9gale \u00e0 7 (sept). Pourquoi est-ce une constante ? Pourquoi ce n'est pas un param\u00e8tre quelconque ?<\/p>\n<p><b>MT :<\/b> \u2013 Un Replica Set peut avoir jusqu'\u00e0 40 n\u0153uds. Il y a toujours une majorit\u00e9. Je ne sais pas quelle version...<\/p>\n<p><b>Q :<\/b> \u2013 Dans un Replica Set, il est possible de faire fonctionner des membres non votants, mais pour les votants, le maximum est de 7. Comment g\u00e9rer un arr\u00eat dans ce cas si notre Replica Set est r\u00e9parti sur 3 centres de donn\u00e9es ? Un centre de donn\u00e9es peut facilement \u00eatre mis hors service, et une autre machine peut \u00e9galement tomber.<\/p>\n<p><b>MT :<\/b> \u2013 Cela d\u00e9passe un peu le cadre de la pr\u00e9sentation. C'est une question g\u00e9n\u00e9rale. Je pourrais en parler plus tard.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Mikha\u00efl Tiouleniev (MongoDB) : La coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique\" src=\"\/wp-content\/uploads\/2020\/02\/161966c7e77704dc619674ff0302ff57.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<center><div class=\"youtube-placeholder\" data-id=\"UnAprFMX1d4\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/UnAprFMX1d4\/hqdefault.jpg\" alt=\"Lire la vid\u00e9o\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<h3>Un peu de publicit\u00e9 \ud83d\ude42<\/h3>\n<p>\nMerci de rester avec nous. Aimez-vous nos articles ? Voulez-vous voir plus de contenu int\u00e9ressant ? Soutenez-nous en passants une commande ou en nous recommandant \u00e0 des amis, <noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/cloudvps\/nl\">VPS cloud pour d\u00e9veloppeurs \u00e0 partir de 4,99 $<\/a><\/noindex>, <b>un \u00e9quivalent unique des serveurs d'entr\u00e9e de gamme, con\u00e7u pour vous :<\/b> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/347386\/\">Toute la v\u00e9rit\u00e9 sur le VPS (KVM) E5-2697 v3 (6 c\u0153urs) 10 Go DDR4 480 Go SSD 1 Gbps \u00e0 partir de 19 $ ou comment bien diviser un serveur ?<\/a><\/noindex> (options disponibles avec RAID1 et RAID10, jusqu'\u00e0 24 c\u0153urs et jusqu'\u00e0 40 Go DDR4).<\/p>\n<p><b>Dell R730xd deux fois moins cher dans le data center Equinix Tier IV \u00e0 Amsterdam ?<\/b> Uniquement chez nous <b><noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/serversnl\">2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64Go DDR4 4x960Go SSD 1Gbps 100 To \u00e0 partir de 199 $<\/a><\/noindex> aux Pays-Bas ! <b>Dell R420 \u2014 2x E5-2430 2.2GHz 6C 128Go DDR3 2x960Go SSD 1Gbps 100To \u2014 \u00e0 partir de 99 $ !<\/b><\/b> Lisez sur <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/329618\/\">Comment construire une infrastructure de classe entreprise avec des serveurs Dell R730xd E5-2650 v4 co\u00fbtant 9000 euros pour des clopinettes ?<\/a><\/noindex><br \/>\n<br \/>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ua-hosting\/blog\/487638\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435. HighLoad++ Siberia 2019. \u0417\u0430\u043b \u00ab\u041a\u0440\u0430\u0441\u043d\u043e\u044f\u0440\u0441\u043a\u00bb. 25 \u0438\u044e\u043d\u044f, 12:00. \u0422\u0435\u0437\u0438\u0441\u044b \u0438 \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f. \u0411\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0443\u044e\u0442 \u0441 \u0442\u0435\u043e\u0440\u0438\u0435\u0439, \u0433\u0434\u0435 \u043d\u0435 \u0443\u0447\u0442\u0435\u043d\u044b \u0432\u0430\u0436\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u0430\u0441\u043f\u0435\u043a\u0442\u044b. \u0412 \u044d\u0442\u043e\u043c \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u044b\u0431\u043e\u0440\u0430 \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432 \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-56365","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47HighLoad++, \u041c\u0438\u0445\u0430\u0438\u043b \u0422\u044e\u043b\u0435\u043d\u0435\u0432 (MongoDB): Causal consistency: \u043e\u0442 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-10T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:04:37+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47HighLoad++, Mikhail Tyulenev (MongoDB) : Coh\u00e9rence causale : de la th\u00e9orie \u00e0 la pratique | ProHoster","description":"La prochaine conf\u00e9rence HighLoad++ se tiendra les 6 et 7 avril 2020 \u00e0 Saint-P\u00e9tersbourg. D\u00e9tails et billets via le lien.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47HighLoad++, \u041c\u0438\u0445\u0430\u0438\u043b \u0422\u044e\u043b\u0435\u043d\u0435\u0432 (MongoDB): Causal consistency: \u043e\u0442 \u0442\u0435\u043e\u0440\u0438\u0438 \u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 | ProHoster","og:description":"\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u044f HighLoad++ \u043f\u0440\u043e\u0439\u0434\u0435\u0442 6 \u0438 7 \u0430\u043f\u0440\u0435\u043b\u044f 2020 \u0433\u043e\u0434\u0430 \u0432 \u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0438 \u0431\u0438\u043b\u0435\u0442\u044b \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/highload-mihail-tyulenev-mongodb-causal-consistency-ot-teorii-k-praktike","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-10T21:00:00+00:00","article:modified_time":"2020-02-18T11:04:37+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"56365","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:26:38","updated":"2022-09-29 16:36:31","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/56365","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=56365"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/56365\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=56365"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=56365"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=56365"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}