Wyślij zapytanie Dołącz do Sii

Każdy system posiada architekturę. W idealnym świecie, gdy pracujemy według wytycznych V-modelu, zostanie ona zaprojektowana jeszcze przed napisaniem pierwszej linii kodu. Jeśli jednak tak się nie stanie, to będzie powstawać samoczynnie wraz z rozwojem projektu.

Znacznie łatwiej byłoby wcześniej zastanowić się nad tym, czego oczekujemy od systemu i które jego cechy są pożądane.  Z tą wiedzą można tak zaplanować system, aby w łatwy sposób maksymalizować pożądane cechy.

Niestety rzadko zdarzają się rozwiązania idealne, dlatego w trakcie projektowania systemu często należy zdecydować się na pewne kompromisy. Najczęściej będą one zachodzić pomiędzy takimi cechami jak:

  • reliability vs. availability,
  • usefulness vs. safety,
  • security vs. performance vs. safety balance,
  • performance vs. reliability,
  • implementation balance.

W poniższym artykule skupię się na pierwszym z nich, czyli reliability vs. availability. Postaram się przedstawić, jak odpowiednie kształtowanie architektury może wpływać na te dwie cechy.

Definicje pojęć

Poniższe rozważania są związane z systemami bezpiecznymi, jednak znajdą zastosowanie również poza tym obszarem. W znacznej większości przypadków najważniejszym aspektem implementowanych systemów jest ich bezpieczeństwo, w literaturze określane jako safety. Jako taki określa się system, który szczególną wagę przywiązuje do ochrony życia lub mienia.

Nierzadko zdarza się, że safety jest mylnie rozumiane jako security. Zanim przejdziemy dalej warto przyjrzeć się definicjom tych dwóch pojęć.

  • Security polega na utrudnianiu korzystania z systemu przez osoby do tego nie uprawnione.
  • Safety troszczy się o to, aby osoby uprawnione podczas korzystania z systemu nie zrobiły sobie (lub innym) krzywdy.

Systemy można opisać 4 cechami (parametry RAMS):

  • Reliability (niezawodność) – otrzymamy poprawny wynik.
  • Availability (dostępność) – zdolność do poprawnego funkcjonowania.
  • Maintainability (obsługiwalność) – łatwość w utrzymaniu.
  • Safety (bezpieczeństwo) – funkcjonowanie systemu nie będzie zagrażać ludziom, rzeczom oraz środowisku.

Reliability i availability

W zależności od systemu i zadań przed nim postawionych jedna cecha będzie bardziej pożądana niż druga. Istnieją systemy, w których ważniejszy jest poprawny wynik, a mniej ważne jest to, czy go otrzymamy (lub otrzymamy na czas – jeśli istnieją wymagania odnośnie do czasu maksymalnej odpowiedzi. Wspomnianą sytuację traktować będziemy jednak jako brak odpowiedzi).

W takich systemach priorytetem będzie reliability, czyli poprawność otrzymanego rezultatu.

Z drugiej strony można wyobrazić sobie system, np. nawigacja, gdzie priorytetem będzie otrzymanie rezultatu, a mniej ważne będzie to, czy odpowiedź systemu jest poprawna.

Dla takiego systemu kluczowe jest availability.

W tym kontekście system może natomiast zawieść na 2 sposoby:

  1. Wynik będzie błędny – brak reliability.
  2. Wyniku nie otrzymamy – brak availability.

Na czym polega konflikt?

W idealnym świecie systemy zawsze zwracałyby odpowiedź w 100% poprawną. W świecie rzeczywistym trzeba wybierać, co jest dla naszego systemu istotniejsze.

Czy jesteśmy w stanie zaakceptować, że czasami odpowiedzi nie uzyskamy, ale gdy już ją uzyskamy, możemy być w pewni jej poprawności? Czy też zależy nam na otrzymaniu wyniku niezależnie od okoliczności, mając jednocześnie świadomość, że może on być obarczony niemałym błędem.

