|
|
pl:dydaktyka:ztb:2010:projekty:nosql_couch:start [2010/07/02 02:12] ztb2010 |
pl:dydaktyka:ztb:2010:projekty:nosql_couch:start [2019/06/27 15:50] |
Sebastian Nanek | |
| |
snanek //posiadający konto w domenie// gmail.com | |
| |
====== Wstęp ====== | |
| |
CouchDB to nierelacyjny, zorientowany na dokumnety, system zarządzania bazami danych, napisany w języku Erlang, nastawiony na wysoką dostępność (wykorzystanie algorytmu Map/Reduce) i replikowalność danych (automatyczna replikacja). W przeciwieństwie do systemów relacyjnych, pojedynczy rekord nie jest związany z określoną strukturą danych - zamiast tego ma on postać tablicy haszującej zapisanej w formacie JSON, w której wartości mogą być dowolnego typu prostego - w tym także typu tablicowego. | |
| |
W świecie oprogramowania komercyjnego, mimo stosunkowo niskiego numeru wersji (0.10), system ten zyskuje coraz większą popularność. Stosują go m.in. Engine Yard, czy nawet BBC [9]. Obecnie (czerwiec 2010), trwają prace edytorskie nad pierwszymi wydaniami książek pomocnych w nauce i zrozumieniu CouchDB. | |
====== Praca z CouchDB ====== | |
| |
Instalacja pakietu CouchDB w systemie operacyjnym GNU/Linux Ubuntu: | |
| |
''$sudo aptitude install couchdb'' | |
| |
Uruchomienie CouchDB z poziomu konta superużytkownika: | |
| |
''$ sudo couchdb'' | |
| |
''Apache CouchDB is running as process 31654. Time to relax.'' | |
| |
Alternatywnie, można program uruchamiać z poziomu konta zwykłego użytkownika, wcześniej upewniając się, że użytkownik będzie miał dostęp do zapisu w katalogu /var/lib/couchdb/0.8.0 (lub innym, odpowiadającym ustawieniom CouchDB i lokalnemu środowisku systemowemu). | |
| |
Sprawdzenie poprawności instalacji | |
| |
| |
Z konsoli: | |
| |
''$curl -X PUT http://127.0.0.1:5984/albums'' | |
| |
''{"ok":true}'' | |
| |
Przy użyciu przeglądarki internetowej: | |
| |
Wejście na stronę www: | |
| |
''http://localhost:5984/'' | |
| |
zwraca: | |
| |
''{"couchdb":"Welcome","version":"0.8.0-incubating"}'' | |
| |
W domyślnej instalacji serwera CouchDB znalazło się także miejsce na wizualny panel administracyjny. Dostęp do niego można uzyskać, wchodząc pod adres: | |
| |
''http://localhost:5984/_utils/'' | |
| |
====== Komunikacja ====== | |
| |
| |
======= Zalety ======= | |
| |
* wersjonowanie dokumentów dostępne "od ręki" | |
* komunikacja poprzez łatwy w implementacji i wykorzystaniu protokół http (mechanizm REST [2]) | |
* dane przekazywane w "lekkiej" formie plików JSON | |
* brak sztywnej struktury danych - o formacie przechowywanej informacji decyduje użytkownik systemu (programista) w chwili tworzenia lub aktualizacji wpisu | |
======= Wady======= | |
| |
* brak wbudowanych mechanizmów autoryzacji oraz list kontroli dostępu, konieczność wykorzystania zabezpieczeń na poziomie protokołów komunikacyjnych [3] | |
* konieczność budowania własnych rozwiązań, które mają na celu zabezpieczanie nieautoryzowanego dostępu do bazy danych | |
* trudności z łączeniem danych wielu rekordów (brak skutecznego odpowiednika operatorów typu JOIN) | |
* słabe możliwości konfiguracji zabezpieczeń danych, pomimo ich istnienia [10] | |
| |
======= Możliwości wykorzystania======= | |
| |
* aplikacje internetowe korzystające ze sporej ilości dokumentów o zmiennej strukturze (np. portale internetowe) [1] | |
* oprogramowanie, które wymaga dostępności wszystkich wersji i historii zmian danego dokumentu lub rekordu | |
======= Kiedy stosować? ======= | |
| |
* Struktura danych przechowywanych w aplikacji ma charakter "drzewiasty" - tj. nie ma, lub występują w ograniczonym stopniu relacje pomiędzy rekordami przechowywanymi w bazie danych. Przykładem typu wpisu, którego przechowywanie w formie, w jakiej odbywa się to w CouchDB, jest rekord pacjenta - zawiera on tablice z diagnozami, stosowanymi terapiami, ale nie ma powiązania z innymi rekordami w bazie danych. | |
* W przypadku replikacji bazy danych, gdy ważniejsza jest wysoka dostępność danych (wysoki uptime) i łatwość ich replikacji od spójności informacji pomiędzy serwerami. Taka sytuacja ma często miejsce w przypadku witryn internetowych i ogólnie w oprogramowaniu, w którym przeważają operacje odczytu nad operacjami zapisu. | |
* W przypadku, kiedy niezbędna jest wysoka wydajność aplikacji, a relacyjna baza danych okazuje się być wąskim gardłem w aplikacji, warto rozważyć przejście na system CouchDB, ze względu na możliwość automatycznej replikacji. Źródła[8] wskazują na łatwość uzyskiwania znaczącej wydajności (>2500 req/s) nawet przy użyciu standardowej konfiguracji, przy niewielkim użyciu pamięci operacyjnej. | |
* Interesujące wydaje się wykorzystanie łatwości pracy z CouchDB w przypadku platform, dla których nie istnieją dobre biblioteki do pracy z RDBMS, lub mają one ograniczoną funkcjonalność. CouchDB, dzięki wykorzystaniu mechanizmu REST, może być obsługiwany na dowolnej platformie, która posiada biblioteki do obsługi protokołu HTTP i przetwarzania plików JSON. | |
| |
======= Kiedy nie stosować? ======= | |
| |
* Stosowanie CouchDB nie jest dobrym pomysłem, w sytuacji, kiedy w budowanym systemie informatycznym ponad wydajność ważniejsza jest spójność danych, jak ma to miejsce np. w systemach informatycznych zarządzania przedsiębiorstwem. | |
* Nie warto stosować CouchDB jako zamiennika systemów relacyjnych w sytuacji, kiedy istnieją skomplikowane zależności między danymi (liczne tabele lub klasy rekordów, wiele odwołań do kolumn w innych tabel, liczne funkcje agregujące). | |
| |
======= Podsumowanie ======= | |
| |
CouchDB jest dojrzałym systemem baz danych, nastawionym na łatwość programowania, wysoką wydajność i sprawną replikację danych. Jest to także dobra alternatywa dla systemów relacyjnych w sytuacji, kiedy w strukturze danych dominującą rolę odgrywa jedna klasa rekordów i nie potrzeba skomplikowanych operacji raportowych. Osobiście, będę chciał zastosować ten system w aplikacji internetowej, w której zdecydowanie przeważać będą operacje odczytu danych. | |
====== Zarys projektu ====== | |
| |
Celem projektu jest napisanie prostej aplikacji w oparciu o zorientowany na dokumenty system zarządzania bazami danych //CouchDB//. Aplikacja umożliwia tworzenie dokumentów (//rekordów//). | |
| |
Całość zostanie zaimplementowana w języku //Ruby//, z wykorzystaniem mikroframeworka do tworzenia aplikacji internetowych //SinatraRB//[4]. W tym przypadku framework zapewnia w zasadzie jedynie funkcjonalność dynamicznego serwera http i mapowania adresów na odpowiednie akcje (''FrontController''). Do komunikacji została wykorzystana przykładowa biblioteka klienta, pochodząca z wiki twórców CouchDB[4]. | |
| |
Aby uprościć tworzenie warstwy widoku aplikacji, zostaną wykorzystane następujące biblioteki: | |
| |
* BluePrintCSS | |
* jQuery | |
* jQueryUI | |
| |
| |
====== Funkcjonalność ====== | |
| |
System umożliwia: | |
* przeglądanie listy dostępnych dokumentów | |
* tworzenie nowego dokumentu | |
* usuwanie bieżącego dokumentu | |
| |
====== Komunikacja z CouchDB ====== | |
| |
<code ruby> | |
# based upon a document at http://wiki.apache.org/couchdb/Getting_started_with_Ruby | |
require 'net/http' | |
| |
module Couch | |
class Server | |
def initialize(host, port, options = nil) | |
@host = host | |
@port = port | |
@options = options | |
end | |
| |
def delete(uri) | |
request(Net::HTTP::Delete.new(uri)) | |
end | |
| |
def get(uri) | |
request(Net::HTTP::Get.new(uri)) | |
end | |
| |
def put(uri, json) | |
req = Net::HTTP::Put.new(uri) | |
req["content-type"] = "application/json" | |
req.body = json | |
request(req) | |
end | |
| |
def post(uri, json) | |
req = Net::HTTP::Post.new(uri) | |
req["content-type"] = "application/json" | |
req.body = json | |
request(req) | |
end | |
| |
def request(req) | |
res = Net::HTTP.start(@host, @port) { |http|http.request(req) } | |
unless res.kind_of?(Net::HTTPSuccess) | |
handle_error(req, res) | |
end | |
res | |
end | |
| |
private | |
| |
def handle_error(req, res) | |
e = RuntimeError.new("#{res.code}:#{res.message}\nMETHOD:#{req.method}\nURI:#{req.path}\n#{res.body}") | |
raise e | |
end | |
end | |
end | |
</code> | |
| |
Przykładowe wywołanie akcji pobierania dokumentu, aby go wyświetlić może wyglądać następująco: | |
<code ruby> | |
request = COUCH.get("/#{CONFIGURATION['database']}/#{params['id']}") | |
@document = JSON.load(request.body) | |
</code> | |
| |
Gdzie ''params['id']'' to przekazany do aplikacji identyfikator żądanego dokumentu. | |
| |
====== Bibliografia ====== | |
| |
* [0] http://couchdb.apache.org/ | |
* [1] http://en.wikipedia.org/wiki/Document-oriented_database | |
* [2] http://en.wikipedia.org/wiki/Representational_State_Transfer | |
* [3] http://britg.com/2008/09/23/accessing-couchdb-admin-without-exposing-it-to-a-public-port/ | |
* [4] http://www.sinatrarb.com/ | |
* [5] http://wiki.apache.org/couchdb/Getting_started_with_Ruby | |
* [6] http://news.cnet.com/8301-13846_3-10412528-62.html?tag=mncol;title | |
* [7] http://news.cnet.com/8301-13846_3-10451248-62.html | |
* [8] http://qconsf.com/sf2008/file?path=/qcon-sanfran-2008/slides//JanLehnardt_CouchDB_in_a_real_world_setting.pdf | |
* [9] http://wiki.apache.org/couchdb/CouchDB_in_the_wild | |
* [10] http://books.couchdb.org/relax/reference/security | |