Помощь в написании студенческих работ
Антистрессовый сервис

Распределенная база данных. 
Предметная область: музыкальные диски

КурсоваяПомощь в написанииУзнать стоимостьмоей работы

Данный модуль содержит функцию DoClientProcess, которая вызывается в случае, если ранг текущего процесса равен нулю. В начале работы данная функция осуществляет подключение клиента к базе данных (на данный момент пустой). Затем происходит ввод SQL — оператора пользователем и функция переходит в режим ожидания приема результатов от серверов. После приема происходит обработка полученной информации… Читать ещё >

Распределенная база данных. Предметная область: музыкальные диски (реферат, курсовая, диплом, контрольная)

Становление систем управления базами данных совпало по времени со значительными успехами в развитии технологий распределенных вычислений и параллельной обработки. В результате возникли системы управления распределенными базами данных и системы управления параллельными базами данных. Именно эти системы становятся доминирующими инструментами для создания приложений интенсивной обработки данных.

Благодаря интеграции рабочих станций в распределенную среду становится возможным более эффективное распределение функций в ней, когда прикладные программы выполняются на рабочих станциях, называемых серверами приложений, а базы данных обслуживаются выделенными компьютерами, называемыми серверами баз данных. Это послужило источником развития таких распределенных архитектур, где в роли узлов выступают не просто компьютеры общего назначения, а специализированные серверы.

Параллельный компьютер или мультипроцессор сам по себе является распределенной системой, составленной из узлов (процессоров, компонентов памяти), соединенных быстрой сетью внутри общего корпуса. Технологии распределенных баз данных могут быть естественным образом пересмотрены и распространены на системы параллельных баз данных, т. е. баз данных на параллельных компьютерах. Благодаря применяемому в системах этого типа параллелизму управления данными пользователи получают серверы баз данных высокой производительности и высокой доступности за существенно меньшую цену, чем эквивалентные системы на основе мэйнфреймов.

Анализ требований

Необходимо разработать распределенную базу данных в компьютерной сети. РБД состоит из набора узлов, связанных коммуникационной сетью, в которой:

1) каждый узел — это полноценная СУБД сама по себе;

2) узлы взаимодействуют между собой таким образом, что пользователь любого из них может получить доступ к любым данным в сети так, как будто они находятся на его собственном узле.

Реализация

Среда параллельного программирования реализована на базе интерфейса передачи сообщений MPI, который фактически является стандартом для разработчиков параллельных программ.

MPI — это программный инструментарий для обеспечения связи между ветвями параллельного приложения. Он предоставляет программисту единый механизм взаимодействия ветвей внутри параллельного приложения независимо от машинной архитектуры (однопроцессорные / многопроцессорные с общей / раздельной памятью), взаимного расположения ветвей (на одном процессоре / на разных) и программного интерфейса пользователя операционной системы.

Программа, использующая MPI, легче отлаживается (сужается простор для совершения стереотипных ошибок параллельного программирования) и быстрее переносится на другие платформы (в идеале, простой перекомпиляцией).

Сильная сторона MPI состоит в том, что этот интерфейс предъявляет очень низкие требования к аппаратной части параллельного компьютера. Все, что нужно этому интерфейсу, — чтобы процессоры или ядра совместно использовали одну сеть, пригодную для передачи сообщений между любыми двумя процессами. Это позволяет MPI работать на любой стандартной параллельной системе, от симметричных многопроцессорных систем до систем с распределенной памятью, от суперкомпьютеров с высокой степенью параллелизма до кластеров.

MPI универсален и всеяден. Он не накладывает практически никаких ограничений на приложение, на железо, на каналы, которые используются для связи между компьютерами.

Система программ данного проекта реализована на основе архитектуры «клиент-сервер».

Описание переменных

int ProcNum

Переменная типа int, хранящая значение числа процессов, выполняющихся в рамках коммуникатора MPI_COMM_WORLD. Необходима для определения границы цикла for при отправке информации.

int ProcRank

Переменная типа int, хранящая значение ранга процесса, выполняющегося в рамках коммуникатора MPI_COMM_WORLD. Необходима для идентификации процесса.

MPI_Status Status

Переменная определенного MPI типа. Хранит информацию об успешности (неудаче) последней MPI операции.

Спецификации на программные модули

Main.cpp

Данный модуль является основным модулем программы. По своей структуре схож с классической MPI — программой, в которой в зависимости от ранга процесса (ProcRank) выполняются те или иные действия. Вначале происходит инициализация MPI, определение ранга текущего процесса и количества выполняемых процессов.

