HBase - Instalacja prostego klastra

Autor: Marcin Kasiński
15.12.2012 21:41:49 +0200

W dzisiejszych czasach obserwowana jest coraz większa potrzeba zarządzania bardzo dużą ilością danych. Ilości tych danych w wielu przypadkach przerasta możliwości relacyjnych baz danych. Okazuje się, że rozwiązaniem jest wykorzystanie rozproszenia w taki sposób aby zamiast używania jednego , czy też kilku serwerów bazodanowych, wykorzystywać ich farmę składającą się z wielu instancji. Oczywiście ilość potrzebnych instancji zależna jest od ilości przechowywanych danych oraz specyfiki operacji wykonywanych na tych danych.

W takich sytuacjach z pomocą przychodzi nam Hbase. Rozwiązanie Hbase jest to silnikiem bazodanowym osadzonym na systemie rozproszonym Hadoop. Ważne jest to, że HBase nie jest relacyjna bazą danych , tylko bazą NoSQL. Oznacz to, że nie odwołujemy się do danych bazy poprzez odpowiednie uniwersalne zapytania SQL, tylko poprzez odpowiednie API Hbase. Dodatkową cechą, jaką należy rozważyć przy wdrażaniu tego rozwiązania jest to, że HBase nie obsługuje transakcji. Nie możemy wykonać na bazie modyfikacje i w przypadku niepowodzenia w jednym z kolejnych kroków wycofać wcześniejsze zmiany. Oznacz to, że takie rozwiązanie nie zawsze będzie odpowiednie, ale jeśli tylko nie jest dla nas problemem brak transakcji oraz brak obsługi SQL , HBase może okazać się niezastąpiony w przypadku przechowywania i analizy bardzo dużych ilości danych.

Instalacja środowiska

Poniżej postaram się opisać kroki potrzebne do instalacji rozwiązania. W produkcyjnych konfiguracjach mamy wiele maszyn w klastrze. Dla naszej testowej instalacji wykorzystałem jedną maszynę wirtualną z zainstalowanym na nim systemem Fedora Core 17. Nazwę maszyny ustaliłem na master1 i ta nazwą dalej będę się posługiwał.

Pierwszą rzeczą, jaką powinniśmy zrobić to zainstalować czysty system operacyjny. Ja rozpocząłem od instalacji Fedora Core 17 w wersji minimalnej. Następnie za pomocą narzędzia yum instalujemy pakiety, jakie mogą nam się przydać podczas pracy.

yum install nano.x86_64 openssh-clients openssh-server.x86_64 \n
rsync.x86_64 mc.x86_64 nc-1.103-3.fc17.x86_64

W dalszym kroku powinniśmy zainstalować JAVA. Ważne jest, że należy tu zainstalować nie poprzez instalacje pakiet openjdk narzędziem yum, tylko poprzez zainstalowanie za pomocą instalatora ściągniętego ze strony http://www.oracle.com/technetwork/java/javase/downloads/index.html . W Internecie można znaleźć informacje o niekompatybilności hbase z openjdk. Ja w moim testowym środowisku zainstalowałem JAVA z instalatora jdk-6u37-linux-x64-rpm.bin .

Konfiguracja SSH

Wszelkie operacje (np. start / stop noda) wykonywane na maszynach naszego klastra odbywają się poprzez SSH. Dlatego aby nie było potrzeby podawania za każdym razem hasła użytkownika należy skonfigurować bezpieczną komunikacje pomiędzy maszyną master1, a wszystkimi maszynami slave skonfigurować bezpieczną komunikację SSH. Taką samą konfiguracje, co na początku może wydawać się dziwne należy wykonać dla komunikacji master1 - master1. W naszej testowej konfiguracji jako że mamy tylko jedną maszynę wykonujemy taką konfiguracje tylko raz.

Pierwszym krokiem jest tu na maszynie master1 wygenerowanie pary kluczy SSL. Poniższe komendy tworzą w katalogu naszego użytkownika katalog .ssh oraz w nim tworzą klucz prywatny i publiczny.

mkdir ~/.ssh
cd ~/.ssh
ssh-keygen -t rsa -N ""

