pyzhov_egor_lab_4 is ready #149
40
pyzhov_egor_lab_4/.gitignore
vendored
Normal file
40
pyzhov_egor_lab_4/.gitignore
vendored
Normal file
@@ -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
|
||||
20
pyzhov_egor_lab_4/conf.xml
Normal file
20
pyzhov_egor_lab_4/conf.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
|
||||
<property name="igniteInstanceName" value="my-cluster"/>
|
||||
<property name="peerClassLoadingEnabled" value="true"/>
|
||||
<property name="cacheConfiguration">
|
||||
<list>
|
||||
<bean class="org.apache.ignite.configuration.CacheConfiguration">
|
||||
<property name="name" value="myCache"/>
|
||||
<property name="backups" value="1"/>
|
||||
<property name="cacheMode" value="PARTITIONED"/>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
35
pyzhov_egor_lab_4/myConf.xml
Normal file
35
pyzhov_egor_lab_4/myConf.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
|
||||
<property name="igniteInstanceName" value="my-cluster"/>
|
||||
<property name="peerClassLoadingEnabled" value="true"/>
|
||||
<property name="discoverySpi">
|
||||
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
|
||||
<property name="ipFinder">
|
||||
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
|
||||
<property name="addresses">
|
||||
<list>
|
||||
<value>192.168.17.117:47500</value>
|
||||
<value>192.168.17.118:47500</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
|
||||
<property name="cacheConfiguration">
|
||||
<list>
|
||||
<bean class="org.apache.ignite.configuration.CacheConfiguration">
|
||||
<property name="name" value="myCache"/>
|
||||
<property name="backups" value="1"/>
|
||||
<property name="cacheMode" value="PARTITIONED"/>
|
||||
</bean>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
||||
50
pyzhov_egor_lab_4/pom.xml
Normal file
50
pyzhov_egor_lab_4/pom.xml
Normal file
@@ -0,0 +1,50 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.urlshort</groupId>
|
||||
<artifactId>sspr4</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>lab4</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.ignite</groupId>
|
||||
<artifactId>ignite-core</artifactId>
|
||||
<version>2.17.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ignite</groupId>
|
||||
<artifactId>ignite-indexing</artifactId>
|
||||
<version>2.17.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.ignite</groupId>
|
||||
<artifactId>ignite-spring</artifactId>
|
||||
<version>2.17.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.7.18</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
171
pyzhov_egor_lab_4/readme.md
Normal file
171
pyzhov_egor_lab_4/readme.md
Normal file
@@ -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<int[][], int[][]> {
|
||||
@Override
|
||||
protected List<ComputeJob> split(int gridSize, int[][] matrix) {
|
||||
List<ComputeJob> 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<int[]> 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<ComputeJobResult> results) {
|
||||
List<int[]> 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
|
||||
|
||||
## Вывод
|
||||
|
||||
Из полученных результатов можно сделать вывод, что в нашем случае, распределение вычислений между контейенерами привело к значительному замедлению во всех случаях. Накладные расходы на координацию между узлами занимают гораздо большее время, чем сам процесс сортировки.
|
||||
|
||||
156
pyzhov_egor_lab_4/src/main/java/MatrixApp.java
Normal file
156
pyzhov_egor_lab_4/src/main/java/MatrixApp.java
Normal file
@@ -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<int[][], int[][]> {
|
||||
@IgniteInstanceResource
|
||||
private Ignite ignite;
|
||||
|
||||
@Override
|
||||
protected List<ComputeJob> split(int gridSize, int[][] matrix) {
|
||||
List<ComputeJob> 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<ComputeJobResult> results) {
|
||||
List<int[]> 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<int[]> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user