Если ранг процесса равен нулю, то вызывается функция DoClientProcess из модуля Client. cpp, иначе (ранг процесса отличен от нуля) вызывается функция DoServerProcess из модуля Server.cpp.

Затем происходит закрытие библиотеки MPI и программа завершает свою работу.

Client.cpp

Данный модуль содержит функцию DoClientProcess, которая вызывается в случае, если ранг текущего процесса равен нулю. В начале работы данная функция осуществляет подключение клиента к базе данных (на данный момент пустой). Затем происходит ввод SQL — оператора пользователем и функция переходит в режим ожидания приема результатов от серверов. После приема происходит обработка полученной информации и запись результатов в базу данных клиента.

Server.cpp

Данный модуль содержит функцию DoServerProcess, которая вызывается в случае, если ранг текущего процесса отличен от нуля. В начале работы данная функция осуществляет подключение сервера к базе данных, соответствующей его номеру (база данных содержит информацию). Сервер ожидает приема SQL — запроса от клиента. После получения SQL — запроса сервер применяет его к своей базе данных и пересылает результат клиенту.

Схема взаимодействия модулей

Схема взаимодействия модулей программы представлена на рисунке 1. Основной код программы содержится в модуле Main.cpp. Модули Server. cpp и Client. cpp содержат функции работы сервера и клиента соответственно.

Рисунок 1 Схема взаимодействия модулей

UML — диаграммы

Диаграмма вариантов использования

Пользователь занимается эксплуатацией программы. Он имеет возможность осуществить SQL — запрос к базам данных серверов или ввести команду exit, соответствующую выходу из программы.

Рисунок 2 Диаграмма вариантов использования

Диаграмма состояний

После запуска программа переходит в состояние инициализации, а затем в состояние ожидание команды. В зависимости от введенной команды состояние меняется на состояние завершения работы или на состояние SQL — запроса, которое сменяется состоянием вывода результатов на экран, после чего программа вновь переходит в состояние ожидания команды.

Рисунок 3 Диаграмма состояний

Диаграмма действий клиента

Действия начинаются с стандартных для любой MPI — программы функции инициализации. Затем осуществляется ввод пользователем строки, которая может быть интерпретирована как команда выхода из программы клиента, либо как SQL — оператор, который должен быть применен к базам данных серверов. SQL — запрос отправляется серверам в виде строки функцией MPI_Send, результаты принимаются функцией MPI_Recv, выводятся на экран и записываются в базу данных клиента.

Рисунок 4 Диаграмма действий клиента

Диаграмма действий сервера

Действия начинаются со стандартных для любой MPI-программы функции инициализации. Затем происходит подключение сервера к соответствующей базе данных. После получения сообщения от клиента оно анализируется, и программа сервера либо завершает свою работу, либо выполняет SQL — запрос к своей базе данных, после чего пересылает результат клиенту.

Рисунок 5 Диаграмма действий сервера

Диаграмма последовательностей

Рассмотрим передачу данных между тремя программами (один клиент, три сервера). Клиент отравляет SQL — запрос всем серверам, после чего ожидает прием результата. Каждый сервер, получив SQL — запрос, применяет его к своей базе данных, после чего пересылает результат клиенту, который, получив его, обновляет свою базу данных.

Рисунок 6 Диаграмма последовательностей

Структурная схема сети

Отличительной особенностью данной сети является то, что все процессы находятся в одной области видимости (выполняются в рамках одного коммуникатора), однако напрямую взаимодействовать с базой данных другого процесса не могут. Только владелец базы данных может изменять или считывать ее содержимое. Это гарантирует защищенность данных.

Рисунок 7 Структурная схема сети

Руководство пользователя

В результате запуска приложения выводится сообщение о результате подключения к базе данных. В случае удачного подключения пользователю предлагается ввести запрос в БД или команду завершения работы. После обработки SQL — запроса, результаты пересылаются клиенту и записываются в базу данных клиента. После успешного SQL — запроса можно выполнить новую команду.

Заключение

В результате выполнения курсового проекта была разработана распределенная база данных в компьютерной сети. Узлы БД взаимодействуют между собой таким образом, что пользователь любого из них может получить доступ к любым данным в сети так, как будто они находятся на его собственном узле. Разработка проводилась на языке программирования С++ в среде Microsoft Visual Studio 2010 с использованием ОС Windows XP. Осуществлено функциональное тестирование разработанных приложений, которое показало корректность их работы.

Список используемой литературы

программный база распределенный диаграмма

1) Э. Таненбаум. «Компьютерные сети», Питер 2011 г.

