04/02/2009

Velocity (cz. 1)

Home

Velocity (z angielskiego prędkość) to mało znany projekt firmy Microsoft, którego celem jest stworzenie rozproszonej pamięci podręcznej czyli rozproszonego cache'a (nie należy mylić z projektem fundacji Apache, którego celem jest opracowanie procesora szablonów). Innymi słowy Velocity ma zwiększyć niezawodność i wydajność działania aplikacji poprzez replikację, rozproszenie oraz zapewnienie szybkiego dostępu do danych. Obecnie dostępna wersja produktu to dopiero tzw. CTP2 (ang. Community Technology Preview) czyli wersja udostępniona społecznością w celach testowych, zgłaszania uwag oraz postulatów. Nie wiadomo kiedy dokładnie pojawi się końcowy produkt ale moim zdaniem już teraz Velocity jest godne zainteresowania, a postem tym chciałbym rozpocząć krótki cykl trzech może czterech wpisów dotyczących tej technologii.

Na początek warto wymienić najważniejsze (moim zdaniem) rzeczy charakteryzujące Velocity. Zestaw ten oparłem na własnych doświadczeniach oraz na tym czego dowiedziałem się z dokumentacji i artykułów.
  • W pamięci podręcznej może zostać umieszczony każdy serializowalny obiekt.
  • Prosty interfejs programistyczny.
  • Wspiera PHP, C#, C++...
  • Możliwość wykorzystania w aplikacjach stacjonarnych, konsolowych i webowych. Przewidziana jest też integracja z dostawcą sesji ASP.NET.
  • Możliwość zarządzania i konfigurowania pomocy konsoli PowerShell.
  • Możliwość uruchomienia klastra złożonego z kilku, a nawet kilkunastu maszyn. Konfiguracja klastra może znajdować się w bazie danych lub w pliku konfiguracyjnym umieszczonym w współdzielonym katalogu.
  • Kilka typów cache'a: replikujący, partycjonujący. Typ replikujący po umieszczeniu w nim porcji danych tworzy jej kopię i umieszcza na węzłach klastra (dobre dla danych wolno-zmiennych). Typ partycjonujący rozmieszcza dane równomiernie pomiędzy poszczególne węzły klastra (dobry dla danych szybko-zmiennych). W wersji CTP2 dostępny jest tylko typ partycjonujący. Dane w cache'u partycjonującym również mogą być replikowane w celu zwiększenia bezpieczeństwa na wypadek awarii (kopia główna i poboczne).
  • Velocity wspiera silne i słaby model spójności dostępu do danych (w zależności od typu cache'a). Model spójności to umowa pomiędzy składnicą danych, a klientem mówiąca, że jeżeli klient będzie postępował zgodnie z określonymi regułami to dane nie ulegną uszkodzeniu. Słaby model spójności bazuje na jawnych zmiennych synchronizacyjnych. Silne modele spójności są implementowane przezroczyście dla klienta.
  • Operacje replikacji, partycjonowania danych, a także synchronizowania ich kopii są w pełni automatyczne i przezroczyste dla klienta.
  • Dostępne podejście optymistyczne (oparte o znaczniki, kto pierwszy ten lepszy) i pesymistyczne (wykorzystujące jawne operacje synchronizacyjne) do synchronizowania współbieżnych dostępów do danych.
  • Możliwość dynamicznego rekonfigurowania klastra poprzez dodawanie nowych węzłów.
  • Automatyczne rekonfigurowanie klastra w wypadku awarii.
  • Automatyczne równoważenie obciążenia węzłów klastra.
  • Velocity może zostać uruchomione jako usługa systemowa lub działać w procesie aplikacji.
  • Można konfigurować ilość pamięci zużywanej przez Velocity.
Osobiście pracowałem z Velocity zbyt krótko aby potwierdzić wszystkie te cechy. W szczególności testowałem tylko klaster złożony z kilku komputerów. Nie wiem też jak sprawuje się dynamiczna rekonfiguracja klastra i automatyczne równoważenie obciążenia.

W następnym poście przedstawię terminologię związaną z Velocity: gospodarz, główny gospodarz, nazwany cache itd. oraz wspomnę trochę o procesie instalowania i konfigurowania. W trzecim poście zajmę się API. Powiem również o wadach i rzeczach, które powinny moim zdaniem zostać zmienione w wersji finalnej. Dla niecierpliwych i żądnych wiedzy garść linków:

03/02/2009

Zakamarki Visual Studio (cz. 3)

Home

W trzecim już poście dotyczącym zakamarków Visual Studio, czyli mało znanych funkcji tego środowiska programistycznego, chciałbym napisać o oknie Object Test Bench. Okno to pozwala na szybkie testowanie wywołań metod statycznych i instancyjnych bez potrzeby pisania małych programików testowych. Jeśli po uruchomieniu środowiska nie jest widoczne możemy je wyświetlić wybierając View->Other Widnows->Object Test Bench. Aby wygodnie pracować z tym oknem przyda się również okno Class View (View->Class View), które służy do przeglądania typów zdefiniowanych w naszych projektach oraz w innych pakietach/podzespołach (ang. assembly), do których się odwołujemy. Ważna uwaga! Widok Object Test Bench może zostać użyty tylko i wyłącznie do testowania klas w projekcie oznaczonym jako StartUp oraz w pakietach, do których ten projekt się odwołuje. Co prawda zgodnie z dokumentacją powinniśmy móc testować wszystkie klasy w bieżącym rozwiązaniu (ang. solution) ale niestety nie jest to możliwe.

Dalej będę posługiwał się prościutką, a wręcz naiwną klasą zdefiniowaną poniżej, w celu omówienia zastosowania okna Object Test Bench.
public class Person
{
 private static int count = 0;
 
 private string name;
 private DateTime dateOfBirth;

 public string Name
 {
  get { return name; }
  set { name = value; }
 }

 public DateTime DateOfBirth
 {
  get { return dateOfBirth; }
  set { dateOfBirth = value; }
 }

 public Person()
 {
  Person.count++;
 }

 public Person(string name, DateTime dateOfBirth)
 : this()
 {
  this.name = name;
  this.dateOfBirth = dateOfBirth;
 }

 public int GetAge(bool inDays)
 {
  if(!inDays)
   return DateTime.Now.Year - dateOfBirth.Year;
  else
   return (DateTime.Now - dateOfBirth).Days ;
 }

 public static int GetCount()
 {
  return Person.count;
 }
}
Aby rozpocząć testowanie jakiejś klasy musimy zlokalizować ją w oknie Class View i wywołać dla niej menu kontekstowe. W menu kontekstowym powinny być widoczne dwie komendy:
  • Create Instance - Pozwala wywołać dowolny konstruktor dla danego typu i przypisać mu identyfikator. Stworzony obiekt pojawi się w oknie Object Test Bench. Dla stworzonych obiektów możemy następnie wywoływać metody instancyjne. W ten sposób nie powołamy do życia instancji klasy abstrakcyjnej czy też delegata.
  • Invoke Static Mehtod - Pozwala wywołać wybraną metodę statyczną danej klasy (również klasy abstrakcyjnej).
Polecenia te będą widoczne tylko dla klas z projektu głównego. Oczywiście przed wywołaniem metody statycznej, instancyjnej czy też konstruktora powinniśmy w interesujących nas miejscach w kodzie ustawić breakpointy.

Zacznijmy od wywołania metody statycznej. Po najechaniu w menu kontekstowym na polecenie Invoke Static Mehtod wyświetlone zostaną wszystkie metody statyczne dostępne w tej klasie. Należy wybrać jedną z nich. W przypadku naszej klasy testowej Person możemy wybierać pomiędzy GetCount() oraz dwie metodami odziedziczonymi po klasie Object: Equals(object, object) oraz ReferenceEquals(object, object). Po wybraniu GetCount() pojawi się okno potwierdzające chęć wywołania tej metody. Natomiast w przypadku metod, które posiadają parametry pojawi się okno pozwalające na wyspecyfikowanie wartości tych parametrów. Kiedy klikniemy Ok metoda zostanie wywołana. Na zakończenie pojawi się okno z wynikiem, które powinno wyglądać jak poniżej: Istnieje również możliwość zapisania wyniku wywołania metody. W tym celu powinniśmy zaznaczyć opcję Save return value (w oknie pokazanym powyżej) i nadać identyfikator dla zwracanego obiektu/struktury. Jeśli zdecydujemy się na zapisanie wyniku pojawi się on w oknie Object Test Bench: Stworzone obiekty reprezentowane są w oknie Object Test Bench przez prostokąty. Dla każdego obiektu możemy wywołać menu kontekstowe, które pozwoli nam wybrać metodę instancyjną do wywołania. Spróbujmy wykonać metodę posiadającą parametry np.: CompareTo(int). Po jej wybraniu powinniśmy zobaczyć okno jak poniżej: Warto zauważyć, że jeżeli metoda opatrzona była komentarze to zostanie on przytoczony. Po podaniu wartości parametru aktualnego i wybraniu przycisku Ok, metoda zostanie wywołana, a wynik zostanie przedstawiony w takim samym oknie jak przy wywoływaniu metody statycznej (jego też możemy zapisać).

Przyjrzyjmy się teraz poleceniu Create Instance i stwórzmy instancję klasy Person korzystając z konstruktora dwuargumentowego. Po wybraniu konstruktora powinno pojawić się okno przedstawionej dalej: Po pierwsze powinniśmy podać nazwę dla tworzonego obiektu. W tym miejscu trzeba uważać bo jeśli podanym nazwę, której już użyliśmy zostaniemy o tym poinformowani dopiero po naciśnięciu przycisku Ok, a nie ma możliwości cofnięcia się i naprawienia błędu.

Po drugie, podobnie jak przy wywoływaniu metod, należy podać wartości poszczególnych argumentów. Napiszę o tym troszeczkę więcej. Jeśli chodzi o typy proste nie ma co się rozpisywać. Po prostu wpisujemy liczbę lub ciąg znaków (zamknięty w cudzysłowy) i koniec. Troszeczkę trudniej jest z typami złożonymi. Na rysunku widać, że dla parametru dateOfBirth wstawiłem dziwną wartość dateTime1. Niestety ale w przypadku typów złożonych musimy najpierw stworzyć instancję danego typu, a dopiero potem powołując się na przypisaną danej instancji nazwę, użyć jej jako argumentu wywołania. Nazwa stworzonej instancji pojawi się na rozwijanej liście dla argumentów o odpowiednim typie.

W tym przypadku stworzyłem uprzednio strukturę typu DateTime i nadałem jej nazwę dateTime1. Zacząłem od zlokalizowania typu struktury w drzewie (najwygodniej posłużyć się przyciskiem Search u góry okna Class View). Następnie wybrałem polecenie Create Instance, dalej zdecydowałem się na konstruktor trójargumentowy, jako argumenty wywołania podając rok, miesiąc i dzień mojego urodzenia (wszystkie wartości to typy proste). Na koniec powróciłem do klasy Person i ponownie wybrałem interesujący mnie konstruktor. Jak widać tworzenie obiektów wymagających skomplikowanej inicjalizacji jest trudne i kłopotliwe ale te okno nie do tego służy.

Po stworzeniu instancji klasy Person możemy przystąpić do testowania jej metod, a właściwie jednej metody. Odbywa się to dokładnie w ten sam sposób jak opisałem na przykładzie metody CompareTo(int). Polecam spróbować wywołać metodę GetAge(bool) z parametrem true oraz false oraz sprawdzić jaki wynik zwraca metoda statyczna GetCount() po utworzeniu instancji klasy Person.

Jeszcze dwie uwagi na koniec. Jeśli wprowadzimy jakieś zmiany do kodu to okno Object Test Bench wymusi na nas ponowną kompilację źródeł. Równoznaczne jest to z utratą wszystkich obiektów, struktur, które umieściliśmy wcześniej w tym oknie.

W drugiej części tej serii postów pisałem o oknie Immediate. W ciekawy sposób współpracuje ono z oknem Object Test Bench. Dla przypomnienia w oknie Immediate również możemy wywoływać metody i tworzyć obiekty. Istotne jest to, że obiekty, które stworzymy w tym oknie pojawią się również w oknie Object Test Bench. Tutaj też obowiązuje warunek, żeby użyty typ pochodził z projektu oznaczonego jako StartUp lub z pakietu/podzespołu, do którego tej projekt się odwołuje. Kolejny warunek jaki musimy spełnić (wygląda to na błąd w Visual Studio) jest taki, że okno Object Test Bench nie może być puste w momencie tworzenia obiektu w oknie Immediate. Jeśli będzie tworzone obiekty nie zostaną do niego dodane. Co ciekawe jeśli w pewnym momencie dodamy jakiś obiekt do okna Object Test Bench (z poziomu okna Class View) to nagle pojawią się w nim również obiekty utworzone wcześniej w oknie Immediate.

Warto jeszcze dodać, że obiekty z okna Immediate w oknie Object Test Bench będą miały takie same identyfikatory jak zmienne użyta w oknie Immediate. Czyli wpisanie takiej komendy:
Person person = new Person();
spowoduje dodanie do okna Object Test Bench obiektu o nazwie person

Opisane techniki testowałem w środowiskach Visual Studio 2005 oraz Visual Studio 2008.

01/02/2009

Awaria Google (część 3)

Home

I wszystko jasne. Zgodnie z komunikatem od Google, awarii zawinił pracownik, który przez przypadek zablokował wszystkie strony zamiast tylko tych z listy stron niebezpiecznych, które Google otrzymuje od serwisu StopBadware.org. Czyli jak się często zdarza najsłabszym ogniwem jest czynnik ludzki. Nie jestem zwolennikiem spiskowej teorii dziejów, więc takie wytłumaczenie jest dla mnie przekonujące. Zresztą czas to zweryfikuje. Przy tej okazji przypomniały mi się dwie zasłyszane kiedyś historie w tym klimacie.

Dla ustalenia uwagi wyobraźmy sobie niezwykle ważny dla jakiejś firmy serwer. Na serwerze przechowywane są bardzo istotne dane, musi on być dostępny on-line 24 godziny na dobę, chroniony jest najnowszym oprogramowaniem antywirusowym itd. Ale jak w każdej firmie ktoś musi odkurzać, wynosić śmiecie, zmywać podłogi, również w serwerowni. Nie ulega wątpliwości, że leżące na ziemi kable zasilająca mogą utrudnić zadanie sprzątaczce czy też sprzątaczowi. Co "powinien", więc zrobić wykonujący skrupulatnie i dokładnie swoją pracę konserwator powierzchni płaskich? ... Od tego czasu we wspomnianej firmie kable zasilające są na stałe przymocowane do gniazdek.

Druga historia dotyczy pewnego administratora sieci, który jako wygaszacz ekranu na serwerze postanowił użyć słynnego "blue screen". Niestety ale zdarzyło się, że koło serwera przechodził pewien menadżer. Kiedy zobaczył wygaszacz ekranu postanowił wyręczyć administratora w jego pracy i zrestartował serwer. Dodam, że nagły restart tego serwera nie był bez znaczenia dla firmy i jego klientów. Ciekawe kto stracił pracę?

Podsumowując, bez względu na to jakich zabezpieczeń użyjemy, zawsze zapomnimy o jakimś małym szczególe lub nie uwzględnimy czegoś co będzie wydawać się nam absurdalnie niemożliwe, a co doprowadzi do mniejszej lub większej katastrofy.

Swoją drogą zastanawialiście się kiedyś jak to jest, że jeżeli pracownicy danej firmy mają ograniczony dostęp do poszczególnych pomieszczeń to sprzątaczka czy sprzątacz mogą wejść wszędzie (lub prawie wszędzie). No chyba, że prezes będzie sprzątać swoje biuro samemu ;)

31/01/2009

Awaria Google (część 2)

Home

Chłopcy z Google szybko rozwiązali problem. "Awaria" trwała tylko, a może aż, małe kilkanaście minut. Jak widać publikuję tego posta jakieś 10 minut po poście, w którym stwierdziłem, że z serwerami Google mogło sie coś stać. Jestem ciekawy czy zostanie opublikowany oficjalny komunikat wyjaśniający cała sytuację.

Awaria Google

Home

Mam wrażenie, że z serwerami Google stało sie coś niedobrego. Jeszcze kilkanaście minut wyszukiwarka działa bardzo dobrze. W tej chwili chyba dla każdego hasła (łącznie z takimi jak: Google, Microsoft) wyszukane strony oznaczone są jako niebezpieczne; do każdej strony dodawany jest komunikat Ta witryna może wyrządzić szkody na Twoim komputerze. Wynik zaobserwowałem na dwóch komputerach. A może Google padło ofiarą ataku hackerów?