Posted at 11:00 AM in localolo.com | Permalink
W ramach projektu localolo.com współpracujemy z kilkudziesięcioma dostawcami danych. To naprawdę wspaniali ludzie, którzy rozumieją zyski płynące z dzielenia się danymi z tymi, którzy potrafią je przetworzyć na korzyść wszystkich (użytkownik dostaje pożyteczne informacje, dostawca dociera do odbiorcy przez localolo.com, a my mamy przy tym okazję też zarobić i tworzyć rzeczy nowe). Bez nich, localolo.com nie miałoby 500,000 wpisów w bazie danych w niecały miesiąc. A to dopiero początek.
Jedynym problemem na jaki napotykamy jest czyszczenia danych z kilku tuzinów formatów. Wewnętrznie składujemy je w formacie UTF-8, ale nasi partnerzy często jeszcze nie korzystają z UTF-8, albo dane nie są wolne od znaków spoza zakresu dozwolonego przez UTF-8. Jeden czy dwa wpisy to nie problem, ale kiedy próbujemy zautomatyzować import kilkunastu tysięcy plików źródłowych, musimy czyścić dane w brzydki sposób, za pomocą zestawu własnych skryptów na pisanych w Pythonie. Na razie to nie problem, ale zastanawiam się nad przepisaniem ich w Erlangu, bo możnaby wtedy zastosować parę ciekawych sztuczek z przetwarzaniem równoległym. Im dłużej o tym myślę, tym bardziej podoba mi się ten pomysł.
Posted at 11:00 AM in localolo.com, Moje oprogramowanie | Permalink
Budując localolo.com doszedłem do wniosku, że początkujący użytkownicy Linuxa mają wiele wspólego z programistami i administratorami budującymi serwisy, które mają działać 24x7 i obsługiwać setki tysięcy, jeśli nie miliony kont użytkowników. I jedni i drudzy chcieliby żeby oprogramowanie, z którego będą korzystać łatwo się instalowało, samo konfigurowało i nie sprawiało problemów przy odpalaniu na dziwnych konfiguracjach sprzętowych i sieciowych.
Przyznaję się bez bicia, że też stałem się leniwy. Przyznam się też że miałem w swoim życiu okres, w którym byłem gotów walczyć do krwi ostatniej z tymi, którzy nie chcieli dotykać ./configure. Przeszło mi od kiedy zacząłem budować własne serwisy z myślą o zarabianiu pieniędzy i wejściu na rynek z własnym startupem. Tu liczy się skuteczność a nie radość z jazdy gołą dupą po szorstkiej krawędzi postępu technologicznego.
Szukanie sposobów na zarabianie kasy ma tę miłą właściwość, że szybko zamienia się w wyszukiwanie sposobów na zaoszczędzenie pieniędzy. A to w praktyce oznacza, że szukamy takiego oprogramowania, które wyciśnie jak najwięcej kasy z dostępnego sprzętu i łącz internetowych. Pierwszym kawałkiem kodu, który idzie pod lupę jest baza danych. Z pozoru wybór jest prosty. Jak masz kasę robisz przelew na konto IBM, Microsoft, albo Oracle i po sprawie. Jeśli kasy nie masz, bierzesz MySQL albo PostgreSQL i po sprawie. Więc w czym problem? No… bo… ja mam taką dużą… bazę…
W przypadku localolo.com mam do czynienia z problemem od którego można wyłysieć, bo rdzeniem systemu jest to rozproszona baza danych GIS, która ma udzielać odpowiedzi w czasie krótszym niż 1 sekunda od chwili otrzymania zapytania (pomijam opóźnienia łącz, na to wpływu nie mam). Baza została zaprojektowana docelowo na 120 000 000 wpisów po 4KB każdy czyli 458TB czystych danych. Debiutujemy z trochę ponad 500 000 wpisów albo niecałymi 2GB więc na razie nie ma problemu, ale chcę mieć swobodę rozbudowy bazy bez konieczności przebudowywania jej co jakiś czas. Swoboda rozbudowy wiąże się dla mnie z maksymalnym uproszczeniem architektury. W systemie mogą pracować graty z 512MB RAM jak i konkretne żelastwo z 64GB RAM. Baza ma się sprawnie replikować, posłusznie poddawać monitoringowi oraz szybko i skutecznie naprawiać. Najlepiej sama, bez udziału administratora. No i ma stabilnie działać na dowolnym sprzęcie od 500zł wzwyż. Koszt? $0.
Oszalałem? Niekoniecznie. Moje oczekiwania są niestandardowe, ale nie są niedorzeczne. W epoce wynajmowanych, zwirtualizowanych centrów obliczeniowych nie możemy być pewni tego, że przy konieczności przejścia z jednego centrum do drugiego będziemy uruchamiali oprogramowanie na takim samym sprzęcie. Colo i wysyłanie sprzętu po świecie jakoś mnie nie kręci, więc zakładam, że wiem, że nic nie wiem na temat sprzętu, na którym będzie działał mój serwis. Jedyne co znam, to kilka podstawowych parametrów (częstotliwość taktowania procesora, rozmiar pamięci RAM, pojemność dysku, system operacyjny i adres IP maszyny). Oprogramowanie nie może liczyć na to, że będzie rozpieszczane. Ma działać na byle czym, ale nie byle jak.
Takie postawienie sprawy mocno zawęża możliwości wyboru, bo od razu eliminuje oprogramowanie komercyjne (koszt = $0). Interesuje mnie tylko i wyłącznie Open Source. To wcale nie ogranicza wyboru aż tak bardzo jakby się mogło wydawać. Ekosystem Open Source oferuje zainteresowanym każdy rodzaj bazy danych w kilku odmianach. Jest tego ze 30-40 różnych projektów. Każdy oferuje jakąś unikalną funkcję, która lepiej lub gorzej pasuje do moich wymagań, ale zanim zacząłem przyglądać się im z bliska, postanowiłem, że muszą spełniać dwa warunki:
To wygodnictwo ma sens, ponieważ skraca czas instalacji i aktualizacji oprogramowania. Zwiększa też stabilność i bezpieczeństwo całości systemu. Zakładam, że ten kto aktualizuje oprogramowanie na bieżąco i dba o jego łatwą instalację, dba też o jakość samego oprogramowania oraz ma długoterminowy plan rozwoju i wsparcia kodu. To uspokaja mnie bardziej niż raporty finansowe spółek giełdowych albo plotki o długości jachtu tego czy innego prezesa.
Te dwa założenia zamknęły drogę kilku bardzo ciekawym projektom. Cassandra, HBase, Hypertable, MongoDB ani Tokyo Cabinet nie udostępniają pakietów dla systemów Ubuntu, CentOS, albo Fedora. Ich kompilacja to typowe piekiełko Open Source, dociąganie pakiecików, kompilacja, szukanie błędów, łatanie ścieżek dostępu, itp. Nie mam na to czasu. Mnesię pominąłem ponieważ musiałbym oprzeć całość rozwiązania na Erlangu, co jest jedną z opcji, ale na razie zbyt czasochłonną. Moją ulubioną trucizną jest Python.
Co nam zostaje? BDB, CouchDB, MySQL, PostgreSQL, Redis, SQLite. To dość przypadkowe towarzystwo, ale kto wie, może wśród nich znajdę nieoszlifowany diament? Na pierwszy rzut oka wydaje się, że każda z tych baz poradzi sobie z prostym zadaniem: odpowiadaj na przynajmniej 1000 zapytań na sekundę jeśli bazę trzymasz w pamięci RAM lub przynajmniej 500 zapytań na sekundę jeśli baza rezyduje na dysku. Problem w tym, że minimalnym systemem, na którym baza danych ma działać jest maszyna wirtualna z systemem Ubuntu z 512MB RAM i dyskiem 80GB podpiętym przez USB. Maszyna działa pod systemem Mac OS X na komputerze MacBook. Żeby była jasność, nie jest to środowisko produkcyjne, ale developerskie. Poza tym wszystko ma działać tak jak w systemie produkcyjnym, nawet jeśli z mniejszą wydajnością. Po prostu, na takim kiepskim "sprzęcie" szybciej wyłapię problemy.
Zanim baza zacznie odpowiadać, musimy wczytać dane. 400 000 adresów po 4KB każdy to ok. 1.4GB. Nie powinno być z tym problemu jeżeli będziemy wpisywali adresy pojedynczo, bez łączenia ich w paczki. Tak przecież będzie działała funkcja dodawania adresów, nikt nie będzie wczytywał bazy z 1000 adresów w jednej sesji, tylko będą to pojedyncze wpisy. Dla każdej bazy napisałem trzy proste skrypty, których zadaniem jest dodanie danych do bazy, zadanie co 15 minut pytania o liczbę wpisów w bazie i sprawdzenie rozmiaru pliku bazy danych (przybrane w shellowe piórka polecienie ls -lh).
Przygotowując się do testu nie dokonywałem żadnych zmian w konfiguracji oprogramowania. Po prostu zainstalowałem pakiety a w przypadku serwera Redis skompilowałem kod poleceniem make. Wszystkie skrypty napisałem w języku Python.
Najszybciej poszło mi z MySQL i PostgreSQL. Wywaliły się zanim skrypty wpisały 100 000 adresów do bazy. Okazuje się, że zwykłe sprawdzenie rozmiarów bazy jest dla nich tak dużym obciążeniem, że odmawiaja współpracy w stylu Controlled Demolition. To nie był dobry początek, chociaż trzeba być sprawiedliwym i przyznać, że oba serwery miały za mało pamięci.
Redis wydawał się być silnym konkurentem, ale zabrakło RAM-u i zdołał zapisać na dysku tylko 110 000 ze 140 000 wpisów, które miał w pamięci. Dodatkowe punkty dostał za styl crashowania systemu. Totalnie czarny ekran bez możliwości dostania się do systemu to rzadkość w systemach Linux. Pomógł dopiero twardy restart. Redisa nie przekreślam, ale musi mieć dużo RAM-u, żeby pokazać co potrafi. Swap zdecydowanie nie jest jego ulubionym habitatem.
Przyjemnie zaskoczył mnie CouchDB. Co prawda wyniki testów dostępne w sieci nie powalają, ale też nie zostały potwierdzone w moich testach. CouchDB jest wg. swojego twórcy bazą dla każdego komputera, od telefonu komórkowego do farmy serwerów wieloprocesorowych. To odważne stwierdzenie, ale muszę powiedzieć że CouchDB przyjemnie mnie zaskoczył. Owszem, wziął całą wolną pamięć RAM, ale nie wymusił stronicowania. Osiągnął mało rewelacyjny wynik 17 wpisów na sekundę, ale ani razu nie padł. Błyskawicznie odpowiadał na zapytania o liczbę wpisów i ani razu nie zauważyłem blokowania dostępu do systemu plików charakterystyznego dla np. Redis lub SQLite w czasie aktualizacji kopii bazy na dysku. Ki diabeł? Autor CouchDB to na pewno dobry programista, ale też mądrze wybrał Erlang jako język programowania. To tylko pierwszy z wielu testów, jakie przeprowadziłem, ale wywarł na mnie bardzo pozytywne wrażenie, ponieważ większość opinii nt. CouchDB krążących w sieci to wypowiedzi w stylu, "fajne, ale do poważnych zastosowań się nie nadaje." No, co jak co, ale stabilna baza danych to chyba podstawa? Owszem, ma swoje ograniczenia. Limit rozmiaru pliku bazy danych ustawiony w domyślnym pliku konfiguracyjnym zdaje się potwierdzać raporty o problemach ze stabilnością serwera po zbliżeniu się rozmiaru bazy danych do magicznej granicy 5GB, ale można to obejść dzieląc bazę na mniejsze części.
SQLite również miło mnie zaskoczył. Działal szybko (31 wpisów na sekundę) i chociaż zaanektował całość dostępnej pamięci RAM, to ani razu nie sprawił, że system uruchomił swap. To kolejna baza danych, która dobrze czuje się na pokładzie telefonu komórkowego (jest częścią systemów iPhone OS i Android) jak i na dużych serwerach. Dodatkowo wspiera transakcje, co przydaje się w wielu zastosowaniach. Może trzymać dane w pamięci RAM albo na dysku co czyni ją jeszcze bardziej elastyczną. SQLite potrzebował też tylko 1.6GB przestrzeni dyskowej do przechowania 400 000 wpisów (CouchDB potrzebuje 4.1GB do przechowania tej samej ilości danych). Podobnie oszczędny jest Redis.
Co zatem sądzę o pretendentach do tronu magazyniera głównej bazy danych localolo.com? Po pierwszym teście na polu bitwy zostały trzy systemy: CouchDB, Redis oraz SQLite. Każdy ma swoje zalety i wady, ale nie ulega wątpliwości, że CouchDB zaskoczył mnie swoją stabilnością i "lekkością" działania. SQLite ma przewagę bycia dostępnym na wszystkich systemach, które są platformą dla aplikacji klienckich localolo, ale niekoniecznie wygrywa na serwerze z CouchDB, który może wysłać dane w formacie, który odpowiada nam najbardziej (JSON, HTML, czysty tekst). A Redis, z odpowiednią ilością RAM rozkłada konkurencję na łopatki. Niektóre funkcje localolo.com będziemy mogli udostępnić właśnie dzięki Redisowi. CouchDB i Redis wspierają replikację, co jest ważne gdy musimy równoważyć obciążenie serwera. SQLite nadaje się bardziej do tych części systemu gdzie potrzebne są transakcje a nie maksymalna wydajność. W przypadku głównej bazy danych ważna jest oczywiście wydajność odczytu i tu bez konkurencji są Redis i SQLite z bazą otwartą w pamięci RAM. Napiszę o tym więcej już niedługo.
Posted at 11:00 AM in localolo.com | Permalink
Posted at 12:55 AM in Android, iPhone, localolo.com, Moje oprogramowanie, Uzupełniona rzeczywistość | Permalink