2) С. А. Зинкин. Курс лекций по курсу «Методы и средства обработки данных»

3) Р. Д. Верма «Справочник по функциям Win32 API»

4) Т. А. Павловская «С/С++ Программирование на языке высокого уровня», Питер 2007 г.

5) В. В. Подбельский, С. С. Фомин «Программирование на языке Си», 2007 г.

Приложение 1. Листинг программных модулей

Модуль Main.cpp

// MISOD_Kurs_Novikov

#include «Header.h»

#include «GlobVar.h»

int main (int argc, char* argv[])

{

setlocale (LC_ALL, «Rus»);

MPI_Init (&argc, &argv);

MPI_Comm_size (MPI_COMM_WORLD, &ProcNum); // количество процессов

MPI_Comm_rank (MPI_COMM_WORLD, &ProcRank); // ранг процесса

printf («n Hello from process % 3dnn», ProcRank);

// - Действия клиента ;

if (ProcRank == 0)

{

DoClientProcess ();

}

// - Действия серверов ;

else

{

DoServerProcess ();

}

MPI_Finalize ();

getch ();

return 0;

}

Модуль Client.cpp

// Client. cpp

#include «Header.h»

#include «Extern.h»

int DoClientProcess ()

{

cout << «- Client -» << endl;

// - Соединение клиента с БД (пока пустая) ;

HSTMT hstmt; // идентификатор оператора

HDBC hdbc; // идентификатор соединения

HENV henv; // идентификатор среды

SQLRETURN retcode;

char dbase[]= «Storage»; // имя БД

char user[]=""; // имя пользователя

char passwd[]=""; // пароль пользователя

SQLINTEGER sStorageID;

SQLCHAR szName [SIZE_BUF];

SQLINTEGER sSeries;

SQLCHAR szColor [SIZE_BUF];

SQLINTEGER sYear;

SQLINTEGER sCost;

SQLINTEGER cbStorageID;

SQLINTEGER cbName;

SQLINTEGER cbSeries;

SQLINTEGER cbColor;

SQLINTEGER cbYear;

SQLINTEGER cbCost;

// Назаначение идентификатора среды

retcode=SQLAllocEnv (&henv);

if (SQL_SUCCESS≠retcode)

{

printf («HENV Error! Exitn»);

_getch ();

return -1;

}

// назначение идентификатора соединения

retcode=SQLAllocConnect (henv,&hdbc);

if (SQL_SUCCESS≠retcode)

{

printf («HDBC Error! Exitn»);

SQLFreeEnv (henv);

_getch ();

return -1;

}

cout << «Connecting to DataBase…»;

retcode=SQLConnect (hdbc, (SQLCHAR*) dbase,

SQL_NTS, (SQLCHAR*) user,

SQL_NTS, (SQLCHAR*) passwd,

SQL_NTS);

if (SQL_SUCCESS≠ retcode)

{

printf («Problem with connect to DB! Exitn»);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

_getch ();

return -1;

}

cout << «DONE!» << endl;

retcode=SQLAllocStmt (hdbc,&hstmt);

if (SQL_SUCCESS≠retcode)

{

printf («HSTMT Error! Exitn»);

SQLDisconnect (hdbc);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

_getch ();

return -1;

}

// для SQL-запроса

char Storage_Id[50];

char Name[50];

char Number[50];

char avtor[50];

char year[50];

char Cost[50];

// - Цикл работы клиента ;

while (1)

{

char *SQLString = new char[50];

cout << «nInput SQL-query to Server DB:»;

gets (SQLString);

cout << «nYour SQL-query:» << SQLString << endl;

int countSend = strlen (SQLString);

cout << «countSend =» << countSend << endl;

for (int i=1; i

{

MPI_Send (&countSend, 1, MPI_INT, i, ProcRank, MPI_COMM_WORLD); // количество отправляемых символов

MPI_Send (SQLString, countSend, MPI_CHAR, i, ProcRank, MPI_COMM_WORLD); // тег — ProcRank

}

if (! strcmp (SQLString, «exit»)) break;

// принимаем результат от серверов

char **mesRecv = new char*[1024]; // не более 1024 строк как результат SQL-запроса

for (int i=1; i

{

int countStrRec = 0;

MPI_Recv (&countStrRec, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);

//printf («countStrRec =%d», &countStrRec);

cout << endl << endl << «countStrRec =» << countStrRec << endl;

for (int j=0; j

{

int lenRecv = 0;

mesRecv[j] = new char [SIZE_BUF];

MPI_Recv (&lenRecv, 1, MPI_INT, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);

MPI_Recv (mesRecv[j], lenRecv, MPI_CHAR, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);

cout << mesRecv[j];

// Разбиваем строку, полученную от сервера

int i = 0;

while ((*(mesRecv[j]))≠ 0×09) // Пробел

{

Storage_Id[i] = *(mesRecv[j]);

i++;

(mesRecv[j])++;

}

Storage_Id[i] = '';

(mesRecv[j])++;

i = 0;

while ((*(mesRecv[j]))≠ 0×09) // Пробел

{

Name[i] = *(mesRecv[j]);

i++;

(mesRecv[j])++;

}

Name[i] = '';

(mesRecv[j])++;

i = 0;

while ((*(mesRecv[j]))≠ 0×09) // Пробел

{

Number[i] = *(mesRecv[j]);

i++;

(mesRecv[j])++;

}

Number[i] = '';

(mesRecv[j])++;

i = 0;

while ((*(mesRecv[j]))≠ 0×09) // Пробел

{

avtor[i] = *(mesRecv[j]);

i++;

(mesRecv[j])++;

}

avtor[i] = '';

(mesRecv[j])++;

i = 0;

while ((*(mesRecv[j]))≠ 0×09) // Пробел

{

year[i] = *(mesRecv[j]);

i++;

(mesRecv[j])++;

}

year[i] = '';

(mesRecv[j])++;

i = 0;

while ((*(mesRecv[j]))≠ 0×09 && (*(mesRecv[j]))≠ 0x0a) // Пробел

{

Cost[i] = *(mesRecv[j]);

i++;

(mesRecv[j])++;

}

Cost[i] = '';

// Вставляем полученное в свою БД

char InsertQuery [SIZE_BUF];

sprintf (InsertQuery, «INSERT INTO Storage ([Storage_Id], [Name], [Number], [avtor], [year], [Cost]) VALUES (%s, ' % s', %s, ' % s', %s, %s)», Storage_Id, Name, Number, avtor, year, Cost);

retcode=SQLExecDirect (hstmt, (SQLTCHAR*) (LPCTSTR) InsertQuery, strlen (InsertQuery));

if (SQL_SUCCESS≠ retcode)

{

printf («Problem with INSERT INTO! Exitn»);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

_getch ();

return 1;

}

}

}

}

// Закрываем соединения

SQLDisconnect (hdbc);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

cout << endl << endl << «End of work client.»;

}

Модуль Server.cpp

// Server. cpp

#include «Header.h»

#include «Extern.h»

int DoServerProcess ()

{

cout << «- Server» << ProcRank << «-» << endl;

// - Соединение сервера с БД (содержит информацию) ;

HSTMT hstmt; // идентификатор оператора

HDBC hdbc; // идентификатор соединения

HENV henv; // идентификатор среды

SQLRETURN retcode;

char dbase[]= «Storage_»; // имя БД

char user[]=""; // имя пользователя

char passwd[]=""; // пароль пользователя

itoa (ProcRank, &dbase[7], 10); // дописываем в название базы ProcRank

cout << «DB:» << dbase << endl;

SQLINTEGER sStorageID;

SQLCHAR szName [SIZE_BUF];

SQLINTEGER sSeries;

SQLCHAR szColor [SIZE_BUF];

SQLINTEGER sYear;

SQLINTEGER sCost;

SQLINTEGER cbStorageID;

SQLINTEGER cbName;

SQLINTEGER cbSeries;

SQLINTEGER cbColor;

SQLINTEGER cbYear;

SQLINTEGER cbCost;

// Назаначение идентификатора среды

retcode=SQLAllocEnv (&henv);

if (SQL_SUCCESS≠retcode)

{

printf («HENV Error! Exitn»);

_getch ();

return -1;

}

// назначение идентификатора соединения

retcode=SQLAllocConnect (henv,&hdbc);

if (SQL_SUCCESS≠retcode)

{

printf («HDBC Error! Exitn»);

SQLFreeEnv (henv);

_getch ();

return -1;

}

cout << «Connecting to DataBase…»;

retcode=SQLConnect (hdbc, (SQLCHAR*) dbase,

SQL_NTS, (SQLCHAR*) user,

SQL_NTS, (SQLCHAR*) passwd,

SQL_NTS);

if (SQL_SUCCESS≠ retcode)

{

printf («Problem with connect to DB! Exitn»);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

_getch ();

return -1;

}

cout << «DONE!» << endl;

retcode=SQLAllocStmt (hdbc,&hstmt);

if (SQL_SUCCESS≠retcode)

{

printf («HSTMT Error! Exitn»);

SQLDisconnect (hdbc);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

_getch ();

return -1;

}

// - Цикл работы сервера ;

while (1)

{

int countRec = 0;

MPI_Recv (&countRec, 1, MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);

cout << «Count to receive:» << countRec << endl;

char *SQLStrRec = new char[50];

MPI_Recv (SQLStrRec, countRec, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &Status);

SQLStrRec[countRec] = '';

cout << «SQLStrRec =» << SQLStrRec << endl; // получили строку SQL-запроса

if (! strcmp (SQLStrRec, «exit»)) break;

// выполнение SQL-оператора

char mes [SIZE_BUF]; // для отправки

char **message = new char*[256]; // не более 256 строк как результат SQL-запроса

retcode=SQLExecDirect (hstmt, (SQLTCHAR*) (LPCTSTR) SQLStrRec, strlen (SQLStrRec));

if (SQL_SUCCESS==retcode)

{

cout << «SQLExecDirect DONE!» << endl << endl;

int countStr = 0;

// выборка следующей строки

while (1)

{

retcode=SQLFetch (hstmt);

if (SQL_SUCCESS==retcode)

{

// выборка данных из колонок

SQLGetData (hstmt, 1, SQL_C_LONG,&sStorageID, 0,&cbStorageID);

SQLGetData (hstmt, 2, SQL_C_CHAR, szName, SIZE_BUF, &cbName);

SQLGetData (hstmt, 3, SQL_C_LONG,&sSeries, 0,&cbSeries);

SQLGetData (hstmt, 4, SQL_C_CHAR, szColor, SIZE_BUF, &cbColor);

SQLGetData (hstmt, 5, SQL_C_LONG,&sYear, 0,&cbYear);

SQLGetData (hstmt, 6, SQL_C_LONG,&sCost, 0,&cbCost);

message[countStr] = new char [SIZE_BUF];

sprintf (message[countStr], «%dt % st % dt % st % dt % dn», sStorageID, szName, sSeries, szColor, sYear, sCost);

cout << message[countStr];

countStr++;

}

else break;

}

// пересылаем результат клиенту

int countStrSend = countStr;

MPI_Send (&countStrSend, 1, MPI_INT, 0, ProcRank, MPI_COMM_WORLD); // сколько строк

cout << «countStrSend =» << countStrSend << endl;

for (int i=0; i

{

int len = strlen (message[i]) + 1;

MPI_Send (&len, 1, MPI_INT, 0, ProcRank, MPI_COMM_WORLD);

MPI_Send (message[i], len, MPI_CHAR, 0, ProcRank, MPI_COMM_WORLD); // сами строки

}

}

else cout << «SQLExecDirect Error»;

}

// Закрываем соединения

SQLDisconnect (hdbc);

SQLFreeConnect (hdbc);

SQLFreeEnv (henv);

cout << endl << endl << «End of work server.»;

}

Приложение 2. Результат работы программы

Рисунок 8 Базы данных зарегистрированы в ODBC

Рисунок 9 База данных (Storage) клиента перед выполнением SQL-запроса (пустая) Рисунок 10 База данных (Storage1) сервера 1 (содержит информацию) Рисунок 11 База данных (Storage2) сервера 2 (содержит информацию) Рисунок 12 База данных (Storage3) сервера 3 (содержит информацию) Рисунок 13 Реакция всех программ системы на SQL-запрос Select * from Storage

Рисунок 14 Реакция клиента на SQL-запрос Select * from Storage

Рисунок 15 Реакция сервера 1 на SQL-запрос Select * from Storage

Рисунок 15 Реакция сервера 2 на SQL-запрос Select * from Storage

Рисунок 16 Реакция сервера 3 на SQL-запрос Select * from Storage

Рисунок 17 База данных (Storage) клиента после выполнением SQL-запроса Select * from Storage

Рисунок 18 Реакция всех программ системы на SQL-запрос Select * from Storage where Number = 11 173

Рисунок 19 Реакция клиента на SQL-запрос Select * from Storage where Number = 11 173

Рисунок 20 Реакция cервера 1 на SQL-запрос Select * from Storage where Number = 11 173

Рисунок 21 Реакция cервера 2 на SQL-запрос Select * from Storage where Number = 11 173

Рисунок 22 Реакция cервера 3 на SQL-запрос Select * from Storage where Number = 11 173

Рисунок 23 База данных (Storage) клиента после выполнением SQL-запроса Select * from Storage where Number = 11 173

Показать весь текст
Заполнить форму текущей работой