{"id":53944,"date":"2019-12-13T00:00:00","date_gmt":"2019-12-12T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah"},"modified":"2020-02-18T14:01:53","modified_gmt":"2020-02-18T11:01:53","slug":"clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah","title":{"rendered":"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/5a2d19e6fea2a28d8d4aa9220653aefc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Greetings, habr.<\/p>\n<p><\/p>\n<p>If someone is running the system <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/graphite-project\/graphite-web\">graphite-web<\/a><\/noindex> and has encountered storage performance issues <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/graphite-project\/whisper\">whisper<\/a><\/noindex> (IO, disk space consumption), then the chance that ClickHouse has been considered as a replacement should approach one. This statement implies that a third-party implementation is already in use as the metrics daemon, for example <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/grobian\/carbonwriter\">carbonwriter<\/a><\/noindex> or <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/go-graphite\/go-carbon\">go-carbon<\/a><\/noindex>.<\/p>\n<p><\/p>\n<p>ClickHouse effectively addresses the described problems. For instance, after transferring 2TiB of data from whisper, it fits into 300GiB. I won\u2019t dwell too much on the comparison; there are plenty of articles on this topic. Furthermore, until recently, our ClickHouse storage had its own issues.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"problemy-s-potreblyaemym-mestom\">Issues with Disk Space Usage<\/h3>\n<p><\/p>\n<p>At first glance, everything should work well. Following <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.yandex\/docs\/ru\/operations\/table_engines\/graphitemergetree\/#primer-konfiguratsii\">the documentation<\/a><\/noindex>, we create a configuration for the metric storage schema (hereafter <code>retention<\/code>), then create a table according to the recommendations of the chosen backend for graphite-web: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lomik\/carbon-clickhouse\">carbon-clickhouse<\/a><\/noindex>+<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lomik\/graphite-clickhouse\">graphite-clickhouse<\/a><\/noindex> or <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/ClickHouse\/graphouse\">graphouse<\/a><\/noindex>, depending on what stack is used. And\u2026 a ticking time bomb is activated.<\/p>\n<p><\/p>\n<p>To understand which one, you need to know how inserts work and the subsequent lifecycle of data in the tables of the *<em>MergeTree<\/em> ClickHouse family (diagrams taken from <noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/PLMSA_gDdyM\">the presentation<\/a><\/noindex> by Alexey Zatelepin):<\/p>\n<p><\/p>\n<ul>\n<li>A <code>block<\/code> of data is inserted. In our case, these are incoming metrics.<br \/>\n<img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/b60d482acca3c8d187d394f58a2d8a16.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Each such block is sorted according to the key <code>ORDER BY<\/code>, specified during table creation.<\/li>\n<li>After sorting, <code>a chunk<\/code> (<code>part<\/code>) of data is written to disk.<br \/>\n<img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/a54903b8efa0866d24da303fa7a68134.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>The server monitors in the background to ensure that there aren't too many chunks, and initiates background <code>merges<\/code> (<code>merge<\/code>, also known as merges).<br \/>\n<img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/151c18c7b73ebc4097493b13a2e26765.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/1921908554981eca0847541f77a15790.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>The server stops initiating merges automatically once data stops flowing actively into the <code>partition<\/code> (<code>partition<\/code>), but the process can be started manually with the command <code>OPTIMIZE<\/code>.<\/li>\n<li>If there is only one chunk left in the partition, a regular merge command cannot be used; it is necessary to use <code>OPTIMIZE ... FINAL<\/code><\/li>\n<\/ul>\n<p><\/p>\n<p>So, the first metrics are coming in. And they occupy a certain amount of space. Subsequent events may vary somewhat depending on many factors:<\/p>\n<p><\/p>\n<ul>\n<li>The partition key can be very small (day) or quite large (several months).<\/li>\n<li>The retention configuration can accommodate several significant thresholds for data aggregation within the active partition (where metrics are recorded), or it may not.<\/li>\n<li>If there is a large amount of data, the earliest chunks, which may already be enormous due to background merges (when an optimal partitioning key is not chosen), will not merge with fresh smaller chunks themselves.<\/li>\n<\/ul>\n<p><\/p>\n<p>And it always ends the same way. The space occupied by metrics in ClickHouse only grows if:<\/p>\n<p><\/p>\n<ul>\n<li>not applying <code>OPTIMIZE ... FINAL<\/code> manually or<\/li>\n<li>not inserting data into all partitions on a regular basis, ultimately to initiate a background merge sooner or later.<\/li>\n<\/ul>\n<p><\/p>\n<p>The second method seems the easiest to implement and thus is wrong and was tested first.<br \/>\nI wrote a fairly simple Python script that sent dummy metrics for each day over the past 4 years and was run every hour by cron.<br \/>\nSince all operations in ClickHouse DBMS are based on the system eventually doing all the background work, but it\u2019s unclear when, I couldn't wait for the old enormous chunks to start merging with the new smaller ones. It became clear that I needed to find a way to automate forced optimizations.<\/p>\n<p>\n<img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/60b0354cb65dcba6e8402b67261041ff.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3 id=\"informaciya-v-sistemnyh-tablicah-clickhouse\">Information in ClickHouse system tables<\/h3>\n<p><\/p>\n<p>Let's look at the structure of the table <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.yandex\/docs\/ru\/operations\/system_tables\/#system_tables-parts\">system.parts<\/a><\/noindex>. It contains comprehensive information about each chunk of all tables on the ClickHouse server. It includes, among other things, the following columns:<\/p>\n<p><\/p>\n<ul>\n<li>database name (<code>database<\/code>);<\/li>\n<li>table name (<code>table<\/code>);<\/li>\n<li>partition name and ID (<code>partition<\/code> &amp; <code>partition_id<\/code>);<\/li>\n<li>when the chunk was created (<code>modification_time<\/code>);<\/li>\n<li>minimum and maximum date in the chunk (partitioning is done by days) (<code>min_date<\/code> &amp; <code>max_date<\/code>);<\/li>\n<\/ul>\n<p><\/p>\n<p>There is also the table <noindex><a rel=\"nofollow\" href=\"https:\/\/clickhouse.yandex\/docs\/ru\/operations\/system_tables\/#system-graphite-retentions\">system.graphite_retentions<\/a><\/noindex>, with the following interesting fields:<\/p>\n<p><\/p>\n<ul>\n<li>database name (<code>Tables.database<\/code>);<\/li>\n<li>table name (<code>Tables.table<\/code>);<\/li>\n<li>the age of the metric when the next aggregation should be applied (<code>age<\/code>);<\/li>\n<\/ul>\n<p><\/p>\n<p>So:<\/p>\n<p><\/p>\n<ol>\n<li>We have a table of chunks and a table of aggregation rules.<\/li>\n<li>We combine their intersection and get all tables *GraphiteMergeTree.<\/li>\n<li>We look for all partitions where:\n<ul>\n<li>there is more than one chunk<\/li>\n<li>or it is time to apply the next aggregation rule, and <code>modification_time<\/code> it is older than this time.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p><\/p>\n<h3 id=\"realizaciya\">Implementation<\/h3>\n<p>\n<b class=\"spoiler_title\">This query<\/b><\/p>\n<pre><code class=\"sql\">SELECT\n    concat(p.database, '.', p.table) AS table,\n    p.partition_id AS partition_id,\n    p.partition AS partition,\n    -- The \"oldest\" rule that can be applied to\n    -- the partition, but not in the future, see (*)\n    max(g.age) AS age,\n    -- The number of parts in the partition\n    countDistinct(p.name) AS parts,\n    -- The oldest metric in the partition is considered to be 00:00:00 of the next day\n    toDateTime(max(p.max_date + 1)) AS max_time,\n    -- When the partition needs to be optimized\n    max_time + age AS rollup_time,\n    -- When the oldest part in the partition was updated\n    min(p.modification_time) AS modified_at\nFROM system.parts AS p\nINNER JOIN\n(\n    -- All rules for all tables *GraphiteMergeTree\n    SELECT\n        Tables.database AS database,\n        Tables.table AS table,\n        age\n    FROM system.graphite_retentions\n    ARRAY JOIN Tables\n    GROUP BY\n        database,\n        table,\n        age\n) AS g ON\n    (p.table = g.table)\n    AND (p.database = g.database)\nWHERE\n    -- Only active parts\n    p.active\n    -- (*) And only rows where aggregation rules should already be applied\n    AND ((toDateTime(p.max_date + 1) + g.age) &lt; now())\nGROUP BY\n    table,\n    partition\nHAVING\n    -- Only partitions that are younger than the optimization moment\n    (modified_at  1)\nORDER BY\n    table ASC,\n    partition ASC,\n    age ASC<\/code><\/pre>\n<p><\/p>\n<p>returns each of the partitions of the *GraphiteMergeTree tables, the merging of which should free up disk space. Now, all that remains is to go through all of them with a query <code>OPTIMIZE ... FINAL<\/code>. The final implementation also takes into account that there is no need to touch partitions with active writes.<\/p>\n<p><\/p>\n<p>This is exactly what the project <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/innogames\/graphite-ch-optimizer\">graphite-ch-optimizer<\/a><\/noindex>. Former colleagues from Yandex.Market tested it in production, and you can see the result of the work below. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"ClickHouse + Graphite: How to Significantly Reduce Disk Space Usage\" src=\"\/wp-content\/uploads\/2019\/12\/858dcbf538135d8d57964a71b2b6ca23.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>If you run the program on a server with ClickHouse, it will simply start working in daemon mode. Once an hour, it will execute a query to check if any new partitions older than three days have appeared that can be optimized.<\/p>\n<p><\/p>\n<p>In the near future, we plan to provide at least deb packages, and possibly also rpm.<\/p>\n<p><\/p>\n<h3 id=\"vmesto-zaklyucheniya\">In conclusion<\/h3>\n<p><\/p>\n<p>Over the past 9 months, I have spent a lot of time within my company <noindex><a rel=\"nofollow\" href=\"https:\/\/www.innogames.com\/ru\/\">InnoGames<\/a><\/noindex> working at the intersection of ClickHouse and graphite-web. It was a good experience, resulting in a possible quick transition from whisper to ClickHouse as a metrics storage. I hope this article serves as some kind of beginning of a cycle about the improvements we have made in various parts of this stack and what will be done in the future.<\/p>\n<p><\/p>\n<p>The development of the request consumed several liters of beer and admin-days together with <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/users\/v0devil\/\" class=\"user_link\">v0devil<\/a><\/noindex>, for which I want to express my gratitude. Also for reviewing this article.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/innogames\/graphite-ch-optimizer\">Project page on GitHub<\/a><\/noindex><\/p>\n<p>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/479564\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e, habr. \u0415\u0441\u043b\u0438 \u043a\u0442\u043e-\u0442\u043e \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0438\u0440\u0443\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 graphite-web \u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 whisper (IO, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u043c\u043e\u0435 \u0434\u0438\u0441\u043a\u043e\u0432\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e), \u0442\u043e \u0448\u0430\u043d\u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b\u043b \u0431\u0440\u043e\u0448\u0435\u043d \u0432\u0437\u0433\u043b\u044f\u0434 \u043d\u0430 ClickHouse \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u0430\u043c\u0435\u043d\u044b, \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f \u043a \u0435\u0434\u0438\u043d\u0438\u0446\u0435. \u0414\u0430\u043d\u043d\u043e\u0435 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u044e\u0449\u0435\u0433\u043e \u043c\u0435\u0442\u0440\u0438\u043a\u0438 \u0434\u0435\u043c\u043e\u043d\u0430 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044f\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 carbonwriter \u0438\u043b\u0438 go-carbon. ClickHouse \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0435\u0448\u0430\u0435\u0442 [&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-53944","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=\".\" \/>\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\/en\/blog\/administrirovanie\/clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\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\udd47ClickHouse + Graphite: \u043a\u0430\u043a \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u043c\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043d\u0430 \u0434\u0438\u0441\u043a\u0430\u0445 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\".\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah\" \/>\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=\"2019-12-12T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:01:53+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\udd47ClickHouse + Graphite: how to significantly reduce disk space usage | ProHoster","description":".","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","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\udd47ClickHouse + Graphite: \u043a\u0430\u043a \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u043c\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u043d\u0430 \u0434\u0438\u0441\u043a\u0430\u0445 | ProHoster","og:description":".","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/clickhouse-graphite-kak-znachitelno-umenshit-potreblyaemoe-mesto-na-diskah","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":"2019-12-12T21:00:00+00:00","article:modified_time":"2020-02-18T11:01:53+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"53944","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":"2026-01-24 09:26:21","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:15:54","updated":"2026-01-24 09:26:21","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/53944","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=53944"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/53944\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=53944"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=53944"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=53944"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}