{"id":398496,"date":"2024-06-29T14:06:35","date_gmt":"2024-06-29T14:06:35","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=398496"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=398496","title":{"rendered":"<span>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0431\u0430\u0437\u0435 ClickHouse \u0432 Yandex Cloud<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9af\/a09\/487\/9afa0948713414bb1454cedb861cf2fd.png\" width=\"920\" height=\"519\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9af\/a09\/487\/9afa0948713414bb1454cedb861cf2fd.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u0435\u043b\u0438\u043c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 \u0421\u0423\u0411\u0414 ClickHouse \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 Yandex Cloud. \u041c\u044b \u043d\u0435 \u043a\u043e\u0441\u043d\u0451\u043c\u0441\u044f \u0442\u043e\u043d\u043a\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a ClickHouse \u0438\u043b\u0438 \u0435\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043d\u0430 \u043d\u0430\u0448 \u0432\u0437\u0433\u043b\u044f\u0434 \u0442\u0435\u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 On-premise \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 ClickHouse \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 Yandex Cloud \u2013 Functions, Object Storage, Message Queue;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\/\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u043c ClickHouse \u2013 \u043e\u0447\u0438\u0449\u0430\u0442\u044c \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u044b; \u043a\u0430\u043a\u0438\u0435 \u00ab\u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438\u00bb \u043d\u0430\u043c \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u043f\u0443\u0442\u0438. <\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430:<\/strong><\/p>\n<p>\u0412 On-premise \u0432 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0442 XML-\u0444\u0430\u0439\u043b\u044b \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 \u043a\u043b\u044e\u0447 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b\/\u043c\u0430\u0441\u0441\u0438\u0432\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. <\/p>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 \u043c\u043e\u0433\u0443\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f: \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u043a\u043b\u044e\u0447\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a \u0432 \u043e\u0434\u043d\u043e\u043c, \u0442\u0430\u043a \u0438 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 XML-\u0444\u0430\u0439\u043b\u0430\u0445. \u0418\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 timestamp \u0438\u0445 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435, \u043d\u043e \u0432 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u043a \u044d\u0442\u043e\u043c\u0443 timestamp.<\/p>\n<p><strong>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:<\/strong> <\/p>\n<ul>\n<li>\n<p>\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 XML-\u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 ClickHouse \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 (\u0441 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438, \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0442.\u0434.) \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0442\u0441\u0442\u0430\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0442.\u0435. \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 ClickHouse \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0432 On-premise;<\/p>\n<\/li>\n<li>\n<p>\u0434\u0430\u043d\u043d\u044b\u0435 \u00ab\u043e\u0447\u0438\u0449\u0430\u0442\u044c\u00bb \u043e\u0442 \u0434\u0443\u0431\u043b\u0435\u0439: \u0441\u0440\u0435\u0434\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u0442, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u043d\u043d\u0438\u0439 timestamp \u0432 \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0442\u0440\u043e\u0438\u0442\u044c\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u0435\u0435.<\/strong><\/p>\n<p><strong>\u0414\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 XML-\u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 ClickHouse \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0442\u0441\u0442\u0430\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. <\/strong><\/p>\n<p>\u041f\u0440\u043e\u0439\u0434\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043a\u0443\u0440\u0441 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u00ab<a href=\"https:\/\/go.teachbase.ru\/course_sessions\/363773\">\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b<\/a>\u00bb (\u043a\u0441\u0442\u0430\u0442\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0442\u0435\u043c, \u043a\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0438 ClickHouse) \u0438 \u0443\u0432\u0438\u0434\u0435\u0432 \u0444\u0438\u0448\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/clickhouse.com\/docs\/en\/integrations\/kafka\/kafka-table-engine\">\u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 Kafka<\/a>, \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b\u0438, \u0447\u0442\u043e \u0434\u043b\u044f ClickHouse \u0438\u043b\u0438 \u0435\u0433\u043e cli-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c XML-\u0444\u0430\u0439\u043b \u0438 \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0441\u0442\u043e\u043b\u0431\u0446\u0430\u043c. \u041d\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 ClickHouse \u043f\u043e\u043a\u0430 <a href=\"https:\/\/clickhouse.com\/docs\/en\/interfaces\/formats\/#xml\">\u043d\u0435 \u0443\u043c\u0435\u0435\u0442<\/a>. \u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c XML \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0442\u0430\u0432\u043a\u0443 \u0432 ClickHouse. <\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u043f\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438. \u0412\u044b\u0431\u0438\u0440\u0430\u043b\u0438 \u043c\u0435\u0436\u0434\u0443 Airflow \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 Yandex Cloud, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u0440\u0438\u0448\u043b\u0438 \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u043c\u0443, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u2014 \u0431\u00f3\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 Yandex Cloud Functions. \u041f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u043a\u0442\u043e\u0440\u044b:<\/p>\n<ul>\n<li>\n<p>ClickHouse \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 Yandex Cloud \u043a\u0430\u043a <a href=\"https:\/\/cloud.yandex.ru\/services\/managed-clickhouse\">\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441<\/a>, \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043e\u0431\u043b\u0430\u043a\u0435 \u0440\u044f\u0434\u043e\u043c \u0441 \u0411\u0414;<\/p>\n<\/li>\n<li>\n<p>Yandex Cloud Functions \u0438\u043c\u0435\u044e\u0442 <a href=\"https:\/\/cloud.yandex.ru\/docs\/billing\/concepts\/serverless-free-tier#sf\">\u043d\u0435\u0442\u0430\u0440\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043c<\/a> (\u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u00abfree tier\u00bb), \u0447\u0442\u043e \u0443\u0434\u0435\u0448\u0435\u0432\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0443\u044e \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044e. \u041d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 On-premise \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 Airflow (\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432);<\/p>\n<\/li>\n<li>\n<p>\u0412 Yandex Cloud \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043b\u0435\u0433\u043a\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f Yandex Cloud Functions: Yandex Object Storage, Yandex Message Queue, Yandex DB \u0438 \u0434\u0440\u0443\u0433\u0438\u0435. \u041e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u0432\u043e\u0439 \u00abfree tier\u00bb;<\/p>\n<\/li>\n<li>\n<p>\u041b\u0435\u0433\u043a\u043e\u0441\u0442\u044c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Yandex Cloud Functions: \u043c\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 Terraform (\u0443 Yandex Cloud \u0435\u0441\u0442\u044c <a href=\"https:\/\/registry.terraform.io\/providers\/yandex-cloud\/yandex\/latest\/docs\">provider<\/a>) \u2013 \u0442\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435, CICD\/DevOps.<\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ea7\/c13\/b13\/ea7c13b137cf6ab48c39c3d0d8e119fd.png\" width=\"1622\" height=\"642\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ea7\/c13\/b13\/ea7c13b137cf6ab48c39c3d0d8e119fd.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0412 On-premise \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0441\u043a\u0440\u0438\u043f\u0442 (\u0435\u0433\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c, \u0442.\u043a. \u043e\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u043f\u043e\u043b\u043b\u0438\u0442 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0438\u0439 \u0432 \u043d\u0435\u0451 XML-\u0444\u0430\u0439\u043b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 (1) \u0432 \u0411\u0430\u043a\u0435\u0442 Yandex Object Storage. \u041e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0411\u0430\u043a\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 (2) \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u00ab\u0414\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u00bb, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043b\u0430\u0434\u0451\u0442 (3) \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u0444\u0430\u0439\u043b\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433 (\u0441\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043d\u0438\u0435) \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0414\u0430\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u00ab\u041f\u0430\u0440\u0441\u0435\u0440\u00bb \u0447\u0438\u0442\u0430\u0435\u0442 (4) \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u0438\u0437 \u0411\u0430\u043a\u0435\u0442\u0430 \u0441\u0435\u0431\u0435 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c, \u043f\u0430\u0440\u0441\u0438\u0442 XML \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 (5) \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. \u041f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0444\u0430\u0439\u043b \u0438\u0437 \u0411\u0430\u043a\u0435\u0442\u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f (6), \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0438 \u043d\u0435 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u0432\u043f\u0443\u0441\u0442\u0443\u044e.<\/p>\n<p>\u0412 ClickHouse \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 XML \u0438\u0437 \u0444\u0430\u0439\u043b\u0430. \u0412\u0441\u0451 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0431\u043e\u0433\u0430\u0442\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443 <a href=\"https:\/\/clickhouse.com\/docs\/en\/sql-reference\/data-types\/\">\u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445<\/a> ClickHouse.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u00ab\u041f\u0430\u0440\u0441\u0435\u0440\u00bb \u043d\u0430 Python \u0432 \u043e\u0431\u043b\u0430\u043a\u0435:<\/p>\n<pre><code># import \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 import boto3  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043e\u0431\u043b\u0430\u043a\u0443 boto_session = boto3.session.Session(     aws_access_key_id=os.getenv('ACCESS_KEY_ID'),     aws_secret_access_key=os.getenv('SECRET_ACCESS_KEY') )  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e\u043c\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 s3 = boto_session.client(     service_name='s3',     endpoint_url='https:\/\/storage.yandexcloud.net' )  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a ClickHouse clickhouse = Client(host=os.getenv('CH_HOST'),                     user=os.getenv('CH_USER'),                     password=os.getenv('CH_PASSWORD'),                     database=os.getenv('CH_DB'),                     secure=True,                     settings={'input_format_import_nested_json': 1})  # \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 # \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0451\u043b \u043f\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, # \u0438\u0437 \u0442\u0435\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0435\u0440\u0451\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0444\u0430\u0439\u043b\u0430, # \u0444\u0430\u0439\u043b \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043f\u0430\u0440\u0441\u0438\u0442\u0441\u044f, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 ClickHouse def handler(event, context):     if 'messages' in event:         for message in event['messages']:             # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:             task_json = json.loads(message['details']['message']['body'])                          # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0437 S3:             get_object_response = s3.get_object(Bucket=task_json['bucket_id'],                                          Key=task_json['object_id'])                                                      # \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430:             parsed_data = parse(data=xmltodict.parse(get_object_response['Body'].read()),                                          filename=task_json['object_id'])                                                      # \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445:             store(data=parsed_data, file=task_json['object_id'])                          # \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430:             s3.delete_object(Bucket=task_json['bucket_id'], Key=task_json['object_id'])                           def parse(data, filename):     # ... \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430      def store(data, filename):     # ... \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 ClickHouse <\/code><\/pre>\n<p>\u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0430 Terraform:<\/p>\n<pre><code># \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Yandex cloud \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0432 Yandex Object Storage terraform {   required_providers {     yandex = {       source = \"yandex-cloud\/yandex\"     }   }   backend \"s3\" {     endpoint   = \"storage.yandexcloud.net\"     bucket     = \"neoflex-tf-state\"     region     = \"ru-central1\"     key        = \"terraform.tfstate\"     access_key = \"xxx\"     secret_key = \"xxx\"      skip_region_validation      = true     skip_credentials_validation = true   } }  provider \"yandex\" {   service_account_key_file = \"key.json\" }  locals {   folder_id    = \"xxx\"   ch_secrets   = jsondecode(file(\"clickhouse.json\"))   cluster_name = \"neoflex\"   network_id   = \"xxx\"   subnet_id    = \"xxx\" }  # \u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 ClickHouse resource \"yandex_mdb_clickhouse_cluster\" \"neoflex\" {   name                    = local.cluster_name   environment             = \"PRESTABLE\"   network_id              = local.network_id   folder_id               = local.folder_id   service_account_id      = yandex_iam_service_account.sa.id   sql_database_management = false   sql_user_management     = false    clickhouse {     resources {       resource_preset_id = \"s2.large\"       disk_type_id       = \"network-ssd\"       disk_size          = 100     }   }    database {     name = local.ch_secrets[\"CH_DB\"]   }    user {     name     = local.ch_secrets[\"CH_USER\"]     password = local.ch_secrets[\"CH_PASSWORD\"]     permission {       database_name = local.ch_secrets[\"CH_DB\"]     }     settings {       max_memory_usage_for_user = 17179869184       max_memory_usage          = 17179869184     }   }    host {     type             = \"CLICKHOUSE\"     zone             = \"ru-central1-a\"     subnet_id        = local.subnet_id     assign_public_ip = true   }    maintenance_window {     type = \"WEEKLY\"     hour = 3     day  = \"MON\"   } }  # \u0411\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 resource \"yandex_storage_bucket\" \"data-input\" {   access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key   bucket     = \"neoflex-data-input\" }  # \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433\u0430 \u0438 dead letter queue resource \"yandex_message_queue\" \"dlq\" {   name = \"dlq\"    access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key }  resource \"yandex_message_queue\" \"neoflex\" {   name                       = \"neoflex\"   visibility_timeout_seconds = 600   receive_wait_time_seconds  = 20   delay_seconds              = 0   message_retention_seconds  = 86400 # 1 day    redrive_policy = jsonencode({     deadLetterTargetArn = yandex_message_queue.dlq.arn     maxReceiveCount     = 3   })    access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key }  # \u0421\u0435\u0440\u0432\u0438\u0441\u043d\u0430\u044f \u0443\u0447\u0451\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c resource \"yandex_iam_service_account\" \"sa\" {   folder_id   = local.folder_id   name        = \"neoflex\"   description = \"Neoflex service account to access resource in the folder\" }  resource \"yandex_resourcemanager_folder_iam_member\" \"sa-editor\" {   folder_id = local.folder_id   role      = \"storage.admin\"   member    = \"serviceAccount:${yandex_iam_service_account.sa.id}\" }  resource \"yandex_iam_service_account_static_access_key\" \"sa-static-key\" {   service_account_id = yandex_iam_service_account.sa.id   description        = \"Static access key for object storage\" }  # \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0414\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0435\u0451 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0411\u0430\u043a\u0435\u0442 data \"archive_file\" \"dispatcher\" {   type        = \"zip\"   output_path = \"${path.module}\/..\/packages\/dispatcher.zip\"    source {     content  = file(\"${path.module}\/..\/src\/dispatcher.py\")     filename = \"dispatcher.py\"   }    source {     content  = file(\"${path.module}\/..\/src\/requirements.txt\")     filename = \"requirements.txt\"   } }  resource \"yandex_function\" \"dispatcher\" {   name               = \"dispatcher\"   description        = \"\"   user_hash          = data.archive_file.dispatcher.output_base64sha256   runtime            = \"python39\"   entrypoint         = \"dispatcher.handler\"   memory             = \"128\"   execution_timeout  = \"10\"   service_account_id = yandex_iam_service_account.sa.id   folder_id          = local.folder_id   environment = {     YMQ_QUEUE_URL     = yandex_message_queue.neoflex.id     ACCESS_KEY_ID     = yandex_iam_service_account_static_access_key.sa-static-key.access_key     SECRET_ACCESS_KEY = yandex_iam_service_account_static_access_key.sa-static-key.secret_key   }   content {     zip_filename = data.archive_file.dispatcher.output_path   } }  resource \"yandex_function_scaling_policy\" \"dispatcher\" {   function_id = yandex_function.dispatcher.id   policy {     tag                  = \"$latest\"     zone_instances_limit = 4     zone_requests_limit  = 150   } }  resource \"yandex_function_trigger\" \"data-dispatcher\" {   name        = \"data-dispatcher\"   description = \"Triggered dispatcher when new file is available on S3\"   folder_id   = local.folder_id   object_storage {     bucket_id = yandex_storage_bucket.data-input.id     prefix    = \"some-input-file\"     create    = true     update    = true   }    function {     id                 = yandex_function.dispatcher.id     service_account_id = yandex_iam_service_account.sa.id   }   dlq {     queue_id           = yandex_message_queue.dlq.arn     service_account_id = yandex_iam_service_account.sa.id   } }  # \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u041f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0435\u0451 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 Yandex Message Queue data \"archive_file\" \"processor\" {   type        = \"zip\"   output_path = \"${path.module}\/..\/packages\/processor.zip\"    source {     content  = file(\"${path.module}\/..\/src\/processor.py\")     filename = \"processor.py\"   }    source {     content  = file(\"${path.module}\/..\/src\/requirements.txt\")     filename = \"requirements.txt\"   } }  resource \"yandex_function\" \"processor\" {   name               = \"processor\"   description        = \"\"   user_hash          = data.archive_file.processor.output_base64sha256   runtime            = \"python39\"   entrypoint         = \"processor.handler\"   memory             = \"512\"   execution_timeout  = \"600\"   service_account_id = yandex_iam_service_account.sa.id   folder_id          = local.folder_id   environment = {     ACCESS_KEY_ID     = yandex_iam_service_account_static_access_key.sa-static-key.access_key     SECRET_ACCESS_KEY = yandex_iam_service_account_static_access_key.sa-static-key.secret_key     CH_DB             = yandex_mdb_clickhouse_cluster.neoflex.database.*.name[0]     CH_HOST           = yandex_mdb_clickhouse_cluster.neoflex.host[0].fqdn     CH_PASSWORD       = yandex_mdb_clickhouse_cluster.neoflex.user.*.password[0]     CH_RAW_TABLE      = local.ch_secrets[\"CH_RAW_TABLE\"]     CH_USER           = yandex_mdb_clickhouse_cluster.neoflex.user.*.name[0]     DATA_BUCKET       = yandex_storage_bucket.data-input.id   }   content {     zip_filename = data.archive_file.processor.output_path   } }  resource \"yandex_function_scaling_policy\" \"processor\" {   function_id = yandex_function.processor.id   policy {     tag                  = \"$latest\"     zone_instances_limit = 4     zone_requests_limit  = 150   } }  resource \"yandex_function_trigger\" \"processor\" {   name        = \"processor\"   description = \"\"   folder_id   = local.folder_id   message_queue {     queue_id           = yandex_message_queue.neoflex.arn     service_account_id = yandex_iam_service_account.sa.id     batch_size         = \"1\"     batch_cutoff       = \"10\"   }   function {     id                 = yandex_function.processor.id     service_account_id = yandex_iam_service_account.sa.id   }   dlq {     queue_id           = yandex_message_queue.dlq.arn     service_account_id = yandex_iam_service_account.sa.id   } }<\/code><\/pre>\n<p>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 ClickHouse \u0441\u0434\u0435\u043b\u0430\u043b\u0438. \u0422\u0435\u043f\u0435\u0440\u044c <strong><em>\u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u00ab\u043e\u0447\u0438\u0449\u0430\u0442\u044c\u00bb \u043e\u0442 \u0434\u0443\u0431\u043b\u0435\u0439.<\/em><\/strong><\/p>\n<p>\u041a\u0430\u043a\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438 \u043f\u0440\u0438 \u043f\u043e\u0434\u0431\u043e\u0440\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0443\u043d\u043a\u0442\u0430 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442: \u043f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 XML-\u0444\u0430\u0439\u043b\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434 \u0432\u0441\u0442\u0430\u0432\u043a\u043e\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 ClickHouse \u00ab\u043d\u0430 \u043b\u0435\u0442\u0443\u00bb \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u2013 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438 \u0434\u0443\u0431\u043b\u0435\u0439 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c insert\/upsert \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438. \u041d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u0442\u0430\u043a \u043a\u0430\u043a ClickHouse \u2013 \u043d\u0435 OLTP, \u0430 OLAP \u0438 \u043e\u0431 \u044d\u0442\u043e\u043c \u044f\u0432\u043d\u043e <a href=\"https:\/\/clickhouse.com\/docs\/en\/faq\/general\/olap\/\">\u0441\u043a\u0430\u0437\u0430\u043d\u043e<\/a> \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u043a\u0430\u043a <a href=\"https:\/\/clickhouse.com\/docs\/en\/sql-reference\/statements\/alter\/#mutations\">\u043c\u0443\u0442\u0430\u0446\u0438\u044f<\/a> \u2013 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u044f\u0436\u0435\u043b\u043e\u0432\u0435\u0441\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0435 \u0443\u0434\u0430\u0441\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0447\u0430\u0441\u0442\u043e\/\u043c\u043d\u043e\u0433\u043e\/\u0431\u044b\u0441\u0442\u0440\u043e. \u0417\u0430\u0442\u043e ClickHouse \u043e\u0447\u0435\u043d\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 (\u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u043a \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044e \u0441\u0442\u0430\u0442\u044c\u044e-benchmark <a href=\"https:\/\/tech.marksblogg.com\/faster-clickhouse-imports-csv-parquet-mysql.html\">Faster ClickHouse Imports<\/a>).<\/p>\n<\/li>\n<li>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u2013 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0442\u0430\u0431\u043b\u0438\u0446 <a href=\"https:\/\/clickhouse.com\/docs\/en\/engines\/table-engines\/mergetree-family\/replacingmergetree\/\">ReplacingMergeTree<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u043a\u0430\u043a \u0440\u0430\u0437 \u0434\u043b\u044f \u0434\u0435\u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043a\u043b\u044e\u0447\u0443. \u041d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043f\u043e <s>\u0434\u0432\u0443\u043c \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c<\/s> \u043f\u0440\u0438\u0447\u0438\u043d\u0435:<\/p>\n<\/li>\n<\/ul>\n<ol>\n<li>\n<p>      \u041d\u0430 \u00ab\u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044b\u0445\u00bb (\u0434\u0435\u0434\u0443\u0431\u043b\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445) \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0443\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u044b \u0432 \u0440\u0435\u0436\u0438\u043c\u0435, \u0431\u043b\u0438\u0437\u043a\u043e\u043c \u043a online, \u0430 \u0434\u0432\u0438\u0436\u043e\u043a ReplacingMergeTree \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442 \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u0444\u043e\u043d\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0438 \u0432 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0440\u0438\u0441\u043a \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u0443 \u043d\u0430 \u0437\u0430\u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0432\u0438\u0442\u0440\u0438\u043d\u0430\u043c \u0432\u044b\u0441\u043e\u043a\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0442\u043e\u0447\u043d\u044b\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>      <s>ReplacingMergeTree \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0434\u0435\u0434\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043f\u043e \u043a\u043b\u044e\u0447\u0443 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u043a\u0438 (\u0441\u0435\u043a\u0446\u0438\u044f ORDER BY \u0432 DLL \u0442\u0430\u0431\u043b\u0438\u0446\u044b), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0434\u0443\u0431\u043b\u0438 \u043f\u043e \u043a\u043b\u044e\u0447\u0443, \u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0438\u0437 \u0434\u0443\u0431\u043b\u0435\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 (\u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 timestamp \u0432 \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430);<\/s> \u2013 <em>\u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439, \u0441\u043f\u0430\u0441\u0438\u0431\u043e <\/em><a class=\"mention\" href=\"\/users\/volrath\">@Volrath<\/a><\/p>\n<\/li>\n<\/ol>\n<ul>\n<li>\n<p>\u0422\u0440\u0435\u0442\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438\u0441\u044c, \u2013 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u0431\u0443\u0444\u0435\u0440\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043b\u043e \u0432 \u0411\u0430\u043a\u0435\u0442 \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c merge \u0431\u0443\u0444\u0435\u0440\u043d\u043e\u0439 \u0432 \u00ab\u0447\u0438\u0441\u0442\u043e\u0432\u0443\u044e\u00bb \u0442\u0430\u0431\u043b\u0438\u0446\u0443. \u042d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043c\u044b \u0438 \u043e\u043f\u0438\u0448\u0435\u043c \u0434\u0430\u043b\u0435\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0411\u0443\u0444\u0435\u0440\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u00ab\u0441\u044b\u0440\u044b\u0435\u00bb \u0434\u0430\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u00ab\u041f\u0430\u0440\u0441\u0435\u0440\u00bb, \u0438\u043c\u0435\u0435\u0442 \u043f\u043e\u043b\u0435 \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0432\u0441\u0442\u0430\u0432\u043a\u0438, \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u0438 \u0441\u0440\u043e\u043a \u0436\u0438\u0437\u043d\u0438 \u0437\u0430\u043f\u0438\u0441\u0435\u0439:<\/p>\n<pre><code>DROP TABLE IF EXISTS raw; CREATE TABLE raw ( ...     insertTime DateTime('Europe\/Moscow') DEFAULT now()   ) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(insertTime) ORDER BY (...) TTL toStartOfDay(insertTime) + INTERVAL 1 DAY;<\/code><\/pre>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435, <a href=\"https:\/\/clickhouse.com\/docs\/en\/engines\/table-engines\/mergetree-family\/mergetree#table_engine-mergetree-ttl\">TTL<\/a> \u0432 ClickHouse \u2013 \u043e\u0442\u043b\u0438\u0447\u043d\u0430\u044f \u0444\u0438\u0447\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0432 DDL \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438\u0437\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u0441 \u043e\u0442 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446 (\u043e\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0434\u0436\u043e\u0431\u043e\u0432, \u0438\u0445 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f, \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430).<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Yandex Cloud Functions Trigger \u0442\u0438\u043f\u0430 Timer, \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u00ab\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0435\u043b\u044c\u00bb, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u00ab\u0441\u044b\u0440\u044b\u0435\u00bb \u0438 \u00ab\u0447\u0438\u0441\u0442\u043e\u0432\u044b\u0435\u00bb \u0434\u0430\u043d\u043d\u044b\u0435, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u0432 \u0441\u044b\u0440\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0435\u0441\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043d\u043e\u0432\u0435\u043d\u044c\u043a\u043e\u0435 \u0438 \u043f\u043e\u0440\u0430 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0447\u0438\u0441\u0442\u043e\u0432\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u0421\u0445\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/db5\/947\/b86\/db5947b8650085bb6eb92bd313b4c474.png\" width=\"1282\" height=\"776\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/db5\/947\/b86\/db5947b8650085bb6eb92bd313b4c474.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 (2), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 merge:<\/p>\n<pre><code>WITH rawParts AS ( SELECT partKey, MAX(insertTime) maxInsertTime FROM raw WHERE insertTime > toStartOfMinute(now()) - INTERVAL 1 HOUR GROUP BY partKey), cleanParts AS ( SELECT partKey, MAX(insertTime) maxInsertTime FROM clean WHERE partKey IN (SELECT partKey FROM rawParts) GROUP BY partKey) SELECT DISTINCT toYYYYMMDD(rawParts.partKey) AS partKey FROM rawParts LEFT JOIN parts USING partKey WHERE rawParts.maxInsertTime > parts.maxInsertTime ORDER BY partKey;<\/code><\/pre>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0438\u0437 \u0431\u0443\u0444\u0435\u0440\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0447\u0430\u0441 \u0438 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0430\u043c\u043e\u0439 \u0441\u0432\u0435\u0436\u0435\u0439 \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0441 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u044f\u043c\u0438 \u00ab\u0447\u0438\u0441\u0442\u043e\u0432\u043e\u0439\u00bb \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0415\u0441\u043b\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u043e \u0440\u0430\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 (\u0435\u0441\u0442\u044c \u043f\u043e\u0434\u043e\u0437\u0440\u0435\u043d\u0438\u0435 \u043d\u0430 \u00ab\u0441\u0432\u0435\u0436\u0438\u0435\u00bb \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0432 \u00ab\u0447\u0438\u0441\u0442\u043e\u0432\u043e\u0439\u00bb \u0442\u0430\u0431\u043b\u0438\u0446\u0435), \u0442\u043e \u0442\u0430\u043a\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u00ab\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0435\u043b\u044c\u00bb, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0437\u0430\u043f\u0440\u043e\u0441 (2), \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u043e \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u00ab\u043f\u043e\u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e\u00bb merge (3). <\/p>\n<p>\u0421\u0430\u043c \u00ab\u043f\u043e\u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439\u00bb merge (5) \u0432 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0440\u044f\u0434\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432:<\/p>\n<pre><code>-- \u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b: ALTER TABLE tmp DROP PARTITION {partKey};  -- \u0412\u0441\u0442\u0430\u0432\u043a\u0430 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043d\u0430\u043a\u043e\u043f\u043b\u0435\u043d\u043d\u044b\u0445, \u0441\u0432\u0435\u0436\u0438\u0445 \u0438 \u0441\u0440\u0430\u0437\u0443 \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445: INSERT INTO tmp SELECT * FROM ( SELECT * FROM raw r WHERE partkey = {partKey} UNION ALL SELECT * FROM clean WHERE partkey = {partKey} ) ORDER BY field1, field2, field3, ... LIMIT 1 BY field1, field2, field3, ...;  -- \u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0432 \u0447\u0438\u0441\u0442\u043e\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435: ALTER TABLE clean DROP PARTITION {partKey};  -- \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0438\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u0432 \u0447\u0438\u0441\u0442\u043e\u0432\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443: ALTER TABLE tmp MOVE PARTITION {partKey} TO TABLE clean;<\/code><\/pre>\n<p>\u0414\u0430\u043d\u043d\u044b\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434\u043c\u0435\u043d\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0432 \u00ab\u0447\u0438\u0441\u0442\u043e\u0432\u043e\u0439\u00bb \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0432\u0435\u0441\u044c\u043c\u0430 \u043d\u0435\u0437\u0430\u043c\u0435\u0442\u043d\u044b\u043c \u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0435\u0451 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u0441\u0442\u0430\u0432\u043a\u0435 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441, \u0430 \u0441 \u044d\u0442\u0438\u043c \u0434\u0435\u043b\u043e\u043c \u0432 ClickHouse \u043d\u0435 \u0432\u0441\u0451 \u0442\u0430\u043a \u0443\u0436 \u043f\u0440\u043e\u0441\u0442\u043e: \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c <a href=\"https:\/\/clickhouse.com\/docs\/ru\/operations\/settings\/query-complexity\/#settings_max_memory_usage\">max_memory_usage<\/a> (\u0438\u043b\u0438 max_memory_usage_for_user). \u0415\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0435 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u044c, \u0442\u043e\u0433\u0434\u0430 \u0432\u0435\u0441\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439:<\/p>\n<p><em>DB::Exception: Memory limit (for query) exceeded<\/em><\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043c\u0430 \u043e\u0434\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 (\u0447\u0438\u0442\u0430\u0439 \u2013 \u043a\u043b\u044e\u0447 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f) \u0438 max_memory_usage (\u0447\u0438\u0442\u0430\u0439 \u2013 \u043e\u0431\u044a\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438 \u0443 \u0445\u043e\u0441\u0442\u0430 ClickHouse \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432).<\/p>\n<p>\u0423\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u00ab\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0435\u043b\u044c\u00bb:<\/p>\n<pre><code># \u0438\u043c\u043f\u043e\u0440\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 # import ...  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043e\u0431\u043b\u0430\u043a\u0443 boto_session = boto3.session.Session(     aws_access_key_id=os.getenv('ACCESS_KEY_ID'),     aws_secret_access_key=os.getenv('SECRET_ACCESS_KEY') )  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a ClickHouse clickhouse = Client(host=os.getenv('CH_HOST'),                     user=os.getenv('CH_USER'),                     password=os.getenv('CH_PASSWORD'),                     database=os.getenv('CH_DB'),                     secure=True)  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043e\u0447\u0435\u0440\u0435\u0434\u0438 Yandex Queue \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 ymq_queue = boto_session.resource(     service_name='sqs',     endpoint_url='https:\/\/message-queue.api.cloud.yandex.net',     region_name='ru-central1' ).Queue(os.getenv('YMQ_QUEUE_URL'))   # \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 def handler(event, context):     try:         if event is not None and type(event) == dict and 'messages' in event:             for message in event['messages']:                 if 'event_metadata' in message and \\                         'event_type' in message['event_metadata'] and \\                         message['event_metadata'][                             'event_type'] == 'yandex.cloud.events.serverless.triggers.TimerMessage':                     # \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044e, \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c\u0443 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u043c \u0441 \u0442\u0438\u043f\u043e\u043c Timer                     # \u043f\u043e\u0438\u0441\u043a \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0434\u043b\u044f merge \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u0439 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c                     queue_partitions()                 else:                     # \u0437\u0430\u043f\u0443\u0441\u043a \u043f\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438                     task_json = json.loads(message['details']['message']['body'])                     partKey = str(task_json['partKey'])                     # merge \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438                     do_partition(partKey=partKey)      except Exception as ex:         logging.error(ex)  # \u043f\u043e\u0438\u0441\u043a \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 def queue_partitions():     # \u0437\u0430\u043f\u0440\u043e\u0441 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u0434\u043b\u044f merge (\u0441\u043c. \u0432\u044b\u0448\u0435 \u043f\u0440\u0438\u043c\u0435\u0440)     query = '...'      rows_gen = clickhouse.execute_iter(query)     # \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c     for partKey in rows_gen:         ymq_queue.send_message(MessageBody=json.dumps({             'partKey': partKey[0]         }))  # merge \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0438 (\u0441\u043c. \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432\u044b\u0448\u0435) def do_partition(partKey):     # ... <\/code><\/pre>\n<p>\u0422\u0430\u043a \u044d\u0442\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 Terraform (\u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f \u0432 \u0434\u043e\u0431\u0430\u0432\u043e\u043a \u043a \u0442\u043e\u0439, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0440\u0430\u043d\u0435\u0435):<\/p>\n<pre><code># \u0424\u0443\u043d\u043a\u0446\u0438\u044f \"\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u0435\u043b\u044c\" data \"archive_file\" \"cleaner\" {   type        = \"zip\"   output_path = \"${path.module}\/..\/packages\/cleaner.zip\"    source {     content  = file(\"${path.module}\/..\/src\/cleaner.py\")     filename = \"cleaner.py\"   }    source {     content  = file(\"${path.module}\/..\/src\/requirements.txt\")     filename = \"requirements.txt\"   } }  resource \"yandex_function\" \"cleaner\" {   name               = \"cleaner\"   description        = \"\"   user_hash          = data.archive_file.cleaner.output_base64sha256   runtime            = \"python39\"   entrypoint         = \"cleaner.handler\"   memory             = \"256\"   execution_timeout  = \"300\"   service_account_id = yandex_iam_service_account.sa.id   folder_id          = local.folder_id   environment        = {     CH_DB             = yandex_mdb_clickhouse_cluster.neoflex.database.*.name[0]     CH_HOST           = yandex_mdb_clickhouse_cluster.neoflex.host[0].fqdn     CH_PASSWORD       = yandex_mdb_clickhouse_cluster.neoflex.user.*.password[0]     CH_USER           = yandex_mdb_clickhouse_cluster.neoflex.user.*.name[0]     ACCESS_KEY_ID     = yandex_iam_service_account_static_access_key.sa-static-key.access_key     SECRET_ACCESS_KEY = yandex_iam_service_account_static_access_key.sa-static-key.secret_key     YMQ_QUEUE_URL     = yandex_message_queue.cleaner.id     YANDEX_FOLDER_ID  = local.folder_id     YDB_ENDPOINT      = yandex_ydb_database_serverless.neoflex.document_api_endpoint   }   content {     zip_filename = data.archive_file.cleaner.output_path   } }  resource \"yandex_function_scaling_policy\" \"cleaner\" {   function_id = yandex_function.cleaner.id   policy {     tag                  = \"$latest\"     zone_instances_limit = 4     zone_requests_limit  = 150   } }  # \u0422\u0440\u0438\u0433\u0433\u0435\u0440-\u0442\u0430\u0439\u043c\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e resource \"yandex_function_trigger\" \"cleaner_cron\" {   name        = \"cleaner-cron\"   description = \"\"   folder_id   = local.folder_id   timer {     cron_expression = \"*\/5 * * * ? *\"   }   function {     id                 = yandex_function.cleaner.id     service_account_id = yandex_iam_service_account.sa.id   } }  # \u0422\u0440\u0438\u0433\u0433\u0435\u0440 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 resource \"yandex_function_trigger\" \"cleaner_queue\" {   name        = \"cleaner-queue\"   description = \"\"   folder_id   = local.folder_id   message_queue {     queue_id           = yandex_message_queue.cleaner.arn     service_account_id = yandex_iam_service_account.sa.id     batch_size         = \"1\"     batch_cutoff       = \"10\"   }   function {     id                 = yandex_function.cleaner.id     service_account_id = yandex_iam_service_account.sa.id   } }  # \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0441 \u0438\u043c\u0435\u043d\u0430\u043c\u0438 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f resource \"yandex_message_queue\" \"cleaner\" {   name                       = \"partitions2merge\"   visibility_timeout_seconds = 600   receive_wait_time_seconds  = 20   delay_seconds              = 0   message_retention_seconds  = 86400 # 1 day    redrive_policy = jsonencode({     deadLetterTargetArn = yandex_message_queue.dlq.arn     maxReceiveCount     = 3   })    access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key } <\/code><\/pre>\n<p>\u0418\u0442\u0430\u043a, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0431\u043b\u0430\u043a\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438 \u0438 \u043e\u0447\u0438\u0441\u0442\u0438\u043b\u0438, \u0442\u0435\u043f\u0435\u0440\u044c<strong><em> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0447\u0438\u0449\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0440\u044f\u0434 \u0432\u0438\u0442\u0440\u0438\u043d \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f\u043c\u0438.<\/em><\/strong><\/p>\n<p>\u0422\u0443\u0442 \u0441\u0445\u0435\u043c\u0430, \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u044b \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u2013 \u0435\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0438 \u043d\u0443\u0436\u043d\u043e \u043d\u0430 \u0435\u0451 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u0438\u0442\u044c\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u0443. \u0421\u0442\u043e\u0438\u0442\u044c \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043d\u044e\u0430\u043d\u0441, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c, \u2013 \u00a0\u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u0432 ClickHouse.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439:<\/p>\n<pre><code>CREATE TABLE clean ( id Int64, positions Nested(         id UInt16,         value1 String, value2 String     ), insertTime DateTime('Europe\/Moscow') DEFAULT now() ) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(insertTime) ORDER BY (id); <\/code><\/pre>\n<p>\u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043b\u043e\u0441\u043a\u043e\u043c \u0432\u0438\u0434\u0435 \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code>SELECT id, p.id, p.value1, p.value2  FROM clean ARRAY JOIN positions AS p <\/code><\/pre>\n<p>\u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. <\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0434\u0440\u0443\u0433\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043c\u0430\u043f\u043f\u0438\u043d\u0433\u0430\u043c\u0438:<\/p>\n<pre><code>CREATE TABLE mappings ( from String, to String ) ENGINE = MergeTree() ORDER BY (from); <\/code><\/pre>\n<p>\u0418 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u043a \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044e \u043d\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u0447\u0438\u0441\u0442\u043e\u0432\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438:<\/p>\n<pre><code>SELECT p.value1, m.to value1_to FROM clean ARRAY JOIN positions AS p LEFT JOIN mappings AS m ON p.value1 = m.from; <\/code><\/pre>\n<p>\u042d\u0442\u043e \u0442\u043e\u0436\u0435 \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. <\/p>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u043f\u043e \u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u043f\u043e\u043b\u044e:<\/p>\n<pre><code>SELECT p.value1, m1.to value1_to, p.value2, m2.to value2_to FROM clean ARRAY JOIN positions AS p LEFT JOIN mappings AS m1 ON p.value1 = m1.from LEFT JOIN mappings AS m2 ON p.value2 = m2.from <\/code><\/pre>\n<p>\u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<p><em>DB::Exception: Multiple JOIN does not support mix with ARRAY JOINs<\/em><\/p>\n<p>\u0414\u0430, \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435. \u0418 \u043e\u0431\u043e\u0439\u0442\u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code>SELECT p.value1, value1_to, p.value2, m2.to value2_to FROM ( SELECT p.value1, m1.to value1_to, p.value2 FROM clean ARRAY JOIN positions AS p LEFT JOIN mappings AS m1 ON p.value1 = m1.from ) t LEFT JOIN mappings AS m2 ON p.value2 = m2.from <\/code><\/pre>\n<p>\u041d\u043e, \u043a\u0430\u043a \u043e\u0442\u043c\u0435\u0447\u0435\u043d\u043e \u0440\u0430\u043d\u0435\u0435, \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0430\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0430 \u043e\u0431\u044a\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445. \u0418, \u0435\u0441\u043b\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0431\u0443\u0434\u0443\u0442 \u0442\u0440\u0438\u043b\u043b\u0438\u043e\u043d\u044b \u0441\u0442\u0440\u043e\u043a, \u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u0440\u044f\u0434 \u043b\u0438 \u0441\u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d. \u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0443\u043f\u0440\u043e\u0449\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 (\u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0432\u0430 \u0440\u0430\u0437\u0430 JOIN), \u043b\u0438\u0431\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0442\u044c \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 (\u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u0430\u043f\u043f\u0438\u043d\u0433\u0430), \u043b\u0438\u0431\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0447\u0430\u0441\u0442\u044f\u043c\u0438 (\u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u043f\u0440\u0438 \u00ab\u043e\u0447\u0438\u0441\u0442\u043a\u0435\u00bb \u0441\u044b\u0440\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445) \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0435 \u0432\u044b\u0448\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u044f.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 ClickHouse \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u00a0\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445. \u00a0\u0414\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0433\u043e SQL \u043e\u043d, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u0442\u044f\u0433\u0438\u0432\u0430\u0435\u0442. \u0422\u043e\u0442 \u0436\u0435 <a href=\"https:\/\/clickhouse.com\/docs\/en\/sql-reference\/statements\/select\/array-join\">ARRAY JOIN<\/a> \u0432 \u043e\u0434\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435\/\u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. <\/p>\n<p>\u041f\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c ClickHouse \u043c\u044b \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0442\u0430\u0431\u043b\u0438\u0446, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0441\u043a\u0432\u043e\u0437\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0443: \u043e\u0442 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441 \u0441\u044b\u0440\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0432\u0438\u0442\u0440\u0438\u043d, \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 ClickHouse. <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0444\u0438\u043d\u0438\u0448\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0430 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0441 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0438\u043d\u043e\u0433\u0434\u0430 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0438\u043b\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446, \u0418\u043d\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0430\u043f\u043f\u0438\u043d\u0433 \u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u00a0\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0435\u0449\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u044b\u0440\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0434 \u0432\u0441\u0442\u0430\u0432\u043a\u043e\u0439 \u0432 ClickHouse. <\/p>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u0447\u0435\u043c \u043f\u0440\u043e\u0449\u0435 \u0438 \u043f\u043e\u043b\u043d\u0435\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 (\u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438), \u0442\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0438 \u0434\u0435\u0448\u0435\u0432\u043b\u0435 \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0441 \u043d\u0438\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0435\u043b\u0435\u0441\u0442\u0435\u0439 Full Scan \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0443 ClickHouse.<\/p>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u043f\u043b\u044e\u0441\u043e\u0432 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f ClickHouse, \u043a\u0430\u043a \u043d\u0430\u043c \u0432\u0438\u0434\u0438\u0442\u0441\u044f, \u044d\u0442\u0430 \u0421\u0423\u0411\u0414 \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u0430 \u0432 \u043a\u0435\u0439\u0441\u0430\u0445, \u043a\u043e\u0433\u0434\u0430 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 online \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043a\u043e\u043b\u043e\u0441\u0441\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0451\u043c\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 (\u0445\u043e\u0442\u044f \u0431\u044b \u0431\u0435\u0437 \u043f\u043e\u0434\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 JOIN \u0441 \u043a\u0440\u0443\u043f\u043d\u044b\u043c\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438).<\/p>\n<p>\u0412\u0441\u0442\u0430\u0432\u043a\u0430 \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 ClickHouse \u2013 \u043d\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u043a\u0430\u043a \u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0430 (\u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0435\u0439) \u0438\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0432\u0435\u0434\u044c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434 \u0442\u0430\u043a\u043e\u0439 \u0442\u0438\u043f \u0437\u0430\u0434\u0430\u0447 ClickHouse \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0441\u044f \u0432 Yandex.Metrica. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u0432\u043e\u0435\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u0433\u043e SQL, \u0445\u043e\u0442\u044c \u0438 \u0432\u0435\u0441\u044c\u043c\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e\u0433\u043e, \u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f JDBC\/ODBC \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u043c \u043f\u043b\u044e\u0441\u043e\u043c.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/688126\/\"> https:\/\/habr.com\/ru\/articles\/688126\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0434\u0435\u043b\u0438\u043c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430 \u0431\u0430\u0437\u0435 \u0421\u0423\u0411\u0414 ClickHouse \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 Yandex Cloud. \u041c\u044b \u043d\u0435 \u043a\u043e\u0441\u043d\u0451\u043c\u0441\u044f \u0442\u043e\u043d\u043a\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a ClickHouse \u0438\u043b\u0438 \u0435\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u043e \u0437\u0430\u0442\u0440\u043e\u043d\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u043d\u0430 \u043d\u0430\u0448 \u0432\u0437\u0433\u043b\u044f\u0434 \u0442\u0435\u043c\u044b:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 On-premise \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0439 ClickHouse \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 Yandex Cloud \u2013 Functions, Object Storage, Message Queue;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0430\u043a \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\/\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u043c ClickHouse \u2013 \u043e\u0447\u0438\u0449\u0430\u0442\u044c \u0438 \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u044b; \u043a\u0430\u043a\u0438\u0435 \u00ab\u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438\u00bb \u043d\u0430\u043c \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0438\u0441\u044c \u043d\u0430 \u044d\u0442\u043e\u043c \u043f\u0443\u0442\u0438. <\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0418\u0441\u0445\u043e\u0434\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430:<\/strong><\/p>\n<p>\u0412 On-premise \u0432 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0442 XML-\u0444\u0430\u0439\u043b\u044b \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. \u041a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u043c\u0435\u0435\u0442 \u043a\u043b\u044e\u0447 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b\/\u043c\u0430\u0441\u0441\u0438\u0432\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432. <\/p>\n<p>\u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 \u043c\u043e\u0433\u0443\u0442 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f: \u0441 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u043a\u043b\u044e\u0447\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a \u0432 \u043e\u0434\u043d\u043e\u043c, \u0442\u0430\u043a \u0438 \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0440\u0430\u0437\u043d\u044b\u0445 XML-\u0444\u0430\u0439\u043b\u0430\u0445. \u0418\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 timestamp \u0438\u0445 \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0435-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0435, \u043d\u043e \u0432 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435, \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u043a \u044d\u0442\u043e\u043c\u0443 timestamp.<\/p>\n<p><strong>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e:<\/strong> <\/p>\n<ul>\n<li>\n<p>\u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 XML-\u0444\u0430\u0439\u043b\u043e\u0432 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 ClickHouse \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 (\u0441 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438, \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 \u0438 \u0442.\u0434.) \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0442\u0441\u0442\u0430\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0442.\u0435. \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 ClickHouse \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0432 On-premise;<\/p>\n<\/li>\n<li>\n<p>\u0434\u0430\u043d\u043d\u044b\u0435 \u00ab\u043e\u0447\u0438\u0449\u0430\u0442\u044c\u00bb \u043e\u0442 \u0434\u0443\u0431\u043b\u0435\u0439: \u0441\u0440\u0435\u0434\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u0442, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u043d\u043d\u0438\u0439 timestamp \u0432 \u0438\u043c\u0435\u043d\u0438 \u0444\u0430\u0439\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0441\u0442\u0440\u043e\u0438\u0442\u044c\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0432\u0438\u0442\u0440\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u043c\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u0435\u0435.<\/strong><\/p>\n<p><strong>\u0414\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 XML-\u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0432 ClickHouse \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0441 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u043c \u043e\u0442\u0441\u0442\u0430\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438. <\/strong><\/p>\n<p>\u041f\u0440\u043e\u0439\u0434\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043a\u0443\u0440\u0441 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u00ab<a href=\"https:\/\/go.teachbase.ru\/course_sessions\/363773\">\u041f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u043f\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b<\/a>\u00bb (\u043a\u0441\u0442\u0430\u0442\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0442\u0435\u043c, \u043a\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0438 ClickHouse) \u0438 \u0443\u0432\u0438\u0434\u0435\u0432 \u0444\u0438\u0448\u043a\u0438 \u0432\u0440\u043e\u0434\u0435 <a href=\"https:\/\/clickhouse.com\/docs\/en\/integrations\/kafka\/kafka-table-engine\">\u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 Kafka<\/a>, \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043b\u0438, \u0447\u0442\u043e \u0434\u043b\u044f ClickHouse \u0438\u043b\u0438 \u0435\u0433\u043e cli-\u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c XML-\u0444\u0430\u0439\u043b \u0438 \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u0441\u0442\u043e\u043b\u0431\u0446\u0430\u043c. \u041d\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 ClickHouse \u043f\u043e\u043a\u0430 <a href=\"https:\/\/clickhouse.com\/docs\/en\/interfaces\/formats\/#xml\">\u043d\u0435 \u0443\u043c\u0435\u0435\u0442<\/a>. \u041f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c XML \u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0442\u0430\u0432\u043a\u0443 \u0432 ClickHouse. <\/p>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u043f\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438. \u0412\u044b\u0431\u0438\u0440\u0430\u043b\u0438 \u043c\u0435\u0436\u0434\u0443 Airflow \u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438 Yandex Cloud, \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u0440\u0438\u0448\u043b\u0438 \u043a\u043e \u0432\u0442\u043e\u0440\u043e\u043c\u0443, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u2014 \u0431\u00f3\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0430 Yandex Cloud Functions. \u041f\u0440\u0438\u0447\u0438\u043d\u043e\u0439 \u0442\u043e\u043c\u0443 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u043b\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0444\u0430\u043a\u0442\u043e\u0440\u044b:<\/p>\n<ul>\n<li>\n<p>ClickHouse \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 Yandex Cloud \u043a\u0430\u043a <a href=\"https:\/\/cloud.yandex.ru\/services\/managed-clickhouse\">\u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441<\/a>, \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0442\u043e\u043c \u0436\u0435 \u043e\u0431\u043b\u0430\u043a\u0435 \u0440\u044f\u0434\u043e\u043c \u0441 \u0411\u0414;<\/p>\n<\/li>\n<li>\n<p>Yandex Cloud Functions \u0438\u043c\u0435\u044e\u0442 <a href=\"https:\/\/cloud.yandex.ru\/docs\/billing\/concepts\/serverless-free-tier#sf\">\u043d\u0435\u0442\u0430\u0440\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043c<\/a> (\u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u00abfree tier\u00bb), \u0447\u0442\u043e \u0443\u0434\u0435\u0448\u0435\u0432\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443, \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430 \u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0443\u044e \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044e. \u041d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 On-premise \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 Airflow (\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432);<\/p>\n<\/li>\n<li>\n<p>\u0412 Yandex Cloud \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043b\u0435\u0433\u043a\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f Yandex Cloud Functions: Yandex Object Storage, Yandex Message Queue, Yandex DB \u0438 \u0434\u0440\u0443\u0433\u0438\u0435. \u041e\u043d\u0438 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u0432\u043e\u0439 \u00abfree tier\u00bb;<\/p>\n<\/li>\n<li>\n<p>\u041b\u0435\u0433\u043a\u043e\u0441\u0442\u044c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f Yandex Cloud Functions: \u043c\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u044b \u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u0445 \u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 Terraform (\u0443 Yandex Cloud \u0435\u0441\u0442\u044c <a href=\"https:\/\/registry.terraform.io\/providers\/yandex-cloud\/yandex\/latest\/docs\">provider<\/a>) \u2013 \u0442\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435, CICD\/DevOps.<\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0412 On-premise \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0441\u043a\u0440\u0438\u043f\u0442 (\u0435\u0433\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043d\u0435 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c, \u0442.\u043a. \u043e\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u043f\u043e\u043b\u043b\u0438\u0442 \u043e\u0431\u0449\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u0432\u0448\u0438\u0439 \u0432 \u043d\u0435\u0451 XML-\u0444\u0430\u0439\u043b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442 (1) \u0432 \u0411\u0430\u043a\u0435\u0442 Yandex Object Storage. \u041e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0411\u0430\u043a\u0435\u0442 \u0441\u043b\u0443\u0436\u0438\u0442 \u0441\u0438\u0433\u043d\u0430\u043b\u043e\u043c \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 (2) \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u00ab\u0414\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u00bb, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043a\u043b\u0430\u0434\u0451\u0442 (3) \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u0444\u0430\u0439\u043b\u0435 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433 (\u0441\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u043d\u0438\u0435) \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438. \u0414\u0430\u043b\u044c\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u00ab\u041f\u0430\u0440\u0441\u0435\u0440\u00bb \u0447\u0438\u0442\u0430\u0435\u0442 (4) \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u0444\u0430\u0439\u043b \u0438\u0437 \u0411\u0430\u043a\u0435\u0442\u0430 \u0441\u0435\u0431\u0435 \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u0443\u044e \u043f\u0430\u043c\u044f\u0442\u044c, \u043f\u0430\u0440\u0441\u0438\u0442 XML \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 (5) \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435. \u041f\u043e \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0444\u0430\u0439\u043b \u0438\u0437 \u0411\u0430\u043a\u0435\u0442\u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f (6), \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c \u043c\u0435\u0441\u0442\u043e \u0438 \u043d\u0435 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u0432\u043f\u0443\u0441\u0442\u0443\u044e.<\/p>\n<p>\u0412 ClickHouse \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 XML \u0438\u0437 \u0444\u0430\u0439\u043b\u0430. \u0412\u0441\u0451 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0431\u043e\u0433\u0430\u0442\u043e\u043c\u0443 \u0441\u043f\u0438\u0441\u043a\u0443 <a href=\"https:\/\/clickhouse.com\/docs\/en\/sql-reference\/data-types\/\">\u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445<\/a> ClickHouse.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u00ab\u041f\u0430\u0440\u0441\u0435\u0440\u00bb \u043d\u0430 Python \u0432 \u043e\u0431\u043b\u0430\u043a\u0435:<\/p>\n<pre><code># import \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439 import boto3  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043e\u0431\u043b\u0430\u043a\u0443 boto_session = boto3.session.Session(     aws_access_key_id=os.getenv('ACCESS_KEY_ID'),     aws_secret_access_key=os.getenv('SECRET_ACCESS_KEY') )  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u043d\u043e\u043c\u0443 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0443 s3 = boto_session.client(     service_name='s3',     endpoint_url='https:\/\/storage.yandexcloud.net' )  # \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a ClickHouse clickhouse = Client(host=os.getenv('CH_HOST'),                     user=os.getenv('CH_USER'),                     password=os.getenv('CH_PASSWORD'),                     database=os.getenv('CH_DB'),                     secure=True,                     settings={'input_format_import_nested_json': 1})  # \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0441\u043e\u0431\u044b\u0442\u0438\u0439 # \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u0447\u0442\u043e \u0432\u044b\u0437\u043e\u0432 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0451\u043b \u043f\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, # \u0438\u0437 \u0442\u0435\u043b\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0431\u0435\u0440\u0451\u0442\u0441\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0444\u0430\u0439\u043b\u0430, # \u0444\u0430\u0439\u043b \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043f\u0430\u0440\u0441\u0438\u0442\u0441\u044f, \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 ClickHouse def handler(event, context):     if 'messages' in event:         for message in event['messages']:             # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f:             task_json = json.loads(message['details']['message']['body'])                          # \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0438\u0437 S3:             get_object_response = s3.get_object(Bucket=task_json['bucket_id'],                                          Key=task_json['object_id'])                                                      # \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430:             parsed_data = parse(data=xmltodict.parse(get_object_response['Body'].read()),                                          filename=task_json['object_id'])                                                      # \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445:             store(data=parsed_data, file=task_json['object_id'])                          # \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430:             s3.delete_object(Bucket=task_json['bucket_id'], Key=task_json['object_id'])                           def parse(data, filename):     # ... \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430      def store(data, filename):     # ... \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0432 ClickHouse <\/code><\/pre>\n<p>\u0414\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0430 Terraform:<\/p>\n<pre><code># \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a Yandex cloud \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0432 Yandex Object Storage terraform {   required_providers {     yandex = {       source = \"yandex-cloud\/yandex\"     }   }   backend \"s3\" {     endpoint   = \"storage.yandexcloud.net\"     bucket     = \"neoflex-tf-state\"     region     = \"ru-central1\"     key        = \"terraform.tfstate\"     access_key = \"xxx\"     secret_key = \"xxx\"      skip_region_validation      = true     skip_credentials_validation = true   } }  provider \"yandex\" {   service_account_key_file = \"key.json\" }  locals {   folder_id    = \"xxx\"   ch_secrets   = jsondecode(file(\"clickhouse.json\"))   cluster_name = \"neoflex\"   network_id   = \"xxx\"   subnet_id    = \"xxx\" }  # \u0420\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 ClickHouse resource \"yandex_mdb_clickhouse_cluster\" \"neoflex\" {   name                    = local.cluster_name   environment             = \"PRESTABLE\"   network_id              = local.network_id   folder_id               = local.folder_id   service_account_id      = yandex_iam_service_account.sa.id   sql_database_management = false   sql_user_management     = false    clickhouse {     resources {       resource_preset_id = \"s2.large\"       disk_type_id       = \"network-ssd\"       disk_size          = 100     }   }    database {     name = local.ch_secrets[\"CH_DB\"]   }    user {     name     = local.ch_secrets[\"CH_USER\"]     password = local.ch_secrets[\"CH_PASSWORD\"]     permission {       database_name = local.ch_secrets[\"CH_DB\"]     }     settings {       max_memory_usage_for_user = 17179869184       max_memory_usage          = 17179869184     }   }    host {     type             = \"CLICKHOUSE\"     zone             = \"ru-central1-a\"     subnet_id        = local.subnet_id     assign_public_ip = true   }    maintenance_window {     type = \"WEEKLY\"     hour = 3     day  = \"MON\"   } }  # \u0411\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u043f\u0440\u0438\u0451\u043c\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043e\u0431\u043b\u0430\u043a\u0435 resource \"yandex_storage_bucket\" \"data-input\" {   access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key   bucket     = \"neoflex-data-input\" }  # \u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0434\u043b\u044f \u0442\u0440\u043e\u0442\u0442\u043b\u0438\u043d\u0433\u0430 \u0438 dead letter queue resource \"yandex_message_queue\" \"dlq\" {   name = \"dlq\"    access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key }  resource \"yandex_message_queue\" \"neoflex\" {   name                       = \"neoflex\"   visibility_timeout_seconds = 600   receive_wait_time_seconds  = 20   delay_seconds              = 0   message_retention_seconds  = 86400 # 1 day    redrive_policy = jsonencode({     deadLetterTargetArn = yandex_message_queue.dlq.arn     maxReceiveCount     = 3   })    access_key = yandex_iam_service_account_static_access_key.sa-static-key.access_key   secret_key = yandex_iam_service_account_static_access_key.sa-static-key.secret_key }  # \u0421\u0435\u0440\u0432\u0438\u0441\u043d\u0430\u044f \u0443\u0447\u0451\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043a \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c resource \"yandex_iam_service_account\" \"sa\" {   folder_id   = local.folder_id   name        = \"neoflex\"   description = \"Neoflex service account to access resource in the folder\" }  resource \"yandex_resourcemanager_folder_iam_member\" \"sa-editor\" {   folder_id = local.folder_id   role      = \"storage.admin\"   member    = \"serviceAccount:${yandex_iam_service_account.sa.id}\" }  resource \"yandex_iam_service_account_static_access_key\" \"sa-static-key\" {   service_account_id = yandex_iam_service_account.sa.id   description        = \"Static access key for object storage\" }  # \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0414\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440 \u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u0435\u0451 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u0430 \u0432 \u0411\u0430\u043a\u0435\u0442 data<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-398496","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/398496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=398496"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/398496\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=398496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=398496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=398496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}