{"id":96515,"date":"2020-10-12T19:43:02","date_gmt":"2020-10-12T17:43:02","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019"},"modified":"2020-10-12T19:43:02","modified_gmt":"2020-10-12T17:43:02","slug":"odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019","status":"publish","type":"post","link":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019","title":{"rendered":"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/6c445191705a4c96939cd094bc457a53.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In het verslag zal Andrej Borodin uitleggen hoe ze de ervaring van het schalen van PgBouncer hebben toegepast bij het ontwerpen van de connection pooler. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/yandex\/odyssey\">Odyssey<\/a><\/noindex>, hoe ze het in productie hebben uitgerold. Daarnaast bespreken we welke functies we in nieuwe versies van de pooler zouden willen zien: het is voor ons belangrijk om niet alleen onze behoeften te vervullen, maar ook de gemeenschap van gebruikers te ontwikkelen. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/yandex\/odyssey\">Odyssee<\/a><\/noindex>.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Video:<\/p>\n<p>\n<center><div class=\"youtube-placeholder\" data-id=\"OUx40ABHFZY\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/OUx40ABHFZY\/hqdefault.jpg\" alt=\"Video afspelen\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/dd2ea50b72e3d9c4e795aecbf9afdd25.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hallo iedereen! Mijn naam is Andrej. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/0a2f1880005bec1f61b72fb23b555adc.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Bij Yandex ben ik betrokken bij de ontwikkeling van open source databases. Vandaag hebben we het onderwerp connection pooler. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/c18e7c937423d2514faa12e820e78e70.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Als je weet hoe je connection pooler in het Nederlands noemt, laat het me weten. Ik wil graag een goede technische term vinden die in de technische literatuur moet vestigen. <\/p>\n<p><\/p>\n<p>Het onderwerp is behoorlijk complex omdat veel databases een ingebouwde connection pooler hebben en je er zelfs niet over na hoeft te denken. Er zijn natuurlijk wel wat instellingen, maar het werkt niet zo in Postgres. Parallel aan deze sessie (op HighLoad++ 2019) geeft Nikolai Samokhvalov een presentatie over het afstemmen van queries in Postgres. En ik begrijp dat hier mensen zijn gekomen die hun queries al perfect hebben afgestemd, en dat zijn de mensen die te maken hebben met zeldzamere systeemproblemen, gerelateerd aan netwerken en resource-utilisatie. Sommige aspecten kunnen behoorlijk ingewikkeld zijn omdat de problemen niet altijd voor de hand liggen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/89c660dd530575e2938e6bf312b83e95.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In Yandex is er Postgres. In Yandex Cloud wonen veel van Yandex's diensten. En we hebben enkele petabytes aan gegevens die niet minder dan een miljoen verzoeken per seconde in Postgres genereren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/288bfa37b9dcd60acd22ba48f0ef8a39.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En we bieden een vrij standaard cluster voor alle diensten aan \u2013 dit is de primaire node van het cluster, samen met twee reguliere replica's (\u00e9\u00e9n synchronisch en \u00e9\u00e9n asynchronisch), back-ups, en het schalen van leesverzoeken op de replica. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/c249ca55bb387e25a5560324024cc523.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Elke node in het cluster is Postgres, waarop naast Postgres en systeemonitoring ook een connection pooler is ge\u00efnstalleerd. De connection pooler wordt gebruikt voor fencing en zijn primaire functie. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/0e29be55cc048007db21c80bbb08a9d4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wat is de primaire functie van een connection pooler? <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/e2fbbd440c2781573cb35deeef358f20.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In Postgres wordt een procesmodel gevolgd bij het werken met de database. Dit betekent dat \u00e9\u00e9n verbinding \u00e9\u00e9n proces is, \u00e9\u00e9n backend van Postgres. En in deze backend zijn er veel verschillende caches, die vrij kostbaar zijn om verschillend te maken voor verschillende verbindingen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/587498063b1af8fac4a845961c654bc2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Daarnaast bevat de Postgres-code een array die procArray wordt genoemd. Dit bevat de belangrijkste gegevens over netverbindingen. En bijna alle algoritmes voor het verwerken van procArray hebben een lineaire complexiteit, omdat ze door de hele array van netverbindingen gaan. Dit is een vrij snelle cyclus, maar met een groot aantal inkomende netverbindingen wordt het allemaal iets duurder. En wanneer alles iets duurder wordt, kan het uiteindelijk heel veel kosten voor een groot aantal netverbindingen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/b534a38d0bfae7a65fc4258155a50280.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Er zijn 3 mogelijke benaderingen:<\/p>\n<p><\/p>\n<ul>\n<li>Aan de applicatiekant. <\/li>\n<li>Aan de databasekant. <\/li>\n<li>En er tussenin, dat wil zeggen, allerlei combinaties. <\/li>\n<\/ul>\n<p><\/p>\n<p>Helaas is de ingebouwde pooler momenteel in ontwikkeling. Vrienden bij PostgreSQL Professional werken hier voornamelijk aan. Wanneer deze beschikbaar komt, is moeilijk te voorspellen. En feitelijk heeft de architect de keuze uit twee oplossingen. Dit is application-side pool en proxy pool. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/702527a09e9fc86dd39b7fd69dcf1fc9.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Application-side pool is de eenvoudigste manier. En bijna alle client-drivers bieden je de mogelijkheid: miljoenen van je verbindingen in de code voorstellen als enkele tientallen verbindingen naar de database. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/7b66b9e20d22f472ca5ac39f6b9e0ba4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Er ontstaat een probleem wanneer je op een bepaald moment de backend wilt schalen en deze op verschillende virtuele machines wilt uitrollen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/f216fd7a8c01c2b07891e2242c48b06a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vervolgens realiseer je je ook dat je meerdere beschikbaarheidszones en verschillende datacenters hebt. En de aanpak met client-side pooling leidt tot grote aantallen. Groot betekent ongeveer 10.000 verbindingen. Dat is de grens waarop het redelijk kan functioneren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/e5bc5f284fd8ff568bbe16c3895b7ac6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Als we het hebben over proxy poolers, zijn er twee poolers die veel kunnen. Het zijn niet alleen poolers. Ze zijn poolers + met een geweldige functionaliteit. Dit is <noindex><a rel=\"nofollow\" href=\"https:\/\/www.pgpool.net\/\">Pgpool<\/a><\/noindex> en <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/CrunchyData\/crunchy-proxy\">Crunchy-Proxy<\/a><\/noindex>. <\/p>\n<p><\/p>\n<p>Maar helaas is die extra functionaliteit niet voor iedereen nodig. En het leidt ertoe dat poolers alleen sessie-pooling ondersteunen, dat wil zeggen, \u00e9\u00e9n inkomende client, \u00e9\u00e9n uitgaande client naar de database. <\/p>\n<p><\/p>\n<p>Voor onze behoeften past dit niet goed, daarom gebruiken we PgBouncer, dat transaction pooling implementeert, dat wil zeggen, serververbindingen worden alleen voor de duur van de transactie toegewezen aan clientverbindingen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/e5fedbe14656d2ac2cde8d1878a950e2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En onder onze belasting is dat waar. <strong>Maar er zijn een paar problemen.<\/strong>.<img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/61fd36cadcd9948d624dafa711777307.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Problemen beginnen wanneer je een sessie wilt diagnosticeren, omdat al je inkomende verbindingen lokaal zijn. Ze komen allemaal van loopback en het wordt moeilijk om een sessie te traceren. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/36108c4956c410a1b1f286a88bc393d6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Natuurlijk kunt u application_name_add_host gebruiken. Dit is een manier aan de Bouncer-kant om een IP-adres aan application_name toe te voegen. Maar application_name wordt ingesteld via een extra verbinding. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/b4cec483aa776f48db7ad3966c3b78e4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In deze grafiek, waar de gele lijn de werkelijke verzoeken weergeeft en de blauwe lijn de verzoeken die de database bereiken. En dit verschil is precies de instelling van application_name, wat alleen nodig is voor tracering, maar helemaal niet gratis is. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/c02ea73a6f1a2a4cd6af6c621f321ab4.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Bovendien kunt u in Bouncer niet \u00e9\u00e9n pool beperken, dat wil zeggen het aantal verbindingen met de database voor een bepaalde gebruiker, voor een bepaalde database. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/3431a463e04106066e2799aead66f571.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Waar leidt dit toe? U hebt een zwaar belaste service, geschreven in C++, en ergens dichtbij een kleine service op Node, die vrij onschuldig met de database omgaat, maar zijn driver gaat totaal door het lint. Het opent 20.000 verbindingen, en de rest kan wachten. Uw code is zelfs normaal. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/d7fa321714dc017b017945dffcf79bc6.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>We hebben natuurlijk een kleine patch voor Bouncer geschreven, die deze instelling toevoegt, dat wil zeggen, het beperken van klanten tot een pool. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/d58884fc5ac0f90ff8442f126972157a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dit zou mogelijk zijn aan de Postgres-kant, dat wil zeggen, rollen in de database beperken tot een bepaald aantal verbindingen.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/8d6ff70db72964ed4eae5eaa47309931.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Maar dan verliest u de mogelijkheid om te begrijpen waarom er geen verbindingen met de server zijn. PgBouncer geeft geen verbindingsfout door, hij retourneert altijd dezelfde informatie. En u kunt niet begrijpen: misschien is uw wachtwoord veranderd, misschien is de database gewoon gecrasht, misschien is er iets mis. Maar er is geen diagnose. Als de sessie niet kan worden ingesteld, komt u er niet achter waarom dit niet kan worden gedaan. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/cb3048344a94f2953bf403485d28e69f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Op een bepaald moment kijkt u naar de grafieken van de applicatie en ziet u dat de applicatie niet werkt.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/e67c6680bb9a7f41242af9f9e4920916.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>U kijkt naar de top en ziet dat Bouncer single-threaded is. Dit is een keerpunt in het leven van de service. U realiseert zich dat u zich had voorbereid op de schaling van de database over anderhalf jaar, maar dat u de pooler moet schalen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/4c140c4ba6db19cb9939c1148638fb73.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>We zijn tot de conclusie gekomen dat we meer PgBouncer's nodig hebben. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/d369f572a66c16a8917e13393324a644.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/lwn.net\/Articles\/542629\/\">https:\/\/lwn.net\/Articles\/542629\/<\/a><\/noindex><\/p>\n<p><\/p>\n<p>We hebben Bouncer een beetje gepatcht. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/97755489a25ebfe38efd56ff897bd8fa.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En we hebben het zo gemaakt dat meerdere Bouncers kunnen worden opgestart met hergebruik van de TCP-poort. En de besturingssystemen herverdelen automatisch de binnenkomende TCP-verbindingen tussen hen in round-robin.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/ac30d3f067de2a8cd66ad2325c3a3b58.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dit is transparant voor klanten, dat wil zeggen, alles ziet eruit alsof u \u00e9\u00e9n Bouncer hebt, maar er is fragmentatie van idle-verbindingen tussen de actieve Bouncer's. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/53825f075db00b026c12013a610be456.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En op een gegeven moment merkt u misschien dat deze 3 Bouncers elk 100% van hun kern gebruiken. U heeft behoorlijk wat Bouncers nodig. Waarom? <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/66c17883a043e157cd7ceab2c2a4e326.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Omdat u TLS heeft. U heeft een versleutelde verbinding. En als u Postgres benchmarkt met en zonder TLS, zult u merken dat het aantal gevestigde verbindingen met bijna twee orden afneemt bij inschakeling van versleuteling, omdat de TLS handshake CPU-bronnen verbruikt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/6101121ebe136af16e5eb1a484c65d66.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En aan de top kunt u een behoorlijk aantal cryptografische functies zien die worden uitgevoerd tijdens de golf van binnenkomende verbindingen. Aangezien onze primaire database kan schakelen tussen beschikbaarheidszones, is een golf van binnenkomende verbindingen een vrij typische situatie. Dat wil zeggen, om de een of andere reden was de oude primaire database niet beschikbaar, en de hele belasting werd naar een ander datacenter gestuurd. Ze zullen allemaal tegelijk komen om zich met TLS voor te stellen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/c238ac2f511568590dc275e01c192c00.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En een groot aantal TLS handshakes kan niet meer met Bouncer begroeten, maar het kan hem verstikken. Vanwege de time-out kan de golf van binnenkomende verbindingen onophoudelijk worden. Als u opnieuw probeert naar de database zonder exponenti\u00eble backoff, zullen ze telkens weer in een coherente golf binnenkomen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/f42d0b210174d4d172254603ae6b834a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hier is een voorbeeld van 16 PgBouncers die 16 kernen op 100% belasten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/8d048d3774c09e5b6a3fb3c7bff62084.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>We zijn gekomen tot cascade PgBouncer. Dit is de beste configuratie die we kunnen bereiken met onze belasting op Bouncer. Externe Bouncers dienen voor de TCP handshake, terwijl interne Bouncers dienen voor de werkelijke pooling, om externe verbindingen niet te veel te fragmenteren.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/3a4ee4ea46d5fe8479a5a7222ee134da.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In deze configuratie is een soepele herstart mogelijk. U kunt al deze 18 Bouncers \u00e9\u00e9n voor \u00e9\u00e9n herstarten. Maar het onderhouden van zulke configuraties is behoorlijk moeilijk. Systeembeheerders, DevOps en mensen die daadwerkelijk verantwoordelijk zijn voor deze server, zullen niet blij zijn met zo'n schema. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/5291fe67dbe02036f3ff8e98bdd84d1b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Het lijkt erop dat we al onze aanpassingen in open source kunnen doorvoeren, maar Bouncer wordt niet zo goed ondersteund. Bijvoorbeeld, de mogelijkheid om meerdere PgBouncers op \u00e9\u00e9n poort te draaien is een maand geleden gecommit. En de pull request voor deze functie was enkele jaren geleden. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/2059d7f49649d136249103db4aa3ec19.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/libpq-cancel.html\">https:\/\/www.postgresql.org\/docs\/current\/libpq-cancel.html<\/a><\/noindex><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pgbouncer\/pgbouncer\/pull\/79\">https:\/\/github.com\/pgbouncer\/pgbouncer\/pull\/79<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Of een ander voorbeeld. In Postgres kunt u een lopende query annuleren door een geheim naar een andere verbinding te sturen zonder extra authenticatie. Maar sommige clients sturen gewoon een TCP-reset, dat wil zeggen, ze verbreken de netwerkverbinding. Wat doet Bouncer dan? Hij doet niets. Hij blijft de query uitvoeren. Als u een enorme hoeveelheid verbindingen heeft die kleine queries naar de database sturen, is het gewoon niet voldoende om de verbinding met Bouncer te verbreken; u moet ook die queries be\u00ebindigen die in de database draaien. <\/p>\n<p><\/p>\n<p>Dit is gepatcht en dit probleem is nog steeds niet opgenomen in de upstream van Bouncer. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/a9695b6d9e640a5543dc73429eb0050b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En zo kwamen we tot de conclusie dat we onze eigen connection pooler nodig hebben, die zal ontwikkelen, gepatcht kan worden, waarin we snel problemen kunnen oplossen en die natuurlijk multi-threaded moet zijn. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/e755cd9b06a004f0eced1dc12fd3a6fb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Multi-threading hebben we als een hoofddoel gesteld. We moeten de golf van binnenkomende TLS-verbindingen goed kunnen verwerken. <\/p>\n<p><\/p>\n<p>Daartoe moesten we een aparte bibliotheek ontwikkelen die Machinarium heet, bedoeld voor het beschrijven van machine-toestanden van de netwerkverbinding als een sequenti\u00eble code. Als je naar de broncode van libpq kijkt, zie je vrij complexe aanroepen die je een resultaat kunnen geven en zeggen: 'Roep me later weer, nu heb ik IO, maar wanneer de IO voorbij is, heeft mijn CPU het druk'. En dit is een meervoudige structuur. Netwerkinteractie wordt meestal beschreven als een machine van toestanden. Veel regels zoals 'Als ik eerder de header van een pakket van grootte N heb ontvangen, verwacht ik nu N bytes', 'Als ik een SYNC-pakket heb verzonden, verwacht ik nu een pakket met metadata van het resultaat'. Het resultaat is vrij moeilijke, contra-intu\u00eftieve code, alsof een doolhof werd omgevormd tot een lineaire uitrol. We hebben het zo gedaan dat in plaats van een machine van toestanden, de programmeur het belangrijkste pad van interactie beschrijft in de vorm van gewone imperatieve code. Gewoonlijk moeten er in deze imperatieve code plaatsen worden ingevoegd waar de volgorde van uitvoering moet worden onderbroken om te wachten op gegevens van het netwerk, door de context van de uitvoering naar een andere coroutine (green thread) te geven. Deze aanpak is vergelijkbaar met het feit dat we het meest verwachte pad in het doolhof aaneengeschakeld opschrijven en er vervolgens vertakkingen aan toevoegen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/a6bfb4b11961c7db3a7c7184674e3bc2.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uiteindelijk hebben we \u00e9\u00e9n thread die een TCP-accept doet en via round-robin meerdere workers een TCP-verbinding doorgeeft. <\/p>\n<p><\/p>\n<p>Elk klantverbinding draait altijd op \u00e9\u00e9n processor. Dit maakt het cachevriendelijk. <\/p>\n<p><\/p>\n<p>Bovendien hebben we een verbetering aangebracht in het verzamelen van kleine pakketten in \u00e9\u00e9n groot pakket om de systeem-TCP-stack te ontlasten.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/7d740c23baecdd2f993c83cd54a0a8e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Daarnaast hebben we de transaction pooling verbeterd, zodat Odyssey bij de juiste instelling CANCEL en ROLLBACK kan verzenden in geval van een netwerkonderbreking, d.w.z. als er niemand op de aanvraag wacht, zal Odyssey tegen de database zeggen dat deze niet hoeft te proberen de aanvraag uit te voeren, die waardevolle middelen kan verbruiken.<\/p>\n<p><\/p>\n<p>Waar mogelijk behouden we verbindingen voor dezelfde klant. Dit voorkomt dat application_name_add_host opnieuw moet worden ingesteld. Indien mogelijk hebben we geen extra herinstelling van parameters die nodig zijn voor diagnostiek. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/afb2fb7fb16d65c9ea73a8978d1eb83c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Wij werken in het belang van Yandex.Cloud. En als je managed PostgreSQL gebruikt en je hebt een connection pooler ingesteld, dan kun je logische replicatie naar buiten cre\u00ebren, d.w.z. je kunt van ons weggaan als je dat wilt, middels logische replicatie. De Bouncer geeft de stroom van logische replicatie niet naar buiten. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/c53defc92ebd8f3bec57ce64d97b9f72.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dit is een voorbeeld van de configuratie van logische replicatie. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/a37d9d1abf288d17fa646b642e8b62ab.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Bovendien hebben we ondersteuning voor fysieke replicatie naar buiten. In de cloud is dit natuurlijk niet mogelijk, omdat je cluster dan te veel informatie over zichzelf zou geven. Maar in jouw installaties, als je fysieke replicatie via een connection pooler in Odyssey nodig hebt, is dat mogelijk. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/572934ce5b08115e57ab4b55d2153c6d.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In Odyssey is er volledige compatibele monitoring met PgBouncer. We hebben dezelfde console die bijna dezelfde commando's uitvoert. Als er iets ontbreekt, stuur dan een pull request, of tenminste een issue op GitHub, en we zullen de benodigde commando's afmaken. Maar de belangrijkste functionaliteit van de PgBouncer-console hebben we al. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/451dd798fb3523a7a174ebfe00a14bc5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En natuurlijk hebben we error forwarding. We geven de fout terug die de database heeft gemeld. Je krijgt informatie over waarom je geen toegang hebt tot de database, en niet alleen dat je er niet in komt. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/14b4cb0efa33a2658dfc528349a5382f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Deze functie kan worden uitgeschakeld als je 100% compatibiliteit met PgBouncer nodig hebt. We kunnen ons gedragen als Bouncer, gewoon voor de zekerheid. <\/p>\n<p><\/p>\n<p><strong>Ontwikkeling<\/strong><\/p>\n<p><\/p>\n<p>Een paar woorden over de broncode van Odyssey. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/6055d5ec9676c331a83592916a6a292f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/yandex\/odyssey\/pull\/66\">https:\/\/github.com\/yandex\/odyssey\/pull\/66<\/a><\/noindex><\/p>\n<p><\/p>\n<p>Bijvoorbeeld, er zijn de commando's 'Pause \/ Resume'. Deze worden meestal gebruikt voor het bijwerken van de database. Als je Postgres moet bijwerken, kun je het in de connection pooler op pauze zetten, pgr_upgraden, en daarna weer hervatten. Voor de klant zal het lijken alsof de database gewoon traag was. Deze functionaliteit is ons gebracht door mensen uit de gemeenschap. Het is nog niet samengevoegd, maar het komt snel. (Al samengevoegd)<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/d2f7c57e0ae3e466ec2a701bbdb8eb3f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/yandex\/odyssey\/pull\/73\">https:\/\/github.com\/yandex\/odyssey\/pull\/73<\/a><\/noindex> \u2014 al samengevoegd<\/p>\n<p><\/p>\n<p>Bovendien is een van de nieuwe functies in PgBouncer de ondersteuning van SCRAM-authenticatie, die ons ook is gebracht door iemand die niet bij Yandex.Cloud werkt. Beide zijn complexe functionaliteiten en belangrijk. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/f39346a543c88d17728233d05c2dff19.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Daarom willen we vertellen waaruit Odyssey is gemaakt, misschien wil je ook een beetje code schrijven. <\/p>\n<p><\/p>\n<p>Je hebt de basisversie van Odyssey, die afhankelijk is van twee belangrijke bibliotheken. De Kiwi-bibliotheek is een implementatie van het Postgres-berichtprotocol. Dat wil zeggen, de native proto 3 bij Postgres zijn de standaardberichten waarmee front-ends en back-ends kunnen communiceren. Deze zijn ge\u00efmplementeerd in de Kiwi-bibliotheek.<\/p>\n<p><\/p>\n<p>De Machinarium-bibliotheek is een bibliotheek voor de implementatie van streams. Een klein fragment van deze Machinarium is geschreven in assembly. Maar maak je geen zorgen, het zijn slechts 15 regels. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/cd18f250af50eabd53536b2c0d7f12b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>De architectuur van Odyssey. Er is een hoofdmachine waarin coroutines draaien. In deze machine worden binnenkomende TCP-verbindingen geaccepteerd en verdeeld over workers. <\/p>\n<p><\/p>\n<p>Binnen \u00e9\u00e9n worker kan een handler voor meerdere klanten werken. Daarnaast draaien de console en de verwerking van cron-taken in de hoofdthread voor het verwijderen van verbindingen die niet meer nodig zijn in de pool.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/7072fb20f406f2ee5788542860ccdf50.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Voor het testen van Odyssey gebruiken we de standaard set tests van Postgres. We draaien gewoon install-check via Bouncer en via Odyssey, en krijgen een nul div. Er zijn verschillende tests die verband houden met datumformattering die absoluut niet hetzelfde passeren in Bouncer en in Odyssey.<\/p>\n<p><\/p>\n<p>Daarnaast zijn er veel drivers die hun eigen testen hebben. En we gebruiken hun tests voor het testen van Odyssey.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/fb01cc9a0e9724ddcd3cc3d088afb182.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Bovendien moeten we vanwege onze cascadeconfiguratie verschillende combinaties testen: Postgres + Odyssey, PgBouncer + Odyssey, Odyssey + Odyssey, om er zeker van te zijn dat als Odyssey in een van de delen van de cascade terechtkomt, het nog steeds werkt zoals we verwachten. <\/p>\n<p><\/p>\n<p><strong>Harken<\/strong><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/25855b691180bca083025b9e8b611c09.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>We use Odyssey in production. It would be unfair to say that everything just works. No, it does, but not always. For example, in production, everything worked fine until our friends from PostgreSQL Professional pointed out that we had a memory leak. They were indeed correct, and we fixed it. But that was just the beginning. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/e638d88397b32b1ca0b74c9c1b905f81.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Then we discovered that the connection pooler has incoming TLS connections and outgoing TLS connections. And these connections require client certificates and server certificates.<\/p>\n<p><\/p>\n<p>The server certificates for Bouncer and Odyssey read from their pcache, but client certificates do not need to be re-read from pcache because our scalable Odyssey eventually hits the performance limits of reading that certificate. This took us by surprise because it didn't happen immediately. Initially, it scaled linearly, but after 20,000 simultaneous incoming connections, this issue became apparent.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/6cff094cd59a990e448b82fa0b1572b7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pluggable Authentication Method is a way to authenticate using built-in Linux tools. In PgBouncer, it is implemented such that there is a separate thread for waiting for a response from PAM and a main PgBouncer thread that handles the current connection and can ask them to reside in the PAM thread. <\/p>\n<p><\/p>\n<p>We didn't implement this for one simple reason. We have many threads. Why do we need this?<\/p>\n<p><\/p>\n<p>Ultimately, this can create problems in cases where you have PAM authentication and non-PAM authentication, as a large wave of PAM authentication can significantly delay non-PAM authentication. This is one of those issues that we haven't fixed. But if you want to address it, you can look into this. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/c7bd9e9980ff7298b30a59c130f03dbb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Another issue we encountered was having one thread that accepts all incoming connections and then passes them to the worker pool, where the TLS handshake will occur.<\/p>\n<p><\/p>\n<p>As a result, if you have a coherent wave of 20,000 network connections, they will all be accepted. On the client side, libpq will start the timeout countdown. By default, it seems to set at 3 seconds. <\/p>\n<p><\/p>\n<p>If they all cannot access the database simultaneously, they won't be able to access it because all of this may be covered by non-exponential retry. <\/p>\n<p><\/p>\n<p>We ended up copying the scheme from PgBouncer with throttling the number of TCP connections that we accept. <\/p>\n<p><\/p>\n<p>Als we zien dat we verbindingen accepteren, maar ze uiteindelijk de handshake niet kunnen voltooien, zetten we ze in de wachtrij zodat ze geen centrales processorresources verbruiken. Dit leidt ertoe dat de gelijktijdige handshakes niet voor alle binnenkomende verbindingen kunnen plaatsvinden. Maar in ieder geval kan iemand de database betreden, zelfs als de belasting behoorlijk hoog is.<\/p>\n<p><\/p>\n<p><strong>Roadmap<\/strong><\/p>\n<p><\/p>\n<p>Wat zouden we in de toekomst willen zien in Odyssey? Wat zijn we bereid zelf te ontwikkelen en wat verwachten we van de gemeenschap?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/4719437d80b33efc3da6572af9a4dedb.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><strong>Per augustus 2019.<\/strong><\/p>\n<p><\/p>\n<p>Zo zag de roadmap van Odyssey eruit in augustus:<\/p>\n<p><\/p>\n<ul>\n<li>We wilden SCRAM- en PAM-authenticatie.<\/li>\n<li>We wilden forward leesverzoeken naar standby. <\/li>\n<li>We zouden graag online-herstarten. <\/li>\n<li>En de mogelijkheid om een pauze op de server te nemen. <\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/455c92f92df826257c2c57dc2b034e22.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Half van deze roadmap is uitgevoerd, en niet door ons. En dat is goed. Laten we dus bespreken wat er nog overblijft en nog wat toevoegen. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/4a1daafbfe8d65ba0dd3e1ebdae8dd94.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/yandex\/odyssey\/issues\/12\">Wat betreft het forward read-only queries naar standby<\/a><\/noindex>? \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0440\u0435\u043f\u043b\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0435\u0437 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0433\u0440\u0435\u0442\u044c \u0432\u043e\u0437\u0434\u0443\u0445. \u041e\u043d\u0438 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f failover \u0438 switchover. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0432 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u0434\u0430\u0442\u0430-\u0446\u0435\u043d\u0442\u0440\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0438\u0445 \u0437\u0430\u043d\u044f\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0435 \u0436\u0435 \u0441\u0430\u043c\u044b\u0435 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u044b, \u0442\u0443 \u0436\u0435 \u0441\u0430\u043c\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u043d\u0430\u0447\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/0873cffd4f1ae15d9ffa6d080671051b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>In principe is er in Postgres, vanaf versie 10, de mogelijkheid om bij een verbinding ook session_attrs op te geven. In de verbinding kun je alle databasehosts opnoemen en aangeven waarom je naar de database gaat: om te schrijven of alleen om te lezen. En de driver kiest zelf de eerste host van de lijst die het het meest prettig vindt, die voldoet aan de vereisten van session_attrs. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/0693d1327fe5826502a01c21d05d5b4c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Maar het probleem met deze aanpak is dat het de replicatievertraging niet controleert. Je kunt een replica hebben die achterloopt voor een tijd die onaanvaardbaar is voor je service. Om leesverzoeken op een replica volledig te ondersteunen, moeten we in feite in Odyssey de mogelijkheid ondersteunen om niet te functioneren wanneer lezen niet mogelijk is. <\/p>\n<p><\/p>\n<p>Odyssey moet af en toe de database raadplegen en het replicatieafstand tot de primaire vragen. En als dit een drempelwaarde heeft bereikt, geen nieuwe verzoeken naar de database toestaan, de klant vertellen dat ze opnieuw verbinding moeten maken en mogelijk een andere host moeten kiezen voor het uitvoeren van verzoeken. Dit zal de database helpen om sneller de replicatievertraging te herstellen en weer te kunnen reageren op verzoeken. <\/p>\n<p><\/p>\n<p>Het is moeilijk om termijnen voor implementatie te noemen, omdat het open source is. Maar ik hoop dat het niet 2,5 jaar duurt zoals bij collega's van PgBouncer. Deze functie zou ik graag in Odyssey willen zien. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/4ec3cd2ff7b2298927cccfe8e0ba890a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/yandex\/odyssey\/issues\/16\">In de gemeenschap vroegen mensen om ondersteuning voor prepared statements.<\/a><\/noindex>U kunt een prepared statement nu op twee manieren aanmaken. Ten eerste kunt u de SQL-opdracht uitvoeren, namelijk 'prepared'. Om deze SQL-opdracht te begrijpen, moeten we leren om SQL aan de kant van Bouncer te begrijpen. Dit zou een overkill zijn, omdat we een volledige parser nodig hebben. We kunnen niet elke SQL-opdracht parseren. <\/p>\n<p><\/p>\n<p>Maar er is een prepared statement op het niveau van het berichtenprotocol op proto3. En dat is waar de informatie over het cre\u00ebren van een prepared statement in gestructureerde vorm binnenkomt. We zouden kunnen ondersteunen dat we begrijpen dat de klant op een bepaalde serververbinding heeft gevraagd om prepared statements aan te maken. En zelfs als de transactie is gesloten, moeten we de connectiviteit tussen server en cli\u00ebnt blijven ondersteunen. <\/p>\n<p><\/p>\n<p>Maar hier ontstaat een discrepantie in de dialoog, omdat iemand zegt dat we moeten begrijpen welke specifieke prepared statements de klant heeft aangemaakt en de serververbinding moeten scheiden tussen alle cli\u00ebnten die deze serververbinding hebben aangemaakt, dat wil zeggen, die zo'n prepared statement hebben aangemaakt. <\/p>\n<p><\/p>\n<p>Andres Freund zei dat als er een klant bij je is gekomen die deze prepared statement al in een andere serververbinding had aangemaakt, je die dan voor hem moet aanmaken. Maar het lijkt een beetje verkeerd om verzoeken in de database uit te voeren in plaats van de client, maar vanuit het perspectief van de ontwikkelaar die het protocol voor interactie met de database schrijft, zou het handig zijn als hij gewoon een netwerkverbinding krijgt waarin zo'n voorbereid verzoek zit. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/cd56b3ad015195d86a64e52be365b16a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>En nog een functie die we moeten implementeren. We hebben momenteel monitoring die compatibel is met PgBouncer. We kunnen de gemiddelde uitvoeringstijd van een verzoek teruggeven. Maar de gemiddelde tijd is de gemiddelde temperatuur in het ziekenhuis: sommige zijn koud, sommige warm - gemiddeld is iedereen gezond. Dat is niet waar. <\/p>\n<p><\/p>\n<p>We moeten ondersteuning voor percentielen implementeren die aangeven dat er trage verzoeken zijn die middelen verbruiken, en de monitoring acceptabeler zouden maken. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/6f285f3eb0d79e7f25d42f0e792b85b1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Het belangrijkste is dat we versie 1.0 willen (versie 1.1 is al uitgekomen). Het probleem is dat Odyssey momenteel in versie 1.0rc is, dat wil zeggen release candidate. En alle problemen die ik heb opgesomd, zijn precies met die versie opgelost, behalve het geheugenlek. <\/p>\n<p><\/p>\n<p>Wat betekent versie 1.0 voor ons? We rollen Odyssey uit naar onze databases. Het werkt nu al op onze databases, maar wanneer het de mijlpaal van 1.000.000 verzoeken per seconde bereikt, kunnen we zeggen dat dit de releaseversie is en dat dit de versie is die we 1.0 kunnen noemen. <\/p>\n<p><\/p>\n<p>In de gemeenschap hebben enkele mensen gevraagd of er in versie 1.0 ook een pauze en SCRAM zouden komen. Maar dat zou betekenen dat we de volgende versie al in productie zouden moeten uitrollen, omdat zowel SCRAM als pauze nog niet zijn samengevoegd. Maar waarschijnlijk zal deze kwestie snel worden opgelost. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Odyssey roadmap: what more do we want from the connection pooler. Andrei Borodin (2019)\" src=\"\/wp-content\/uploads\/2020\/10\/2f50de9f51f653a7396965239bd545e1.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ik wacht op jullie pull requests. En ik zou ook graag horen welke problemen jullie met Bouncer hebben. Laten we die bespreken. Misschien kunnen we bepaalde functies implementeren die jullie nodig hebben. <\/p>\n<p><\/p>\n<p>Dit was mijn deel, ik wil graag jullie horen. Dank jullie!<\/p>\n<p><\/p>\n<p>Vragen<\/p>\n<p><\/p>\n<p><em>Als ik mijn application_name instel, wordt deze dan correct doorgegeven, ook in transaction pooling in Odyssey?<\/em><\/p>\n<p><\/p>\n<p>In Odyssey of in Bouncer?<\/p>\n<p><\/p>\n<p><em>In Odyssey. In Bouncer wordt het doorgegeven.<\/em> <\/p>\n<p><\/p>\n<p>We zullen de set maken. <\/p>\n<p><\/p>\n<p><em>En als mijn echte verbinding springt naar andere verbindingen, wordt deze dan doorgegeven?<\/em><\/p>\n<p><\/p>\n<p>We zullen een set maken van alle parameters die in de lijst staan. Ik kan niet zeggen of application_name in die lijst staat. Ik denk dat ik het daar heb gezien. We zullen alle dezelfde parameters instellen. E\u00e9n verzoek zal alles doen wat door de cli\u00ebnt is ingesteld bij de opstart. <\/p>\n<p><\/p>\n<p><em>Dank je, Andrei, voor de presentatie! Goede presentatie! Ik ben blij dat Odyssey met elke minuut sneller en sneller ontwikkelt. Ik wens je veel succes. We hebben al contact met jullie opgenomen met het verzoek om multi data-source verbinding te hebben, zodat Odyssey gelijktijdig kan verbinden met verschillende databases, dat wil zeggen master-slave, en vervolgens automatisch na failover kan verbinden met een nieuwe master.<\/em> <\/p>\n<p><\/p>\n<p>Ja, ik herinner me die discussie. Er zijn momenteel verschillende storages. Maar er is geen schakeling tussen hen. We moeten aan onze kant de server controleren of deze nog actief is en begrijpen dat er een failover heeft plaatsgevonden, wie pg_recovery zal aanroepen. Ik heb een standaardmethode om te begrijpen dat we niet op de master zijn gekomen. En we moeten op een of andere manier uit de fouten afleiden, of niet? De idee is interessant, het wordt besproken. Schrijf meer commentaren. Als je werkende handen hebt die C kennen, is dat geweldig. <\/p>\n<p><\/p>\n<p>De vraag naar schaling met replicaties is ook voor ons van belang, omdat we de adoptie van gerepliceerde clusters zo eenvoudig mogelijk willen maken voor applicatie-ontwikkelaars. We zouden hier echter graag meer toelichting over willen, namelijk hoe we dit exact moeten realiseren en hoe we dit goed kunnen doen. <\/p>\n<p><\/p>\n<p><em>De vraag gaat ook over de replicaties. Dus jullie hebben een master en verschillende replicaties. En het is duidelijk dat er minder verbindingen naar de replicatie gaan dan naar de master, omdat er verschillen kunnen zijn. Je zei dat de afwijkingen in gegevens zo groot kunnen zijn dat dit niet voldoet aan jullie bedrijfsvereisten en dat jullie de replicatie niet zullen gebruiken totdat deze weer gesynchroniseerd is. Als je daar echter lange tijd niet naartoe bent gegaan en dan weer begint te connecteren, zijn de benodigde gegevens misschien niet direct beschikbaar. Dat betekent dat als we constant verbinding maken met de master, de cache daar warm is, terwijl de cache in de replicatie iets achterloopt.<\/em> <\/p>\n<p><\/p>\n<p>Ja, dat klopt. In pcache zullen de gegevensblokken die je wilt niet aanwezig zijn, in de echte cache zullen er geen informatie over de tabellen zijn die je wilt, in de plannen zullen er geen geparsed queries zijn, er zal helemaal niets zijn. <\/p>\n<p><\/p>\n<p><em>En wanneer je een cluster hebt en je voegt een nieuwe replicatie toe, dan is het aanvankelijk slecht, dat wil zeggen dat het zijn cache aan het opbouwen is.<\/em> <\/p>\n<p><\/p>\n<p>Ik begrijp het idee. De juiste aanpak zou zijn om een klein percentage van de verzoeken eerst naar de replicatie te sturen, die de cache zou verhitten. Grof gezegd, we hebben de voorwaarde dat we niet meer dan 10 seconden achter mogen lopen op de master. En deze voorwaarde moet niet in \u00e9\u00e9n keer worden ingevoerd, maar geleidelijk voor sommige klanten. <\/p>\n<p><\/p>\n<p><em>Ja, het gewicht verhogen.<\/em><\/p>\n<p><\/p>\n<p>Dit is een goed idee. Maar we moeten eerst deze uitschakeling implementeren. Eerst moeten we onszelf uitschakelen, en dan denken we na over hoe we weer kunnen inschakelen. Dit is een geweldige functie om geleidelijk in te schakelen.<\/p>\n<p><\/p>\n<p><em>In nginx is er een dergelijke optie <code>langzaam starten<\/code> in het cluster voor de server. En hij verhoogt geleidelijk de belasting.<\/em> <\/p>\n<p><\/p>\n<p>Ja, geweldig idee, we zullen het proberen wanneer we daar zijn.<\/p>\n<p>Bron: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/522734\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0434\u043e\u043a\u043b\u0430\u0434\u0435 \u0410\u043d\u0434\u0440\u0435\u0439 \u0411\u043e\u0440\u043e\u0434\u0438\u043d \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u0442, \u043a\u0430\u043a \u043e\u043d\u0438 \u0443\u0447\u043b\u0438 \u043e\u043f\u044b\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f PgBouncer \u043f\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0443\u043b\u0435\u0440\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439 Odyssey, \u043a\u0430\u043a \u0432\u044b\u043a\u0430\u0442\u044b\u0432\u0430\u043b\u0438 \u0435\u0433\u043e \u0432 production. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043a\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0443\u043b\u0435\u0440\u0430 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0432 \u043d\u043e\u0432\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u044f\u0445: \u043d\u0430\u043c \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u041e\u0434\u0438\u0441\u0441\u0435\u044f. \u0412\u0438\u0434\u0435\u043e: \u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0410\u043d\u0434\u0440\u0435\u0439. \u0412 \u042f\u043d\u0434\u0435\u043a\u0441\u0435 \u044f \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0441\u044c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":96516,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-96515","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\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\/nl\/blog\/administrirovanie\/odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\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\udd47Odyssey roadmap: \u0447\u0442\u043e \u0435\u0449\u0451 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442 \u043f\u0443\u043b\u0435\u0440\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439. \u0410\u043d\u0434\u0440\u0435\u0439 \u0411\u043e\u0440\u043e\u0434\u0438\u043d (2019) | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019\" \/>\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-10-12T17:43:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-10-12T17:43:02+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\udd47Odyssey roadmap: wat willen we nog meer van de verbindingen pooler. Andrei Borodin (2019) | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","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\udd47Odyssey roadmap: \u0447\u0442\u043e \u0435\u0449\u0451 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442 \u043f\u0443\u043b\u0435\u0440\u0430 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0439. \u0410\u043d\u0434\u0440\u0435\u0439 \u0411\u043e\u0440\u043e\u0434\u0438\u043d (2019) | ProHoster","og:url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/odyssey-roadmap-chto-eshhyo-my-hotim-ot-pulera-soedinenij-andrej-borodin-2019","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-10-12T17:43:02+00:00","article:modified_time":"2020-10-12T17:43:02+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"96515","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 10:41:30","updated":"2022-10-01 00:02:14","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/96515","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=96515"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/96515\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/96516"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=96515"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=96515"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=96515"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}