{"id":55734,"date":"2020-01-27T00:00:00","date_gmt":"2020-01-26T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie"},"modified":"2020-02-18T14:03:52","modified_gmt":"2020-02-18T11:03:52","slug":"highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie","title":{"rendered":"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>We will discuss the operation of Zabbix with the TimescaleDB database as a backend. We will show how to set it up from scratch and how to migrate from PostgreSQL. We will also provide comparative performance tests of the two configurations.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/fb4f7ea4585b6dcdafec9d0d1e3a71e4.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHighLoad++ Siberia 2019. Hall \"Tomsk\". June 24, 16:00. Theses and <noindex><a rel=\"nofollow\" href=\"https:\/\/www.highload.ru\/siberia\/2019\/abstracts\/5390\">presentation<\/a><\/noindex>. The next HighLoad++ conference will take place on April 6 and 7, 2020, in St. Petersburg. Details and tickets <noindex><a rel=\"nofollow\" href=\"http:\/\/bit.ly\/2sSxgBx\">at the link<\/a><\/noindex>.<\/p>\n<p><b>Andrey Gushchin (hereafter \u2013 AG):<\/b> \u2013 I am a technical support engineer for ZABBIX (hereafter \u2013 \"Zabbix\"), a trainer. I have been working in technical support for over 6 years and have directly encountered performance issues. Today, I will talk about the performance that TimescaleDB can deliver compared to regular PostgreSQL 10. I will also provide some introductory information on how this works in general.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>The main performance challenges: from data collection to data cleanup<\/h3>\n<p>\nLet\u2019s start with the fact that there are certain performance challenges that every monitoring system faces. The first performance challenge is the rapid collection and processing of data.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/a2cb78b549a55c3b59d7fcdb8b8865b3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA good monitoring system should promptly and timely receive all data, process it according to trigger expressions, which means processing based on certain criteria (this varies in different systems), and store it in a database for future use.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/a3ce55c3aec3eb93948150684838a5b3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe second performance challenge is historical data storage. Storing metrics in the database and having quick and easy access to these metrics collected over a period of time. Most importantly, the data should be conveniently accessible for use in reports, graphs, triggers, threshold values, alerts, etc.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/325363d79f0270d620f956eeb8ab3402.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe third performance challenge is data cleanup, that is, when you reach a point where you no longer need to store certain detailed metrics that have been collected over five years (or even months or two months). Some network nodes have been removed, or certain hosts are no longer needed because they are outdated and have stopped being collected. All this needs to be cleaned up to prevent your database from growing too large. In fact, data cleanup is often a serious test for storage and heavily impacts performance.<\/p>\n<h3>How to solve caching problems?<\/h3>\n<p>\nI am now going to specifically talk about 'Zabbix'. In 'Zabbix', the first and second calls are resolved through caching.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/d5510b31553ee8e63a0c240789d51622.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nData collection and processing \u2013 we use RAM to store all this data. More details about this data will be provided now.<\/p>\n<p>There is also certain caching on the database side for main queries \u2013 for graphs and other items.<\/p>\n<p>Caching on the Zabbix server side: we have ConfigurationCache, ValueCache, HistoryCache, TrendsCache. What is this?<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/241a131145eccd280a7411c43b2cdce4.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nConfigurationCache is the main cache where we store metrics, hosts, data items, triggers; everything needed for preprocessing, data collection, what hosts to collect from, and how often. All of this is stored in ConfigurationCache to avoid unnecessary database queries. After the server starts, we update this cache and periodically refresh it (depending on configuration settings).<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/474ac0db2e46aa945a0da62197f72987.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Caching in Zabbix. Data collection<\/h3>\n<p>\nThe scheme here is quite large:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/a6ad9dbd5deebac5440433a47c693fcf.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe main elements in the scheme are these collectors:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/feb932586302e2284bd44595caf9ee1b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThese are the assembly processes themselves, various 'pollers' that are responsible for different types of collections. They gather data via ICMP, IPMI, various protocols, and transmit it all for preprocessing.<\/p>\n<h3>PreProcessing HistoryCache<\/h3>\n<p>\nAlso, if we have calculated data items (those familiar with 'Zabbix' will know), meaning derived, aggregated data items, we pull them directly from ValueCache. I will explain how it gets filled later. All these collectors use ConfigurationCache to obtain their tasks and then pass them on for preprocessing.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/3948ee1167c52856949c25e2043be974.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nPreprocessing also uses ConfigurationCache to get preprocessing steps and processes this data in various ways. Starting from version 4.2, it has been offloaded to proxies. This is very convenient because preprocessing is quite a heavy operation. If you have a very large 'Zabbix', with a significant number of data items and a high collection frequency, this greatly eases the workload.<\/p>\n<p>Accordingly, after we have processed this data in some way using preprocessing, we save it in HistoryCache for further processing. This concludes the data collection phase. We move on to the main process.<\/p>\n<h3>History syncer operation<\/h3>\n<p>\n<img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/66539e4184d041ed84f797080226ba24.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe main process in Zabbix (since it is a monolithic architecture) is the History syncer. This is the primary process responsible for atomic processing of each data element, meaning each value:<\/p>\n<ul>\n<li>it receives a value (it takes it from HistoryCache);<\/li>\n<li>it checks in the Configuration syncer: are there any triggers for calculation \u2013 it calculates them;<br \/>\nif there are \u2013 it creates events, escalates to generate notifications if necessary according to the configuration;<\/li>\n<li>it records triggers for subsequent processing, aggregation; if you are aggregating over the last hour and so on, this value is remembered in ValueCache, so as not to query the history table; thus, ValueCache is filled with the necessary data needed for calculating triggers, computed elements, etc.;<\/li>\n<li>then the History syncer writes all the data to the database;<\/li>\n<li>the database writes them to disk \u2013 this is where the processing ends.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Databases. Caching<\/h3>\n<p>\nOn the DB side, when you want to view graphs or some reports on events, there are various caches. However, I will not discuss them in this report.<\/p>\n<p>For MySQL, there is Innodb_buffer_pool, and a bunch of other caches that can also be configured.<br \/>\nBut these are the main ones:<\/p>\n<ul>\n<li>shared_buffers;<\/li>\n<li>effective_cache_size;<\/li>\n<li>shared_pool.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/925e7abb21cfaa2516ff2b33ab161dc0.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI have listed that there are specific caches for all databases that allow frequently needed data for queries to be held in RAM. They have their own technologies for this.<\/p>\n<h3>About database performance<\/h3>\n<p>\nAccordingly, there is a competitive environment, meaning the Zabbix server collects data and writes it. Upon restart, it also reads from history to fill ValueCache and so on. At the same time, you may have scripts and reports that use the Zabbix API, which is built on the web interface. The Zabbix API accesses the DB and retrieves the necessary data to obtain graphs, reports, or a list of events, latest problems.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/10a55cb1af660aace3172a572bea6692.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA very popular solution for visualization is Grafana, which is used by our users. It can directly access both via the Zabbix API and through the DB. It also creates certain competition for data retrieval: a more refined, good DB configuration is needed to ensure fast results and testing.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/8a008e55dbee5635d386cec2fc1c40f5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>History Cleanup. In Zabbix, there is a Housekeeper<\/h3>\n<p>\nThe third call used in Zabbix is the history cleanup using Housekeeper. The Housekeeper adheres to all settings, meaning we specify in the data items how long to keep data (in days), how long to retain trends, and the dynamics of changes.<\/p>\n<p>I haven't mentioned TrendCache, which we calculate on the fly: data comes in, we aggregate it over one hour (mostly this is numbers from the last hour), the average\/minimum count and record this once an hour in the dynamics changes table (Trends). The Housekeeper runs and deletes data from the database using regular selects, which is not always efficient.<\/p>\n<p>How to understand that this is inefficient? You can see the following picture on the performance graphs of internal processes:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/f413ec989491d4186a05c779978e2f6d.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nYour History syncer is constantly busy (red graph). And the 'orange' graph that runs above it. This is the Housekeeper, which runs and waits for the database to delete all rows that it has specified.<\/p>\n<p>Let's take some Item ID: we need to delete the last 5,000; of course, based on indices. But usually, the dataset is large enough\u2014the database still reads this from the disk and brings it into the cache, and this is a very expensive operation for the database. Depending on its size, this can lead to certain performance issues.<\/p>\n<p>You can disable the Housekeeper in a simple way \u2013 we have the familiar web interface. In Administration general (settings for the Housekeeper), we turn off internal housekeeping for internal history and trends. Accordingly, the Housekeeper no longer manages this:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/c9dc3ca86e7fd0c1229f6b9bc5d31270.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nWhat can be done next? You have disabled it, your graphs have aligned\u2026 What further problems might arise in this case? What could help?<\/p>\n<h3>Partitioning<\/h3>\n<p>\nUsually, this is configured on each relational database that I mentioned, in various ways. MySQL has its own technology. But overall, they are very similar when it comes to PostgreSQL 10 and MySQL. Of course, there are many internal differences in how everything is implemented and how it affects performance. But overall, creating a new partition often leads to certain problems as well.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/729114d61794314e19383f09ee9b5d61.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDepending on your setup (how much data you generate in a day), the minimum is typically set to 1 day\/partition, while for 'trends' and change dynamics, it's set to 1 month\/new partition. This can change if you have a very large setup.<\/p>\n<p>Let me start by discussing the sizes of setups: up to 5,000 new values per second (nvps) is considered a small setup. An average setup ranges from 5,000 to 25,000 values per second. Anything beyond that is categorized as large or very large installations, which require meticulous database configuration.<\/p>\n<p>In very large installations, 1 day may not be optimal. I have personally observed MySQL partitions reaching 40 gigabytes per day (and more). This is a substantial volume of data that can lead to various issues. It needs to be reduced.<\/p>\n<h3>What is the purpose of partitioning?<\/h3>\n<p>\nWhat Partitioning offers is well known \u2013 it's the segmentation of tables. Often, this involves separate files on disk and spans of queries. It selects one partition more optimally if it falls within the usual partitioning scheme.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/4920fb3415733799f0a90b1bc7af0114.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFor 'Zabbix', particularly, it is used by range, meaning we utilize a timestamp (a standard numeric value representing time since the epoch). You set the start of the day\/end of the day, which acts as the partition. Consequently, if you query data from two days ago, it retrieves it from the database faster since it only needs to load one file into cache rather than a large table.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/f5ee4e0b471eb5ebe701615aa617d66d.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nMany databases also speed up insert operations (inserting into one child table). While I am speaking abstractly, it is also feasible. Partitioning often helps.<\/p>\n<h3>Elasticsearch for NoSQL<\/h3>\n<p>\nRecently, in version 3.4, we implemented a NoSQL solution. We added the ability to write to Elasticsearch. You can write specific types of data: you choose to either write numbers or certain characters; we support string text, and logs can be written to Elasticsearch... Accordingly, the web interface will also interact with Elasticsearch. This works excellently in certain scenarios, but it's currently usable.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/24fe7d19c9e42474cd786ba59846c18c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>TimescaleDB. Hypertables<\/h3>\n<p>\nFor 4.4.2, we noticed one thing, like TimescaleDB. What is it? It's an extension for PostgreSQL, meaning it has a native PostgreSQL interface. Additionally, this extension allows for much more efficient handling of time-series data and supports automatic partitioning. Here's how it looks:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/de921f06453476215b6240ab9da6fae1.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThis is a hypertable \u2013 a concept in Timescale. It's a hyper table that you create, which contains chunks. Chunks are partitions, they are child tables, if I'm not mistaken. This is really efficient.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/719eb3f5d8c9f57544dfc4010850610c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>TimescaleDB and PostgreSQL<\/h3>\n<p>\nAs the producers of TimescaleDB assure, they use a more efficient query processing algorithm, particularly for inserts, which allows for roughly constant performance as the size of the dataset being inserted increases. So, after 200 million rows, regular PostgreSQL greatly declines and loses performance literally to zero, while Timescale allows for inserts to be processed as efficiently as possible regardless of the data volume.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/a613d505a9dfe6008551ce981da7b24e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>How to install TimescaleDB? It's simple!<\/h3>\n<p>\nIt is described in the documentation - you can install it from packages for any... It depends on the official PostgreSQL packages. You can compile it manually. It just happened that I had to compile it for the database.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/6767927fa92260103d318f9aa70ef5b3.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn Zabbix, we simply activate the extension. I think those who have used the extension in PostgreSQL... You just activate the extension, create it for the Zabbix database you use.<\/p>\n<p>And the last step...<\/p>\n<h3>TimescaleDB. Migrating historical tables<\/h3>\n<p>\nYou need to create a hypertable. There is a special function for this \u2013 Create hypertable. In it, you specify the table that is needed in this database (for which you want to create a hypertable) as the first parameter.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/47350f79fd9829c12685c1df8f0ff9a6.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe field to create on, and chunk_time_interval (this is the interval of chunks (partitions that need to be used). 86,400 \u2013 this is one day. <\/p>\n<p>The migrate_data parameter: if you set it to true, it moves all the current data into the pre-created chunks.<\/p>\n<p>I personally used migrate_data \u2013 it takes a considerable amount of time, depending on the size of your database. I had over a terabyte \u2013 creation took more than an hour. In some cases during testing, I deleted historical data for text (history_text) and string (history_str) to avoid migrating them \u2013 they weren't actually of interest to me.<\/p>\n<p>And the last update we make in our db_extension: we are installing timescaledb so that the database, and in particular our 'Zabbix', understands that there is a db_extension. It activates it and uses the correct syntax and queries to the database, employing the 'features' necessary for TimescaleDB.<\/p>\n<h3>Server Configuration<\/h3>\n<p>\nI used two servers. The first server is a relatively small virtual machine, 20 processors, 16 gigabytes of RAM. I set it up with PostgreSQL 10.8:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/990805374a2380a5c645c578404489bd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe operating system was Debian, and the file system \u2013 xfs. I made minimal configurations to use this database specifically, aside from what 'Zabbix' itself would use. The same machine also hosted the 'Zabbix' server, PostgreSQL, and load agents.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/a6efa9ab9cd58f0061d04f13fe31018c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI used 50 active agents that utilize LoadableModule to quickly generate various results. They generated strings, numbers, and so on. I filled the database with a large volume of data. Initially, the configuration contained 5,000 data items per host, and approximately each data item had a trigger \u2013 to make it a real setup. Sometimes, using even more than one trigger is required.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/d5a3c306402e08bf2532eb6203a4aab4.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI regulated the update interval and the load not only by using 50 agents (adding more), but also through dynamic data elements, reducing the update interval to 4 seconds.<\/p>\n<h3>Performance Test. PostgreSQL: 36,000 NVPs<\/h3>\n<p>\nThe first launch, my initial setup was on clean PostgreSQL 10 on this hardware (35,000 values per second). Overall, as seen on the screen, data insertion takes fractions of a second \u2013 everything is fine and fast, SSD drives (200 gigabytes). The only issue is that 20 GB fills up quite quickly.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/6803a64fedd26093b9117a036d2993ae.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThere will be quite a few such graphs ahead. This is the standard performance dashboard of the 'Zabbix' server.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/081cc11c6bf42db3f8f16b6cc4e6ee0c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe first graph \u2013 the number of values per second (blue, top left), 35,000 values in this case. This (center top) is the load of the processing units, and this (top right) is the load of the internal processes: history syncers and the housekeeper, which here (center bottom) was running for a significant time.<\/p>\n<p>This chart (below center) shows the usage of ValueCache \u2013 how many hits ValueCache receives for triggers (several thousand values per second). Another important chart is the fourth one (bottom left), which shows the usage of HistoryCache, which I mentioned, serving as a buffer before insertion into the database.<\/p>\n<h3>Performance test. PostgreSQL: 50,000 NVPs<\/h3>\n<p>\nNext, I increased the load to 50,000 values per second on the same hardware. When loaded with the Housekeeper, 10,000 values were recorded in just 2-3 seconds with computation. This is actually shown in the following screenshot:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/80824da986dbee2f8d5ebe0ead4fbcfd.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe Housekeeper is starting to interfere with the operation, but overall the load on the history syncers is still at about 60% (the third chart, top right). During the Housekeeper's operation, HistoryCache starts to fill up actively (bottom left). It was around half a gigabyte, filling up by 20%.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/9e1bcd4f3b9f3e8a1c9a36b2083ec61b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Performance test. PostgreSQL: 80,000 NVPs<\/h3>\n<p>\nI then increased to 80,000 values per second:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/13ae1589d6b9d35b4dda9c6c7d989cc2.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThis amounted to about 400,000 data elements, 280,000 triggers. As you can see, the insertion load for the history syncers (there were 30 of them) was already quite high. I then adjusted various parameters: history syncers, cache\u2026 On this hardware, the load on the history syncers began to reach its maximum, almost 'in the shelf' \u2013 consequently, HistoryCache went into very high load:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/0ec528256c8fa7b16e1c7c95c8119535.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDuring all this time, I monitored all the system parameters (how the CPU is used, RAM) and found that disk utilization was at its peak \u2013 I reached the maximum capability of this disk on this hardware, on this virtual machine. PostgreSQL started to actively drop data under such intensity, and the disk could no longer keep up with writing, reading\u2026<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/0809dbd7638e7ee003ea24c611984a0c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI took another server, which already had 48 processors and 128 gigabytes of RAM:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/53410b502a4574aac5d40f1a2a6d3f42.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI also 'tuned' it \u2013 installed 60 History syncers and achieved acceptable performance. In fact, we are not 'in the shelf', but this is probably the performance limit where something needs to be done.<\/p>\n<h3>Performance test. TimescaleDB: 80,000 NVPs<\/h3>\n<p>\nMy main task was to use TimescaleDB. A drop is visible on each graph:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/b0064068895a34b93b5aa6771aba05cb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThese failures are essentially data migration. Afterward, as you can see, the loading profile of the history syncers on the 'Zabbix' server changed significantly. It allows data to be inserted nearly three times faster and uses less HistoryCache \u2014 consequently, data will be delivered to you in a timely manner. Again, 80,000 values per second is a quite high rate (certainly not for 'Yandex'). Overall, this is a fairly large setup with a single server.<\/p>\n<h3>PostgreSQL Performance Test: 120,000 NVPs<\/h3>\n<p>\nNext, I increased the number of data elements to half a million and obtained a calculated value of 125,000 per second:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/7d0cf2ef7c6691c1bbf4b90afd34e4bb.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nAnd obtained these graphs:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/9c09333a50e016921a8a5b70e00397a1.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIn principle, this is a working setup; it can operate for a sufficiently long time. However, since I only had a disk of 1.5 terabytes, I used it up in a couple of days. The most important thing is that new partitions in TimescaleDB were being created at the same time, and this had no noticeable impact on performance, unlike MySQL.<\/p>\n<p>Typically, partitions are created at night, as this blocks any data insertion and interaction with tables, potentially leading to service degradation. However, this was not the case here! The main goal was to test the capabilities of TimescaleDB. The result was: 120,000 values per second.<\/p>\n<p>There are also examples in the community:<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/66aa6b1d4c559d12082e4d91b6a1ca10.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nA person also activated TimescaleDB, and the I\/O weight load decreased on the processor; the use of internal process elements also dropped thanks to the activation of TimescaleDB. Moreover, these are standard spinning disks, i.e., a regular virtual machine on conventional disks (not SSDs)!<\/p>\n<p>For smaller setups that reach disk performance limits, TimescaleDB seems to be an excellent solution. It allows continued operation until you migrate to faster hardware for the database.<\/p>\n<p>I invite all of you to our events: Conference in Moscow, Summit in Riga. Use our channels \u2014 Telegram, forum, IRC. If you have any questions, come to our booth; we can discuss everything.<\/p>\n<h3>Audience questions<\/h3>\n<p>\nQuestion from the audience (hereinafter \u2013 A): \u2013 If TimescaleDB is so easy to set up and provides such a performance boost, might it be worth using it as the best practice for configuring 'Zabbix' with 'Postgres'? Are there any pitfalls or downsides to this solution? Or if I decide to set up 'Zabbix', can I safely choose 'Postgres', install 'Timescale' right away, use it, and not worry about any issues?<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/314845a019724806283a957b15d857cc.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>AG:<\/b> \u2013 Yes, I would say it's a good recommendation: to use 'Postgres' right away with the TimescaleDB extension. As I mentioned, there are many positive reviews, despite this 'feature' being experimental. But tests show that it\u2019s an excellent solution (with TimescaleDB), and I believe it will continue to develop! We are monitoring how this extension evolves and will adjust as needed.<\/p>\n<p>During development, we relied on one of its known 'features': there was a way to work with chunks a bit differently. But then they removed that in the next release, and we had to stop relying on that code. I would recommend using this solution in many setups. If you\u2019re using MySQL... For medium setups, any solution works well.<\/p>\n<p><b>A:<\/b> \u2013 In the latest charts from the community, there was a chart with 'Housekeeper':<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/d01549b6b9b97d8bdf5372efe05d9039.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIt kept working. What does 'Housekeeper' do in the case of TimescaleDB?<\/p>\n<p><b>AG:<\/b> \u2013 I can\u2019t say for sure right now \u2013 I\u2019ll check the code and provide more details. It uses TimescaleDB queries not for dropping chunks, but aggregates data in some way. I\u2019m not ready to answer this technical question just yet. We\u2019ll clarify on the stand today or tomorrow.<\/p>\n<p><b>A:<\/b> \u2013 I have a similar question \u2013 about the performance of delete operations in 'Timescale'.<br \/>\nA (response from the audience): \u2013 When you delete data from a table, if you do it through delete, you need to go through the table \u2013 delete, clean up, mark everything for future vacuuming. In 'Timescale', since you have chunks, you can drop them. Essentially, you're just telling the file that\u2019s in big data: 'Delete!'<\/p>\n<p>\"Timescale\" simply understands that there is no more of that chunk. And since it integrates into the query planner, it catches your conditions in the select or in other operations via hooks and immediately realizes that this chunk no longer exists \u2013 \"I won't go there anymore!\" (data is missing). That's it! That is, scanning the table is replaced by deleting a binary file, so it\u2019s quick.<\/p>\n<p><b>A:<\/b> \u2013 We've already touched on the topic of non-SQL. As far as I understand, \"Zabbix\" doesn\u2019t really need to modify data, and all of this is like a log. Can specialized databases be used that cannot change their data but are much faster at saving, accumulating, and retrieving \u2013 like Clickhouse, for example, or something Kafka-like?.. Kafka is also a log! Is there any way to integrate them?<\/p>\n<p><b>AG:<\/b> \u2013 You can export data. We have a certain \"feature\" starting from version 3.4: you can write all historical files, events, and so on to files; then use some processor to send them to any other database. In fact, many people rewrite and write directly to the database. On the fly, history-syncers write all this to files, rotate these files, and so on, and you can transfer this to \"Clickhouse.\" I can't speak to future plans, but there may continue to be support for NoSQL solutions (like \"Clickhouse\").<\/p>\n<p><b>A:<\/b> \u2013 So, it turns out you can completely get rid of Postgres?<\/p>\n<p><b>AG:<\/b> \u2013 Of course, the most challenging part in \"Zabbix\" is the historical tables, which create the most problems, along with events. In this case, if you don\u2019t keep events for long and store the history with trends in some other fast storage, then overall I think there won\u2019t be any problems.<\/p>\n<p><b>A:<\/b> \u2013 Can you estimate how much faster everything will work if you switch to Clickhouse, for example?<\/p>\n<p><b>AG:<\/b> \u2013 I haven't tested it. I think at least the same numbers could be achieved quite easily, given that Clickhouse has its own interface, but I can't say for sure. It's better to test. It all depends on the configuration: how many hosts you have, etc. Insertion is one thing, but you also need to retrieve that data \u2013 with Grafana or something else.<\/p>\n<p><b>A:<\/b> \u2013 So it's a level playing field, not a significant advantage for these fast databases?<\/p>\n<p><b>AG:<\/b> \u2013 I think that when we integrate, there will be more accurate tests.<\/p>\n<p><b>A:<\/b> \u2013 Where has the good old RRD gone? What led us to switch to SQL databases? Initially, all metrics were collected on RRD.<\/p>\n<p><b>AG:<\/b> \u2013 RRD might have been in a very old version of 'Zabbix'. There have always been SQL databases \u2013 the classical approach. The classical approach involves MySQL and PostgreSQL (which have existed for a very long time). We have a common interface for SQL databases and we have hardly ever used RRD.<\/p>\n<p><img decoding=\"async\" alt=\"HighLoad++, Andrey Gushchin (Zabbix): High performance and native partitioning\" src=\"\/wp-content\/uploads\/2020\/01\/ac5f02494c63983601cc09c0b22e722b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<center><div class=\"youtube-placeholder\" data-id=\"umRk94j5M8o\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/umRk94j5M8o\/hqdefault.jpg\" alt=\"Play video\" 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>A little advertisement \ud83d\ude42<\/h3>\n<p>\nThank you for staying with us. Do you enjoy our articles? Want to see more interesting content? Support us by placing an order or recommending us to your friends, <noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/cloudvps\/nl\">cloud VPS for developers starting at $4.99<\/a><\/noindex>, <b>a unique entry-level server alternative that we have created for you:<\/b> <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/347386\/\">The whole truth about VPS (KVM) E5-2697 v3 (6 Cores) 10GB DDR4 480GB SSD 1Gbps from $19 or how to properly share a server?<\/a><\/noindex> (options available with RAID1 and RAID10, up to 24 cores and up to 40GB DDR4).<\/p>\n<p><b>Dell R730xd at half the price in the Equinix Tier IV data center in Amsterdam?<\/b> Only with us <b><noindex><a rel=\"nofollow\" href=\"https:\/\/ua-hosting.company\/serversnl\">2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100TB starting at $199<\/a><\/noindex> in the Netherlands! <b>Dell R420 \u2014 2x E5-2430 2.2GHz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB \u2014 from $99!<\/b><\/b> Read about how <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/company\/ua-hosting\/blog\/329618\/\">To build a corporate-class infrastructure using Dell R730xd E5-2650 v4 servers costing 9000 euros for peanuts?<\/a><\/noindex><br \/>\n<br \/>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/ua-hosting\/blog\/485470\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 Zabbix \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 TimescaleDB \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend. \u041f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441 \u043d\u0443\u043b\u044f \u0438 \u043a\u0430\u043a \u043c\u0438\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 PostgreSQL. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u0432\u0443\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0439. HighLoad++ Siberia 2019. \u0417\u0430\u043b \u00ab\u0422\u043e\u043c\u0441\u043a\u00bb. 24 \u0438\u044e\u043d\u044f, 16:00. \u0422\u0435\u0437\u0438\u0441\u044b \u0438 \u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0446\u0438\u044f. \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 [&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-55734","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=\"\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 Zabbix \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 TimescaleDB \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend. \u041f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441 \u043d\u0443\u043b\u044f \u0438 \u043a\u0430\u043a \u043c\u0438\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 PostgreSQL.\" \/>\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\/highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie\" \/>\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\udd47HighLoad++, \u0410\u043d\u0434\u0440\u0435\u0439 \u0413\u0443\u0449\u0438\u043d (Zabbix): \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 Zabbix \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 TimescaleDB \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend. \u041f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441 \u043d\u0443\u043b\u044f \u0438 \u043a\u0430\u043a \u043c\u0438\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 PostgreSQL.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie\" \/>\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-01-26T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:03:52+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++, Andrey Gushchin (Zabbix): high performance and native partitioning | ProHoster","description":"We will examine how Zabbix works with the TimescaleDB database as a backend. We'll show you how to start from scratch and how to migrate from PostgreSQL.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie","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\udd47HighLoad++, \u0410\u043d\u0434\u0440\u0435\u0439 \u0413\u0443\u0449\u0438\u043d (Zabbix): \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 | ProHoster","og:description":"\u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0443 Zabbix \u0441 \u0431\u0430\u0437\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 TimescaleDB \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 backend. \u041f\u043e\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441 \u043d\u0443\u043b\u044f \u0438 \u043a\u0430\u043a \u043c\u0438\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 PostgreSQL.","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/highload-andrej-gushhin-zabbix-vysokaya-proizvoditelnost-i-nativnoe-partitsionirovanie","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-01-26T21:00:00+00:00","article:modified_time":"2020-02-18T11:03:52+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"55734","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:37:39","updated":"2022-09-28 01:51:35","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\/55734","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=55734"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/55734\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=55734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=55734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=55734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}