Następnie musimy przekazać klucz publiczny wszystkim innym maszynom klastra. Klucz ten znajduje się w pliku .ssh/id_rsa.pub . Automatycznie dokonuje się tego komendą ssh-copy-id , gdzie jako parametr przekazuje się nazwę pliku oraz nazwę użytkownika i maszyny gdzie plik ma być skopiowany.

ssh-copy-id -i id_rsa.pub user@machine1

Innym sposobem, jest ręczne zapisanie pliku już na maszynie docelowej.

chmod 700 ~/.ssh
cat id_dsa.pub >> ./authorized_keys
chmod 600 ~/.ssh/authorized_keys

Weryfikacje powyższej konfiguracji możemy dokonać poprzez próbę wykonania poniższej komendy:

ssh master1

Jeśli nie zostaniemy poproszeni o podanie hasła, oznacza to, że wszystko jest poprawnie skonfigurowane.

Ustawienie zmiennych środowiskowych

W dalszej części artykuły znajdzie się opis konfiguracji trzech kluczowych komponentów naszego rozwiązania Hadoop, ZooKeeper oraz oczywiście HBase. Zanim do tego dojdziemy musimy zmodyfikować plik .bash_profile dodając w nim zmienne środowiskowe dla katalogów domowych JAVA, Hadoop, ZooKeeper oraz HBase.


export JAVA_HOME=/usr
export HADOOP_HOME=/usr/local/hadoop/current
export ZK_HOME=/usr/local/ZooKeeper/current
export HBASE_HOME=/usr/local/hbase/current

Po tych zmianach za pomocą poniższego polecenia ustawiamy zapisane zmienne.

source ~/.bash_profile

W naszym przykładowym środowisku aby nie skupiać się na kwestiach bezpieczeństwa wyłączymy iptables poniższymi komendami. Mam nadzieję, że nie muszę tłumaczyć dlaczego nie powinniśmy tego robić w środowisku do którego jest dostęp z zewnątrz.

systemctl stop iptables.service
systemctl disable iptables.service

Instalacja Hadoop

Dystrybucje Hadoop możemy ściągnąć ze strony http://hadoop.apache.org/releases.html#Download Po ściągnięciu hadoop rozpakowujemy go w katalogu /usr/local/ oraz w nim tworzymy link symboliczny current, do którego później będziemy się odwoływać. Pozwala to, w przypadku wgrania nowszej wersji zminimalizować wymagane zmiany konfiguracyjne, ponieważ w takiej konfiguracji niezależnie od wersji zawsze będziemy się odwoływać do katalogu current.

ln -s hadoop-1.0.4 current

Następnie tworzymy katalogi dla danych hadoop.

mkdir -p /usr/local/hadoop/var/dfs/name
mkdir -p /usr/local/hadoop/var/dfs/data
mkdir -p /usr/local/hadoop/var/dfs/namesecondary
mkdir -p /usr/local/hadoop/var/mapred

Konfiguracja Hadoop

Teraz możemy przejść do modyfikacji plików konfiguracyjnych znajdujących się w katalogu conf.

W pliku hadoop-env.sh ustawiamy zmienną środowiskową JAVA_HOME .

export JAVA_HOME=/usr

W pliku core-site.xml umieszczamy wskazanie na katalog z danymi wcześniej przez nas utworzony oraz definicje linka do naszego repozytorium plikowego hdfs.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
	<property>
		<name>hadoop.tmp.dir</name>
		<value>/usr/local/hadoop/var</value>
	</property>
	<property>
		<name>fs.default.name</name>
		<value>hdfs://master1:9000</value>
	</property>
</configuration>

W pliku mapred-site.xml umieszczamy konfigurację mapreduce. O samym mapreduce postaram się napisać w jednym z kolejnych artykułów.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
	<property>
		<name>mapred.job.tracker</name>
        <value>master1:9001</value>
    </property>
</configuration>

W pliku masters umieszczamy listę maszyn zarządzających naszym klastrem. W naszym testowym rozwiązaniu umieszczamy tu tylko nazwę master1 .

W pliku slaves umieszczamy listę maszyn podrzędnych klastra. Zazwyczaj będzie tam lista konkretnych maszyn. W naszym testowym rozwiązaniu skoro wszystko będzie działało na jednej maszynie umieszczamy tu tylko nazwę master1 .

