poniedziałek, 5 stycznia 2015

Alternatywne sposoby przechowywania dużych zbiorów danych - SQLite i MongoDB

Problem
 
Big Data Dzisiejszy temat pod bardzo popularnym hasłem kluczowym - Big Data. Big Data czyli dane których wolumen, prędkość napływania lub zróżnicowanie przekracza możliwości tradycyjnych metod analizy. Czym jest Big Data dla przeciętnego PC, a czym dla klastrów Amazona. Tajemniczy termin jest często używany przesadnie tłumacząc nieumiejętne zarządzanie danymi (też tak mówiłem). Prawdą jest jest, że przeciętny PC z asystą typowych narzędzi jest w stanie przerobić kupę danych. Nie sposób wyczerpać tak rozległego tematu jednym wpisem. Big Data stanowi problem na każdym etapie procesu analizy danych. Dzisiaj skupię się na przechowywaniu danych, a temat obliczeń poruszę przy nadarzającej się okazji.
R przechowuje dane w RAM'ie co sprawia, że operacje są wykonywane szybciej niż gdyby dane przechowywane były na dysku twardym. Przechowywanie danych w pamięci podręcznej jest jednak mocno ograniczona rozmiarem. Niejednokrotnie zdarzało się, że ładowanie danych do R kończyło się fiaskiem, zwieńczając męki komunikatem "out of memory ...". W zależności od problemu przed jakim stoimy proponuje się różne rozwiązania.
Sposobem na limity związane z pamięcią jest trzymanie baz na dysku, a tylko potrzebne dane zaczytywać do R. Można w tym celu skorzystać z dowolnego systemu bazodanowego. W dzisiejszym rozwiązaniu zademonstruję dwa zupełnie różne silniki bazodanowe - SQLite i MongoDB.
  1. SQLite - bardzo popularny, prosty, relacyjny system, który nie wymaga od Nas budowania serwera zarządzającego bazą danych. Silnik bazodanowy może być wpięty do dowolnej aplikacji (w tym R), z której możemy tworzyć i zarządzać bazami SQLite. Bazę SQLite możemy budować na danych o względnie stałej strukturze dla każdego rekordu np. notowania giełdowe OHLCV, baza kodów pocztowych, baza TERYT itd. SQL'owe bazy są stale rozwijane, odpowiadając potrzebom rynku, dodając interfejsy pozwalające na budowanie tablic z danymi o bardziej skomplikowanej strukturze. Dla SQLite stworzono rozszerzenie dla danych przestrzennych spatialite, a także rozszerzenie UnQLite do przechowywania dokumentów. Więc jak widać wcale nie trzeba rezygnować z SQL'owej bazy w przypadku danych o bardziej skomplikowanej strukturze.W formie SQLite przechowamy Nasz zbiór Olis.
  2. MongoDB - nierelacyjny system (NoSQL), stworzony do przechowywania dokumentów i danych nie ustrukturyzowanych. Dzisiejszy pomysł na MongoDB nie wziął się znikąd. Po pierwszej jej rosnąca popularność wymusza na mistrzach danych przynajmniej podstawową znajomość tego systemu. Po drugie, naturalnym środowiskiem pracy z MongoDB jest JSON, typowy format w przypadku danych z WebAPI. W formacie JSON pobieramy dane z większości WebAPI, w tym również ze znanego już Nam last.fm, dlatego uznałem to za dobry pretekst do zaprezentowania tego ciekawego systemu. MongoDB w odróżnieniu od SQLite nie działa samodzielnie w R, należy uprzednio zainstalować serwer, do którego kierować będziemy zapytania. Instrukcja instalacji serwera (Windows) poniżej:
    1. Ściągamy ze strony http://www.mongodb.org/downloads i instalujemy np. "D:/Program Files/MongoDB 2.6 Standard"
    2. Folder "D:/Program Files/MongoDB 2.6 Standard/bin" wstawiamy do zmiennej środowiskowej Path, tak jak w instrukcji
    3. Tworzymy folder w dowolnej lokalizacji, w którym przechowywać będziemy bazy danych np. "D:\Dokumenty\databases\mongo"
    4. Otwieramy wiersz poleceń i uruchamiamy bazę danych.
    5. Powyższą procedurę musimy wpisywać za każdym razem gdy będziemy uruchamiać MongoDB. Zamiast tego proponuję utworzyć plik .bat, który po dwukrotnym kliknięciu będzie uruchamiać bazę danych.