Musimy wiedzieć czego oczekujemy, gdyż zwiększenie jednego parametru, odbędzie się to będzie kosztem innego. Chcąc zwiększyć availability systemu, najczęściej ucierpi na tym reliability i vice versa. Dlatego tak ważne jest, aby już na samym początku projektu określić, co jest dla nas priorytetem.

Czemu tak się dzieje, opiszę poniżej. Zobaczymy jak w praktyce, przy użyciu architektury, możemy manipulować opisanymi powyżej parametrami oraz dlaczego zwiększenie jednego z nich automatycznie pociąga za sobą zmniejszenie innego.

Powielenie

Zaczniemy od prostego powielenia.

Powielenie (replication) polega na zwiększeniu liczby identycznych elementów lub systemów. Posiada tę zaletę, że można bardzo łatwo zwiększać pożądaną cechę systemu.

Wyobraźmy sobie, że projektujemy system, który powinien obliczać przechyłkę toru kolejowego. Ma on się składać z 2 identycznych komputerów, wykonujących identyczny program przy pomocy identycznych danych wejściowych. Teraz należy zadać sobie pytanie, czy będzie dla nas akceptowalne otrzymanie wyniku operacji później niż np. 1 ms po dostarczeniu danych wejściowych (availability), czy chcemy mieć pewność, że system będzie na tyle precyzyjny, że nie pomyli się o więcej niż np. 0.1 milimetra (reliability)?

Tu oczywiście wybór będzie zależał od wymagań. Jeśli projektujemy system, który działać będzie w czasie rzeczywistym na pociągu pomiarowym i wiemy, że nie wolno nam przekroczyć 1ms przy wyliczaniu odpowiedzi, ważniejsze będzie dla nas availability.

Architektura 1oo2 i 2oo2

Jeśli jednak system będzie działać w post-processingu i nie będzie problemem ponowne uruchomienie obliczeń np. po korekcie danych wejściowych, naszym priorytetem będzie reliability.

W pierwszym przypadku zbudujemy system w architekturze 1oo2 (one–out-of-two), czyli akceptujemy wynik, który otrzymamy jako pierwszy, a jeśli jeden z komputerów ulegnie awarii, system dalej będziemy w stanie wykonać swoje zadanie.

W drugim przypadku zbudujemy system w architekturze 2oo2 (two–out-of-two) i jako poprawny uznamy wynik tylko wtedy, gdy będzie identyczny na obu komputerach (lub różnica tych wyników będzie mieścić się w akceptowalnym zakresie tolerancji).

Brzmi rozsądnie, ale czemu miałoby to zredukować nasze availability?

Odpowiedź tu jest dosyć prosta. Przykładowo nasz system jest złożony z identycznych modułów zarówno pod względem sprzętu jak i oprogramowania. Każdy element modułu posiada pewną awaryjność, więc wraz ze wzrostem złożoności, rosnąć będzie awaryjność modułu. Oznacza to, że powielając element lub system, powielamy również jego awaryjność.

Może zdarzyć się też tak, że będziemy mieli dużo czasu i możliwe będzie parokrotne wykonanie obliczeń oraz uznanie wyniku za poprawny, jeśli był identyczny za każdym razem.

Choć 1oo2 i 2oo2 są najbardziej popularnymi architekturami, w praktyce stosuje się również systemy 1oo3, 2oo3.

Dygresja do certyfikacji

Czasami możliwe jest uzyskanie wyższego poziomu SIL, przy pomocy 2 systemów połączonych równolegle. Przykładowo, możemy zbudować system elektroniczny SIL2 z 2 połączonych równolegle elektronicznych systemów SIL1, jednak chcąc zbudować elektroniczny system SIL3 z 2 elektronicznych systemów SIL2, potrzebna będzie szczegółowa analiza czy możemy tak zrobić. Dużo zależy tu od rodzaju systemu oraz normy, z którą pracujemy. Więcej dowiesz się z artykułu H. J. i H. Schäbe [1].

