From edd57abf794911f0cdc3a7963a7c4edf8c046530 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 27 Apr 2025 17:28:41 +0400 Subject: [PATCH 1/3] lab 4 is ready --- .gitignore | 3 +- pyzhov_egor_lab_4/conf.xml | 20 ++ pyzhov_egor_lab_4/myConf.xml | 35 ++++ pyzhov_egor_lab_4/pom.xml | 50 +++++ pyzhov_egor_lab_4/readme.md | 171 ++++++++++++++++++ .../src/main/java/MatrixApp.java | 156 ++++++++++++++++ 6 files changed, 434 insertions(+), 1 deletion(-) create mode 100644 pyzhov_egor_lab_4/conf.xml create mode 100644 pyzhov_egor_lab_4/myConf.xml create mode 100644 pyzhov_egor_lab_4/pom.xml create mode 100644 pyzhov_egor_lab_4/readme.md create mode 100644 pyzhov_egor_lab_4/src/main/java/MatrixApp.java diff --git a/.gitignore b/.gitignore index f562b67..343e18d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,6 @@ *.tar.gz *.rar *.iml -*.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* replay_pid* @@ -29,3 +28,5 @@ replay_pid* /.idea/.name .idea +pyzhov_egor_lab_3/ +pyzhov_egor_lab_4/target/ diff --git a/pyzhov_egor_lab_4/conf.xml b/pyzhov_egor_lab_4/conf.xml new file mode 100644 index 0000000..8cd816d --- /dev/null +++ b/pyzhov_egor_lab_4/conf.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pyzhov_egor_lab_4/myConf.xml b/pyzhov_egor_lab_4/myConf.xml new file mode 100644 index 0000000..8273f6f --- /dev/null +++ b/pyzhov_egor_lab_4/myConf.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + 192.168.17.117:47500 + 192.168.17.118:47500 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pyzhov_egor_lab_4/pom.xml b/pyzhov_egor_lab_4/pom.xml new file mode 100644 index 0000000..8d3acda --- /dev/null +++ b/pyzhov_egor_lab_4/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + + org.urlshort + sspr4 + 1.0-SNAPSHOT + jar + + lab4 + http://maven.apache.org + + + UTF-8 + + + + + org.apache.ignite + ignite-core + 2.17.0 + + + org.apache.ignite + ignite-indexing + 2.17.0 + + + org.apache.ignite + ignite-spring + 2.17.0 + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.7.18 + + + + repackage + + + + + + + diff --git a/pyzhov_egor_lab_4/readme.md b/pyzhov_egor_lab_4/readme.md new file mode 100644 index 0000000..fa68117 --- /dev/null +++ b/pyzhov_egor_lab_4/readme.md @@ -0,0 +1,171 @@ +# Лабораторная работа 4 + +## Задание + +Разработка распределенного приложения с использованием платформы Apache Ignite. +Необходимо разработать параллельный вариант алгоритма с применением подхода Grid +Gain и платформа Apache Ignite, замерить время его работы. + +**Вариант:** "Упорядочить строки матрицы по убыванию первых элементов." + +## Описание работы программы + +1. **Инициализация Ignite:** Запускает Ignite-кластер, используя конфигурационный файл `conf.xml`. +2. **Генерация матрицы:** Создает квадратную матрицу заданного размера (из аргументов командной строки). +3. **Распределенная сортировка матрицы:** + * Использует Ignite для распределенного выполнения задачи `MatrixSortingTask`. + * Задача `MatrixSortingTask` разделяет работу на подзадачи (`MatrixSortingJob`), распределяя обработку строк матрицы между узлами кластера. +4. **Разделение задачи(`split`)** + * Игнайт автоматически определяет количество узлов (gridSize). + * Матрица разбивается на блоки строк, каждый из которых обрабатывается отдельной подзадачей (MatrixSortingJob). +5. **Параллельная сортировка (`execute`)** + * Каждый узел получает свой диапазон строк, сортирует их по первому элементу (по убыванию) и возвращает результат. +6. **Объединение результатов (`reduce`)** + * Главный узел собирает все отсортированные блоки и выполняет финальную сортировку для получения итоговой матрицы. +7. **Вывод результата:** + * Если размер матрицы меньше 10x10, выводит отсортированную матрицу в консоль. + * В противном случае выводит сообщение о завершении сортировки. + * Замеряет и выводит время выполнения (duration). +## Описание кода +```java +public static void main(String[] args) { + String workingDir = System.getProperty("user.dir") + File.separator + "conf.xml"; + Path path = Paths.get(workingDir); + int size = Integer.parseInt(args[args.length - 1]); + + try (Ignite ignite = Ignition.start(workingDir)) { + int[][] matrix = new int[size][size]; + Random r = new Random(); + } +``` +Основной метод программы, который: +* Загружает конфигурацию Ignite из файла conf.xml +* Получает размер матрицы из аргументов командной строки +* Инициализирует Ignite-кластер +* Создает матрицу заданного размера и заполняет случайными числами + + +```java +public static class MatrixSortingTask extends ComputeTaskSplitAdapter { + @Override + protected List split(int gridSize, int[][] matrix) { + List jobs = new ArrayList<>(); + int batchSize = Math.max(1, matrix.length / gridSize); +``` +Класс задачи, который Разделяет матрицу на части по количеству доступных узлов (gridSize) и создает подзадачи (MatrixSortingJob) для обработки каждой части. + +```java +public static class MatrixSortingJob implements ComputeJob { + @Override + public int[][] execute() { + List rows = new ArrayList<>(); + for (int[] row : part) { + rows.add(row); + } + Collections.sort(rows, (row1, row2) -> Integer.compare(row2[0], row1[0])); +``` +Класс подзадачи, который получает часть для обработки, сортирует и возвращает отсортированную часть. + +```java +@Override +public int[][] reduce(List results) { + List sortedRows = new ArrayList<>(); + for (ComputeJobResult res : results) { + int[][] part = res.getData(); + Collections.sort(sortedRows, (row1, row2) -> Integer.compare(row2[0], row1[0])); + } + return sortedRows.toArray(new int[0][]); +} +``` +Метод получающий результаты со всех узлов, выполняет финальную сортировку объединенной матрицы. + + +## Запуск приложения +1) На обоих контейнерах должен быть установлен Apache Ignite. + ```bush + wget https://dlcdn.apache.org/ignite/2.17.0/apache-ignite-2.17.0-bin.zip + unzip apache-ignite-2.17.0-bin.zip + ``` +2) На первом контейнере должен быть jar файл в одной папке с conf.xml, на втором в apache-ignite-2.17.0-bin/config должен находиться наш myConf.xml +3) Переходим на второй контейнер, который без jar файла и переходим в директорию apache-ignite-2.17.0-bin/bin, выполняем следующую команду: + ```bash + ignite.sh -i + ``` + Выбираем myConf.xml +4) На контейнере с jar файлом запускаем программу + ```bash + java -jar sspr4-1.0-SNAPSHOT.jar SIZE + ``` + +## Основные технологии + +- **Maven** +- **Apache Ignite** +- **Java 11** + +## Результат работы программы +Запуск: +```bash +java -jar sspr4-1.0-SNAPSHOT.jar 5 +``` + +Вывод в первом контейнере: +``` +Original matrix: +29 75 96 81 52 +21 97 49 1 72 +51 66 20 60 71 +0 20 30 70 66 +49 72 49 91 11 +[MAIN] Created job for rows 0 to 1 +[MAIN] Created job for rows 2 to 4 +[Node-52c56677] Processing rows 0 to 1 +[Node-52c56677] Part before sorting: +29 75 96 81 52 +21 97 49 1 72 +[Node-52c56677] Part after sorting: +29 75 96 81 52 +21 97 49 1 72 + +Sorted matrix (by first element in descending order): +51 66 20 60 71 +49 72 49 91 11 +29 75 96 81 52 +21 97 49 1 72 +0 20 30 70 66 +Execution time: 109 ms +[12:04:46] Ignite node stopped OK [name=my-cluster, uptime=00:00:00.327] +``` + +Вывод в втором контейенере: +``` +[Node-85bfc0d0] Processing rows 2 to 4 +[Node-85bfc0d0] Part before sorting: +51 66 20 60 71 +0 20 30 70 66 +49 72 49 91 11 +[Node-85bfc0d0] Part after sorting: +51 66 20 60 71 +49 72 49 91 11 +0 20 30 70 66 +``` + + +Были проведены замеры работы программы на разных объёмах данных: + +Замеры с использованием двух узлов: +- size 1000: 171 ms +- size 3000: 967 ms +- size 5000: 1881 ms +- size 7000: 4744 ms + +Замеры с выполнением на одном узле: +- size 1000: 32 ms +- size 3000: 29 ms +- size 5000: 50 ms +- size 7000: 68 ms + +## Вывод + +Из полученных результатов можно сделать вывод, что в нашем случае, распределение вычислений между контейенерами привело к значительному замедлению во всех случаях. Накладные расходы на координацию между узлами занимают гораздо большее время, чем сам процесс сортировки. + diff --git a/pyzhov_egor_lab_4/src/main/java/MatrixApp.java b/pyzhov_egor_lab_4/src/main/java/MatrixApp.java new file mode 100644 index 0000000..8798c51 --- /dev/null +++ b/pyzhov_egor_lab_4/src/main/java/MatrixApp.java @@ -0,0 +1,156 @@ +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteException; +import org.apache.ignite.Ignition; +import org.apache.ignite.compute.ComputeTaskSplitAdapter; +import org.apache.ignite.compute.ComputeJob; +import org.apache.ignite.compute.ComputeJobResult; +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.cluster.ClusterNode; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.UUID; + +public class MatrixApp { + public static void main(String[] args) { + String workingDir = System.getProperty("user.dir") + File.separator + "conf.xml"; + Path path = Paths.get(workingDir); + int size = Integer.parseInt(args[args.length - 1]); + + try (Ignite ignite = Ignition.start(workingDir)) { + int[][] matrix = new int[size][size]; + Random r = new Random(); + + System.out.println("Original matrix:"); + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + matrix[i][j] = r.nextInt(100); + System.out.print(matrix[i][j] + "\t"); + } + System.out.println(); + } + + long start = System.currentTimeMillis(); + int[][] sortedMatrix = ignite.compute().execute(new MatrixSortingTask(), matrix); + long duration = System.currentTimeMillis() - start; + + System.out.println("\nSorted matrix (by first element in descending order):"); + for (int[] row : sortedMatrix) { + for (int value : row) { + System.out.print(value + "\t"); + } + System.out.println(); + } + + System.out.println("Execution time: " + duration + " ms"); + } catch (IgniteException e) { + System.err.println("Ignite Exception: " + e.getMessage()); + e.printStackTrace(); + } catch (Exception e) { + System.err.println("General Exception: " + e.getMessage()); + e.printStackTrace(); + } + } + + public static class MatrixSortingTask extends ComputeTaskSplitAdapter { + @IgniteInstanceResource + private Ignite ignite; + + @Override + protected List split(int gridSize, int[][] matrix) { + List jobs = new ArrayList<>(); + int batchSize = Math.max(1, matrix.length / gridSize); + + for (int i = 0; i < gridSize; i++) { + int start = i * batchSize; + int end = (i == gridSize - 1) ? matrix.length : (i + 1) * batchSize; + + if (start < matrix.length) { + jobs.add(new MatrixSortingJob(matrix, start, end)); + System.out.println("[MAIN] Created job for rows " + start + " to " + (end - 1)); + } + } + + return jobs; + } + + @Override + public int[][] reduce(List results) { + List sortedRows = new ArrayList<>(); + + for (ComputeJobResult res : results) { + int[][] part = res.getData(); + for (int[] row : part) { + sortedRows.add(row); + } + } + + Collections.sort(sortedRows, (row1, row2) -> Integer.compare(row2[0], row1[0])); + + return sortedRows.toArray(new int[0][]); + } + } + + public static class MatrixSortingJob implements ComputeJob { + @IgniteInstanceResource + private Ignite ignite; + + private final int[][] matrix; + private final int start; + private final int end; + + public MatrixSortingJob(int[][] matrix, int start, int end) { + this.matrix = matrix; + this.start = start; + this.end = end; + } + + @Override + public int[][] execute() { + ClusterNode node = ignite.cluster().localNode(); + UUID nodeId = node.id(); + String nodeName = "Node-" + nodeId.toString().substring(0, 8); + + System.out.println("[" + nodeName + "] Processing rows " + start + " to " + (end - 1)); + + int[][] part = new int[end - start][]; + System.arraycopy(matrix, start, part, 0, end - start); + + System.out.println("[" + nodeName + "] Part before sorting:"); + for (int[] row : part) { + for (int value : row) { + System.out.print(value + "\t"); + } + System.out.println(); + } + + List rows = new ArrayList<>(); + for (int[] row : part) { + rows.add(row); + } + + Collections.sort(rows, (row1, row2) -> Integer.compare(row2[0], row1[0])); + + System.out.println("[" + nodeName + "] Part after sorting:"); + for (int[] row : rows) { + for (int value : row) { + System.out.print(value + "\t"); + } + System.out.println(); + } + + return rows.toArray(new int[0][]); + } + + @Override + public void cancel() { + System.out.println("Job was cancelled"); + } + } +} \ No newline at end of file -- 2.25.1 From b9045f40318d8154bcb92c8638dd069c28bf47ac Mon Sep 17 00:00:00 2001 From: user Date: Sun, 27 Apr 2025 17:34:06 +0400 Subject: [PATCH 2/3] Revert "lab 4 is ready" This reverts commit edd57abf794911f0cdc3a7963a7c4edf8c046530. --- .gitignore | 3 +- pyzhov_egor_lab_4/conf.xml | 20 -- pyzhov_egor_lab_4/myConf.xml | 35 ---- pyzhov_egor_lab_4/pom.xml | 50 ----- pyzhov_egor_lab_4/readme.md | 171 ------------------ .../src/main/java/MatrixApp.java | 156 ---------------- 6 files changed, 1 insertion(+), 434 deletions(-) delete mode 100644 pyzhov_egor_lab_4/conf.xml delete mode 100644 pyzhov_egor_lab_4/myConf.xml delete mode 100644 pyzhov_egor_lab_4/pom.xml delete mode 100644 pyzhov_egor_lab_4/readme.md delete mode 100644 pyzhov_egor_lab_4/src/main/java/MatrixApp.java diff --git a/.gitignore b/.gitignore index 343e18d..f562b67 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,7 @@ *.tar.gz *.rar *.iml +*.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* replay_pid* @@ -28,5 +29,3 @@ replay_pid* /.idea/.name .idea -pyzhov_egor_lab_3/ -pyzhov_egor_lab_4/target/ diff --git a/pyzhov_egor_lab_4/conf.xml b/pyzhov_egor_lab_4/conf.xml deleted file mode 100644 index 8cd816d..0000000 --- a/pyzhov_egor_lab_4/conf.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/pyzhov_egor_lab_4/myConf.xml b/pyzhov_egor_lab_4/myConf.xml deleted file mode 100644 index 8273f6f..0000000 --- a/pyzhov_egor_lab_4/myConf.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - 192.168.17.117:47500 - 192.168.17.118:47500 - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/pyzhov_egor_lab_4/pom.xml b/pyzhov_egor_lab_4/pom.xml deleted file mode 100644 index 8d3acda..0000000 --- a/pyzhov_egor_lab_4/pom.xml +++ /dev/null @@ -1,50 +0,0 @@ - - 4.0.0 - - org.urlshort - sspr4 - 1.0-SNAPSHOT - jar - - lab4 - http://maven.apache.org - - - UTF-8 - - - - - org.apache.ignite - ignite-core - 2.17.0 - - - org.apache.ignite - ignite-indexing - 2.17.0 - - - org.apache.ignite - ignite-spring - 2.17.0 - - - - - - org.springframework.boot - spring-boot-maven-plugin - 2.7.18 - - - - repackage - - - - - - - diff --git a/pyzhov_egor_lab_4/readme.md b/pyzhov_egor_lab_4/readme.md deleted file mode 100644 index fa68117..0000000 --- a/pyzhov_egor_lab_4/readme.md +++ /dev/null @@ -1,171 +0,0 @@ -# Лабораторная работа 4 - -## Задание - -Разработка распределенного приложения с использованием платформы Apache Ignite. -Необходимо разработать параллельный вариант алгоритма с применением подхода Grid -Gain и платформа Apache Ignite, замерить время его работы. - -**Вариант:** "Упорядочить строки матрицы по убыванию первых элементов." - -## Описание работы программы - -1. **Инициализация Ignite:** Запускает Ignite-кластер, используя конфигурационный файл `conf.xml`. -2. **Генерация матрицы:** Создает квадратную матрицу заданного размера (из аргументов командной строки). -3. **Распределенная сортировка матрицы:** - * Использует Ignite для распределенного выполнения задачи `MatrixSortingTask`. - * Задача `MatrixSortingTask` разделяет работу на подзадачи (`MatrixSortingJob`), распределяя обработку строк матрицы между узлами кластера. -4. **Разделение задачи(`split`)** - * Игнайт автоматически определяет количество узлов (gridSize). - * Матрица разбивается на блоки строк, каждый из которых обрабатывается отдельной подзадачей (MatrixSortingJob). -5. **Параллельная сортировка (`execute`)** - * Каждый узел получает свой диапазон строк, сортирует их по первому элементу (по убыванию) и возвращает результат. -6. **Объединение результатов (`reduce`)** - * Главный узел собирает все отсортированные блоки и выполняет финальную сортировку для получения итоговой матрицы. -7. **Вывод результата:** - * Если размер матрицы меньше 10x10, выводит отсортированную матрицу в консоль. - * В противном случае выводит сообщение о завершении сортировки. - * Замеряет и выводит время выполнения (duration). -## Описание кода -```java -public static void main(String[] args) { - String workingDir = System.getProperty("user.dir") + File.separator + "conf.xml"; - Path path = Paths.get(workingDir); - int size = Integer.parseInt(args[args.length - 1]); - - try (Ignite ignite = Ignition.start(workingDir)) { - int[][] matrix = new int[size][size]; - Random r = new Random(); - } -``` -Основной метод программы, который: -* Загружает конфигурацию Ignite из файла conf.xml -* Получает размер матрицы из аргументов командной строки -* Инициализирует Ignite-кластер -* Создает матрицу заданного размера и заполняет случайными числами - - -```java -public static class MatrixSortingTask extends ComputeTaskSplitAdapter { - @Override - protected List split(int gridSize, int[][] matrix) { - List jobs = new ArrayList<>(); - int batchSize = Math.max(1, matrix.length / gridSize); -``` -Класс задачи, который Разделяет матрицу на части по количеству доступных узлов (gridSize) и создает подзадачи (MatrixSortingJob) для обработки каждой части. - -```java -public static class MatrixSortingJob implements ComputeJob { - @Override - public int[][] execute() { - List rows = new ArrayList<>(); - for (int[] row : part) { - rows.add(row); - } - Collections.sort(rows, (row1, row2) -> Integer.compare(row2[0], row1[0])); -``` -Класс подзадачи, который получает часть для обработки, сортирует и возвращает отсортированную часть. - -```java -@Override -public int[][] reduce(List results) { - List sortedRows = new ArrayList<>(); - for (ComputeJobResult res : results) { - int[][] part = res.getData(); - Collections.sort(sortedRows, (row1, row2) -> Integer.compare(row2[0], row1[0])); - } - return sortedRows.toArray(new int[0][]); -} -``` -Метод получающий результаты со всех узлов, выполняет финальную сортировку объединенной матрицы. - - -## Запуск приложения -1) На обоих контейнерах должен быть установлен Apache Ignite. - ```bush - wget https://dlcdn.apache.org/ignite/2.17.0/apache-ignite-2.17.0-bin.zip - unzip apache-ignite-2.17.0-bin.zip - ``` -2) На первом контейнере должен быть jar файл в одной папке с conf.xml, на втором в apache-ignite-2.17.0-bin/config должен находиться наш myConf.xml -3) Переходим на второй контейнер, который без jar файла и переходим в директорию apache-ignite-2.17.0-bin/bin, выполняем следующую команду: - ```bash - ignite.sh -i - ``` - Выбираем myConf.xml -4) На контейнере с jar файлом запускаем программу - ```bash - java -jar sspr4-1.0-SNAPSHOT.jar SIZE - ``` - -## Основные технологии - -- **Maven** -- **Apache Ignite** -- **Java 11** - -## Результат работы программы -Запуск: -```bash -java -jar sspr4-1.0-SNAPSHOT.jar 5 -``` - -Вывод в первом контейнере: -``` -Original matrix: -29 75 96 81 52 -21 97 49 1 72 -51 66 20 60 71 -0 20 30 70 66 -49 72 49 91 11 -[MAIN] Created job for rows 0 to 1 -[MAIN] Created job for rows 2 to 4 -[Node-52c56677] Processing rows 0 to 1 -[Node-52c56677] Part before sorting: -29 75 96 81 52 -21 97 49 1 72 -[Node-52c56677] Part after sorting: -29 75 96 81 52 -21 97 49 1 72 - -Sorted matrix (by first element in descending order): -51 66 20 60 71 -49 72 49 91 11 -29 75 96 81 52 -21 97 49 1 72 -0 20 30 70 66 -Execution time: 109 ms -[12:04:46] Ignite node stopped OK [name=my-cluster, uptime=00:00:00.327] -``` - -Вывод в втором контейенере: -``` -[Node-85bfc0d0] Processing rows 2 to 4 -[Node-85bfc0d0] Part before sorting: -51 66 20 60 71 -0 20 30 70 66 -49 72 49 91 11 -[Node-85bfc0d0] Part after sorting: -51 66 20 60 71 -49 72 49 91 11 -0 20 30 70 66 -``` - - -Были проведены замеры работы программы на разных объёмах данных: - -Замеры с использованием двух узлов: -- size 1000: 171 ms -- size 3000: 967 ms -- size 5000: 1881 ms -- size 7000: 4744 ms - -Замеры с выполнением на одном узле: -- size 1000: 32 ms -- size 3000: 29 ms -- size 5000: 50 ms -- size 7000: 68 ms - -## Вывод - -Из полученных результатов можно сделать вывод, что в нашем случае, распределение вычислений между контейенерами привело к значительному замедлению во всех случаях. Накладные расходы на координацию между узлами занимают гораздо большее время, чем сам процесс сортировки. - diff --git a/pyzhov_egor_lab_4/src/main/java/MatrixApp.java b/pyzhov_egor_lab_4/src/main/java/MatrixApp.java deleted file mode 100644 index 8798c51..0000000 --- a/pyzhov_egor_lab_4/src/main/java/MatrixApp.java +++ /dev/null @@ -1,156 +0,0 @@ -import org.apache.ignite.Ignite; -import org.apache.ignite.IgniteException; -import org.apache.ignite.Ignition; -import org.apache.ignite.compute.ComputeTaskSplitAdapter; -import org.apache.ignite.compute.ComputeJob; -import org.apache.ignite.compute.ComputeJobResult; -import org.apache.ignite.resources.IgniteInstanceResource; -import org.apache.ignite.cluster.ClusterNode; - -import java.io.File; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Random; -import java.util.UUID; - -public class MatrixApp { - public static void main(String[] args) { - String workingDir = System.getProperty("user.dir") + File.separator + "conf.xml"; - Path path = Paths.get(workingDir); - int size = Integer.parseInt(args[args.length - 1]); - - try (Ignite ignite = Ignition.start(workingDir)) { - int[][] matrix = new int[size][size]; - Random r = new Random(); - - System.out.println("Original matrix:"); - for (int i = 0; i < size; i++) { - for (int j = 0; j < size; j++) { - matrix[i][j] = r.nextInt(100); - System.out.print(matrix[i][j] + "\t"); - } - System.out.println(); - } - - long start = System.currentTimeMillis(); - int[][] sortedMatrix = ignite.compute().execute(new MatrixSortingTask(), matrix); - long duration = System.currentTimeMillis() - start; - - System.out.println("\nSorted matrix (by first element in descending order):"); - for (int[] row : sortedMatrix) { - for (int value : row) { - System.out.print(value + "\t"); - } - System.out.println(); - } - - System.out.println("Execution time: " + duration + " ms"); - } catch (IgniteException e) { - System.err.println("Ignite Exception: " + e.getMessage()); - e.printStackTrace(); - } catch (Exception e) { - System.err.println("General Exception: " + e.getMessage()); - e.printStackTrace(); - } - } - - public static class MatrixSortingTask extends ComputeTaskSplitAdapter { - @IgniteInstanceResource - private Ignite ignite; - - @Override - protected List split(int gridSize, int[][] matrix) { - List jobs = new ArrayList<>(); - int batchSize = Math.max(1, matrix.length / gridSize); - - for (int i = 0; i < gridSize; i++) { - int start = i * batchSize; - int end = (i == gridSize - 1) ? matrix.length : (i + 1) * batchSize; - - if (start < matrix.length) { - jobs.add(new MatrixSortingJob(matrix, start, end)); - System.out.println("[MAIN] Created job for rows " + start + " to " + (end - 1)); - } - } - - return jobs; - } - - @Override - public int[][] reduce(List results) { - List sortedRows = new ArrayList<>(); - - for (ComputeJobResult res : results) { - int[][] part = res.getData(); - for (int[] row : part) { - sortedRows.add(row); - } - } - - Collections.sort(sortedRows, (row1, row2) -> Integer.compare(row2[0], row1[0])); - - return sortedRows.toArray(new int[0][]); - } - } - - public static class MatrixSortingJob implements ComputeJob { - @IgniteInstanceResource - private Ignite ignite; - - private final int[][] matrix; - private final int start; - private final int end; - - public MatrixSortingJob(int[][] matrix, int start, int end) { - this.matrix = matrix; - this.start = start; - this.end = end; - } - - @Override - public int[][] execute() { - ClusterNode node = ignite.cluster().localNode(); - UUID nodeId = node.id(); - String nodeName = "Node-" + nodeId.toString().substring(0, 8); - - System.out.println("[" + nodeName + "] Processing rows " + start + " to " + (end - 1)); - - int[][] part = new int[end - start][]; - System.arraycopy(matrix, start, part, 0, end - start); - - System.out.println("[" + nodeName + "] Part before sorting:"); - for (int[] row : part) { - for (int value : row) { - System.out.print(value + "\t"); - } - System.out.println(); - } - - List rows = new ArrayList<>(); - for (int[] row : part) { - rows.add(row); - } - - Collections.sort(rows, (row1, row2) -> Integer.compare(row2[0], row1[0])); - - System.out.println("[" + nodeName + "] Part after sorting:"); - for (int[] row : rows) { - for (int value : row) { - System.out.print(value + "\t"); - } - System.out.println(); - } - - return rows.toArray(new int[0][]); - } - - @Override - public void cancel() { - System.out.println("Job was cancelled"); - } - } -} \ No newline at end of file -- 2.25.1 From 3377c7f24581125cd2e722c591766779d6daec43 Mon Sep 17 00:00:00 2001 From: user Date: Sun, 27 Apr 2025 17:44:34 +0400 Subject: [PATCH 3/3] lab 4 is ready --- pyzhov_egor_lab_4/.gitignore | 40 ++++ pyzhov_egor_lab_4/conf.xml | 20 ++ pyzhov_egor_lab_4/myConf.xml | 35 ++++ pyzhov_egor_lab_4/pom.xml | 50 +++++ pyzhov_egor_lab_4/readme.md | 171 ++++++++++++++++++ .../src/main/java/MatrixApp.java | 156 ++++++++++++++++ 6 files changed, 472 insertions(+) create mode 100644 pyzhov_egor_lab_4/.gitignore create mode 100644 pyzhov_egor_lab_4/conf.xml create mode 100644 pyzhov_egor_lab_4/myConf.xml create mode 100644 pyzhov_egor_lab_4/pom.xml create mode 100644 pyzhov_egor_lab_4/readme.md create mode 100644 pyzhov_egor_lab_4/src/main/java/MatrixApp.java diff --git a/pyzhov_egor_lab_4/.gitignore b/pyzhov_egor_lab_4/.gitignore new file mode 100644 index 0000000..d048d4b --- /dev/null +++ b/pyzhov_egor_lab_4/.gitignore @@ -0,0 +1,40 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +!conf.xml +!myConf.xml +!pom.xml +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/pyzhov_egor_lab_4/conf.xml b/pyzhov_egor_lab_4/conf.xml new file mode 100644 index 0000000..8cd816d --- /dev/null +++ b/pyzhov_egor_lab_4/conf.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pyzhov_egor_lab_4/myConf.xml b/pyzhov_egor_lab_4/myConf.xml new file mode 100644 index 0000000..8273f6f --- /dev/null +++ b/pyzhov_egor_lab_4/myConf.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + 192.168.17.117:47500 + 192.168.17.118:47500 + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pyzhov_egor_lab_4/pom.xml b/pyzhov_egor_lab_4/pom.xml new file mode 100644 index 0000000..8d3acda --- /dev/null +++ b/pyzhov_egor_lab_4/pom.xml @@ -0,0 +1,50 @@ + + 4.0.0 + + org.urlshort + sspr4 + 1.0-SNAPSHOT + jar + + lab4 + http://maven.apache.org + + + UTF-8 + + + + + org.apache.ignite + ignite-core + 2.17.0 + + + org.apache.ignite + ignite-indexing + 2.17.0 + + + org.apache.ignite + ignite-spring + 2.17.0 + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.7.18 + + + + repackage + + + + + + + diff --git a/pyzhov_egor_lab_4/readme.md b/pyzhov_egor_lab_4/readme.md new file mode 100644 index 0000000..fa68117 --- /dev/null +++ b/pyzhov_egor_lab_4/readme.md @@ -0,0 +1,171 @@ +# Лабораторная работа 4 + +## Задание + +Разработка распределенного приложения с использованием платформы Apache Ignite. +Необходимо разработать параллельный вариант алгоритма с применением подхода Grid +Gain и платформа Apache Ignite, замерить время его работы. + +**Вариант:** "Упорядочить строки матрицы по убыванию первых элементов." + +## Описание работы программы + +1. **Инициализация Ignite:** Запускает Ignite-кластер, используя конфигурационный файл `conf.xml`. +2. **Генерация матрицы:** Создает квадратную матрицу заданного размера (из аргументов командной строки). +3. **Распределенная сортировка матрицы:** + * Использует Ignite для распределенного выполнения задачи `MatrixSortingTask`. + * Задача `MatrixSortingTask` разделяет работу на подзадачи (`MatrixSortingJob`), распределяя обработку строк матрицы между узлами кластера. +4. **Разделение задачи(`split`)** + * Игнайт автоматически определяет количество узлов (gridSize). + * Матрица разбивается на блоки строк, каждый из которых обрабатывается отдельной подзадачей (MatrixSortingJob). +5. **Параллельная сортировка (`execute`)** + * Каждый узел получает свой диапазон строк, сортирует их по первому элементу (по убыванию) и возвращает результат. +6. **Объединение результатов (`reduce`)** + * Главный узел собирает все отсортированные блоки и выполняет финальную сортировку для получения итоговой матрицы. +7. **Вывод результата:** + * Если размер матрицы меньше 10x10, выводит отсортированную матрицу в консоль. + * В противном случае выводит сообщение о завершении сортировки. + * Замеряет и выводит время выполнения (duration). +## Описание кода +```java +public static void main(String[] args) { + String workingDir = System.getProperty("user.dir") + File.separator + "conf.xml"; + Path path = Paths.get(workingDir); + int size = Integer.parseInt(args[args.length - 1]); + + try (Ignite ignite = Ignition.start(workingDir)) { + int[][] matrix = new int[size][size]; + Random r = new Random(); + } +``` +Основной метод программы, который: +* Загружает конфигурацию Ignite из файла conf.xml +* Получает размер матрицы из аргументов командной строки +* Инициализирует Ignite-кластер +* Создает матрицу заданного размера и заполняет случайными числами + + +```java +public static class MatrixSortingTask extends ComputeTaskSplitAdapter { + @Override + protected List split(int gridSize, int[][] matrix) { + List jobs = new ArrayList<>(); + int batchSize = Math.max(1, matrix.length / gridSize); +``` +Класс задачи, который Разделяет матрицу на части по количеству доступных узлов (gridSize) и создает подзадачи (MatrixSortingJob) для обработки каждой части. + +```java +public static class MatrixSortingJob implements ComputeJob { + @Override + public int[][] execute() { + List rows = new ArrayList<>(); + for (int[] row : part) { + rows.add(row); + } + Collections.sort(rows, (row1, row2) -> Integer.compare(row2[0], row1[0])); +``` +Класс подзадачи, который получает часть для обработки, сортирует и возвращает отсортированную часть. + +```java +@Override +public int[][] reduce(List results) { + List sortedRows = new ArrayList<>(); + for (ComputeJobResult res : results) { + int[][] part = res.getData(); + Collections.sort(sortedRows, (row1, row2) -> Integer.compare(row2[0], row1[0])); + } + return sortedRows.toArray(new int[0][]); +} +``` +Метод получающий результаты со всех узлов, выполняет финальную сортировку объединенной матрицы. + + +## Запуск приложения +1) На обоих контейнерах должен быть установлен Apache Ignite. + ```bush + wget https://dlcdn.apache.org/ignite/2.17.0/apache-ignite-2.17.0-bin.zip + unzip apache-ignite-2.17.0-bin.zip + ``` +2) На первом контейнере должен быть jar файл в одной папке с conf.xml, на втором в apache-ignite-2.17.0-bin/config должен находиться наш myConf.xml +3) Переходим на второй контейнер, который без jar файла и переходим в директорию apache-ignite-2.17.0-bin/bin, выполняем следующую команду: + ```bash + ignite.sh -i + ``` + Выбираем myConf.xml +4) На контейнере с jar файлом запускаем программу + ```bash + java -jar sspr4-1.0-SNAPSHOT.jar SIZE + ``` + +## Основные технологии + +- **Maven** +- **Apache Ignite** +- **Java 11** + +## Результат работы программы +Запуск: +```bash +java -jar sspr4-1.0-SNAPSHOT.jar 5 +``` + +Вывод в первом контейнере: +``` +Original matrix: +29 75 96 81 52 +21 97 49 1 72 +51 66 20 60 71 +0 20 30 70 66 +49 72 49 91 11 +[MAIN] Created job for rows 0 to 1 +[MAIN] Created job for rows 2 to 4 +[Node-52c56677] Processing rows 0 to 1 +[Node-52c56677] Part before sorting: +29 75 96 81 52 +21 97 49 1 72 +[Node-52c56677] Part after sorting: +29 75 96 81 52 +21 97 49 1 72 + +Sorted matrix (by first element in descending order): +51 66 20 60 71 +49 72 49 91 11 +29 75 96 81 52 +21 97 49 1 72 +0 20 30 70 66 +Execution time: 109 ms +[12:04:46] Ignite node stopped OK [name=my-cluster, uptime=00:00:00.327] +``` + +Вывод в втором контейенере: +``` +[Node-85bfc0d0] Processing rows 2 to 4 +[Node-85bfc0d0] Part before sorting: +51 66 20 60 71 +0 20 30 70 66 +49 72 49 91 11 +[Node-85bfc0d0] Part after sorting: +51 66 20 60 71 +49 72 49 91 11 +0 20 30 70 66 +``` + + +Были проведены замеры работы программы на разных объёмах данных: + +Замеры с использованием двух узлов: +- size 1000: 171 ms +- size 3000: 967 ms +- size 5000: 1881 ms +- size 7000: 4744 ms + +Замеры с выполнением на одном узле: +- size 1000: 32 ms +- size 3000: 29 ms +- size 5000: 50 ms +- size 7000: 68 ms + +## Вывод + +Из полученных результатов можно сделать вывод, что в нашем случае, распределение вычислений между контейенерами привело к значительному замедлению во всех случаях. Накладные расходы на координацию между узлами занимают гораздо большее время, чем сам процесс сортировки. + diff --git a/pyzhov_egor_lab_4/src/main/java/MatrixApp.java b/pyzhov_egor_lab_4/src/main/java/MatrixApp.java new file mode 100644 index 0000000..8798c51 --- /dev/null +++ b/pyzhov_egor_lab_4/src/main/java/MatrixApp.java @@ -0,0 +1,156 @@ +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteException; +import org.apache.ignite.Ignition; +import org.apache.ignite.compute.ComputeTaskSplitAdapter; +import org.apache.ignite.compute.ComputeJob; +import org.apache.ignite.compute.ComputeJobResult; +import org.apache.ignite.resources.IgniteInstanceResource; +import org.apache.ignite.cluster.ClusterNode; + +import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.UUID; + +public class MatrixApp { + public static void main(String[] args) { + String workingDir = System.getProperty("user.dir") + File.separator + "conf.xml"; + Path path = Paths.get(workingDir); + int size = Integer.parseInt(args[args.length - 1]); + + try (Ignite ignite = Ignition.start(workingDir)) { + int[][] matrix = new int[size][size]; + Random r = new Random(); + + System.out.println("Original matrix:"); + for (int i = 0; i < size; i++) { + for (int j = 0; j < size; j++) { + matrix[i][j] = r.nextInt(100); + System.out.print(matrix[i][j] + "\t"); + } + System.out.println(); + } + + long start = System.currentTimeMillis(); + int[][] sortedMatrix = ignite.compute().execute(new MatrixSortingTask(), matrix); + long duration = System.currentTimeMillis() - start; + + System.out.println("\nSorted matrix (by first element in descending order):"); + for (int[] row : sortedMatrix) { + for (int value : row) { + System.out.print(value + "\t"); + } + System.out.println(); + } + + System.out.println("Execution time: " + duration + " ms"); + } catch (IgniteException e) { + System.err.println("Ignite Exception: " + e.getMessage()); + e.printStackTrace(); + } catch (Exception e) { + System.err.println("General Exception: " + e.getMessage()); + e.printStackTrace(); + } + } + + public static class MatrixSortingTask extends ComputeTaskSplitAdapter { + @IgniteInstanceResource + private Ignite ignite; + + @Override + protected List split(int gridSize, int[][] matrix) { + List jobs = new ArrayList<>(); + int batchSize = Math.max(1, matrix.length / gridSize); + + for (int i = 0; i < gridSize; i++) { + int start = i * batchSize; + int end = (i == gridSize - 1) ? matrix.length : (i + 1) * batchSize; + + if (start < matrix.length) { + jobs.add(new MatrixSortingJob(matrix, start, end)); + System.out.println("[MAIN] Created job for rows " + start + " to " + (end - 1)); + } + } + + return jobs; + } + + @Override + public int[][] reduce(List results) { + List sortedRows = new ArrayList<>(); + + for (ComputeJobResult res : results) { + int[][] part = res.getData(); + for (int[] row : part) { + sortedRows.add(row); + } + } + + Collections.sort(sortedRows, (row1, row2) -> Integer.compare(row2[0], row1[0])); + + return sortedRows.toArray(new int[0][]); + } + } + + public static class MatrixSortingJob implements ComputeJob { + @IgniteInstanceResource + private Ignite ignite; + + private final int[][] matrix; + private final int start; + private final int end; + + public MatrixSortingJob(int[][] matrix, int start, int end) { + this.matrix = matrix; + this.start = start; + this.end = end; + } + + @Override + public int[][] execute() { + ClusterNode node = ignite.cluster().localNode(); + UUID nodeId = node.id(); + String nodeName = "Node-" + nodeId.toString().substring(0, 8); + + System.out.println("[" + nodeName + "] Processing rows " + start + " to " + (end - 1)); + + int[][] part = new int[end - start][]; + System.arraycopy(matrix, start, part, 0, end - start); + + System.out.println("[" + nodeName + "] Part before sorting:"); + for (int[] row : part) { + for (int value : row) { + System.out.print(value + "\t"); + } + System.out.println(); + } + + List rows = new ArrayList<>(); + for (int[] row : part) { + rows.add(row); + } + + Collections.sort(rows, (row1, row2) -> Integer.compare(row2[0], row1[0])); + + System.out.println("[" + nodeName + "] Part after sorting:"); + for (int[] row : rows) { + for (int value : row) { + System.out.print(value + "\t"); + } + System.out.println(); + } + + return rows.toArray(new int[0][]); + } + + @Override + public void cancel() { + System.out.println("Job was cancelled"); + } + } +} \ No newline at end of file -- 2.25.1