{"id":348346,"date":"2023-06-03T15:01:33","date_gmt":"2023-06-03T15:01:33","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=348346"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=348346","title":{"rendered":"<span>\u041c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u043c\u0430\u044f Big Data \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 Kubernetes \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Spark \u0438 Cassandra<\/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<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/679248\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b, \u043a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 GPU NVidia, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044f\u0437\u044b\u043a Java \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 Spring, Spark ML, XGBoost, DML \u0432 standalone \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Spark. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u044f\u0432\u043b\u044f\u043b\u043e\u0441\u044c \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u041e\u0421 Windows 10 Pro, \u0432 Docker-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445. \u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043d\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u0435\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Spark Jobs \u0432 Kubernetes \u0432 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 client \u0438 cluster, \u043e\u043f\u0438\u0448\u0443 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Cassandra \u0432 Spark, \u043f\u043e\u043a\u0430\u0436\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0435\u0435 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044f\u0437\u044b\u043a Kotlin. \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/gitlab.com\/AlexPit\/java-ml-spark-example\/\" rel=\"noopener noreferrer nofollow\">GitLab<\/a>.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 Big Data \u0438 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 Spark \u0432 Kubernetes, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f GPU NVidia \u0438 Cassandra \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<h2>\u0412\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432<\/h2>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0432\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b &#8212; \u043e\u043d\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u0441 \u0440\u044f\u0434\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c. \u0422\u0430\u043a \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Rapids, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Boot 3 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f &#8212; \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f Java 17, \u0438, \u0445\u043e\u0442\u044c Spark \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0435\u043b\u044c GPU-\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 Rapids \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0432 \u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, Java 17 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0432\u0435\u0440\u0441\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u0437\u0430\u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 Spark 3.4.0. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 Spark (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 3.4.0) \u0431\u0440\u0430\u0442\u044c \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, DataStax \u0442\u0430\u043a \u0436\u0435 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0430 \u0441\u0432\u043e\u0439 cassandra connector, \u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412\u0435\u0440\u0441\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>JDK 8<\/p>\n<\/li>\n<li>\n<p>Spring Boot 2.7.11 <\/p>\n<\/li>\n<li>\n<p>Spark 3.3.2<\/p>\n<\/li>\n<li>\n<p>NVidia Rapids 23.04.0 <\/p>\n<\/li>\n<li>\n<p>Cassandra 4.1.1<\/p>\n<\/li>\n<li>\n<p>PostgreSQL 15.3-1.pgdg110+1 <\/p>\n<\/li>\n<li>\n<p>scala-library 2.12.15<\/p>\n<\/li>\n<li>\n<p>spark-cassandra-connector_2.12 3.3.0 <\/p>\n<\/li>\n<li>\n<p>com.fasterxml.jackson.core 2.13.5<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<ul>\n<li>\n<p>Kubernetes 1.26.3<\/p>\n<\/li>\n<li>\n<p>ContainerD 1.7.0<\/p>\n<\/li>\n<li>\n<p>NVidia GPU Operator 0.13.0<\/p>\n<\/li>\n<li>\n<p>NVidia Driver 530.30.02-1 (\u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0441 CUDA)<\/p>\n<\/li>\n<li>\n<p>CUDA &#8212; \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u043d\u0438\u0436\u0435 11.8 \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u043c \u043e\u0431\u0440\u0430\u0437\u0435 NVidia, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0436\u0435 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430\u0445 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 12+ <\/p>\n<\/li>\n<li>\n<p>Ubuntu 22.04.2<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0441\u0442\u0435\u043d\u0434\u0430:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"112\" width=\"112\">\n<p align=\"left\"><strong>\u0423\u0437\u0435\u043b<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\"><strong>CPU<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"93\" width=\"93\">\n<p align=\"left\"><strong>RAM<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>GPU<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0410\u0434\u0440\u0435\u0441 \u0432 \u041b\u0412\u0421<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"112\" width=\"112\">\n<p align=\"left\">master1<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">Intel i7-2700k<\/p>\n<\/td>\n<td data-colwidth=\"93\" width=\"93\">\n<p align=\"left\">16 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">NVidia GTX 1650 4 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">192.168.0.150<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"112\" width=\"112\">\n<p align=\"left\">worker1<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">AMD 3800x<\/p>\n<\/td>\n<td data-colwidth=\"93\" width=\"93\">\n<p align=\"left\">32 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">NVidia RTX 2600 6 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">192.168.0.125<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438<\/h2>\n<ol>\n<li>\n<p>\u041d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c spring-boot-starter-parent. \u041e\u043d \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0443\u044e\u0442 \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 Spark. \u0412 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 Java 17 (\u0432\u044b\u043f\u0443\u0441\u0442\u044f\u0442 \u0436\u0435 \u043a\u043e\u0433\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 Rapids \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0443\u044e \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e) \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Tomcat, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Undertow (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 classloader&#8217;\u0430\u043c\u0438 Rapids \u0438 Tomcat, \u0430 \u043d\u0430 Undertow \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u043e\u0441\u044c). \u041d\u043e \u0438 \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Jackson (\u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0432\u044b\u0448\u0435) \u0438 \u0440\u044f\u0434 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a jakarta \u0438 javax servlet:<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>pom.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency&gt;   &lt;groupId&gt;org.glassfish.web&lt;\/groupId&gt;   &lt;artifactId&gt;jakarta.servlet.jsp.jstl&lt;\/artifactId&gt;   &lt;version&gt;3.0.1&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt;   &lt;groupId&gt;jakarta.servlet&lt;\/groupId&gt;   &lt;artifactId&gt;jakarta.servlet-api&lt;\/artifactId&gt;   &lt;version&gt;6.0.0&lt;\/version&gt;   &lt;scope&gt;provided&lt;\/scope&gt; &lt;\/dependency&gt;   &lt;dependency&gt;   &lt;groupId&gt;jakarta.servlet.jsp.jstl&lt;\/groupId&gt;   &lt;artifactId&gt;jakarta.servlet.jsp.jstl-api&lt;\/artifactId&gt;   &lt;version&gt;3.0.0&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt;   &lt;groupId&gt;javax.servlet&lt;\/groupId&gt;   &lt;artifactId&gt;javax.servlet-api&lt;\/artifactId&gt;   &lt;version&gt;4.0.1&lt;\/version&gt;   &lt;scope&gt;provided&lt;\/scope&gt; &lt;\/dependency&gt; &lt;dependency&gt;   &lt;groupId&gt;ch.qos.logback&lt;\/groupId&gt;   &lt;artifactId&gt;logback-classic&lt;\/artifactId&gt;   &lt;version&gt;1.2.9&lt;\/version&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ol start=\"2\">\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c scala-library 2.12.15. \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c spark-cassandra-connector_2.12 3.3.0 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u0435\u0440\u0441\u0438\u044e 2.12.11, \u0430 Spark 3.3.2 &#8212; 2.12.15. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c, \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b SerialVersionUID. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c, \u0432 pom.xml \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c scala-library \u043f\u0435\u0440\u0435\u0434 spark-cassandra-connector.<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u044e\u0430\u043d\u0441\u044b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0431\u044b\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a \u043e\u0442\u043b\u0430\u0434\u043a\u0435. \u041f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438.<\/p>\n<\/li>\n<\/ol>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0438\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u043f\u043e\u043a\u043e\u0440\u043e\u0447\u0435, \u043d\u043e \u043d\u0430 \u0432\u0430\u0436\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u0445 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0441\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435. \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043e\u0431\u0440\u0430\u0437\u0430 executor \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043d\u043e \u0432 \u044d\u0442\u043e\u0439 \u0441\u0430\u043c \u043c\u0435\u0442\u043e\u0434 \u0441\u0431\u043e\u0440\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f. \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043d\u0435 \u0431\u0443\u0434\u0443, \u0441\u043a\u0430\u0436\u0443 \u043b\u0438\u0448\u044c, \u0447\u0442\u043e \u0432\u0437\u044f\u043b KubeSpray \u0438 \u0440\u0430\u0441\u043a\u0430\u0442\u0430\u043b 1.26.3.<\/p>\n<h3>Nvidia drivers<\/h3>\n<p><a href=\"https:\/\/developer.nvidia.com\/cuda-downloads\" rel=\"noopener noreferrer nofollow\">\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e Cuda<\/a>, \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>install CUDA and NVidia driver<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">wget https:\/\/developer.download.nvidia.com\/compute\/cuda\/repos\/ubuntu2204\/x86_64\/cuda-ubuntu2204.pin sudo mv cuda-ubuntu2204.pin \/etc\/apt\/preferences.d\/cuda-repository-pin-600 wget https:\/\/developer.download.nvidia.com\/compute\/cuda\/12.1.0\/local_installers\/cuda-repo-ubuntu2204-12-1-local_1 sudo dpkg -i cuda-repo-ubuntu2204-12-1-local_12.1.0-530.30.02-1_amd64.deb sudo cp \/var\/cuda-repo-ubuntu2204-12-1-local\/cuda-*-keyring.gpg \/usr\/share\/keyrings\/ sudo apt-get update sudo apt-get -y install cuda<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0448\u0430\u0433\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c:     <\/p>\n<details class=\"spoiler\">\n<summary>nvidia-smi<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">nvidia-smi Sun Mar 19 20:56:18 2023        +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 530.30.02              Driver Version: 530.30.02    CUDA Version: 12.1     | |-----------------------------------------+----------------------+----------------------+ | GPU  Name                  Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC | | Fan  Temp  Perf            Pwr:Usage\/Cap|         Memory-Usage | GPU-Util  Compute M. | |                                         |                      |               MIG M. | |=========================================+======================+======================| |   0  NVIDIA GeForce GTX 1650         On | 00000000:02:00.0 Off |                  N\/A | |  0%   47C    P2               N\/A \/  75W|    332MiB \/  4096MiB |      2%      Default | |                                         |                      |                  N\/A | +-----------------------------------------+----------------------+----------------------+                                                                                           +---------------------------------------------------------------------------------------+ | Processes:                                                                            | |  GPU   GI   CI        PID   Type   Process name                            GPU Memory | |        ID   ID                                                             Usage      | |=======================================================================================| |    0   N\/A  N\/A      1346      G   \/usr\/lib\/xorg\/Xorg                           62MiB | |    0   N\/A  N\/A      1905    C+G   ...libexec\/gnome-remote-desktop-daemon      132MiB | |    0   N\/A  N\/A      2013      G   \/usr\/bin\/gnome-shell                        131MiB | +---------------------------------------------------------------------------------------+<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c:   <\/p>\n<details class=\"spoiler\">\n<summary>nvidia-container-toolkit<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">sudo -i apt-get update &amp;&amp; apt-get install -y nvidia-container-toolkit  distribution=$(. \/etc\/os-release;echo $ID$VERSION_ID) curl -s -L https:\/\/nvidia.github.io\/nvidia-docker\/gpgkey | sudo apt-key add - curl -s -L https:\/\/nvidia.github.io\/nvidia-docker\/$distribution\/nvidia-docker.list | sudo tee \/etc\/apt\/sources.list.d\/nvidia-docker.list  sudo apt-get update &amp;&amp; sudo apt-get install -y nvidia-container-toolkit sudo systemctl restart docker  nvidia-ctk runtime configure --runtime=docker<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441\u043e \u0441\u043f\u0430\u0440\u043a \u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c\u0438 (\u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438).<\/p>\n<h3>Containerd<\/h3>\n<p><a href=\"https:\/\/github.com\/NVIDIA\/k8s-device-plugin#quick-start\" rel=\"noopener noreferrer nofollow\">GitHub &#8212; NVIDIA\/k8s-device-plugin: NVIDIAdevice plugin for Kubernetes<\/a><\/p>\n<p><a href=\"https:\/\/thenewstack.io\/tutorial-deploy-the-nvidia-gpu-operator-on-kubernetes-based-on-containerd-runtime\/\" rel=\"noopener noreferrer nofollow\">Tutorial: Deploy the Nvidia GPU Operator on Kubernetes Based on containerd Runtime<\/a><\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c:<\/p>\n<pre><code class=\"bash\">nano \/etc\/containerd\/config.toml<\/code><\/pre>\n<p>\u041e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c:   <\/p>\n<details class=\"spoiler\">\n<summary>config.toml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">version = 2 root = \"\/var\/lib\/containerd\" state = \"\/run\/containerd\" oom_score = 0  [grpc]   max_recv_message_size = 16777216   max_send_message_size = 16777216  [debug]   level = \"info\"  [metrics]   address = \"\"   grpc_histogram = false  [plugins]   [plugins.\"io.containerd.grpc.v1.cri\"]     sandbox_image = \"registry.k8s.io\/pause:3.8\"     max_container_log_line_size = -1     enable_unprivileged_ports = false     enable_unprivileged_icmp = false     [plugins.\"io.containerd.grpc.v1.cri\".containerd]       default_runtime_name = \"nvidia\"       snapshotter = \"overlayfs\"        [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes]         [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.nvidia]           privileged_without_host_devices = false           runtime_engine = \"\"           runtime_root = \"\"           runtime_type = \"io.containerd.runc.v2\"            [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.nvidia.options]             BinaryName = \"\/usr\/bin\/nvidia-container-runtime\"          [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc]           runtime_type = \"io.containerd.runc.v2\"           runtime_engine = \"\"           runtime_root = \"\"           base_runtime_spec = \"\/etc\/containerd\/cri-base.json\"            [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options]             systemdCgroup = true      [plugins.\"io.containerd.grpc.v1.cri\".registry]       [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors]         [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"]           endpoint = [\"https:\/\/registry-1.docker.io\"]       [plugins.\"io.containerd.grpc.v1.cri\".registry.configs]         [plugins.\"io.containerd.grpc.v1.cri\".registry.configs.\"registry-1.docker.io\".auth]             username = \"login\"             password = \"password\"             auth = \"\"             identitytoken = \"\"<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0449\u0430\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0441\u0435\u043a\u0446\u0438\u044e &#8212; \u0432 \u043d\u0435\u0439 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0430\u0448 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u0437\u0434\u0435\u0441\u044c \u044f \u043f\u0440\u0438\u0432\u0435\u043b \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c Docker Hub <code>\"registry-1.docker.io\"<\/code>. <\/p>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441:<\/p>\n<pre><code class=\"bash\">sudo systemctl restart containerd<\/code><\/pre>\n<h3>Kubernetes<\/h3>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/manage-gpus\/scheduling-gpus\/\" rel=\"noopener noreferrer nofollow\">Schedule GPUs<\/a> <\/p>\n<p><a href=\"https:\/\/github.com\/NVIDIA\/k8s-device-plugin#quick-start\" rel=\"noopener noreferrer nofollow\">GitHub &#8212; NVIDIA\/k8s-device-plugin: NVIDIA device plugin for Kubernetes<\/a><\/p>\n<p>\u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 Spark 3.1.1, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 Spark \u0432 Kubernetes \u0434\u043e\u0432\u0435\u0434\u0435\u043d\u0430 production-ready. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u044f\u0432\u043b\u0438\u043b\u0430\u0441\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Kubernetes \u043a\u0430\u043a \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 Spark, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0430\u0441\u0442\u0435\u0440\u0430 Kube API Server:   <\/p>\n<pre><code class=\"bash\">k8s:\/\/https:\/\/${KUBE_API_SERVER}:6443<\/code><\/pre>\n<p>\u0438\u043b\u0438<\/p>\n<pre><code class=\"bash\">k8s:\/\/https:\/\/kubernetes.default.svc<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 Spark Job, \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 K8S \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f Spark Executors \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c Docker \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c\u0438 \u0438 \u043f\u0440\u043e\u0447\u0438\u043c\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0430\u043c\u0438. \u0415\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0437 \u0443\u0436\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043c\u0430\u0448\u0438\u043d\u044b, POD \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e, \u043d\u0430 \u043c\u043e\u0438\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0438 5 \u0441\u0435\u043a\u0443\u043d\u0434 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u043b\u0438\u0441\u044c 2 \u044d\u043a\u0437\u0435\u043a\u0443\u043a\u0442\u043e\u0440\u0430, \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u043a \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<p>\u0412 \u0441\u0432\u044f\u0437\u043a\u0435 \u0441\u043e Spring \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c Spring Bean \u0441 JavaSparkContext\/SparkSession. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431: \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c SparkSession \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e Spark Job, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430. \u042d\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0434\u043b\u044f \u0440\u0435\u0434\u043a\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e \/ \u0437\u0430\u043f\u0440\u043e\u0441\u0443, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0449\u0438\u043c\u0441\u044f \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 (\u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e Spark Executors, CPU, \u043f\u0430\u043c\u044f\u0442\u044c, \u0432\u0438\u0434\u0435\u043e\u043f\u0430\u043c\u044f\u0442\u044c \u0438 \u0442.\u043f.), \u043d\u043e \u0438\u043c\u0435\u0435\u0442 \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0435 \u0440\u0430\u0441\u0445\u043e\u0434\u044b \u043d\u0430 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u0435 \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u043e\u0432 \u0438 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447. \u041d\u0430 \u043c\u043e\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0432\u0441\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e Spark \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0438 \u201c\u043f\u0440\u043e\u0433\u0440\u0435\u0432\u0430\u201d, \u0442.\u0435. \u043a\u0430\u0436\u0434\u0430\u044f \u043f\u0435\u0440\u0432\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0430\u0441\u044c \u0434\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435. \u0421\u0442\u043e\u0438\u0442 \u0438\u043c\u0435\u0442\u044c \u044d\u0442\u043e \u0432 \u0432\u0438\u0434\u0443, \u0438, \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u043f\u043e \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e, \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u043f\u043e\u0434 \u0441\u043f\u0430\u0440\u043a\u043e\u0432\u044b\u0435 \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u044b.<\/p>\n<h3>Nvidia GPU Operator<\/h3>\n<p>\u0414\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 GPU \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 Kubernetes \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Nvidia GPU Operator. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c:  <\/p>\n<details class=\"spoiler\">\n<summary>Install GPU Operator<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">kubectl create -f https:\/\/raw.githubusercontent.com\/NVIDIA\/k8s-device-plugin\/v0.13.0\/nvidia-device-plugin.yml  helm repo add nvidia https:\/\/nvidia.github.io\/gpu-operator helm repo update  kubectl create ns gpu-operator       helm install --wait gpu-operator \\      -n gpu-operator \\      nvidia\/gpu-operator \\      --set operator.defaultRuntime=containerd<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>kubectl run gpu-test \\      --rm -t -i \\      --restart=Never \\      --image=nvcr.io\/nvidia\/cuda:10.1-base-ubuntu18.04 nvidia-smi<\/code><\/pre>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 nvidia-smi:  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1ff\/34a\/d5c\/1ff34ad5c576efa259426b5a8879378e.png\" width=\"1024\" height=\"909\"><\/figure>\n<p>\u0412 \u0446\u0435\u043b\u044f\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c deployment \u0441 \u0434\u0432\u0443\u043c\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u043c\u0438 \u0437\u0430\u0433\u043e\u0442\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430 Spark executor:  <\/p>\n<details class=\"spoiler\">\n<summary>executor deployment<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">--- kind: Deployment apiVersion: apps\/v1 metadata:   name: cuda-example spec:   replicas: 2   selector:     matchLabels:       app: cuda-example   template:     metadata:       labels:         app: cuda-example     spec:       containers:         - name: cuda-jdk8           image: repo\/cuda-jdk8-spark-3.3.2:v2           resources:             limits:               cpu: 2               memory: 4Gi               nvidia.com\/gpu: 1             requests:               cpu: \"200m\"               memory: 0.5Gi               nvidia.com\/gpu: 1<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u0434\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u0434\u0443, \u0438, \u0435\u0441\u043b\u0438 \u044d\u043a\u0437\u0435\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u0432 \u043d\u0438\u0445, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 nvidia-smi \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041e\u0431\u0440\u0430\u0449\u0430\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u043e\u0432 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0438\u0445 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, K8S Scheduler \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u043e \u0441\u0430\u043c. \u041c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 GPU Operator, \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c.<\/p>\n<h3>\u041e\u0431\u0440\u0430\u0437 Spark executor<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c <code>spark\/kubernetes\/dockerfiles\/Dockerfile<\/code>:  <\/p>\n<details class=\"spoiler\">\n<summary>Dockerfile<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>ARG java_image_tag=17-jre FROM ${java_image_tag}  ARG spark_uid=1001 ARG UID_GID=1001 ENV UID=${UID_GID} ENV GID=${UID_GID}  ENV SPARK_RAPIDS_DIR=\/opt\/sparkRapidsPlugin ENV SPARK_RAPIDS_PLUGIN_JAR=${SPARK_RAPIDS_DIR}\/rapids-4-spark_2.12-23.04.0.jar  RUN set -ex &amp;&amp; \\     sed -i 's\/http:\\\/\\\/deb.\\(.*\\)\/https:\\\/\\\/deb.\\1\/g' \/etc\/apt\/sources.list &amp;&amp; \\     apt-get update &amp;&amp; \\     ln -s \/lib \/lib64 &amp;&amp; \\     apt install -y bash tini libc6 libpam-modules libnss3 procps nano iputils-ping net-tools iptables sudo \\     wget software-properties-common build-essential libnss3-dev zlib1g-dev libgdbm-dev libncurses5-dev \\     libssl-dev libffi-dev libreadline-dev libsqlite3-dev libbz2-dev python3 &amp;&amp; \\     mkdir -p \/opt\/spark &amp;&amp; \\     mkdir -p \/opt\/spark\/examples &amp;&amp; \\     mkdir -p \/opt\/spark\/conf &amp;&amp; \\     mkdir -p \/opt\/spark\/work-dir &amp;&amp; \\     mkdir -p \/opt\/sparkRapidsPlugin &amp;&amp; \\     touch \/opt\/spark\/RELEASE &amp;&amp; \\     rm \/bin\/sh &amp;&amp; \\     ln -sv \/bin\/bash \/bin\/sh &amp;&amp; \\     echo \"auth required pam_wheel.so use_uid\" &gt;&gt; \/etc\/pam.d\/su &amp;&amp; \\     chgrp root \/etc\/passwd &amp;&amp; chmod ug+rw \/etc\/passwd &amp;&amp; \\     rm -rf \/var\/cache\/apt\/* RUN apt-get install libnccl2 libnccl-dev -y --allow-change-held-packages &amp;&amp; rm -rf \/var\/cache\/apt\/*  COPY jars \/opt\/spark\/jars COPY rapids ${SPARK_RAPIDS_DIR} COPY extraclasspath \/opt\/spark\/extraclasspath COPY bin \/opt\/spark\/bin COPY sbin \/opt\/spark\/sbin COPY conf \/opt\/spark\/conf COPY kubernetes\/dockerfiles\/spark\/entrypoint.sh \/opt\/ COPY kubernetes\/dockerfiles\/spark\/decom.sh \/opt\/ COPY kubernetes\/tests \/opt\/spark\/tests COPY data \/opt\/spark\/data COPY datasets \/opt\/spark\/  ENV SPARK_HOME \/opt\/spark  WORKDIR \/opt\/spark\/work-dir RUN chmod g+w \/opt\/spark\/work-dir RUN chmod a+x \/opt\/decom.sh RUN chmod a+x \/opt\/entrypoint.sh RUN chmod a+x \/opt\/sparkRapidsPlugin\/getGpusResources.sh RUN ls -lah \/opt  RUN groupadd --gid $UID appuser &amp;&amp; useradd --uid $UID --gid appuser --shell \/bin\/bash --create-home appuser RUN mkdir \/var\/logs &amp;&amp; chown -R appuser:appuser \/var\/logs RUN mkdir \/opt\/spark\/logs &amp;&amp; chown -R appuser:appuser \/opt\/spark\/ RUN chown -R appuser:appuser \/tmp  RUN ls -lah \/home\/appuser RUN touch \/home\/appuser\/.bashrc  RUN echo -e '\\ export SPARK_HOME=\/opt\/spark\\n\\ export PATH=$PATH:$SPARK_HOME\/bin:$SPARK_HOME\/sbin\\ ' &gt; \/home\/appuser\/.bashrc  RUN chown -R appuser:appuser \/home\/appuser  EXPOSE 4040 EXPOSE 8081  USER ${spark_uid}  ENTRYPOINT [ \"\/opt\/entrypoint.sh\" ]<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>entrypoint.sh \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f, \u043d\u043e \u0434\u043b\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e standalone \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0432\u043e\u0440\u043a\u0435\u0440\u0430 (\u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0432 Windows). spark\/kubernetes\/dockerfiles\/entrypoint.sh \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0430:  <\/p>\n<details class=\"spoiler\">\n<summary>entryoint.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements.  See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the \"License\"); you may not use this file except in compliance with # the License.  You may obtain a copy of the License at # #    http:\/\/www.apache.org\/licenses\/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an \"AS IS\" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #  # echo commands to the terminal output set -ex  # Check whether there is a passwd entry for the container UID myuid=$(id -u) mygid=$(id -g) # turn off -e for getent because it will return error code in anonymous uid case set +e uidentry=$(getent passwd $myuid) set -e  # If there is no passwd entry for the container UID, attempt to create one if [ -z \"$uidentry\" ] ; then     if [ -w \/etc\/passwd ] ; then echo \"$myuid:x:$myuid:$mygid:${SPARK_USER_NAME:-anonymous uid}:$SPARK_HOME:\/bin\/false\" &gt;&gt; \/etc\/passwd     else echo \"Container ENTRYPOINT failed to add passwd entry for anonymous UID\"     fi fi  SPARK_CLASSPATH=\"$SPARK_CLASSPATH:${SPARK_HOME}\/jars\/*\" env | grep SPARK_JAVA_OPT_ | sort -t_ -k4 -n | sed 's\/[^=]*=\\(.*\\)\/\\1\/g' &gt; \/tmp\/java_opts.txt readarray -t SPARK_EXECUTOR_JAVA_OPTS &lt; \/tmp\/java_opts.txt  if [ -n \"$SPARK_EXTRA_CLASSPATH\" ]; then   SPARK_CLASSPATH=\"$SPARK_CLASSPATH:$SPARK_EXTRA_CLASSPATH\" fi  if ! [ -z ${PYSPARK_PYTHON+x} ]; then     export PYSPARK_PYTHON fi if ! [ -z ${PYSPARK_DRIVER_PYTHON+x} ]; then     export PYSPARK_DRIVER_PYTHON fi  # If HADOOP_HOME is set and SPARK_DIST_CLASSPATH is not set, set it here so Hadoop jars are available to the executor. # It does not set SPARK_DIST_CLASSPATH if already set, to avoid overriding customizations of this value from elsewhere e.g. Docker\/K8s. if [ -n \"${HADOOP_HOME}\"  ] &amp;&amp; [ -z \"${SPARK_DIST_CLASSPATH}\"  ]; then   export SPARK_DIST_CLASSPATH=\"$($HADOOP_HOME\/bin\/hadoop classpath)\" fi  if ! [ -z ${HADOOP_CONF_DIR+x} ]; then   SPARK_CLASSPATH=\"$HADOOP_CONF_DIR:$SPARK_CLASSPATH\"; fi  if ! [ -z ${SPARK_CONF_DIR+x} ]; then   SPARK_CLASSPATH=\"$SPARK_CONF_DIR:$SPARK_CLASSPATH\"; elif ! [ -z ${SPARK_HOME+x} ]; then   SPARK_CLASSPATH=\"$SPARK_HOME\/conf:$SPARK_CLASSPATH\"; fi  case \"$1\" in   driver)     shift 1     CMD=(       \"$SPARK_HOME\/bin\/spark-submit\"       --conf \"spark.driver.bindAddress=$SPARK_DRIVER_BIND_ADDRESS\"       --deploy-mode client       \"$@\"     )     ;;   executor)     shift 1     CMD=(       ${JAVA_HOME}\/bin\/java       \"${SPARK_EXECUTOR_JAVA_OPTS[@]}\"       -Xms$SPARK_EXECUTOR_MEMORY       -Xmx$SPARK_EXECUTOR_MEMORY       -cp \"$SPARK_CLASSPATH:$SPARK_DIST_CLASSPATH\"       org.apache.spark.executor.CoarseGrainedExecutorBackend       --driver-url $SPARK_DRIVER_URL       --executor-id $SPARK_EXECUTOR_ID       --cores $SPARK_EXECUTOR_CORES       --app-id $SPARK_APPLICATION_ID       --hostname $SPARK_EXECUTOR_POD_IP       --resourceProfileId $SPARK_RESOURCE_PROFILE_ID     )     ;;    *)     echo \"Non-spark-on-k8s command provided, proceeding in pass-through mode...\"     CMD=(\"$@\")     ;; esac  # Execute the container CMD under tini for better hygiene exec \/usr\/bin\/tini -s -- \"${CMD[@]}\" <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0444\u0430\u0439\u043b <code>spark\/kubernetes\/dockerfiles\/decom.sh<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:  <\/p>\n<details class=\"spoiler\">\n<summary>decom.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/usr\/bin\/env bash  # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements.  See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the \"License\"); you may not use this file except in compliance with # the License.  You may obtain a copy of the License at # #    http:\/\/www.apache.org\/licenses\/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an \"AS IS\" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #   set -ex echo \"Asked to decommission\" # Find the pid to signal date | tee -a ${LOG} WORKER_PID=$(ps -o pid -C java | tail -n 1| awk '{ sub(\/^[ \\t]+\/, \"\"); print }') echo \"Using worker pid $WORKER_PID\" kill -s SIGPWR ${WORKER_PID} # For now we expect this to timeout, since we don't start exiting the backend. echo \"Waiting for worker pid to exit\" # If the worker does exit stop blocking the cleanup. timeout 60 tail --pid=${WORKER_PID} -f \/dev\/null date echo \"Done\" date sleep 1 <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u0432\u0430 \u043e\u0431\u0440\u0430\u0437\u0430 &#8212; \u0434\u043b\u044f \u0447\u0438\u0441\u0442\u043e\u0433\u043e JVM \u0438 PySpark (\u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439):<\/p>\n<details class=\"spoiler\">\n<summary>build-java-8-spark-3.3.2.sh<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">#!\/bin\/bash echo \"=========== 1st stage ===========\" echo \"Docker repo: $DOCKER_REPO\" echo \"### build base cuda11.8 java8 image ###\" docker build -f Dockerfile-cuda-java8 -t localhost:5000\/cuda11.8-jdk8:v1 .  echo \"=========== 2nd stage ===========\" echo \"### build Spark and PySpark images ###\" cd spark-3.3.2  .\/bin\/docker-image-tool.sh -r localhost:5000 \\       -t jdk8-3.3.2 -b java_image_tag=localhost:5000\/cuda11.8-jdk8:v1 \\       -p .\/kubernetes\/dockerfiles\/spark\/bindings\/python\/Dockerfile \\       -n build  cd ..  docker tag localhost:5000\/spark-py:jdk8-3.3.2 $DOCKER_REPO\/cuda-jdk8-spark-py-3.3.2:v2 docker tag localhost:5000\/spark:jdk8-3.3.2 $DOCKER_REPO\/cuda-jdk8-spark-3.3.2:v2  echo \"=========== 3rt stage ===========\" echo \"### push Spark and PySpark images ###\" docker push $DOCKER_REPO\/cuda-jdk8-spark-py-3.3.2:v2 docker push $DOCKER_REPO\/cuda-jdk8-spark-3.3.2:v2 <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>, \u0433\u0434\u0435 <code>$DOCKER_REPO<\/code> &#8212; \u0432\u0430\u0448 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 Docker.  <\/p>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u0430 executor \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043e\u0431\u0440\u0430\u0437 <code>localhost:5000\/cuda-jdk8:v1<\/code>. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c Dockerfile:  <\/p>\n<details class=\"spoiler\">\n<summary>Dockerfile localhost:5000\/cuda11.8-jdk8:v1<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>FROM nvcr.io\/nvidia\/cuda:11.8.0-runtime-ubuntu22.04  ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8'  ARG DEBIAN_FRONTEND=noninteractive  RUN apt-get update &amp;&amp; apt install -y bash tini libc6 libpam-modules libnss3 procps nano iputils-ping net-tools  RUN apt-get update &amp;&amp; \\ apt-get install -y openjdk-8-jdk &amp;&amp; \\ apt-get install -y ant &amp;&amp; \\ apt-get clean &amp;&amp; \\ rm -rf \/var\/lib\/apt\/lists\/* &amp;&amp; \\ rm -rf \/var\/cache\/oracle-jdk8-installer;  RUN apt-get update &amp;&amp; \\ apt-get install -y ca-certificates-java &amp;&amp; \\ apt-get clean &amp;&amp; \\ update-ca-certificates -f &amp;&amp; \\ rm -rf \/var\/lib\/apt\/lists\/* &amp;&amp; \\ rm -rf \/var\/cache\/oracle-jdk8-installer;  ENV JAVA_HOME \/usr\/lib\/jvm\/java-8-openjdk-amd64\/ RUN export JAVA_HOME  CMD [\"tail\", \"-f\", \"\/dev\/null\"] <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0430 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u0432\u044b\u0448\u0435:  <\/p>\n<pre><code>docker build -f Dockerfile-cuda-java8 -t localhost:5000\/cuda-jdk8:v1 .<\/code><\/pre>\n<h2>\u0422\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 Spark Driver<\/h2>\n<h3>Service account<\/h3>\n<p><a href=\"https:\/\/spark.apache.org\/docs\/latest\/running-on-kubernetes.html#client-mode-networking\" rel=\"noopener noreferrer nofollow\">Running Spark on Kubernetes &#8212; Spark 3.4.0 Documentation<\/a><\/p>\n<p><a href=\"https:\/\/spark.apache.org\/docs\/latest\/running-on-kubernetes.html#client-mode-executor-pod-garbage-collection\" rel=\"noopener noreferrer nofollow\">Running Spark on Kubernetes &#8212; Spark 3.4.0 Documentation<\/a><\/p>\n<p><a href=\"https:\/\/www.oak-tree.tech\/blog\/spark-kubernetes-primer\" rel=\"noopener noreferrer nofollow\">Spark on Kubernetes: First Steps<\/a><\/p>\n<p>\u0414\u043b\u044f \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c K8S Service Account \u0441 \u043f\u043e\u043b\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 \u043d\u0430 \u043d\u0435\u0439\u043c\u0441\u043f\u0435\u0439\u0441 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 namespace <code>default<\/code>, \u043d\u043e \u0432 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435, \u0440\u0430\u0437\u0443\u043c\u0435\u0435\u0442\u0441\u044f, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 namespace). \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b SA \u0438 CRB:<\/p>\n<details class=\"spoiler\">\n<summary>Service Account \u0438 ClusterRoleBinding<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">--- apiVersion: v1 kind: ServiceAccount metadata:   name: spark-driver   namespace: default  --- apiVersion: rbac.authorization.k8s.io\/v1 kind: ClusterRoleBinding metadata:   name: spark-driver-crb roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: cluster-admin subjects:   - kind: ServiceAccount     name: spark-driver     namespace: default <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u043c\u044f SA \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 SparkContext:<\/p>\n<pre><code>.set(\"spark.kubernetes.authenticate.driver.serviceAccountName\", driverSa)<\/code><\/pre>\n<p>\u0412 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a \u0436\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f SA:<\/p>\n<pre><code>serviceAccountName: spark-driver<\/code><\/pre>\n<p>\u0412 \u0438\u0434\u0435\u0430\u043b\u0435, \u0434\u043b\u044f Executor \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 SA \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438 (ClusterRole \u201cedit\u201d), \u043d\u043e \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043e\u043d \u043d\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f.<\/p>\n<h3>Headless service<\/h3>\n<p><a href=\"https:\/\/spark.apache.org\/docs\/latest\/running-on-kubernetes.html#client-mode-networking\" rel=\"noopener noreferrer nofollow\">Running Spark on Kubernetes &#8212; Spark 3.4.0 Documentation<\/a><\/p>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u044b \u043c\u043e\u0433\u043b\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0443, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c headless service:<\/p>\n<pre><code class=\"bash\">kubectl expose pod $SPARK_DRIVER_NAME --port=$SPARK_DRIVER_PORT \\   --type=ClusterIP --cluster-ip=None<\/code><\/pre>\n<p>\u041c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>headless service<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">kind: Service apiVersion: v1 metadata:   labels:     app: ml-app   name: ml-app spec:   type: ClusterIP   clusterIP: None   clusterIPs:     - None   internalTrafficPolicy: Cluster   ipFamilies:     - IPv4   ipFamilyPolicy: SingleStack   ports:     - name: driver-port       port: 33139       targetPort: 33139       protocol: TCP     - name: block-manager-port       port: 45029       targetPort: 45029       protocol: TCP   selector:     app: ml-app   sessionAffinity: None<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a Spring \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p><a href=\"https:\/\/www.oak-tree.tech\/blog\/spark-kubernetes-primer\" rel=\"noopener noreferrer nofollow\">Spark on Kubernetes: First Steps<\/a><\/p>\n<p>\u041d\u0430 \u0440\u044f\u0434\u0443 \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043c\u0430\u0441\u0442\u0435\u0440\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <\/p>\n<pre><code>spark.submit.deployMode<\/code><\/pre>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c cluster \u0438\u043b\u0438 client.<\/p>\n<h3>Cluster mode<\/h3>\n<p>\u0412 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0430\u0431\u043e\u0442\u044b Cluster \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (spark driver) \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u043d\u0435 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 K8S, \u0435\u0433\u043e \u043f\u043e\u0434 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430. \u0425\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u043b\u0438\u0431\u043e \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435\/\u0441\u0435\u0440\u0432\u0435\u0440\u0435.<\/p>\n<h3>Client mode<\/h3>\n<p><a href=\"https:\/\/spark.apache.org\/docs\/latest\/running-on-kubernetes.html#client-mode\" rel=\"noopener noreferrer nofollow\">Running Spark on Kubernetes &#8212; Spark 3.4.0 Documentation<\/a><\/p>\n<p>\u0412 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0430\u0431\u043e\u0442\u044b Client \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (spark driver) \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435, \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a POD. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 (\u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e \u043d\u0438\u0436\u0435, \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0441 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f).<\/p>\n<h3>\u041c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h3>\n<details class=\"spoiler\">\n<summary>application.yml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"yaml\">--- apiVersion: v1 kind: Pod metadata:   labels:     app: ml-app   name: ml-app spec:   serviceAccountName: spark-driver   containers:     - name: ml-app       image: repo\/ml:cuda11.8-jdk8       imagePullPolicy: Always       env:         - name: \"SPARK_EXECUTORS\"           value: \"2\"         - name: \"SPARK_MODE\"           value: \"client\"         - name: \"POSTGRES_HOST\"           value: \"192.168.0.125\"         - name: \"CASSANDRA_HOST\"           value: \"192.168.0.125,192.168.0.150\"           # add your own env vars from ConfigMaps\/Secrets       resources:         limits:           cpu: \"2\"           memory: 4Gi         requests:           cpu: \"200m\"           memory: 0.5Gi       ports:         - containerPort: 4040         - containerPort: 9090         - containerPort: 33139         - containerPort: 45029 --- kind: Service apiVersion: v1 metadata:   labels:     app: ml-app   name: ml-app spec:   type: ClusterIP   clusterIP: None   clusterIPs:     - None   internalTrafficPolicy: Cluster   ipFamilies:     - IPv4   ipFamilyPolicy: SingleStack   ports:     - name: driver-port       port: 33139       targetPort: 33139       protocol: TCP     - name: block-manager-port       port: 45029       targetPort: 45029       protocol: TCP   selector:     app: ml-app   sessionAffinity: None <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0430 Spark Executor \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0434\u0430\u0445:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/183\/f8d\/54c\/183f8d54c12feb64d680888832512316.png\" width=\"1579\" height=\"356\"><\/figure>\n<h2>Cassandra<\/h2>\n<p>Cassandra &#8212; \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u044a\u0435\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u042d\u0442\u043e OLTP \u0411\u0414, \u0442\u0435. \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u043d\u0430\u044f \u043d\u0430 \u0447\u0430\u0441\u0442\u044b\u0435 \u0437\u0430\u043f\u0438\u0441\u0438. \u0422\u0430\u043a\u0436\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u044d\u0442\u043e\u0439 \u0411\u0414 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u0434\u0435\u043b\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0443\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435: \u043f\u0440\u0438 \u043d\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0438 \u043a\u043b\u044e\u0447\u0435\u0439 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043a\u043b\u044e\u0447\u0435\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0430\u0431\u043b\u0438\u0446 \u043b\u0435\u0433\u043a\u043e \u043f\u0440\u0438\u0439\u0442\u0438 \u043a \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c \u0441 ALLOW FILTERING \u0438\u043b\u0438 \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u0440\u0430\u0432\u043d\u043e\u043c\u0435\u0440\u043d\u043e\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u043e\u0432 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430 Cassandra. <\/p>\n<p>\u0414\u043b\u044f \u0447\u0430\u0441\u0442\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0442 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 (OLAP) \u0411\u0414. \u0415\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 wide-column DB, \u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c Cassandra \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c Clickhouse. \u041e\u0434\u043d\u0430\u043a\u043e, \u0431\u044b\u0432\u0430\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0431\u043e\u0440\u0430 Cassandra \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f Clickhouse: \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432, \u043a\u043e\u043c\u043f\u0435\u0442\u0435\u043d\u0446\u0438\u0439 \u043a\u043e\u043c\u0430\u043d\u0434 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0442\u0430\u043a\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a \u043a\u0430\u043a, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0411\u0414, \u0432 Cassandra \u043d\u0435\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0439 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 join-\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Apache Spark, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a Cassandra \u043a\u0430\u043a \u043a \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0415\u0441\u043b\u0438 \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e Cassandra \u0434\u0430\u0442\u0430\u0446\u0435\u043d\u0442\u0440\u043e\u0432, \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439, \u0440\u0430\u0437\u0433\u0440\u0443\u0437\u0438\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0434\u0430\u0442\u0430\u0446\u0435\u043d\u0442\u0440(\u044b) \u0434\u043b\u044f \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u0439 \u0437\u0430\u043f\u0438\u0441\u0438.<\/p>\n<p>\u0421\u0432\u044f\u0437\u043a\u043e\u0439 Spark-Cassandra \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c ETL-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b, \u043a\u0430\u043a \u043c\u0435\u0436\u0434\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0430\u043c\u0438 Cassandra, \u0442\u0430\u043a \u0438 \u0432 \u0434\u0440\u0443\u0433\u0438\u0435 \u0411\u0414, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0442\u043e\u0442 \u0436\u0435 Clickhouse, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440\u044b Spark.<\/p>\n<h2>\u0421\u0443\u0449\u043d\u043e\u0441\u0442\u0438 Big Data \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/h2>\n<p>\u0421\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0438\u043b\u0438 \u043d\u0435\u0442, \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0443\u0431\u043b\u0438\u043a\u0443\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0435\u0437\u043e\u043d\u0430 Big Data \u043d\u0430 Habr. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0442\u0430\u0442\u044c\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e\u043c \u0438 \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0434\u043b\u044f \u043d\u043e\u0432\u0438\u0447\u043a\u043e\u0432 \u0432 \u044d\u0442\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438, \u043a\u0440\u0430\u0442\u043a\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u044f: \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 ETL, Data Lake, DWH \u0438 Data Mart.<\/p>\n<p><strong>Data Lake<\/strong> &#8212; \u044d\u0442\u043e \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f. Data Lake \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043e\u0431\u044a\u0435\u043c\u044b \u0440\u0430\u0437\u043d\u043e\u0440\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u043b\u0443\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438 \u043d\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0438\u0434\u044b \u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c.<\/p>\n<p><strong>DWH <\/strong>&#8212; \u044d\u0442\u043e \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u044d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430, \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u043c\u0438. DWH \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0437\u0430\u043a\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u0444\u0430\u0439\u043b\u044b, \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0434\u0438\u043d\u043e\u0435 \u0438 \u043a\u043e\u043d\u0441\u043e\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0438 \u043e\u0442\u0447\u0435\u0442\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p><strong>Data Mart<\/strong> (\u0412\u0438\u0442\u0440\u0438\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0445) \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0442.\u0435. \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c DWH), \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438 \u0431\u0438\u0437\u043d\u0435\u0441\u0430 \u0438\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u043e\u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. Data Mart \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0438 \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0434\u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438.<\/p>\n<p><strong>ETL <\/strong>(\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435, \u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0438 \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430) &#8212; \u044d\u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0432 \u0446\u0435\u043b\u0435\u0432\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445. \u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 ETL \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432, \u0437\u0430\u0442\u0435\u043c \u043f\u043e\u0434\u0432\u0435\u0440\u0433\u0430\u044e\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0435\u0439 \u043e\u0447\u0438\u0441\u0442\u043a\u0443, \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0432 \u0446\u0435\u043b\u0435\u0432\u0443\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u0442\u0430\u043a\u0443\u044e \u043a\u0430\u043a DWH \u0438\u043b\u0438 Data Mart. \u041f\u0440\u043e\u0446\u0435\u0441\u0441 ETL \u0438\u0433\u0440\u0430\u0435\u0442 \u0432\u0430\u0436\u043d\u0443\u044e \u0440\u043e\u043b\u044c \u0432 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0446\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0438 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435.<\/p>\n<h2>\u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0432 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435<\/h2>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0443\u044e\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043d\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u041f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c &#8212; \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0430 \u0446\u0435\u043d \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0442\u043e\u0440\u0433\u0443\u044e\u0449\u0438\u0445\u0441\u044f \u043d\u0430 \u0444\u043e\u043d\u0434\u043e\u0432\u044b\u0445 \u0440\u044b\u043d\u043a\u0430\u0445. \u0422\u0430\u043a \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 GPU, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0446\u0435\u043d\u0443 \u043a\u0443\u0440\u0441\u0430 \u0430\u043a\u0446\u0438\u0439 NVidia (\u0442\u0438\u043a\u0435\u0440 NVDA) \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0438\u043e\u0434\u043e\u0432 \u0432\u043f\u0435\u0440\u0435\u0434. \u0410\u043d\u0430\u043b\u0438\u0437 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b\u0441\u044f \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043d\u0435\u0432\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0444\u0440\u0435\u0439\u043c\u0430 (1 day) \u0441 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u043d\u0430 2 \u043f\u0435\u0440\u0438\u043e\u0434\u0430 (2 \u0434\u043d\u044f) \u0432\u043f\u0435\u0440\u0435\u0434.<\/p>\n<p>\u0421\u0445\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e, \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4bf\/b87\/f28\/4bfb87f288b074b4b5e9f773b2ea24e1.png\" width=\"1474\" height=\"1152\"><\/figure>\n<p>\u041a\u0440\u0430\u0441\u043d\u043e\u0439 \u043f\u0443\u043d\u043a\u0442\u0438\u0440\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0435\u0439 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b ETL \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u044b \u0438\u0437 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0437\u0430 Data Lakes. \u0414\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445 \u0437\u0430\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c Data Extractor, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442 \u043d\u0430 k8s node pool \u0442\u043e\u043b\u044c\u043a\u043e \u0441 CPU, \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 OLTP DWH \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Cassandra.<\/p>\n<p>\u041f\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438\/\u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u0438\u044e\/\u0441\u043e\u0431\u044b\u0442\u0438\u044e Analytics Service, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442 \u043d\u0430 k8s node pool \u0441 GPU, \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 DWH \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430, \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u0438\u0445 \u0432 \u0435\u0434\u0438\u043d\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u0432 Data Mart \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Cassandra, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d \u0434\u043b\u044f OLAP \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439. \u042d\u0442\u043e \u0442\u043e\u0436\u0435 ETL \u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u043e\u043d \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d \u0447\u0435\u0440\u043d\u044b\u043c\u0438 \u0441\u043f\u043b\u043e\u0448\u043d\u044b\u043c\u0438 \u043b\u0438\u043d\u0438\u044f\u043c\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c Spark Executors, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b Analytics Service &#8212; \u0432 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0438 Spark \u044d\u0442\u043e driver.<\/p>\n<p>\u0413\u043e\u0432\u043e\u0440\u044f \u043e\u0431 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043b\u0438\u0448\u043d\u0438\u043c \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044c \u0435\u0449\u0435 \u043f\u0430\u0440\u0443 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0441 Big Data \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439: <\/p>\n<p><strong>Apache Zeppelin<\/strong> &#8212; \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u043d \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u043e\u0431\u044a\u0435\u043c\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Apache Zeppelin \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u043e\u0443\u0442\u0431\u0443\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043a\u043b\u044e\u0447\u0430\u044f Java, Scala, Kotlin \u0438 \u043c\u043d\u043e\u0433\u0438\u0435 \u0434\u0440\u0443\u0433\u0438\u0435. Zeppelin \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0448\u0438\u0440\u043e\u043a\u0438\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0438\u043d\u0442\u0435\u0440\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0435\u0433\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. Zeppelin \u0438\u043c\u0435\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u043e\u043c Spark.<\/p>\n<p><strong>Spring Cloud Data Flow (SCDF)<\/strong> &#8212; \u044d\u0442\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 (Data Flow) \u0432 \u043e\u0431\u043b\u0430\u0447\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f, \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c\u0438 \u0438 \u043f\u0440\u0438\u0435\u043c\u043d\u0438\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. SCDF \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0432\u0438\u0434\u0435 \u0433\u0440\u0430\u0444\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e \u0438\u0437 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u0438 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e SCDF \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435.<\/p>\n<p>\u041e\u0431\u0430 \u044d\u0442\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430, Apache Zeppelin \u0438 Spring Cloud Data Flow, \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c\u0438 \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0446\u0435\u043d \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432. Apache Zeppelin \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0443\u0434\u043e\u0431\u043d\u0443\u044e \u0441\u0440\u0435\u0434\u0443 \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u0430 Spring Cloud Data Flow \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u0442\u043e\u043a\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.<\/p>\n<h2>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/h2>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043e Spark. <\/p>\n<pre><code class=\"java\">public static JavaSparkContext sparkContext(SparkSettings sparkSettings) {         String host = sparkSettings.getHost();         SparkConf sparkConf = new SparkConf(true)                 .setAppName(sparkSettings.getAppName())                 .setMaster(sparkSettings.getMasterHost())                 .setJars(sparkSettings.getJars())                 ...                 .set(\"spark.driver.resource.gpu.amount\", \"0\") \/\/ (1)                 ...                 \/\/ Cassandra \/\/ (2)                 .set(\"spark.jars.packages\", \"datastax:spark-cassandra-connector:3.3.0-s_2.12\")                 .set(\"spark.sql.extensions\", \"com.datastax.spark.connector.CassandraSparkExtensions\")                 .set(\"spark.cassandra.auth.username\", sparkSettings.getCassandraUser())                 .set(\"spark.cassandra.auth.password\", sparkSettings.getCassandraPass())                 .set(\"spark.cassandra.connection.host\", sparkSettings.getCassandraHosts());          if (sparkSettings.isKubernetesEnabled()) { \/\/ (3)             sparkConf.set(\"spark.kubernetes.container.image\", sparkSettings.getExecutorImage());              if (sparkSettings.getDeployMode().equals(\"client\")) {                 sparkConf                     .set(\"spark.kubernetes.driver.pod.name\", sparkSettings.getHostName())                     .set(\"spark.kubernetes.namespace\", sparkSettings.getNamespace())                     .set(\"spark.kubernetes.authenticate.driver.serviceAccountName\", sparkSettings.getDriverSa());             }         }         return new JavaSparkContext(sparkConf);     }<\/code><\/pre>\n<p>(1) &#8212; \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 (spark driver) \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441\u044b GPU \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u201c0\u201d, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434 \u043d\u0435\u0433\u043e \u043d\u0435 \u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 Spark Executor&#8217;\u0430\u043c \u0440\u0435\u0441\u0443\u0440\u0441.<\/p>\n<p>(2) &#8212; \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 cassandra spark connector. \u0414\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u043e\u0432 \u043a \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0443 Cassandra \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438. \u041a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440 cassandra \u0438\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u0432\u0441\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 <a href=\"https:\/\/github.com\/datastax\/spark-cassandra-connector\/blob\/master\/doc\/reference.md\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>;<\/p>\n<p>(3) &#8212; \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 k8s, \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043d\u0435\u0433\u043e, \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c. \u0417\u0434\u0435\u0441\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0431\u0440\u0430\u0437 spark executor, \u0438\u043c\u044f driver k8s Pod (\u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>InetAddress.getLocalHost().getHostName();<\/code>), namespace, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f executor Pods, \u0438 Service Account. \u0412\u0441\u0435 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435.<\/p>\n<p><code>JavaSparkContext<\/code>  \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 SparkSession, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043b\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 executor&#8217;\u0430\u043c\u0438.<\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 Cassandra \u0432 Spark<\/h2>\n<h3>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u0412 \u0441\u0435\u0440\u0432\u0438\u0441\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Dataset \u043a\u0430\u043a \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c\u0438. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0430\u043a \u0436\u0435 RDD \u0438 Dataframe, \u0438, \u043f\u043e\u0447\u0435\u043c\u0443 \u0432 Java\/Kotlin \u0441\u0442\u043e\u0438\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Dataset, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/www.bigdataschool.ru\/blog\/rdd-vs-dataframe-vs-dataset.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c <\/a>\u0438 <a href=\"https:\/\/www.bigdataschool.ru\/blog\/what-to-use-in-spark-rdd-vs-dataframe-vs-dataset.html\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043a\u0430\u0441\u0441\u0430\u043d\u0434\u0440\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>AbstractCassandraRepository <\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">abstract class AbstractCassandraRepository constructor(     private val sparkSession: SparkSession ) {      companion object {         internal const val keyspace: String = \"instrument_data\"     }      fun cassandraDataset(keyspace: String, table: String): Dataset&lt;Row&gt; {         val cassandraDataset: Dataset&lt;Row&gt; = sparkSession.read()             .format(\"org.apache.spark.sql.cassandra\")             .option(\"keyspace\", keyspace)             .option(\"table\", table)             .load()          cassandraDataset.createOrReplaceTempView(table)         return cassandraDataset     } } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441\u043e \u0441\u043f\u0430\u0440\u043a\u043e\u0432\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0435\u0439: \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u0439, \u0447\u0442\u043e Dataset&lt;Row&gt; \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d \u0438\u0437 \u043a\u0430\u0441\u0441\u0430\u043d\u0434\u0440\u044b, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u0435\u0439\u0441\u043f\u0435\u0439\u0441 \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0443, \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0438\u043c\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u0445 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043a\u043e\u043b\u043e\u043d\u043a\u0430\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043f\u043e \u0435\u0435 \u0438\u043c\u0435\u043d\u0438.<\/p>\n<p>\u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u0438\u043a\u043e\u0433\u043e \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c full scan \u0442\u0430\u0431\u043b\u0438\u0446\u044b &#8212; \u0443 \u043a\u0430\u0436\u0434\u043e\u0439 \u0435\u0441\u0442\u044c Partition Key, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043a\u0430\u0442\u044c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b instrument_data.time_series_history:<\/p>\n<details class=\"spoiler\">\n<summary>instrument_data.time_series_history<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">create table instrument_data.time_series_history (     ticker      text,     task_number uuid,     datetime    timestamp,     timeframe   text,     close       decimal,     high        decimal,     low         decimal,     open        decimal,     volume      bigint,     primary key (ticker, task_number, datetime, timeframe)     )     with compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'};  create index time_series_history_datetime_index     on instrument_data.time_series_history (datetime);  create index time_series_history_task_number_index     on instrument_data.time_series_history (task_number);  create index time_series_history_timeframe_index     on instrument_data.time_series_history (timeframe);<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0443 \u043d\u0435\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f Partition Key ticker \u0438 \u0442\u0440\u0438 Clustering Column: <\/p>\n<p><code>task_number<\/code> &#8212; \u043d\u043e\u043c\u0435\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u043c\u0435\u0436\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435;<\/p>\n<p><code>datetime<\/code> &#8212; \u0434\u0430\u0442\u0430 \u0438 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043f\u0438\u0441\u0438;<\/p>\n<p><code>timeframe<\/code> &#8212; \u0442\u0430\u0439\u043c\u0444\u0440\u0435\u0439\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u044f\u0434\u0430 (1day \u0432 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435).<\/p>\n<p>\u0417\u0430\u0434\u0430\u0447\u0430 &#8212; \u0434\u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e ticker, task_number \u0438 datetime between (dateStart, dateEnd) \u0438\u0437 \u0432\u0441\u0435\u0445 \u0442\u0430\u0431\u043b\u0438\u0446.<\/p>\n<details class=\"spoiler\">\n<summary>AbstractIndicatorRepository<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">abstract class AbstractIndicatorRepository constructor(     sparkSession: SparkSession,     private val table : String ) : AbstractCassandraRepository(sparkSession) {      fun getBaseDataSet(         ticker: String,         taskNumber : UUID,         dateStart : LocalDate,         dateEnd : LocalDate     ): Dataset&lt;Row&gt; {         return cassandraDataset(table)             .filter(                 functions.col(\"ticker\").equalTo(ticker)                     .and(functions.col(\"task_number\").equalTo(taskNumber.toString()))                     .and(functions.col(\"datetime\").between(dateStart, dateEnd)))     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u043c\u0435\u0442\u043e\u0434\u0443 \u0438 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c Spark \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c \u0434\u0430\u0442\u0430\u0441\u0435\u0442, \u0437\u0430\u0442\u0435\u043c \u0435\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c &#8212; \u0432 \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u044b \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0443\u0436\u0435 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. <\/p>\n<p>\u0414\u0430\u043d\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u0435\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0443:<\/p>\n<pre><code class=\"sql\">select * from instrument_data.time_series_history where ticker = ?1   AND task_number = ?2   AND datetime &gt; ?3 and datetime &lt; ?4;<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c partition key, \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u043d\u0430 DAG \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 Spark UI. \u042d\u0442\u043e \u043b\u0435\u0436\u0438\u0442 \u043d\u0430 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043a\u0430\u043a\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442 \u0440\u0430\u0431\u043e\u0442\u0443.<\/p>\n<p>&nbsp;\u0427\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c select \u043f\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0441\u0442\u043e\u043b\u0431\u0446\u0430\u043c, \u0443\u0436\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>TimeSeriesRepository<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Component class TimeSeriesRepository(     sparkSession: SparkSession ) : AbstractIndicatorRepository(sparkSession, \"time_series_history\") {      fun getDataset(         ticker: String,         taskNumber : UUID,         dateStart : LocalDate,         dateEnd : LocalDate     ) : Dataset&lt;Row&gt; {         val dataset = getBaseDataSet(ticker, taskNumber, dateStart, dateEnd)             .selectExpr(                 \"to_date(datetime) as dateTime\",                 \"CAST(close AS Double) as close\"             )          dataset.createOrReplaceTempView(\"ts\")         return dataset     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0442\u043e\u0433\u0434\u0430 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0432\u0435\u0440\u043d\u0435\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u0437 \u0434\u0432\u0443\u0445 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0441 \u0434\u0430\u0442\u043e\u0439 \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0438 \u0446\u0435\u043d\u043e\u0439 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0432 Double. Double \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0432 GPU.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<details class=\"spoiler\">\n<summary>getMainDataset<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">private fun getMainDataset(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     currentOffset : Int,     batchSize : Int ) : Dataset&lt;Row&gt; {     val timeSeries = timeSeriesRepository         .getDataset(ticker, taskNumber, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"ts\")     val emaDataSet = emaRepository         .getEmaDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"ema\")     val stochasticDataset = stochasticRepository         .getStochasticDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"stoch\")     val bBandsDataset = bBandIndicatorRepository         .getBBandsDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"bb\")     val macdDataset = macdRepository         .getMacdDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"macd\")     val rsiDataset = rsiRepository         .getRsiDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"rsi\")     val smaDataset = smaRepository         .getSmaDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"sma\")     val willrDataset = willrRepository         .getWillrDataSet(ticker, dateStart, dateEnd, currentOffset, batchSize)         .`as`(\"willr\")      return combineDatasets(         timeSeries, emaDataSet, stochasticDataset, bBandsDataset, macdDataset, rsiDataset, smaDataset, willrDataset     ) }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443 Java\/Kotlin \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0443\u0442\u044c \u0436\u0435\u043b\u0430\u043d\u0438\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0435\u0440\u0435\u0437 <code>CompletableFuture&lt;Dataset&lt;Row&gt;&gt;<\/code> \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u0432 \u043e\u0434\u043d\u043e\u043c \u0442\u0440\u0435\u0434\u043f\u0443\u043b\u0435. \u041e\u0434\u043d\u0430\u043a\u043e, \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c. \u0421\u043f\u0430\u0440\u043a \u0441\u0430\u043c \u0440\u0430\u0441\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0432\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 FutureTask&#8217;s, \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0443 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0440\u0430\u0441\u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u0438\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0435 \u043f\u043e\u0442\u043e\u043a\u0438. <\/p>\n<\/div>\n<\/details>\n<p>\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>combineDatasets<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">private fun combineDatasets(     timeSeries : Dataset&lt;Row&gt;,     emaDataSet : Dataset&lt;Row&gt;,     stochasticDataset : Dataset&lt;Row&gt;,     bBandsDataset : Dataset&lt;Row&gt;,     macdDataset : Dataset&lt;Row&gt;,     rsiDataset : Dataset&lt;Row&gt;,     smaDataset : Dataset&lt;Row&gt;,     willrDataset : Dataset&lt;Row&gt; ): Dataset&lt;Row&gt; {      val result = timeSeries         .join(emaDataSet, timeSeries.col(\"datetime\")                 .equalTo(emaDataSet.col(\"datetime\")), \"leftouter\")         .join(stochasticDataset, timeSeries.col(\"datetime\")                 .equalTo(stochasticDataset.col(\"datetime\")), \"leftouter\")         .join(bBandsDataset, timeSeries.col(\"datetime\")                 .equalTo(bBandsDataset.col(\"datetime\")), \"leftouter\")         .join(macdDataset, timeSeries.col(\"datetime\")                 .equalTo(macdDataset.col(\"datetime\")), \"leftouter\")         .join(rsiDataset, timeSeries.col(\"datetime\")                 .equalTo(rsiDataset.col(\"datetime\")), \"leftouter\")         .join(smaDataset, timeSeries.col(\"datetime\")                 .equalTo(smaDataset.col(\"datetime\")), \"leftouter\")         .join(willrDataset, timeSeries.col(\"datetime\")                 .equalTo(willrDataset.col(\"datetime\")), \"leftouter\")         .selectExpr(             \"ts.dateTime as dateTime\",             \"ema.emaTimePeriod as emaTimePeriod\",             \"ema.ema as ema\",             \"stoch.fastKPeriod as fastKPeriod\",             \"stoch.slowKPeriod as slowKPeriod\",             \"stoch.slowDPeriod as slowDPeriod\",             \"stoch.slowD as slowD\",             \"stoch.slowK as slowK\",             \"bb.timePeriod as bbTimePeriod\",             \"bb.sd as bbSd\",             \"bb.lowerBand as lowerBand\",             \"bb.middleBand as middleBand\",             \"bb.upperBand as upperBand\",             \"macd.signalPeriod as signalPeriod\",             \"macd.fastPeriod as fastPeriod\",             \"macd.slowPeriod as slowPeriod\",             \"macd.macd as macd\",             \"macd.macdHist as macdHist\",             \"macd.macdSignal as macdSignal\",             \"rsi.timePeriod as rsiTimePeriod\",             \"rsi.rsi as rsi\",             \"sma.timePeriod as smaTimePeriod\",             \"sma.sma as sma\",             \"willr.timePeriod as willrTimePeriod\",             \"willr.willr as willr\",             \"ts.close as close\"         )      val windowSpec = Window.orderBy(functions.asc(\"dateTime\"))     return result         .withColumn(\"id\", functions.row_number().over(windowSpec))         .filter(functions.col(\"dateTime\").isNotNull) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <code>combineDatasets<\/code> \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 Cassandra \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442, \u0430 Spark \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0430\u043a\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0430 id, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438. \u0417\u0434\u0435\u0441\u044c \u0436\u0435 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e \u043a\u043e\u043b\u043e\u043d\u043a\u0435 <code>dateTime<\/code> \u0438 \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u044f\u0447\u0435\u0439\u043a\u0430\u043c\u0438.<\/p>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0438\u043d\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Dataset &#8212; \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0443 sparkSession, \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 sql() \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043d\u0435\u0433\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 SQL \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445, \u0438 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c SQL \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043c\u043e\u0436\u043d\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0439 \u0432 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u043c\u043e\u0438\u0445 <u>\u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432 \u0434\u043b\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u043e\u0432<\/u> \u043d\u0435 \u0431\u044b\u043b\u043e \u0437\u0430\u043c\u0435\u0447\u0435\u043d\u043e. Spark \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u043e\u0439 &#8212; \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 (UDF) \u0438 \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441, \u044d\u0442\u043e \u043f\u043b\u043e\u0445\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0417\u0430 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432 \u044d\u0442\u043e\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u0435 <a href=\"https:\/\/spark.apache.org\/docs\/latest\/sql-programming-guide.html\" rel=\"noopener noreferrer nofollow\">\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u043a \u043e\u0444. \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/a> Spark \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0442 ANSI \u0444\u043e\u0440\u043c\u0430\u0442. \u0415\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u0434\u0438\u0430\u043b\u0435\u043a\u0442\u0435, \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"https:\/\/www.jooq.org\/translate\/\" rel=\"noopener noreferrer nofollow\">\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c<\/a>.<\/p>\n<p>\u0412 \u0430\u0431\u0437\u0430\u0446\u0435 \u0432\u044b\u0448\u0435 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0430\u043a \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043e \u043f\u043e\u043b\u0443\u0436\u0438\u0440\u043d\u044b\u043c \u0441 \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u0438\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0434\u043d\u043e \u0432\u0430\u0436\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 <code>timeSeries<\/code>, \u0438 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0445\u043e\u0442\u0438\u043c \u0447\u0435\u0440\u0435\u0437 sparkSession.sql() \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0441\u0434\u0436\u043e\u0439\u043d\u0438\u0442\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u041e\u043f\u044b\u0442\u043d\u044b\u043c \u043f\u0443\u0442\u0435\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e, \u0447\u0442\u043e sparkSession \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434 sql() \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u043c \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u0434\u0435\u043b\u0430\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <code>timeSeries<\/code>, \u0438 \u043d\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u0444\u0438\u043b\u044c\u0442\u0440\u044b \u0434\u043b\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u044f \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u043c\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u043a\u0430\u0441\u0441\u0430\u043d\u0434\u0440\u044b, \u0447\u0442\u043e \u0441\u0430\u043c\u044b\u043c \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0441\u043a\u0430\u0437\u044b\u0432\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 &#8212; \u043e\u0442 2 \u0434\u043e 3 \u0438 \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0437. <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c sparkSession.sql() \u043c\u043e\u0436\u043d\u043e, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0442\u0435\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u0436\u043e\u0431\u044b. \u0410 \u0435\u0449\u0435 \u043b\u0443\u0447\u0448\u0435 &#8212; \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0447\u0435\u0440\u0435\u0437 \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043c\u0435\u0442\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>getDatasetWithLabel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun getDatasetWithLabel(     ticker: String,     taskNumber: UUID,     dateStart: LocalDate,     dateEnd: LocalDate,     offset : Long,     currentOffset : Int,     batchSize : Int ): Dataset&lt;Row&gt; {     val mainDataset = getMainDataset(ticker, taskNumber, dateStart, dateEnd, currentOffset, batchSize)     return datasetWithLabel(mainDataset, offset) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0437\u0430\u0442\u0435\u043c \u043e\u043d\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434 <code>datasetWithLabel<\/code>. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u0430\u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f, \u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d label &#8212; \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0446\u0435\u043d\u044b \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0442\u043e\u0440\u0433\u043e\u0432 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043d\u0430 \u0434\u0430\u0442\u0443 offset \u043f\u043e\u0437\u0434\u043d\u0435\u0435 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 2 \u0434\u043d\u044f).<\/p>\n<details class=\"spoiler\">\n<summary>datasetWithLabel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">private fun datasetWithLabel(     mainDataset: Dataset&lt;Row&gt;,     offset: Long ): Dataset&lt;Row&gt; {     val labelDataset = getLabelDatasetFromMain(mainDataset, offset)      val combinedDataset = labelDataset         .join(             mainDataset, labelDataset.col(\"id_eval\")                 .equalTo(mainDataset.col(\"id\")), LEFT_OUTER_JOIN         )         .withColumn(\"dateTimeUnix\", functions.unix_timestamp(functions.col(\"dateTime\")))         .withColumn(\"labelDateTimeUnix\", functions.unix_timestamp(functions.col(\"labelDateTime\")))      return combinedDataset         .withColumn(             \"id\",             functions.coalesce(combinedDataset.col(\"id_eval\"), combinedDataset.col(\"id\"))         )         .drop(\"id_eval\")         .selectExpr(*allColumns)         .filter(functions.col(\"dateTime\").isNotNull)         .orderBy(functions.asc(\"dateTime\")) }  private fun getLabelDatasetFromMain(     mainDataset: Dataset&lt;Row&gt;,     offset: Long ): Dataset&lt;Row&gt; {     val windowSpec = Window.orderBy(functions.asc(\"dateTime\"))     val labelDateTimeColumn = functions.lead(mainDataset.col(\"dateTime\"), offset.toInt()).over(windowSpec)     val labelColumn = functions.lead(mainDataset.col(\"close\"), offset.toInt()).over(windowSpec)      val labelDataset = mainDataset         .withColumn(\"labelDateTime\", labelDateTimeColumn)         .withColumn(\"label\", labelColumn)         .filter(functions.col(\"labelDateTime\").isNotNull)         .select(\"labelDateTime\", \"label\")         .orderBy(\"labelDateTime\")      return labelDataset         .withColumn(\"id_eval\", functions.row_number()             .over(Window.orderBy(functions.asc(\"labelDateTime\"))))         .select(\"id_eval\", \"labelDateTime\", \"label\") }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>getLabelDatasetFromMain<\/code> \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0434\u043b\u044f \u043a\u0430\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043b\u043e\u043d\u043e\u043a &#8212; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044e lead<\/p>\n<pre><code class=\"kotlin\">val labelDateTimeColumn = functions.lead(mainDataset.col(\"dateTime\"), offset.toInt()).over(windowSpec) val labelColumn = functions.lead(mainDataset.col(\"close\"), offset.toInt()).over(windowSpec)<\/code><\/pre>\n<p>\u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0434\u0430\u0442\u0443 \u0438 \u0446\u0435\u043d\u0443 \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u043e\u0433\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 offset \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432\u043f\u0435\u0440\u0435\u0434. \u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0430 \u0431\u0438\u0440\u0436\u0435 \u0432\u0435\u0434\u0443\u0442\u0441\u044f \u043d\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u0434\u0435\u043d\u044c, \u0435\u0441\u0442\u044c \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435 \u0438 \u043f\u0440\u0430\u0437\u0434\u043d\u0438\u0447\u043d\u044b\u0435 \u0434\u043d\u0438, \u043a\u043e\u0433\u0434\u0430 \u0431\u0438\u0440\u0436\u0430 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430\u0445 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u043f\u043e \u0434\u0430\u0442\u0430\u043c. \u041c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u0443\u0442\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0438 \u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u0434\u0430\u0442\u0430\u043c\u0438 \u0446\u0435\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f. \u0410 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 lead() \u043d\u0430 \u0438\u043c\u0435\u044e\u0449\u0435\u043c\u0441\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0435. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u044f \u043f\u043e\u0448\u0435\u043b \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u043f\u0443\u0442\u0435\u043c, \u0437\u0430\u043e\u0434\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 spark sql \u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u043e\u0432. \u0412 \u044d\u0442\u043e\u043c \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u0435 \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u043a\u043e\u043b\u043e\u043d\u043a\u0430 \u0441 <code>id_eval<\/code>.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>datasetWithLabel<\/code> \u0434\u0432\u0430 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c <code>id_eval<\/code> \u0438 <code>id<\/code>, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0447\u0435\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442.<\/p>\n<p>\u041d\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u0430\u0442\u0447\u0430\u043c\u0438 \u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043d\u043e\u0432\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443.<\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043d\u0435 \u0445\u0438\u0442\u0440\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>DataTransformService<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Service class DataTransformService(     private val dataReaderService: DataReaderService,     private val combinedDataRepository : CombinedDataRepository ) {      companion object {         private val log = LogManager.getLogger(this::class.java.name)     }      fun transformData(         ticker : String,         taskNumber : UUID,         dateStart : LocalDate,         dateEnd : LocalDate,         offset : Long,         batchSize : Int     ) {         var currentBatchOffset = 0         var i = 0          var tdf: Dataset&lt;Row&gt;?         do {             log.info(\"Data transformation: task {}, iteration {},: currentOffset {}\",                 taskNumber,i + 1, currentBatchOffset)              tdf = dataReaderService.getDatasetWithLabel(                 ticker, taskNumber, dateStart, dateEnd, offset, currentBatchOffset, batchSize             )             if (tdf.isEmpty) break              combinedDataRepository.saveData(tdf.selectExpr(*DataReaderService.allColumns), ticker, taskNumber)             currentBatchOffset += batchSize             i++         } while (tdf?.isEmpty == false)          log.info(\"Data transformation of task {} completed\", taskNumber)     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>combinedDataRepository.saveData(tdf.selectExpr(*DataReaderService.allColumns), ticker, taskNumber)<\/code> \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0431\u0430\u0442\u0447\u0430.  <\/p>\n<h3>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 Spark \u0432 Cassandra<\/h3>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0432 Cassandra \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043d\u043d\u0435\u043a\u0442\u043e\u0440:<\/p>\n<pre><code class=\"kotlin\">fun saveDataSet(dataset: Dataset&lt;Row&gt;) {     dataset.write()         .format(\"org.apache.spark.sql.cassandra\")         .mode(\"append\")                             \/\/ (1)         .option(\"confirm.truncate\", \"false\")        \/\/ (2)         .option(\"keyspace\", keyspace)         .option(\"table\", table)         .save(); }<\/code><\/pre>\n<p>\u0437\u0434\u0435\u0441\u044c, \u043a\u0440\u043e\u043c\u0435 \u0443\u0436\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0437\u0430\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f:<\/p>\n<p>(1) &#8212; \u0440\u0435\u0436\u0438\u043c, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u044c. append &#8212; \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435;<\/p>\n<p>(2) &#8212; \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u044f \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u0417\u0434\u0435\u0441\u044c \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d false, \u0438, \u0432 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439, \u0441\u043f\u0430\u0440\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u0430\u0441\u0441\u0430\u043d\u0434\u0440\u0435 \u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438. \u0421 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438<\/p>\n<pre><code class=\"kotlin\">.mode(\"overwrite\") .option(\"confirm.truncate\", \"true\")<\/code><\/pre>\n<p>\u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u043d\u043e\u0432\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0438\u0441\u044c\u044e \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0448\u0430\u043c\u0430\u043d\u0438\u0442\u044c \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0434\u043b\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0438 \u043f\u0440\u043e\u0447\u0438\u0445 \u043d\u0443\u0436\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>CombinedDataRepository<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Component class CombinedDataRepository(sparkSession: SparkSession)     : AbstractIndicatorRepository(sparkSession, \"combined_data\") {      fun saveData(         dataset : Dataset&lt;Row&gt;,         ticker : String,         taskNumber : UUID     ) {         val modifiedDataset = dataset             .withColumn(\"dateTime\",                 from_unixtime(col(\"dateTimeUnix\")))             .selectExpr(             \"dateTime as datetime\",             \"bbTimePeriod as bbands_time_period\",             \"bbSd as sd\",              \"emaTimePeriod as ema_time_period\",             \"ema\",              \"fastKPeriod as fast_k_period\",             \"slowKPeriod as slow_k_period\",             \"slowDPeriod as slow_d_period\",             \"slowD as slow_d\",             \"slowK as slow_k\",              \"lowerBand as lower_band\",             \"middleBand as middle_band\",             \"upperBand as upper_band\",              \"signalPeriod as macd_signal_period\",             \"fastPeriod as macd_fast_period\",             \"slowPeriod as macd_slow_period\",             \"macd\",             \"macdHist as macd_hist\",             \"macdSignal as macd_signal\",              \"rsiTimePeriod as rsi_time_period\",             \"rsi\",              \"smaTimePeriod as sma_time_period\",             \"sma\",              \"willrTimePeriod as willr_time_period\",             \"willr\",              \"close\")             .withColumn(\"ticker\", lit(ticker))             .withColumn(\"task_number\", lit(taskNumber.toString()))             .withColumn(\"timeframe\", lit(\"1day\"))             .na().drop()          saveDataSet(modifiedDataset)     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043c\u0435\u043d \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u043a \u0444\u043e\u0440\u043c\u0430\u0442\u0443 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0422\u0430\u043a\u0436\u0435 UUID \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a string, \u043f\u0440\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u0442\u0430\u0439\u043c\u0444\u0440\u0435\u0439\u043c\u0430 (\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443), \u0438, \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438, \u0442\u0430\u043a\u043e\u0432\u044b\u0435 \u0443\u0434\u0430\u043b\u044f\u044e\u0442\u0441\u044f.<\/p>\n<h3>\u041c\u0430\u043f\u043f\u0438\u043d\u0433 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432<\/h3>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b Dataset&lt;Row&gt; \u043c\u043e\u0436\u043d\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: <\/p>\n<p>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f Encoder:<\/p>\n<pre><code class=\"kotlin\">val result = joinResult.as(Encoders.bean(ModelTrainResult.class)); val resultList : List&lt;ModelTrainResult&gt; = result.collectAsList();<\/code><\/pre>\n<p>\u0438\u043b\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044f \u043a\u0430\u0436\u0434\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 Row:<\/p>\n<details class=\"spoiler\">\n<summary>ModelTrainResult<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) data class ModelTrainResult @JsonCreator constructor(     @get:JsonProperty(\"date_time\") val dateTime : LocalDateTime,     @get:JsonProperty(\"close\") val close : Double,     @get:JsonProperty(\"label_datetime\") val labelDateTime : LocalDateTime,     @get:JsonProperty(\"real_result\") val realResult : Double,     @get:JsonProperty(\"prediction\") val prediction : Double,     @get:JsonProperty(\"error\") val error : Double ) {     companion object {         private val formatter = DateTimeFormatter.ofPattern(\"yyyy-MM-dd HH:mm:ss\")          fun listFromDataset(dataset: Dataset&lt;Row&gt;): List&lt;ModelTrainResult&gt; {             val list = mutableListOf&lt;ModelTrainResult&gt;()             val iterator = dataset.toLocalIterator()             while (iterator.hasNext()) {                 val row = iterator.next()                 list.add(fromRow(row))             }             return list         }          private fun fromRow(row: Row): ModelTrainResult {             return ModelTrainResult(                 LocalDateTime.parse(row.getString(0), formatter),                 row.getDouble(1),                 LocalDateTime.parse(row.getString(2), formatter),                 row.getDouble(3),                 row.getDouble(4),                 row.getDouble(5)             )         }     }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e \u043c\u043e\u0435\u043c\u0443 \u043c\u043d\u0435\u043d\u0438\u044e, \u0432\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0437 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0435 \u0432 \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u0430\u043a, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u0430\u0442\u0430 \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435. \u041d\u043e \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u0430\u043a \u0436\u0435 \u0438\u043c\u0435\u0435\u0442 \u043c\u0435\u0441\u0442\u043e \u0431\u044b\u0442\u044c, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<h3>\u0417\u0430\u043c\u0435\u0442\u043a\u0438 \u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0441\u043b\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 join, groupBy, shuffle (\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u0441\u043f\u0430\u0440\u043a\u043e\u043c \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u0430\u043f\u0438\u043d\u0433\u0430 \u0441\u0442\u0440\u043e\u043a \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u0430 \u0432 java pojo, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) &#8212; \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0440\u043e\u0433\u0438\u0435 \u043f\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0435 \u0442\u044e\u043d\u0438\u043d\u0433\u0430. \u0421\u043f\u0430\u0440\u043a &#8212; \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0438 \u043a\u0430\u043a \u0432\u0441\u044f\u043a\u0430\u044f \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u0414\u0430\u0442\u0430\u0441\u0435\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u0430\u0445, \u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f join \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u044d\u043a\u0437\u0435\u043a\u0443\u0442\u043e\u0440\u0430\u043c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u0435\u044e\u0449\u0435\u0439\u0441\u044f \u0443 \u043d\u0438\u0445 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439, \u0447\u0442\u043e \u044f\u0432\u043d\u043e \u0432\u043b\u0435\u0447\u0435\u0442 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043d\u0430 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0432\u044b\u0437\u043e\u0432, \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e, \u0434\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0432\u0432\u043e\u0434-\u0432\u044b\u0432\u043e\u0434 \u0438 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<p>\u0421\u043d\u0438\u0437\u0438\u0442\u044c \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u043e\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 shuffle \u0438 join \u043c\u043e\u0436\u043d\u043e, \u0435\u0441\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u0430\u044f <a href=\"https:\/\/towardsdatascience.com\/strategies-of-spark-join-c0e7b4572bcf\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u044f <\/a>\u043d\u0430 \u044d\u0442\u0443 \u0442\u0435\u043c\u0443.<\/p>\n<p>\u0412 Spark \u0432\u044b \u043f\u0438\u0448\u0435\u0442\u0435 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435, \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043b\u0435\u043d\u0438\u0432\u043e \u0438 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u043b\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0442\u0430\u043a\u043e\u0435 \u043a\u0430\u043a collect () \u0438\u043b\u0438 write (). Spark \u0434\u0435\u043b\u0438\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u0440\u0430\u0437\u0434\u0435\u043b\u044b , \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b \u043d\u0438\u0442\u0435\u043b\u044f\u043c\u0438 , \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u0440\u0430\u0437\u0434\u0435\u043b\u043e\u0432. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430, \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0443\u0437\u043a\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0432 \u0441\u0435\u0431\u044f \u0442\u0430\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u0430\u043a map \u0438\u043b\u0438 filter . \u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438 \u2014 \u044d\u0442\u043e \u0448\u0438\u0440\u043e\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 .\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043c\u0435\u0436\u0434\u0443 \u0443\u0437\u043b\u0430\u043c\u0438, \u0447\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0440\u043e\u0433\u043e. \u0421\u0430\u043c \u043f\u043b\u0430\u043d \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0432\u0443\u0445 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432: \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043b\u0430\u043d \u0438 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u043b\u0430\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u0435\u0442 \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043a\u0430\u0441\u0430\u044e\u0449\u0435\u0435\u0441\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 Spark, \u0437\u0432\u0443\u0447\u0438\u0442 \u0442\u0430\u043a: Minimize Data Shuffles. <a href=\"https:\/\/medium.com\/@dvcanton\/wide-and-narrow-dependencies-in-apache-spark-21acf2faf031\" rel=\"noopener noreferrer nofollow\">\u042d\u0442\u043e \u0432\u044b\u0437\u0432\u0430\u043d\u043e \u0448\u0438\u0440\u043e\u043a\u0438\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438 \u0432 Spark,<\/a> \u0442\u0430\u043a\u0438\u043c\u0438 \u043a\u0430\u043a \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0430\u0433\u0440\u0435\u0433\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0440\u043e\u0433\u0438 \u0438\u0437-\u0437\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043e\u0432\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/711\/d85\/eb0\/711d85eb05e4f857c6f07707a38f1d51.png\" width=\"1133\" height=\"685\"><\/figure>\n<p>\u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0435\u0449\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0442\u0435\u043c\u0443 \u0442\u044e\u043d\u0438\u043d\u0433\u0430:<\/p>\n<p><a href=\"https:\/\/developer.ibm.com\/blogs\/spark-performance-optimization-guidelines\/\" rel=\"noopener noreferrer nofollow\">IBM Developer<\/a><\/p>\n<p><a href=\"https:\/\/spark.apache.org\/docs\/latest\/sql-performance-tuning.html\" rel=\"noopener noreferrer nofollow\">Performance Tuning &#8212; Spark 3.4.0 Documentation<\/a><\/p>\n<p><a href=\"https:\/\/itnext.io\/spark-cassandra-all-you-need-to-know-tips-and-optimizations-d3810cc0bd4e\" rel=\"noopener noreferrer nofollow\">Spark + Cassandra, All You Need to Know: Tips and Optimizations<\/a><\/p>\n<p><a href=\"https:\/\/luminousmen.com\/post\/spark-tips-partition-tuning\" rel=\"noopener noreferrer nofollow\">Spark Tips. Partition Tuning<\/a><\/p>\n<p>\u0423\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043e\u0432\u0435\u0442 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<figure class=\"bordered full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/98a\/847\/e38\/98a847e383a2fb72619e4c0493cada55.png\" width=\"530\" height=\"487\"><\/figure>\n<p>\u041d\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0437\u0430\u0447\u0430\u0441\u0442\u0443\u044e, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435, \u0431\u0435\u0437 shuffle \u043d\u0435 \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c.<\/p>\n<h2>\u041e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438<\/h2>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0438 \u043c\u043e\u0434\u0435\u043b\u0438 \u043d\u0435 \u0432\u0438\u0436\u0443 \u0441\u043c\u044b\u0441\u043b\u0430, \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u044b \u043f\u0440\u0438\u043c\u0435\u0440\u044b. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043e\u0431\u0443\u0447\u0430\u043b XGBoostRegressor \u0438 \u043e\u043f\u0438\u0448\u0443 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0438 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.  <\/p>\n<details class=\"spoiler\">\n<summary>trainModel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun trainModel(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     evalPivotPoint : Long,     offset : Long,     modelParameters : AnalyticsRequest.ModelParameters ) : ModelTrainResultResponse {     val pivot = dateEnd.minusDays(evalPivotPoint)      val tdf = dataReaderService.getDatasetWithLabel(ticker, taskNumber, dateStart, pivot, offset)     val edf = dataReaderService.getDatasetWithLabel(ticker, taskNumber, pivot, dateEnd, offset)         .selectExpr(*allColumns)      val modelParams = createModelParams(modelParameters)     val regressor = xgBoostRegressor(modelParams)      val model: PredictionModel&lt;Vector, XGBoostRegressionModel&gt; = regressor.fit(tdf)     val predictions = model.transform(edf)      combinedDataRepository.saveData(tdf.selectExpr(*allColumns).unionAll(edf), ticker, taskNumber)     modelService.saveModel(model, taskNumber, modelParameters)      val result = predictions.withColumn(\"error\", col(\"prediction\").minus(col(labelName)))     return ModelTrainResultResponse(ModelTrainResult.listFromDataset(result.selectExpr(*resultExp))) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c train \u0438 eval \u0434\u0430\u0442\u0430\u0441\u0435\u0442\u044b, \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c, \u043e\u0431\u0443\u0447\u0430\u0435\u043c \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0432 postgres. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0430\u0442\u0430\u0441\u0435\u0442 \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<details class=\"spoiler\">\n<summary>saveModel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code>fun saveModel(     model : PredictionModel&lt;Vector, XGBoostRegressionModel&gt;,     taskId : UUID,     modelParameters : AnalyticsRequest.ModelParameters ) {     val byteArrayOutputStream = ByteArrayOutputStream()     ObjectOutputStream(byteArrayOutputStream).use { it.writeObject(model) }     val modelByteArray: ByteArray = byteArrayOutputStream.toByteArray()     val jsonParams : JsonNode = objectMapper.convertValue(modelParameters, JsonNode::class.java)      val entity = ModelEntity(modelByteArray, taskId, jsonParams)     modelRepository.save(entity)     log.info(\"Model for task id {} saved. Parameters map: {}, jsonNode: {}\",         taskId, modelParameters, jsonParams) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0431\u0430\u0439\u0442\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u044f\u0447\u0435\u0439\u043a\u0443 \u0441 \u0442\u0438\u043f\u043e\u043c \u0434\u0430\u043d\u043d\u044b\u0445 bytea.<\/p>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 Json \u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043c\u043e\u0434\u0435\u043b\u044c\u044e.<\/p>\n<h3>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438<\/h3>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\/\u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f.<\/p>\n<details class=\"spoiler\">\n<summary>loadModel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">internal inline fun &lt;reified T&gt; loadModel(modelId: Long): T {     val optional = modelRepository.findById(modelId)      val entity = optional.get()     val modelByteArray = entity.model      val byteArrayInputStream = ByteArrayInputStream(modelByteArray)     val modelObject = ObjectInputStream(byteArrayInputStream).use { it.readObject() }      if (modelObject is T) {         return modelObject     } else {         throw ServiceException.withMessage(\"Model id $modelId has incorrect format\")     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>predictWithExistingModel<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun predictWithExistingModel(     ticker : String,     taskNumber : UUID,     dateStart : LocalDate,     dateEnd : LocalDate,     modelId : Long ): StockPredictDto {     val model: PredictionModel&lt;Vector, XGBoostRegressionModel&gt; = modelService.loadModel(modelId)     val data = dataReaderService.getMainDataset(ticker, taskNumber, dateStart, dateEnd)      var predictions = model.transform(data)     predictions = predictions.select(\"dateTime\", \"prediction\")     return StockPredictDto.fromDataset(predictions) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h2>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b<\/h2>\n<ol>\n<li>\n<p>\u042f \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0435\u043b\u0438 XGBoost, \u043d\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u0435\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 Java (\u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 <a href=\"https:\/\/gist.github.com\/ylogx\/53fef94cc61d6a3e9b3eb900482f41e0\" rel=\"noopener noreferrer nofollow\">Python<\/a>) \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f, \u0438 \u043c\u043e\u0434\u0435\u043b\u044c \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u043d\u0435 \u0430\u043f\u0434\u0435\u0439\u0442\u0438\u0442\u0441\u044f, \u0430 \u043f\u0435\u0440\u0435\u043e\u0431\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0441 \u0438\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0438 \u043f\u043e\u0442\u043e\u043a\u043e\u0432\u044b\u043c \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043d\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0440 \u0434\u043b\u044f \u043d\u043e\u0432\u044b\u0445 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0439.<\/p>\n<\/li>\n<\/ol>\n<p>\u041e\u0442\u0432\u0435\u0442\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 XGboost \u043f\u043e \u044d\u0442\u043e\u0439 \u0442\u0435\u043c\u0435 \u043f\u0440\u0438\u0432\u043e\u0436\u0443 \u0437\u0434\u0435\u0441\u044c:<\/p>\n<p><a href=\"https:\/\/github.com\/dmlc\/xgboost\/issues\/3055\" rel=\"noopener noreferrer nofollow\">Is it possible to update a model with new data without retraining the model from scratch? \u00b7 Issue #3055 \u00b7 dmlc\/xgboost<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/dmlc\/xgboost\/issues\/4188\" rel=\"noopener noreferrer nofollow\">xgboost4j spark supports incremental learning \u00b7 Issue #4188 \u00b7 dmlc\/xgboost<\/a><\/p>\n<p>2. \u0412 \u0432\u0438\u0434\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0432 Double \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043d\u0430 GPU, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0441 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u043e\u0432 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/03d\/b9f\/ab8\/03db9fab862cb8240a6fa88454b7d830.png\" width=\"464\" height=\"162\"><\/figure>\n<p>\u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u043d\u0435 \u043d\u0430\u0448\u0435\u043b, \u043d\u0443\u0436\u0435\u043d \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0441\u0435\u0440\u0447.<\/p>\n<p>3. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u0442\u0438\u0446\u0438\u0439 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043e\u043a\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435 &#8212; \u0435\u0441\u043b\u0438 \u0438\u0445 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0442\u043e \u0435\u0441\u0442\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0434\u0435\u0433\u0440\u0430\u0434\u0430\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u0422\u0435\u043c\u0443 \u043c\u0430\u043b\u043e \u0440\u0435\u0441\u0435\u0440\u0447\u0438\u043b, \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0438 \u043c\u043d\u043e\u0433\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u043b \u043d\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446.<\/p>\n<h2>\u041b\u0430\u0434\u043d\u043e \u0442\u0435\u0431\u0435 \u0441\u043e \u0441\u0432\u043e\u0435\u0439 \u0431\u0438\u0433 \u0434\u0430\u0442\u043e\u0439, \u0447\u0442\u043e \u0441 \u0446\u0435\u043d\u043e\u0439 \u0430\u043a\u0446\u0438\u0439?<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0442\u0430\u043a \u0441\u0435\u0431\u0435 (: \u0421 \u043d\u0430\u0441\u043a\u043e\u043a\u0430 \u0442\u0435\u043c\u0443 \u0430\u043d\u0430\u043b\u0438\u0442\u0438\u043a\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0446\u0435\u043d\u044b \u0444\u0438\u043d\u0430\u043d\u0441\u043e\u0432\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435 \u0432\u043e\u0437\u044c\u043c\u0435\u0448\u044c, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043e\u0441\u043d\u043e\u0432\u044b\u0432\u0430\u044f\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u0445. \u0412 \u044d\u0442\u043e\u0439 \u043f\u0440\u0435\u0434\u043c\u0435\u0442\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432, \u0441\u0430\u043c\u0438 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b, \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043b\u0438\u0447\u043d\u043e\u0439 \u0442\u043e\u0440\u0433\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u0438. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u0443 EMA \u0438 SMA, \u0445\u043e\u0442\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435, \u0441 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438. \u0422\u0430\u043a\u0436\u0435 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u043e\u043f\u0435\u0440\u0435\u0436\u0430\u044e\u0449\u0438\u0435 \u0438 \u0437\u0430\u043f\u0430\u0437\u0434\u044b\u0432\u0430\u044e\u0449\u0438\u0435, \u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0437 \u0437\u0430\u0434\u0430\u0447\u0438, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0432 \u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438, \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0438\u0435 \u0444\u0438\u0433\u0443\u0440\u044b \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0438 \u043f\u043e\u0442\u043e\u043a\u0438 \u043d\u043e\u0432\u043e\u0441\u0442\u0435\u0439 \u0438\u0437 \u0430\u0432\u0442\u043e\u0440\u0438\u0442\u0435\u0442\u043d\u044b\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432, \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u043f\u043e\u0434 \u0441\u0432\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443. <\/p>\n<p>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043f\u043b\u043e\u0445\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f\u0441\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0435\u0430\u0433\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u201c\u0432\u044b\u0431\u0440\u043e\u0441\u044b\u201d, \u0442\u0430\u043a, \u043d\u0430 \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043a\u0430\u0447\u043e\u043a \u0446\u0435\u043d\u044b \u0441 $305 \u0434\u043e $379 \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c, \u0434\u0430 \u0438 \u0435\u0449\u0435 \u043f\u0440\u0435\u0434\u0438\u043a\u0442 \u043f\u043e\u0448\u0435\u043b \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5c1\/5a3\/818\/5c15a3818d5e6c99da4bc23aa3f41ad4.png\" width=\"449\" height=\"932\"><\/figure>\n<p>\u041d\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0434\u043e\u0432\u043e\u043b\u0435\u043d: \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0449\u0443\u044e \u0448\u0438\u0440\u043e\u043a\u0438\u043c\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f Kubernetes, Spark \u0438 Cassandra, \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 Java\/Kotlin, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043d\u0435 \u0438\u043c\u043f\u043e\u043d\u0438\u0440\u0443\u044e\u0442 \u043d\u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c Python.<\/p>\n<p>\u0422\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u043e\u043c \u043d\u0435 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b\u0438\u0441\u044c &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0442\u0435\u043c\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438. \u041d\u0443\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0434\u0430\u0442\u0430\u0441\u0435\u0442, \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0434\u0435\u043b\u0438 \u0434\u043b\u044f \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u044b\u0445 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0435\u043d\u0434\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438<\/summary>\n<div class=\"spoiler__content\">\n<p><a href=\"https:\/\/medium.com\/@erkansirin\/spark-on-kubernetes-cdeee9462315\" rel=\"noopener noreferrer nofollow\">Spark on Kubernetes<\/a> <\/p>\n<p><a href=\"https:\/\/forums.developer.nvidia.com\/t\/nvidia-smi-has-failed-because-it-couldnt-communicate-with-the-nvidia-driver-make-sure-that-the-latest-nvidia-driver-is-installed-and-running\/197141\" rel=\"noopener noreferrer nofollow\">NVIDIA-SMI has failed because it couldn&#8217;t communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running<\/a> <\/p>\n<p><a href=\"https:\/\/github.com\/NVIDIA\/nvidia-docker\/issues\/1243\" rel=\"noopener noreferrer nofollow\"><u>docker: Error response from daemon: could not select device driver &#171;&#187; with capabilities: [[gpu]]. \u00b7 Issue #1243 \u00b7 NVIDIA\/nvidia-docker<\/u><\/a>   <\/p>\n<p><a href=\"https:\/\/docs.nvidia.com\/datacenter\/cloud-native\/container-toolkit\/install-guide.html#docker\" rel=\"noopener noreferrer nofollow\"><u>nstallation Guide \u2014 NVIDIA Cloud Native Technologies  documentation<\/u><\/a>   <\/p>\n<p><a href=\"https:\/\/docs.docker.com\/compose\/gpu-support\/\" rel=\"noopener noreferrer nofollow\">Enabling GPU access with Compose<\/a>   <\/p>\n<p><a href=\"https:\/\/forums.developer.nvidia.com\/t\/nvidia-smi-has-failed-because-it-couldnt-communicate-with-the-nvidia-driver-make-sure-that-the-latest-nvidia-driver-is-installed-and-running\/197141\" rel=\"noopener noreferrer nofollow\">NVIDIA-SMI has failed because it couldn&#8217;t communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running<\/a>   <\/p>\n<p><a href=\"https:\/\/github.com\/NVIDIA\/nvidia-docker\" rel=\"noopener noreferrer nofollow\">GitHub &#8212; NVIDIA\/nvidia-docker: Build and run Docker containers leveraging NVIDIA GPUs<\/a>   <\/p>\n<p><a href=\"https:\/\/docs.nvidia.com\/networking\/pages\/releaseview.action?pageId=39266293\" rel=\"noopener noreferrer nofollow\">RDG: Kubernetes cluster deployment with NVIDIA GPU over InfiniBand fabric. &#8212; Solutions &#8212; NVIDIA Networking Docs<\/a>   <\/p>\n<p><a href=\"https:\/\/thenewstack.io\/tutorial-deploy-the-nvidia-gpu-operator-on-kubernetes-based-on-containerd-runtime\/\" rel=\"noopener noreferrer nofollow\"><u>Tutorial: Deploy the Nvidia GPU Operator on Kubernetes Based on containerd Runtime<\/u><\/a>   <\/p>\n<p><a href=\"https:\/\/docs.rapids.ai\/install\" rel=\"noopener noreferrer nofollow\">Installation Guide &#8212; RAPIDS Docs<\/a>   <\/p>\n<p><a href=\"https:\/\/github.com\/GoogleCloudPlatform\/spark-on-k8s-operator\/blob\/master\/docs\/user-guide.md\" rel=\"noopener noreferrer nofollow\">spark-on-k8s-operator\/user-guide.md at master \u00b7 GoogleCloudPlatform\/spark-on-k8s-operator<\/a>   <\/p>\n<p><a href=\"https:\/\/michalklempa.com\/2021\/01\/spark-in-docker-standalone-cluster-2\/\" rel=\"noopener noreferrer nofollow\">Apache Spark on Kubernetes &#8212; Submitting a job to Spark on Kubernetes (Part 2)<\/a>   <\/p>\n<p>About client and cluster modes:  <\/p>\n<p><a href=\"http:\/\/www.bigdatainterview.com\/what-are-deployment-modes-in-spark-client-vs-cluster-modes\/\" rel=\"noopener noreferrer nofollow\">What are the deployment modes in Spark (Client vs Cluster modes)? &#8212; Big Data Interview<\/a>   <\/p>\n<p><a href=\"https:\/\/blog.cellenza.com\/en\/data\/using-spark-with-kubernetes-k8s\/\" rel=\"noopener noreferrer nofollow\">Using Spark with Kubernetes (K8s) | Le blog de Cellenza<\/a><\/p>\n<p><a href=\"https:\/\/medium.com\/@sephinreji98\/understanding-spark-cluster-modes-client-vs-cluster-vs-local-d3c41ea96073\" rel=\"noopener noreferrer nofollow\">Understanding Spark Deployment Modes: Client vs Cluster vs Local<\/a>   <\/p>\n<h3>XGboost<\/h3>\n<p><a href=\"https:\/\/xgboost.readthedocs.io\/en\/stable\/gpu\/index.html\" rel=\"noopener noreferrer nofollow\">XGBoost GPU Support \u2014 xgboost 1.7.5 documentation<\/a>   <\/p>\n<p><a href=\"https:\/\/xgboost.readthedocs.io\/en\/stable\/jvm\/xgboost4j_spark_gpu_tutorial.html\" rel=\"noopener noreferrer nofollow\">XGBoost4J-Spark-GPU Tutorial (version 1.6.1+) \u2014 xgboost 1.7.5 documentation<\/a>   <\/p>\n<p><a href=\"https:\/\/xgboost.readthedocs.io\/en\/stable\/tutorials\/spark_estimator.html#\" rel=\"noopener noreferrer nofollow\">Distributed XGBoost with PySpark \u2014 xgboost 1.7.5 documentation<\/a>   <\/p>\n<p><a href=\"https:\/\/xgboost.readthedocs.io\/en\/stable\/parameter.html\" rel=\"noopener noreferrer nofollow\">XGBoost Parameters \u2014 xgboost 1.7.5 documentation<\/a>   <\/p>\n<h3>NVidia guides<\/h3>\n<p><a href=\"https:\/\/www.oak-tree.tech\/blog\/spark-kubernetes-primer\" rel=\"noopener noreferrer nofollow\">Spark on Kubernetes: First Steps<\/a>   <\/p>\n<p><a href=\"https:\/\/medium.com\/empathyco\/running-apache-spark-on-kubernetes-2e64c73d0bb2\" rel=\"noopener noreferrer nofollow\">Running Apache Spark on Kubernetes<\/a>   <\/p>\n<p><a href=\"https:\/\/medium.com\/@georgelai\/apache-spark-on-kubernetes-3b9d1c936f64\" rel=\"noopener noreferrer nofollow\">Apache Spark On Kubernetes<\/a>   <\/p>\n<p><a href=\"https:\/\/www.nvidia.com\/en-us\/ai-data-science\/spark-ebook\/appendix-code\/\" rel=\"noopener noreferrer nofollow\">What&#8217;s New in Deep Learning &amp; Artificial Intelligence from NVIDIA<\/a>   <\/p>\n<p><a href=\"https:\/\/youtu.be\/RRQ3kn-WA7o\" rel=\"noopener noreferrer nofollow\"><u>Ready to run! Get Started with Spark on Kubernetes<\/u><\/a>   <\/p>\n<p><a href=\"https:\/\/spot.io\/blog\/setting-up-managing-monitoring-spark-on-kubernetes\/\" rel=\"noopener noreferrer nofollow\">Setting up, Managing &amp; Monitoring Spark on Kubernetes &#8212; Spot.io<\/a>   <\/p>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/run-application\/access-api-from-pod\/\" rel=\"noopener noreferrer nofollow\">Accessing the Kubernetes API from a Pod<\/a>   <\/p>\n<h3>\u041a\u043d\u0438\u0433\u0438 \u043f\u043e Machine Learning \u0432 \u0444\u0438\u043d\u0430\u043d\u0441\u0430\u0445<\/h3>\n<p><a href=\"https:\/\/www.amazon.com\/Learn-Algorithmic-Trading-algorithmic-strategies\/dp\/178934834X\" rel=\"noopener noreferrer nofollow\">Learn Algorithmic Trading: Build and deploy algorithmic trading systems and strategies<\/a>  <\/p>\n<p><a href=\"https:\/\/www.amazon.com\/Machine-Learning-Algorithmic-Trading-alternative\/dp\/1839217715\" rel=\"noopener noreferrer nofollow\">Machine Learning for Algorithmic Trading<\/a>  <\/p>\n<p><a href=\"https:\/\/www.amazon.com\/Machine-Learning-Finance-Theory-Practice\/dp\/3030410676\" rel=\"noopener noreferrer nofollow\">Machine Learning in Finance: From Theory to Practice<\/a>  <\/p>\n<p><a href=\"https:\/\/www.amazon.com\/Advances-Financial-Machine-Learning-Marcos\/dp\/1119482089\" rel=\"noopener noreferrer nofollow\">Advances in Financial Machine Learning<\/a>  <\/p>\n<\/div>\n<\/details>\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\/739634\/\"> https:\/\/habr.com\/ru\/articles\/739634\/<\/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<p>\u0412 <a href=\"https:\/\/habr.com\/ru\/articles\/679248\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b, \u043a\u0430\u043a \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 GPU NVidia, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u044f\u0437\u044b\u043a Java \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u043c\u0438 Spring, Spark ML, XGBoost, DML \u0432 standalone \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 Spark. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u044f\u0432\u043b\u044f\u043b\u043e\u0441\u044c \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u043e\u0434 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u041e\u0421 Windows 10 Pro, \u0432 Docker-\u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430\u0445. \u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043d\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c. \u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043c\u0435\u044e\u0449\u0438\u043c\u0438\u0441\u044f \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c Spark Jobs \u0432 Kubernetes \u0432 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 client \u0438 cluster, \u043e\u043f\u0438\u0448\u0443 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 Cassandra \u0432 Spark, \u043f\u043e\u043a\u0430\u0436\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u0435\u0435 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f. \u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044f\u0437\u044b\u043a Kotlin. \u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u043e\u0434\u043e\u043c \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/gitlab.com\/AlexPit\/java-ml-spark-example\/\" rel=\"noopener noreferrer nofollow\">GitLab<\/a>.<\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u043c\u0438 Big Data \u0438 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0448\u0438\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 Spark \u0432 Kubernetes, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f GPU NVidia \u0438 Cassandra \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<h2>\u0412\u0435\u0440\u0441\u0438\u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432<\/h2>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u044c \u0432\u043e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b &#8212; \u043e\u043d\u0430 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u0430\u044f, \u0441 \u0440\u044f\u0434\u043e\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c. \u0422\u0430\u043a \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Rapids, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Boot 3 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f &#8212; \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f Java 17, \u0438, \u0445\u043e\u0442\u044c Spark \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u0435\u043b\u044c GPU-\u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 Rapids \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0432 \u043f\u043e\u043b\u043d\u043e\u0439 \u043c\u0435\u0440\u0435. \u0421\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, Java 17 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0432 \u0432\u0435\u0440\u0441\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u0437\u0430\u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 Spark 3.4.0. \u041f\u043e \u044d\u0442\u043e\u0439 \u043f\u0440\u0438\u0447\u0438\u043d\u0435, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 Spark (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 3.4.0) \u0431\u0440\u0430\u0442\u044c \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, DataStax \u0442\u0430\u043a \u0436\u0435 \u043d\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043b\u0430 \u0441\u0432\u043e\u0439 cassandra connector, \u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412\u0435\u0440\u0441\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0437\u0430\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430:<\/p>\n<ul>\n<li>\n<p>JDK 8<\/p>\n<\/li>\n<li>\n<p>Spring Boot 2.7.11 <\/p>\n<\/li>\n<li>\n<p>Spark 3.3.2<\/p>\n<\/li>\n<li>\n<p>NVidia Rapids 23.04.0 <\/p>\n<\/li>\n<li>\n<p>Cassandra 4.1.1<\/p>\n<\/li>\n<li>\n<p>PostgreSQL 15.3-1.pgdg110+1 <\/p>\n<\/li>\n<li>\n<p>scala-library 2.12.15<\/p>\n<\/li>\n<li>\n<p>spark-cassandra-connector_2.12 3.3.0 <\/p>\n<\/li>\n<li>\n<p>com.fasterxml.jackson.core 2.13.5<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<ul>\n<li>\n<p>Kubernetes 1.26.3<\/p>\n<\/li>\n<li>\n<p>ContainerD 1.7.0<\/p>\n<\/li>\n<li>\n<p>NVidia GPU Operator 0.13.0<\/p>\n<\/li>\n<li>\n<p>NVidia Driver 530.30.02-1 (\u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0441 CUDA)<\/p>\n<\/li>\n<li>\n<p>CUDA &#8212; \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u043d\u0438\u0436\u0435 11.8 \u0432 \u0431\u0430\u0437\u043e\u0432\u043e\u043c \u043e\u0431\u0440\u0430\u0437\u0435 NVidia, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0445 \u0436\u0435 \u0434\u0440\u0430\u0439\u0432\u0435\u0440\u0430\u0445 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e 12+ <\/p>\n<\/li>\n<li>\n<p>Ubuntu 22.04.2<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0441\u0442\u0435\u043d\u0434\u0430:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"112\" width=\"112\">\n<p align=\"left\"><strong>\u0423\u0437\u0435\u043b<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\"><strong>CPU<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"93\" width=\"93\">\n<p align=\"left\"><strong>RAM<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>GPU<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\"><strong>\u0410\u0434\u0440\u0435\u0441 \u0432 \u041b\u0412\u0421<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"112\" width=\"112\">\n<p align=\"left\">master1<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">Intel i7-2700k<\/p>\n<\/td>\n<td data-colwidth=\"93\" width=\"93\">\n<p align=\"left\">16 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">NVidia GTX 1650 4 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">192.168.0.150<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"112\" width=\"112\">\n<p align=\"left\">worker1<\/p>\n<\/td>\n<td data-colwidth=\"127\" width=\"127\">\n<p align=\"left\">AMD 3800x<\/p>\n<\/td>\n<td data-colwidth=\"93\" width=\"93\">\n<p align=\"left\">32 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">NVidia RTX 2600 6 Gb<\/p>\n<\/td>\n<td>\n<p align=\"left\">192.168.0.125<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<h2>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438<\/h2>\n<ol>\n<li>\n<p>\u041d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c spring-boot-starter-parent. \u041e\u043d \u0442\u044f\u043d\u0435\u0442 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u0443\u044e\u0442 \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 Spark. \u0412 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435, \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 Java 17 (\u0432\u044b\u043f\u0443\u0441\u0442\u044f\u0442 \u0436\u0435 \u043a\u043e\u0433\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 Rapids \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0443\u044e \u0434\u0430\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e) \u043b\u0443\u0447\u0448\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Tomcat, \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Undertow (\u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 classloader&#8217;\u0430\u043c\u0438 Rapids \u0438 Tomcat, \u0430 \u043d\u0430 Undertow \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u043e\u0441\u044c). \u041d\u043e \u0438 \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438: \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Jackson (\u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u0432\u044b\u0448\u0435) \u0438 \u0440\u044f\u0434 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a jakarta \u0438 javax servlet:<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>pom.xml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"xml\">&lt;dependency&gt;   &lt;groupId&gt;org.glassfish.web&lt;\/groupId&gt;   &lt;artifactId&gt;jakarta.servlet.jsp.jstl&lt;\/artifactId&gt;   &lt;version&gt;3.0.1&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt;   &lt;groupId&gt;jakarta.servlet&lt;\/groupId&gt;   &lt;artifactId&gt;jakarta.servlet-api&lt;\/artifactId&gt;   &lt;version&gt;6.0.0&lt;\/version&gt;   &lt;scope&gt;provided&lt;\/scope&gt; &lt;\/dependency&gt;   &lt;dependency&gt;   &lt;groupId&gt;jakarta.servlet.jsp.jstl&lt;\/groupId&gt;   &lt;artifactId&gt;jakarta.servlet.jsp.jstl-api&lt;\/artifactId&gt;   &lt;version&gt;3.0.0&lt;\/version&gt; &lt;\/dependency&gt; &lt;dependency&gt;   &lt;groupId&gt;javax.servlet&lt;\/groupId&gt;   &lt;artifactId&gt;javax.servlet-api&lt;\/artifactId&gt;   &lt;version&gt;4.0.1&lt;\/version&gt;   &lt;scope&gt;provided&lt;\/scope&gt; &lt;\/dependency&gt; &lt;dependency&gt;   &lt;groupId&gt;ch.qos.logback&lt;\/groupId&gt;   &lt;artifactId&gt;logback-classic&lt;\/artifactId&gt;   &lt;version&gt;1.2.9&lt;\/version&gt; &lt;\/dependency&gt;<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<ol start=\"2\">\n<li>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c scala-library 2.12.15. \u0417\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c spark-cassandra-connector_2.12 3.3.0 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u0435\u0440\u0441\u0438\u044e 2.12.11, \u0430 Spark 3.3.2 &#8212; 2.12.15. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c, \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b SerialVersionUID. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c, \u0432 pom.xml \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c scala-library \u043f\u0435\u0440\u0435\u0434 spark-cassandra-connector.<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u044e\u0430\u043d\u0441\u044b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0431\u044b\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043a \u043e\u0442\u043b\u0430\u0434\u043a\u0435. \u041f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438.<\/p>\n<\/li>\n<\/ol>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441 \u0438\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u043f\u043e\u043a\u043e\u0440\u043e\u0447\u0435, \u043d\u043e \u043d\u0430 \u0432\u0430\u0436\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u0445 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0441\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435. \u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043e\u0431\u0440\u0430\u0437\u0430 executor \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435, \u043d\u043e \u0432 \u044d\u0442\u043e\u0439 \u0441\u0430\u043c \u043c\u0435\u0442\u043e\u0434 \u0441\u0431\u043e\u0440\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f. \u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0442\u0435\u0440 Kubernetes. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u043d\u0435 \u0431\u0443\u0434\u0443, \u0441\u043a\u0430\u0436\u0443 \u043b\u0438\u0448\u044c, \u0447\u0442\u043e \u0432\u0437\u044f\u043b KubeSpray \u0438 \u0440\u0430\u0441\u043a\u0430\u0442\u0430\u043b 1.26.3.<\/p>\n<h3>Nvidia drivers<\/h3>\n<p><a href=\"https:\/\/developer.nvidia.com\/cuda-downloads\" rel=\"noopener noreferrer nofollow\">\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e Cuda<\/a>, \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>install CUDA and NVidia driver<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">wget https:\/\/developer.download.nvidia.com\/compute\/cuda\/repos\/ubuntu2204\/x86_64\/cuda-ubuntu2204.pin sudo mv cuda-ubuntu2204.pin \/etc\/apt\/preferences.d\/cuda-repository-pin-600 wget https:\/\/developer.download.nvidia.com\/compute\/cuda\/12.1.0\/local_installers\/cuda-repo-ubuntu2204-12-1-local_1 sudo dpkg -i cuda-repo-ubuntu2204-12-1-local_12.1.0-530.30.02-1_amd64.deb sudo cp \/var\/cuda-repo-ubuntu2204-12-1-local\/cuda-*-keyring.gpg \/usr\/share\/keyrings\/ sudo apt-get update sudo apt-get -y install cuda<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u0448\u0430\u0433\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438, \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c:     <\/p>\n<details class=\"spoiler\">\n<summary>nvidia-smi<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">nvidia-smi Sun Mar 19 20:56:18 2023        +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 530.30.02              Driver Version: 530.30.02    CUDA Version: 12.1     | |-----------------------------------------+----------------------+----------------------+ | GPU  Name                  Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC | | Fan  Temp  Perf            Pwr:Usage\/Cap|         Memory-Usage | GPU-Util  Compute M. | |                                         |                      |               MIG M. | |=========================================+======================+======================| |   0  NVIDIA GeForce GTX 1650         On | 00000000:02:00.0 Off |                  N\/A | |  0%   47C    P2               N\/A \/  75W|    332MiB \/  4096MiB |      2%      Default | |                                         |                      |                  N\/A | +-----------------------------------------+----------------------+----------------------+                                                                                           +---------------------------------------------------------------------------------------+ | Processes:                                                                            | |  GPU   GI   CI        PID   Type   Process name                            GPU Memory | |        ID   ID                                                             Usage      | |=======================================================================================| |    0   N\/A  N\/A      1346      G   \/usr\/lib\/xorg\/Xorg                           62MiB | |    0   N\/A  N\/A      1905    C+G   ...libexec\/gnome-remote-desktop-daemon      132MiB | |    0   N\/A  N\/A      2013      G   \/usr\/bin\/gnome-shell                        131MiB | +---------------------------------------------------------------------------------------+<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043e\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c:   <\/p>\n<details class=\"spoiler\">\n<summary>nvidia-container-toolkit<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">sudo -i apt-get update &amp;&amp; apt-get install -y nvidia-container-toolkit  distribution=$(. \/etc\/os-release;echo $ID$VERSION_ID) curl -s -L https:\/\/nvidia.github.io\/nvidia-docker\/gpgkey | sudo apt-key add - curl -s -L https:\/\/nvidia.github.io\/nvidia-docker\/$distribution\/nvidia-docker.list | sudo tee \/etc\/apt\/sources.list.d\/nvidia-docker.list  sudo apt-get update &amp;&amp; sudo apt-get install -y nvidia-container-toolkit sudo systemctl restart docker  nvidia-ctk runtime configure --runtime=docker<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e: \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u044b \u0441\u043e \u0441\u043f\u0430\u0440\u043a \u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c\u0438 (\u043c\u043e\u0436\u043d\u043e \u0432\u0437\u044f\u0442\u044c \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438).<\/p>\n<h3>Containerd<\/h3>\n<p><a href=\"https:\/\/github.com\/NVIDIA\/k8s-device-plugin#quick-start\" rel=\"noopener noreferrer nofollow\">GitHub &#8212; NVIDIA\/k8s-device-plugin: NVIDIAdevice plugin for Kubernetes<\/a><\/p>\n<p><a href=\"https:\/\/thenewstack.io\/tutorial-deploy-the-nvidia-gpu-operator-on-kubernetes-based-on-containerd-runtime\/\" rel=\"noopener noreferrer nofollow\">Tutorial: Deploy the Nvidia GPU Operator on Kubernetes Based on containerd Runtime<\/a><\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c:<\/p>\n<pre><code class=\"bash\">nano \/etc\/containerd\/config.toml<\/code><\/pre>\n<p>\u041e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c:   <\/p>\n<details class=\"spoiler\">\n<summary>config.toml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"bash\">version = 2 root = \"\/var\/lib\/containerd\" state = \"\/run\/containerd\" oom_score = 0  [grpc]   max_recv_message_size = 16777216   max_send_message_size = 16777216  [debug]   level = \"info\"  [metrics]   address = \"\"   grpc_histogram = false  [plugins]   [plugins.\"io.containerd.grpc.v1.cri\"]     sandbox_image = \"registry.k8s.io\/pause:3.8\"     max_container_log_line_size = -1     enable_unprivileged_ports = false     enable_unprivileged_icmp = false     [plugins.\"io.containerd.grpc.v1.cri\".containerd]       default_runtime_name = \"nvidia\"       snapshotter = \"overlayfs\"        [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes]         [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.nvidia]           privileged_without_host_devices = false           runtime_engine = \"\"           runtime_root = \"\"           runtime_type = \"io.containerd.runc.v2\"            [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.nvidia.options]             BinaryName = \"\/usr\/bin\/nvidia-container-runtime\"          [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc]           runtime_type = \"io.containerd.runc.v2\"           runtime_engine = \"\"           runtime_root = \"\"           base_runtime_spec = \"\/etc\/containerd\/cri-base.json\"            [plugins.\"io.containerd.grpc.v1.cri\".containerd.runtimes.runc.options]             systemdCgroup = true      [plugins.\"io.containerd.grpc.v1.cri\".registry]       [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors]         [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"]           endpoint = [\"https:\/\/registry-1.docker.io\"]       [plugins.\"io.containerd.grpc.v1.cri\".registry.configs]         [plugins.\"io.containerd.grpc.v1.cri\".registry.configs.\"registry-1.docker.io\".auth]             username = \"login\"             password = \"password\"             auth = \"\"             identitytoken = \"\"<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0449\u0430\u044e \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0441\u0435\u043a\u0446\u0438\u044e &#8212; \u0432 \u043d\u0435\u0439 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0430\u0448 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439, \u0437\u0434\u0435\u0441\u044c \u044f \u043f\u0440\u0438\u0432\u0435\u043b \u043f\u0440\u0438\u043c\u0435\u0440 \u0441 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c Docker Hub <code>\"registry-1.docker.io\"<\/code>. <\/p>\n<p>\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441:<\/p>\n<pre><code class=\"bash\">sudo systemctl restart containerd<\/code><\/pre>\n<h3>Kubernetes<\/h3>\n<p><a href=\"https:\/\/kubernetes.io\/docs\/tasks\/manage-gpus\/scheduling-gpus\/\" rel=\"noopener noreferrer nofollow\">Schedule GPUs<\/a> <\/p>\n<p><a href=\"https:\/\/github.com\/NVIDIA\/k8s-device-plugin#quick-start\" rel=\"noopener noreferrer nofollow\">GitHub &#8212;<\/a><\/p>\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-348346","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/348346","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=348346"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/348346\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=348346"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=348346"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=348346"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}