Dywersyfikacja

Drugą, nieco bardziej skomplikowaną metodą, jest dywersyfikacja (diversification). O dywersyfikacji jest mowa wtedy, gdy powielane elementy nie są już identyczne. Dywersyfikować można na 3 poziomach: software, hardware oraz na poziomie danych.

Modyfikując powyższy przykład, dalej możemy budować system 2oo2, ale teraz każdy z komputerów będzie posiadał procesor o innej architekturze, inny algorytm do obliczania przechyłki lub dane wejściowe pochodzące z różnych źródeł. Dywersyfikacja jest przeważnie bardziej kosztowna, ale pozwala dodatkowo zabezpieczyć się przed błędami innymi niż w przypadku powielenia.

Błąd Common cause failure

Przykładowym typem takiego błędu jest common cause failure, który może polegać na tym, że:

  1. Dwa lub więcej elementów zawiedzie w określonym czasie, co może wpłynąć na zdolność operacyjną systemu.
  2. Element zawiedzie z powodu jednej wspólnej usterki w obu kanałach w jednakowy sposób.

Rozważmy dwa układy, każdy z innym procesorem, wykonywujące ten sam program oraz posiadające ten sam zestaw danych wejściowych. W tym przypadku jesteśmy odporni na część błędów procesora (bohrbugów), które prawdopodobnie nie zostałyby wykryte w przypadku powielenia.

Czemu tylko częścią? Ponieważ większość tego typu błędów to heisenbugi, więc prawdopodobieństwo, że wystąpią równocześnie jest znikome.

Jak często procesory się mylą? Otóż dużo częściej niż można by się było spodziewać. Erraty procesorów liczą dziesiątki stron i raczej nie zawierają wszystkich istniejących błędów, a jedynie te wykryte.

Co można powielać lub dywersyfikować?

Decydując się na jedną z metod powielania lub dywersyfikacji, warto jeszcze wyjaśnić co można powielać lub dywersyfikować. Istnieją 2 opcje: można powielić pojedynczy komponent lub cały system. Na czym polega różnica? Popatrzmy na prosty schemat systemu składającego się z 3 elementów:

1 - Cechy systemów bezpiecznych reliability i availability a architektura

Najbardziej awaryjny jest element C, mamy zatem 2 opcje.

  1. Powielić cały system:
    2 - Cechy systemów bezpiecznych reliability i availability a architektura
  2. Powielić newralgiczny element:
    3 - Cechy systemów bezpiecznych reliability i availability a architektura

Należy sobie zadać pytanie, która opcja jest lepsza. Tu odpowiedź zależy od specyfiki systemu, jednak w większości przypadków taniej i łatwiej powielić pojedynczy komponent niż cały system.

Duplikacja systemu oznacza większą złożoność całego rozwiązania (a więc i awaryjność). Może wymusić potrzebę synchronizacji tych systemów lub po prostu większe koszty niż duplikacja pojedynczego elementu.

Systemy działające w architekturze 1oo2 (lub zbliżonej np. 1oo3), mogą korzystać z funkcjonalności hot swap. Polega ona na utrzymaniu w gotowości zapasowego systemu/systemów i w momencie, gdy wykryjemy awarię pierwszego systemu, system zapasowy przejmuje jego funkcje „w locie”, w taki sposób, aby ciągłość funkcjonowania została zachowana.

Safety bag

Safety bag jest specyficzną formą dywersyfikacji. Czasami występującą pod nazwą “diverse monitor”. W skład tej architektury wchodzą 2 elementy: system oraz monitor. System ma większą swobodę działania i jest przeważnie dużo bardziej skomplikowany. Monitor z kolei będzie dużo prostszy, a jego zadanie polega na tym, aby cały układ nie opuścił strefy bezpieczeństwa.