Po zakończeniu powyższej konfiguracji możemy sformatować nasz system plikowy HDFS za pomocą poniższego polecenia.

$HADOOP_HOME/bin/hadoop namenode -format

Instalacja ZooKeeper

Dystrybucje ZooKeeper możemy ściągnąć ze strony http://www.apache.org/dyn/closer.cgi/zookeeper/ Po ściągnięciu ZooKeeper rozpakowujemy go w katalogu /usr/local/ oraz w nim tworzymy link symboliczny current, do którego później będziemy się odwoływać.

ln -s ZooKeeper-3.4.5 current

Następnie tworzymy katalogi dla danych ZooKeeper.

mkdir -p /usr/local/ZooKeeper/var/data
mkdir -p /usr/local/ZooKeeper/var/datalog

Konfiguracja ZooKeeper

Teraz możemy przejść do modyfikacji plików konfiguracyjnych znajdujących się w katalogu conf.

W pliku zoo.cfg ustawiamy wskazanie na przed chwilą stworzone katalogi z danymi.

dataDir=/usr/local/ZooKeeper/var/data
dataLogDir=/usr/local/ZooKeeper/var/datalog

W pliku java.env ustawiamy zmienną środowiskową JAVA_HOME .

JAVA_HOME=/usr
export PATH=$JAVA_HOME/bin:$PATH

Instalacja HBase

Dystrybucje HBase możemy ściągnąć ze strony http://www.apache.org/dyn/closer.cgi/hbase/ Po ściągnięciu HBase rozpakowujemy go w katalogu /usr/local/ oraz w nim tworzymy link symboliczny current, do którego później będziemy się odwoływać.

ln -s hbase-0.94.2 current

Następnie tworzymy katalogi dla danych hadoop.

mkdir -p /usr/local/hbase/var

Konfiguracja HBase

Teraz możemy przejść do modyfikacji plików konfiguracyjnych znajdujących się w katalogu conf.

W pliku hbase-env.sh ustawiamy zmienną środowiskową JAVA_HOME oraz poprzez zmienną HBASE_MANAGES_ZK wskazujemy, że HBase nie będzie samodzielnie uruchamiał usługi ZooKeeper razem przy starcie. Robimy to aby wykorzystać zewnętrzną usługę ZooKeeper wcześniej skonfigurowaną w tym artykule.

export JAVA_HOME=/usr
export HBASE_MANAGES_ZK=false

W pliku hbase-site.xml ustawiamy wskazanie na nasz rozproszony system plikowy HDFS, katalog danych HBase, lokalizację serwisu / serwisów ZooKeeper.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
	<property>
		<name>hbase.rootdir</name>
		<value>hdfs://master1:9000/hbase</value>
	</property>
	<property>
		<name>hbase.master</name>
		<value>master1:60000</value>
	</property>
	<property>
		<name>hbase.cluster.distributed</name>
		<value>true</value>
	</property>
	<property>
		<name>hbase.tmp.dir</name>
		<value>/usr/local/hbase/var</value>
	</property>
	<property>
		<name>hbase.zookeeper.quorum</name>
		<value>master1</value>
	</property>
</configuration>

W pliku regionservers umieszczamy listę maszyn podrzędnych klastra HBase. Zazwyczaj będzie tam lista konkretnych maszyn. W naszym testowym rozwiązaniu, skoro wszystko będzie działało na jednej maszynie, umieszczamy tu tylko nazwę master1 .

Uruchomienie i zatrzymanie klastra

W celu uruchomienia klastra należy uruchomić wszystkie jego komponenty. Ja do moich wewnętrznych celów testowych mam przygotowany prosty skrypt. W nim w pierwszej kolejności kasuje logi, aby łatwiej je analizować w przypadku problemów. Dalej startuje wszystkie komponenty hadoop, potem ZooKeeper oraz HBase. Następnie ustawiam pauzę 3 sekundy oraz listuje odpowiednie porty na których nasłuchuje maszyna. Robię tak ponieważ wiem, że po starcie komponentów czasami musi upłynąć czas aby uruchomić wszystkie moduły. Weryfikując porty mogę nawet bez analizy logów stwierdzić , czy cały klaster uruchomił się poprawnie, czy nie. Jeśli pojawi się problem nie pozostaje nic innego, jak analiza logów poszczególnych komponentów klastra.

