SYSTEM MONITORINGU PARAMETRÓW WĘZŁÓW PRZECHOWYWANIA DANYCH DLA PROJEKTU KRAJOWY MAGAZYN DANYCH PODRĘCZNIK DEWELOPERA 1
Spis treści: Wstęp... 3 Opis architektury systemu... 4 Architektura modułu KMD... 6 Opis pakietów modułu KMD... 7 Poszerzanie systemu o nowe parametry... 9 Poszerzanie systemu o obsługę nowych systemów składowania danych... 13 Kompilacja systemu... 14 Uruchamianie i zatrzymywanie systemu... 15 Uwagi końcowe... 16 2
Wstęp W niniejszym dokumencie zostały zawarte informacje potrzebne do pracy nad rozwijaniem systemu monitoringu węzłów przechowywania danych opracowanego dla projektu Krajowy Magazyn Danych. Zamieszczono w nim krótki opis architektury całego systemu, opis szczegółowy tych części systemu które związane są z monitoringiem systemów składowania danych oraz przykłady możliwych rozszerzeń systemu. Zamieszczono także informacje na temat sposobu kompilacji i uruchamiania systemu. Niniejszy dokument nie zawiera informacji na temat sposobu konfiguracji systemu, informacje te zawarte zostały w podręczniku użytkownika systemu monitoringu dla projektu Krajowy Magazyn Danych. 3
Opis architektury systemu System monitoringu węzłów przechowywania danych jest systemem rozproszonym, z wyróżnionym centralnym węzłem (tzw. Gateway'em). Węzeł centralny odpowiedzialny jest za komunikację z pozostałymi węzłami (tj. węzłami monitorowanymi), pobieranie z nich monitorowanych danych, oraz ich udostępnienie. System monitoringu został zrealizowany na bazie systemu JIMS (JMX based Infrastructure Monitoring System), który jest wydajnym i skalowalnym systemem monitorującym ogólnego przeznaczenia. Architektura systemu JIMS opiera się na komponentach, implementowanych w formie Mbean'ów. Komunikacja w systemie JIMS odbywa się poprzez protokół JMX (Java Management Extensions). Kod programu wykonywany na poszczególnych węzłach monitorowanych ładowany jest z węzła centralnego za pomocą MletClassLoader'a, co pozwala na uniknięcie konieczności kopiowania całości systemu na każdy z monitorowanych węzłów. Szczegółowa architektura systemu JIMS przedstawiona jest na rysunku 1. Konektory SOAP Connector RMI Connector SNMP Adapter HTML Adapter Gateway JIMS Serwisy JIMS Discovery Auto-conf. Self-organ. Dyn. loading Security Warstwa abstrakcji zasobu Managed Element MBean MBean Managed Element MBean MBean Managed Element MBean MBean Resource interface Resource interface Resource interface Warstwa instrumentacji Warstwa zarzadzanych zasobów Resource Resource Resource Resource Resource Resource Rys. 1: Architektura systemu JIMS Monitoring węzłów przechowywania danych realizowany jest poprzez specjalizowany Mbean, który odpowiada za pobieranie z monitorowanego systemu HSM (Hierarchical Storage Management) parametrów dostępnych w sposób bezpośredni (za pomocą poleceń systemowych lub API), oraz wykonywanie pomiarów w celu uzyskania tych parametrów, które nie są dostępne w sposób bezpośredni. Oprócz specjalizowanego Mbean'a przeznaczonego do monitorowania systemów HSM, na każdym z monitorowanych węzłów ładowany jest Mbean odpowiedzialny za monitoring ogólnych parametrów systemowych monitorowanego węzła (np. zajętości pamięci, obciążenia procesora). 4
Proces pobierania danych z monitorowanych węzłów, oraz ich udostępniania realizowany jest poprzez inny, specjalizowany Mbean, który ładowany jest jedynie na węźle centralnym. Mbean ten odpowiada za pobranie danych z wszystkich monitorowanych węzłów, z którymi w aktualnym momencie nawiązane jest połączenie, oraz ich udostępnienie poprzez zapis ich w określonej bazie danych. Ten sposób udostępniania danych pozwala na maksymalną separację warstwy monitoringu danych od innych części projektu KMD. Wszystkie specjalizowane Mbean'y opracowane dla potrzeb projektu KMD w dalszej części dokumentu określane są wspólną nazwą modułu KMD. 5
Architektura modułu KMD Moduł KMD systemu JIMS oparty jest o dwa główne wzorce projektowe: wzorzec Command Factory oraz wzorzec Data Object. Wzorzec Command Factory użyty został w celu zapewnienia ujednoliconego interfejsu dostępu do wartości monitorowanych parametrów uzyskiwanych za pomocą poleceń systemowych, natomiast wzorzec Data Object został użyty w celu zapewnienia ujednoliconego interfejsu dostępu do baz danych. Dodatkowo w skład modułu KMD wchodzą następujące pomniejsze moduły: moduł ładowania plików konfiguracyjnych obsługuje proces ładowania danych z plików konfiguracyjnych modułu KMD (kmd.properties i hsms_config.json), moduły reprezentujące implementację interfejsów mbean-ów wchodzących w skład modułu KMD (KMDMonitoring i KMDDBTask), moduł serwera informacji o plikach obsługuje żądania informacji o pojedynczych plikach znajdujących się w systemie składowania danych, klasy zadań okresowych są to zadania pomiaru szybkości transferu, nawiązywania połączeń z mbean-ami oraz zapisu danych do bazy danych, moduł parsera formatu JSON. 6
Opis pakietów modułu KMD W tabeli 1 zamieszony został szczegółowy opis poszczególnych pakietów języka JAVA, wchodzących w skład modułu KMD: Pakiet org.jims.modules.kmd.commands org.jims.modules.kmd.commands.fse org.jims.modules.kmd.commands.tsm org.jims.modules.kmd.common org.jims.modules.kmd.configuration org.jims.modules.kmd.dto org.jims.modules.kmd.mbeans org.jims.modules.kmd.natives org.jims.modules.kmd.persistence.dao org.jims.modules.kmd.persistence.dao.postgres org.jims.modules.kmd.threads org.jims.modules.kmd.timertasks Opis Pakiet zawiera klasy abstrakcyjne reprezentujące wartości parametrów zwracanych przez polecenia systemowe. Dodatkowo w pakiecie znajduje się klasa wyjątku rzucanego przez operacje pobierania parametrów z systemu i abstrakcyjna klasa fabryki. Pakiet zawiera implementację klas abstrakcyjnych pakietu org.jims.modules.kmd.commands dla systemów HP-FSE. Pakiet zawiera implementację klas abstrakcyjnych pakietu org.jims.modules.kmd.commands dla systemów IBM-TSM. Pakiet zawiera klasę, która przechowuje wartości stałych wykorzystywanych w module KMD. Pakiet zawiera klasy ładujące informacje konfiguracyjne modułu KMD zawarte w plikach kmd.properties i hsms_config.json. Pakiet przechowuje klasy reprezentujące tabele w bazie danych (tzw. model programowy). Pakiet zawiera interfejsy mbean-ów modułu KMD oraz ich implementacje. Pakiet zawiera klasę reprezentującą operacje natywne modułu KMD. W obecnej wersji systemu pakiet ten nie jest wykorzystywany. Pakiet zawiera klasy abstrakcyjne i interfejsy reprezentujące operacje wykonywane na bazie danych. Pakiet zawiera implementację klas abstrakcyjnych i interfejsów z pakietu org.jims.modules.kmd.persistence.dao dla bazy danych PostgreSQL przy użyciu technologii JDBC (Java Database Connectivity). Pakiet zawiera klasy wątków związanych z serwerem informacji o plikach. Pakiet zawiera klasy reprezentujące zadania wykonywane okresowo. 7
org.json Pakiet zawiera źródła parsera JSON pobrane z oficjalnej strony. Tab. 1: Opis pakietów modułu KMD. 8
Poszerzanie systemu o nowe parametry Proces poszerzania obecnej wersji systemu o nowe parametry składa się z następujących kroków: Wykonanie migracji w bazie danych: aby dodać do wybranej tabeli nową kolumnę korzystamy z polecenia alter języka SQL. Przykładowo chcąc dodać nową kolumnę reprezentującą parametr o nazwie server_age typu całkowitego, niepustego, z wartością domyślną -1 do tabeli static_server_parametrs wywołujemy następujące polecenie: ALTER TABLE static_server_parameters ADD COLUMN server_age integer NOT NULL DEFAULT -1; Poszerzenie modelu programowego: aby poszerzyć model programowy odszukujemy w pakiecie org.jims.modules.kmd.dto klasę reprezentującą poszerzaną tabelę i dodajemy do niej odpowiednie pole prywatne, wraz z getter'em i setter'em. Zaleca się aby polu przypisać wartość domyślną, która nie spowoduje błędu przy próbie zapisu jej do bazy danych. Kontynuując przykład parametru server_age z poprzedniego punktu do klasy org.jims.modules.kmd.dto.staticserverparameters dodajemy odpowiednie pole i metody: private int serverage = 2; public void setserverage(int serverage) { this.serverage = serverage; } public int getserverage() { return this.serverage; } Poszerzenie klas DAO: aby poszerzyć klasy DAO odszukujemy pakiet odpowiadający właściwej implementacji DAO (np. dla baz danych PostgreSQL) i w nim klasę odpowiadającą implementacji operacji na właściwej tabeli. Następnie musimy poszerzyć wszystkie operacje tej klasy o obsługę naszego parametru. Najczęściej polega to na odpowiedniej modyfikacji stringów reprezentujących operacje w języku SQL, oraz ustawieniu w nich wartości przy pomocy metod dopisanych w poprzednim kroku do modelu programowego. Kontynuując przykład z parametrem server_age modyfikujemy klasę odpowiadającą za operacje na tabeli static_server_parametrs czyli klasę: org.jims.modules.kmd.persistence.dao.postgres.postgresstaticserverparametersd AO. Zmiany w odpowiednich metodach tej klasy są następujące: 9
metoda getstaticserverparameters: // nowy kod znajduje się pomiędzy liniami oznaczonymi sekwencją // $$$ if (resultset.next()) { ssp = new StaticServerParameters(); ssp.setid(resultset.getint("id")); ssp.setservername(resultset.getstring("server_name")); ssp.settotalcapacity(resultset.getfloat("total_capacity")); ssp.setnumberofmountpoint(resultset.getint("number_of_mount_points")); ssp.setnumberoflibraries(resultset.getint("number_of_libraries")); // $$$ ssp.setserverage(resultset.getint("server_age")); // $$$ } metoda insertstaticserverparameters: modyfikacja polecenia SQL: // poprzednie polecenie PreparedStatement statement_ssp = connection.preparestatement("insert INTO static_server_parameters " + "(server_name, total_capacity, number_of_mount_points, number_of_libraries) " + "VALUES (?,?,?,?)"); // nowe polecenie PreparedStatement statement_ssp = connection.preparestatement("insert INTO static_server_parameters " + "(server_name, total_capacity, number_of_mount_points, number_of_libraries, server_age) " + "VALUES (?,?,?,?,?)"); oraz dodanie kodu ustawienia wartości pola: statement_ssp.setint(5, staticserverparameters.getserverage()); metoda updatestaticserverparameters: modyfikacja polecenia SQL: // poprzednie polecenie PreparedStatement ssp_update_statement = connection.preparestatement("update static_server_parameters " + "SET server_name =?, total_capacity =?, number_of_mount_points =?, number_of_libraries =? " + "WHERE id =?"); 10
// nowe polecenie PreparedStatement ssp_update_statement = connection.preparestatement("update static_server_parameters " + "SET server_name =?, total_capacity =?, number_of_mount_points =?, number_of_libraries =?, server_age =? " + "WHERE id =?"); oraz dodanie kodu ustawienia wartości pola i modyfikacja numerów parametrów po nim następujących (dla tego przykładu jest tylko jeden taki parametr id): ssp_update_statement.setint(5, staticserverparameters.getserverage()); // zmiana 5 6 ssp_update_statement.setint(6, serverid); Oczywiście modyfikacje zapytań SQL są zależne od poszczególnych tabel i nie da się tutaj podać ogólnej reguły. Przy wszelkich zmianach należy się kierować swoim doświadczeniem i istniejącym kodem. Poszerzenie implementacji Command Factory : poszerzenie implementacji Command Factory polega na dodaniu do klas reprezentujących komendy dla różnych systemów składowania danych fragmentów kodu odpowiedzialnych za pobranie wartości parametru z systemu i ustawieniu jej w modelu programowym. Implementacja tej części kodu jest mocno zależna od rodzaju systemu (HP-FSE/IBM-TSM) i może się łączyć z wykonaniem wielu operacji (parsowanie plików konfiguracyjnych, wykonanie wywołań systemowych, ). W naszym przykładzie zastosujemy banalną implementację polegającą na losowaniu wartości parametru server_age za pomocą generatora liczb pseudolosowych, nie będzie to zatem operacja zależna od systemu składowania danych, co powoduje że zmian dokonamy jedynie w klasie org.jims.modules.kmd.commands.staticserverparameterscommand. W przypadku zależności od systemu składowania danych zmiany musiałyby zostać dokonane w odpowiednich klasach z pakietu org.jims.modules.kmd.commands, np. org.jims.modules.kmd.commands.tsm. Zmianom podlega zawsze metoda główna zwracająca obiekt modelu programowego (zatem w naszym przykładzie będzie to metoda getstaticserverparameters), pozostałe metody w klasach reprezentujących wzorzec Command Factory mają charakter pomocniczy: 11
// nowy kod znajduje się pomiędzy liniami oznaczonymi sekwencją // $$$ JSONObject hsmsconfiguration = HSMParametersLoader.getHSMsParameters(); try { StaticServerParameters ssp = new StaticServerParameters(); ssp.setservername(hsmsconfiguration.getstring("server_domain")); ssp.settotalcapacity(hsmsconfiguration.getint("total_capacity")); ssp.setnumberofmountpoint(hsmsconfiguration.getint("number_of_mount_points")); int numberoflibraries = 0; int numberofhsms = hsmsconfiguration.getint("number_of_hsms"); for (int i = 0; i < numberofhsms; i++) numberoflibraries += hsmsconfiguration.getjsonarray("hsms").getjsonobject(i).getint("number_of_libraries"); ssp.setnumberoflibraries(numberoflibraries); // $$$ ssp.setserverage(new Random().nextInt()); // $$$ return ssp; } catch (JSONException ex) { throw new CommandException(ex); } catch (NumberFormatException ex) { throw new CommandException(ex); } Jeśli wszystkie zmiany zostały przeprowadzone poprawnie to kompilacja i restart systemu powinno spowodować pojawienie się poprawnej wartości nowego parametru w bazie danych. 12
Poszerzanie systemu o obsługę nowych systemów składowania danych Proces poszerzania obecnej wersji systemu o obsługę nowych systemów składowania danych (np. systemu Disk Extended) w zasadzie sprowadza się do implementacji właściwej implementacji Command Factory, czyli dodania nowego pakietu do pakietu org.jims.modules.kmd.commands o nazwie identycznej z nazwą podawaną w pliku konfiguracyjnym kmd.properties w kluczu vendorstring. W pakiecie należy zamieścić odpowiednie klasy implementujące, najlepiej jest się w tym wypadku kierować przykładem implementacji dla systemów HP-FSE i IBM-TSM. 13
Kompilacja systemu Proces kompilacji systemu jest mocno zautomatyzowany poprzez zastosowanie w nim programu Maven 2. W zasadzie całość procesu kompilacji przeprowadza się za pomocą polecenia: mvn assembly:directory które należy wykonać w głównym katalogu JIMS. Polecenie to kompiluje całość kodu do odpowiednich plików.jar. Należy pamiętać o tym że aktualne pliki.jar muszą znajdować się na węźle GW, w przeciwnym razie nie będą wykorzystywane uwaga ta szczególnie tyczy się sytuacji w której system kompilowany jest na innym komputerze niż GW. Należy także zwrócić uwagę czy kompilacja nie nadpisała istniejących plików konfiguracyjnych kmd.properties i hsms_config.json jeśli tak to należy przywrócić oryginalne pliki po przeprowadzeniu kompilacji. W przypadku problemów z ładowaniem plików.jar przy starcie systemu należy zwrócić uwagę na poprawność konfiguracji JIMS zapisaną w plikach.mlet. Aby uzyskać szczegółowe informacje na temat ich zawartości należy zapoznać się z dokumentacją systemu JIMS. 14
Uruchamianie i zatrzymywanie systemu Proces uruchamiania systemu należy rozpocząć od uruchomienia agenta JIMS na węźle centralnym, a dopiero później przejść do uruchamiania agentów JIMS na węzłach monitorowanych. Dobrze jest na bieżąco śledzić zawartość logów JIMS znajdujących się w katalogu ${JIMS_HOME}/var/jims/log/ w celu wykrycia ewentualnych błędów. Aby uruchomić agenta JIMS na danym węźle, należy przejść do katalogu ${JIMS_HOME}/ bin/ i wywołać polecenie jims-agent start. Jako opcjonalny parametr często podaje się interfejs sieciowy do którego ma się podpiąć agent, co specyfikowane jest przy pomocy opcji -b, na przykład: jims-agent -b 10.0.0.1 start. Aby zatrzymać agenta JIMS na danym węźle, należy przejść do katalogu ${JIMS_HOME}/ bin/ i wywołać polecenie jims-agent stop. Aby sprawdzić status agenta na danym węźle, należy przejść do katalogu $ {JIMS_HOME}/bin/ i wywołać polecenie jims-agent status. Szczegółowe informacje na temat uruchamiania agenta JIMS znajdują się w jego dokumentacji. 15
Uwagi końcowe Niniejszy dokument powstał w ramach projektu Krajowy Magazyn Danych i stanowi jego integralną część. Kopiowanie, powielanie i rozpowszechnianie niniejszego dokumentu w całości bądź we fragmentach bez zgody podmiotu będącego właścicielem praw autorskich do niniejszego dokumentu stanowi naruszenie obowiązującego prawa. 16