Warto zaznaczyć, że poprawność działania nie jest równa bezpieczeństwu, tak więc monitor nie gwarantuje poprawnego działania, a tylko działanie bezpieczne. W momencie, gdy monitor zauważy, potencjalne niebezpieczeństwo, przejmuje kontrolę i reaguje, aby wprowadzić system w stan bezpieczny.

Podsumowanie

Powyższy tekst opisuje najprostsze metody modyfikacji właściwości systemów przy pomocy ich architektury. Zbiór dostępnych rozwiązań jest oczywiście dużo szerszy. Przedstawiony opis jest dosyć ogólny, gdyż powyższe rozwiązania mogą być stosowane zarówno w warstwach mechanicznych, elektronicznych jak i softwarowych.

Jednak nawet tak ogólny opis pokazuje, że nie jesteśmy w stanie zbudować systemu, który zwraca w 100% poprawną odpowiedź i jest dostępny przez 100% czasu. Należy więc pamiętać, aby potrzeby naszego systemu zidentyfikować na jak najwcześniejszym etapie projektowania, gdyż pozwoli to na nadanie mu takiego kształtu, który zmaksymalizuje cechy przez nas pożądane.

Ponadto decyzja o tym, aby przykładowo powielić element czy podsystem w późniejszych fazach projektu, będzie bardziej kosztowna niż taka sama decyzja podjęta na samym początku.

Konflikt reliability z availability, nie jest jedynym, który należy mieć na uwadze projektując system. We wstępie wymieniłem kilka innych, jednak jest to temat na osobny artykuł.

Ostatecznie: to co musimy, co powinniśmy, a czego nie wolno nam robić, będzie definiować norma “branżowa” związana z przeznaczeniem naszego systemu. Normą bazową traktującą o bezpieczeństwie jest “IEC 61508: Functional Safety of Electrical/Electronic/Programmable Electronic Safety-related Systems”, a przykładowe normy uszczegóławiające to:

  • ISO 26262 – automotive.
  • IEC 62279 – rail.
  • IEC 61513 – power plants.

Źródła

[1] H. J. &. H. Schäbe, “Computer architectures and safety integrity level apportionment”, TÜV InterTraffic GmbH, Köln, Germany, 2004

[2] C. Hobbs, Embedded Software Development for Safety-Critical Systems, 2015.

***

Jeśli interesują Cię tematyka Embedded, zachęcamy do zapoznania się z publikacjami naszych specjalistów: Branchless programming czyli programowanie „bezgałęziowe” i Praktyczne wykorzystanie kryptografii na przykładzie komunikatora oraz cyklem dotyczącym Maszyn wirtualnych – interpreterów. 

Ocena:
Autor
Avatar
Piotr Orzechowski

Absolwent automatyki i robotyki na Politechnice Śląskiej. Inżynier oprogramowania z wieloletnim doświadczeniem w branży kolejowej, głównie jako programista C/C++. Obecnie związany z projektami safety dla działu R&D producenta infrastruktury kolejowej. Wolny czas poświęca na wspinaczkę.

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany.

Może Cię również zainteresować

Pokaż więcej postów

Bądź na bieżąco

Zapisz się do naszego newslettera i otrzymuj najświeższe informacje ze świata Sii.

Otrzymaj ofertę

Jeśli chcesz dowiedzieć się więcej na temat oferty Sii, skontaktuj się z nami.

Wyślij zapytanie Wyślij zapytanie

Natalia Competency Center Director

Get an offer

Dołącz do Sii

Znajdź idealną pracę – zapoznaj się z naszą ofertą rekrutacyjną i aplikuj.

APLIKUJ APLIKUJ

Paweł Process Owner

Join Sii

ZATWIERDŹ

This content is available only in one language version.
You will be redirected to home page.

Are you sure you want to leave this page?