rm $HADOOP_HOME/logs/*
rm $HBASE_HOME/logs/*
rm $ZK_HOME/logs/*

cd $HADOOP_HOME/logs/

$HADOOP_HOME/bin/start-all.sh
$ZK_HOME/bin/zkServer.sh start
$HBASE_HOME/bin/start-hbase.sh

sleep 3s

netstat -nlp | grep 600

Po wystartowaniu klastra możemy za pomocą narzędzi webowych administrować środowiskiem.

URLOpis
http://master1:50070/dfshealth.jspKonsola administracyjna Hadoop
http://master1:60010/Konsola administracyjna HBase
http://master1:50030/Konsola administracyjna JobTracker

W celu zatrzymania klastra należy zatrzymać wszystkie jego komponenty. W poniższym skrypcie zatrzymuje HBase, ZooKeeper oraz wszystkie komponenty hadoop. Następnie ustawiam pauzę 3 sekundy oraz listuje procesy java. Ostatnie dla weryfikacji, czy poprawnie klaster został zatrzymany.

$HBASE_HOME/bin/stop-hbase.sh
$ZK_HOME/bin/zkServer.sh stop
$HADOOP_HOME/bin/stop-all.sh
sleep 3s
ps -ef | grep java

Synchronizacja pomiędzy nodami

W naszym środowisku przykładowym nie musimy nic synchronizować. Inaczej to wygląda, kiedy mamy klaster składający się z więcej niż jedną maszynę. W takiej sytuacji konfigurujemy jedną maszynę w całości a następnie dane pliki kopiujemy na inne maszyny. Przed synchronizacją dodatkowe maszyny muszą być skonfigurowane zgodnie z opisem z rozdziału "Instalacja środowiska". Po tym będąc zalogowanym na głównej maszynie wykonujemy poniższe komendy synchronizujące katalogi hadoop, ZooKeeper oraz hbase.

rsync -avz /usr/local/hadoop/ slave1:/usr/local/hadoop/
rsync -avz /usr/local/ZooKeeper/ slave1:/usr/local/ZooKeeper/
rsync -avz /usr/local/hbase/ slave1:/usr/local/hbase/

Tą operacje wykonujemy tylko raz. Następnym razem synchronizujemy tylko katalogi konfiguracyjne.

rsync -avz /usr/local/hadoop/current/conf/ slave1:/usr/local/hadoop/current/conf/
rsync -avz /usr/local/ZooKeeper/current/conf/ slave1:/usr/local/ZooKeeper/current/conf/
rsync -avz /usr/local/hbase/current/conf/ slave1:/usr/local/hbase/current/conf/

Przykładowe operacje na tabeli

Podstawowym narzędziem hbase jest shell pozwalający na wykonywanie operacji na bazie z poziomy konsoli. Startujemy je poprzez poniższą komendę

$HBASE_HOME/bin/hbase shell

Przykładowe komendy tworzące tabele, zapisujące do niej rekord oraz odczytywanie rekordów znajdują się poniżej.

create 'testtable', 'columnfamily'
put 'testtable', 'id', 'columnfamily:mkcolumn', 'mkvalue124'
scan 'testtable', {LIMIT => 15}

Podsumowanie

To byłoby na tyle jeśli chodzi o informacje na temat HBase. Mam nadzieję, że taki sposób czytelnikom odpowiada. Nie chciałem tu opisywać ze szczegółami Hbase i wszystkie jego komponenty. Nie taki był cel. Celem było przygotowanie prostego środowisk opisując tylko najważniejsze rzeczy potrzebne do zrozumienia procesu tworzenia środowiska. Celem lepszego zrozumienia HBase proponuje zapoznać się z wieloma materiałami dostępnymi w Internecie. Ja osobiście postaram się tu umieścić jeszcze kilka artykułów związanych z HBase.


powrót
Zachęcam do przedstawienia swoich uwag i opinii w polu komentarzy.

Komentarze

Dodaj Komentarz