Po uruchomieniu możemy tworzyć dokumenty, modyfikować, wybierać określone dane. Instrukcja poleceń dla systemu MongoDB dostępna jest na stronie głównej projektu i na cran'ie pakietu "rmongodb".
UWAGA! NALEŻY URUCHOMIĆ SERWER MongoDB PRZED ROZPOCZĘCIEM PRACY Z R. 

Rozwiązanie

Sprawę bazy SQLite rozwiązuje pakiet sqldf, który ma bardzo dokładną i przyjazną dokumentację. Fajną funkcjonalnością pakietu jest to, że wszystkie data.frame są automatycznie załadowywane do bazy danych/ Kwerendy SQL'owe możemy stosować nie tylko na zapisanych na dysku bazach ale również na data.frame'ach znajdujących się w aktualnej przestrzeni roboczej. Poniżej kod wykorzystujący plik Olis.

Załóżmy teraz dla potrzeb przykładu, że Nasz plik jest zbyt duży żeby załadować go bezpośrednio do R, utworzymy w tym celu bazę SQLite. Od teraz baza znajdować się będzie na dysku, a my możemy wykonywać dowolne operacje, konstruując odpowiednio kwerendy. Poniżej kod tworzący plik bazodanowy oraz przykładowe kwerendy.

Z MongoDB sprawa wygląda trochę trudniej. Zapytania kierowane do bazy mają formę, która zupełnie odbiega od znanych nam kwerend SQL, co może sprawiać pewne trudności na początku. Zaletą jest szybkie kodowanie skryptu przy WebAPI, czego dowiedzie kod poniżej. Zanim przejdziemy do tworzenia bazy w pierwszej kolejności należy załatwić formalności związane z last.fm uwierzytelniając sesję, zgodnie z tym co zaprezentowałem w poprzednim wpisie (sugeruję zapoznać się z treścią, przed przejściem do dalszego etapu). Zmodyfikowana funkcja artist_tags zamyka się teraz w trzech poleceniach, co znacząco skróciło poprzednią wersję.

Po autoryzowaniu sesji można przechodzić do pobierania danych. Jeżeli mamy uruchomiony serwer Mongo, otwieramy wpierw połączenie za pomocą R, tworząc jednocześnie bazę "music_artists". Podobnie jak poprzednim razem każda iteracja to osobne zapytanie wysyłane do WebAPI korzystając z utworzonej wcześniej funkcji artist_tags. Tym razem funkcja zwraca dane w formacie JSON, co po uprzedniej zamianie na format binarny (BSON) trafia do kolekcji "last_fm" zawartej w bazie "music_artist". Za przekazywanie danych do bazy odpowiada funkcja mongo.insert(). Plik nowo-utworzonej bazy znajduje się we wcześniej zdefiniowanym folderze - w przykładzie "D:\Dokumenty\databases\mongo"

Dla tych, którym nie udało się połączyć z last.fm API proponuję skorzystać z przykładowego zbioru danych kodów pocztowych w USA. Poniżej kod, który zaczytuje dane bezpośrednio ze strony i zapisuje je do bazy MongoDB. Przykłady agregacji do bazy kodów pocztowych znajdują się na oficjalnej stronie MongoDB. Baza kodów pocztowych jest przykładem najprostszym z możliwych, stąd też nakłaniam do podwyższenia poprzeczki danymi z last.fm.

Dane z last.fm mają specyficzną strukturę, trudniejszą niż przykład kodów pocztowych wałkowanych w większości tutoriali. W bazie last.fm mamy zagnieżdżoną tablicę w elemencie tag, który jest w elemencie top.tags. W top.tags znajduje się również @attr.artist przechowujący nazwę wykonawcy. Struktura danych poniżej na przykładzie jednego artysty.
W odniesieniu do struktury danych konstruujemy zapytania do bazy. Radzę wnikliwie zapoznać się przykładowymi zapytaniami i pamiętajcie o MongoDB bo prędzej czy później część z Nas będzie musiała Ją poznać.

Enjoy!

3 komentarze:

  1. Ten komentarz został usunięty przez autora.

    OdpowiedzUsuń
  2. Pracując w biurze będziemy zmuszeni odpowiednio gospodarować różnymi dokumentami. Aby ułatwić sobie zadanie, warto wyposażyć się w różne akcesoria. Pojemniki z szufladami na klucz https://somax.eu/267-pojemniki-z-szufladami są idealnym rozwiązaniem jeżeli mamy zamiar posegregować oraz zabezpieczyć duże ilości danych. Z pewnością takie przedmioty przydadzą nam się w biurze i poprawią jego funkcjonalność.

    OdpowiedzUsuń
  3. Bardzo ciekawy artykuł. Czekam na kolejne.

    OdpowiedzUsuń