金融データ分析基盤の構築 - Hadoop(1)
前回:
今回やること
AnsibleでHadoopクラスタ構築
Hadoopクラスタへの接続
使用するマシン
今回はHadoopクラスタの構築・検証を行うことを主な目的とするため、NameNodeの可用性やDataNodeによる処理性能についてはあまり考えないことにする。それらについては、一通り構築してみてからまた別の記事で取り扱う。
使用するマシンは以下の二つで、クラスタとしては最小構成となる。
NameNode:格安シンクラ1台
DataNode:格安シンクラ1台
格安シンクラはすべてCPUがX5-E8000、RAMが2GB、ストレージはHDD500GBとなり、全体的にスペックはかなり低めだ。OSはUbuntu server 24.04で、初期設定のみをしたマシンとなっている。
AnsibleでHadoopクラスタ構築
事前準備
事前準備として必要なのはJavaのインストールとHadoopのソースコードのダウンロード。JavaのバージョンはHadoopのバージョンに依存しているが、公式ドキュメントに貼ってあるリンクを見るとHadoop2.7から3.3(とそれ以上)はJava 8にすべて対応されているようだった。
Java 8のインストール
Hadoopの安定版ソースコード(Apache mirrorから)
Javaのインストール
Java(OpenJDK)のインストールは圧縮ファイルをそのまま解凍して配置するような形になるので、とりあえずJava8のOpenJDK(圧縮)をOpenLogicからダウンロードしてきた。
このファイルをfiles配下に置いて、以下のようにAnsibleのタスクを書いていく。
$ tree roles/java
roles/java
├── files
│ └── openlogic-openjdk-8u422-b05-linux-x64.tar.gz
├── tasks
│ └── main.yaml
└── vars
└── main.yaml
# roles/java/tasks/main.yaml
- name: "Copy Java 8 to the server"
copy:
src: "{{ jdk_archive }}"
dest: "/opt/{{ jdk_archive }}"
- name: "Unarchive the file"
ansible.builtin.unarchive:
src: "/opt/{{ jdk_archive }}"
dest: "/opt/"
remote_src: yes
- name: "Set Java 8 as the default"
alternatives:
name: java
link: "/usr/bin/java"
path: "/opt/{{ jdk_directory }}/bin/java"
priority: 1000
- name: Set JAVA_HOME environment variable
template:
src: jdk.sh.j2
dest: /etc/profile.d/jdk.sh
mode: '0755'
# roles/java/vars/main.yaml
jdk_version: "8u422-b05"
jdk_archive: "openlogic-openjdk-{{ jdk_version }}-linux-x64.tar.gz"
jdk_directory: "openlogic-openjdk-{{ jdk_version }}-linux-x64"
Hadoopの安定版ソースコード
ApacheのミラーサイトでHadoopの安定版バージョンをダウンロードしてくる。下のページだと現状は3.4.0が最も新しいバージョンとなっている。これのBinaryをダウンロードしてくる。
ダウンロードして解答するとこんな感じの中身になっており、基本的にはetc配下に設定ファイルが入っており、それらを適宜設定して各ノードに置くような形になる。
❯ ls -la
total 116
drwxr-xr-x 10 yuuki yuuki 4096 Mar 4 2024 .
drwxr-xr-x 6 yuuki yuuki 4096 Sep 15 20:34 ..
-rw-r--r-- 1 yuuki yuuki 23756 Mar 4 2024 LICENSE-binary
-rw-r--r-- 1 yuuki yuuki 15696 Mar 4 2024 LICENSE.txt
-rw-r--r-- 1 yuuki yuuki 27165 Mar 4 2024 NOTICE-binary
-rw-r--r-- 1 yuuki yuuki 1541 Mar 4 2024 NOTICE.txt
-rw-r--r-- 1 yuuki yuuki 175 Mar 4 2024 README.txt
drwxr-xr-x 2 yuuki yuuki 4096 Mar 4 2024 bin
drwxr-xr-x 3 yuuki yuuki 4096 Mar 4 2024 etc
drwxr-xr-x 2 yuuki yuuki 4096 Mar 4 2024 include
drwxr-xr-x 3 yuuki yuuki 4096 Mar 4 2024 lib
drwxr-xr-x 4 yuuki yuuki 4096 Mar 4 2024 libexec
drwxr-xr-x 2 yuuki yuuki 4096 Mar 4 2024 licenses-binary
drwxr-xr-x 3 yuuki yuuki 4096 Mar 4 2024 sbin
drwxr-xr-x 4 yuuki yuuki 4096 Mar 4 2024 share
Hadoopのセットアップ(ユーザ作成・ファイル設置など)は以下のタスクで行う。
# roles/hadoop/tasks/main.yaml
- name: Create Group
group:
name: hadoop
state: present
- name: Create HDFS user
user:
name: hdfs
group: hadoop
state: present
shell: /bin/bash
- name: Install ACL
apt:
name: acl
state: present
- name: Copy Hadoop archive file
copy:
src: "{{ hadoop_archive }}"
dest: "/tmp/{{ hadoop_archive }}"
force: no
- name: Unarchive the file
ansible.builtin.unarchive:
src: "/tmp/{{ hadoop_archive }}"
dest: "/opt/"
creates: "/opt/{{ hadoop_directory }}"
remote_src: yes
group: hadoop
- name: Create a log directory
file:
path: "/opt/{{ hadoop_directory }}/logs"
group: hadoop
mode: "0775"
state: "directory"
- name: Create necessary directories
file:
path: "/opt/{{ hadoop_directory }}/{{ item }}"
group: hadoop
mode: "0775"
state: "directory"
loop:
- logs
- tmp
- name: Create a symbolic link
file:
src: "/opt/{{ hadoop_directory }}"
dest: "/opt/hadoop"
state: "link"
- name: Configure workers file to namenode
template:
src: workers.j2
dest: /opt/hadoop/etc/hadoop/workers
- name: Copy setting files to hadoop dir
copy:
src: etc/hadoop/
dest: /opt/hadoop/etc/hadoop/
group: hadoop
mode: "0644"
directory_mode: "0755"
デフォルト設定のHadoopではHADOOP_HOME(今回は/opt/hadoop)の下にlogsというディレクトリが作られ、その中にデーモンのログなどが入る。しかし、HADOOP_HOMEの権限はグループに対して書き込みを入れてないので、グループのユーザが書き込む場所(logs, tmp)は権限をいじってある。
ちなみに、"Copy setting files to hadoop dir"でやっているように、特定の設定ファイルのみをroles/hadoop/files/配下に入れて各マシンにコピーさせることもできる。これを使ってデフォルトから設定をいじれる。
SSH設定とHadoopクラスタの起動
これでJavaのインストールとHadoopのファイル群の設置が出来たので、あとはSSH設定をしてNameNodeからDataNodeに接続できるようにして、NameNodeからshellスクリプト(sbin/start-dfs.sh)を呼び出すだけで行ける。
メインとなるPlaybookは以下のようになっている。
- name: Setup Hadoop Cluster
hosts: all
become: yes
roles:
- java
- hadoop
- name: SSH key setting (namenode)
hosts: namenode
become: yes
vars:
hadoop_users:
- hdfs
tasks:
- name: Generate SSH key for hadoop users
user:
name: "{{ item }}"
generate_ssh_key: yes
ssh_key_bits: 2048
ssh_key_file: .ssh/id_rsa
loop: "{{ hadoop_users }}"
- name: Fetch SSH public key from namenode
slurp:
src: "/home/{{ item }}/.ssh/id_rsa.pub"
register: slurped_keys
loop: "{{ hadoop_users }}"
- name: Set public keys fact
set_fact:
public_keys: "{{ public_keys | default({}) | combine({ item.item: (item.content | b64decode) }) }}"
loop: "{{ slurped_keys.results }}"
- name: SSH key setting
hosts: all
become: yes
vars:
hadoop_users:
- hdfs
tasks:
- name: Copy SSH public keys to datanode
authorized_key:
user: "{{ item }}"
key: "{{ hostvars[groups['namenode'][0]].public_keys[item] }}"
loop: "{{ hadoop_users }}"
- name: HDFS Format NameNode
hosts: namenode
become: yes
become_user: hdfs
become_flags: "-i"
tasks:
- name: Format NameNode
command: /opt/hadoop/bin/hdfs namenode -format -force
- name: HDFS Start
hosts: namenode
become: yes
become_user: hdfs
become_flags: "-i"
tasks:
- name: Start
command: /opt/hadoop/sbin/start-dfs.sh
これとinventory(各ノードのipを設定)を合わせて実行するとHadoopクラスタの構築と起動をすることができる。起動後はNameNodeの9870ポート(Hadoop 2.x.xの場合は50070)にアクセスするとHadoopのWebUIを見ることができる。
とりあえず、Ansibleを使ったHadoopの構築はいったんこんな感じ。ただ、これはまだ「構築ができる」という検証をしたまでで、設定がほぼデフォルトなので実用性はないと思う。
次やること
ここから使えるデータ分析基盤にするまでに、今のところ思いつく必要そうなものは以下のような感じだと思う。
Hadoopクラスタの認証(調べたらKerberosというのが出てきた)
Hadoopクラスタの適切な設定(/etc/hadoop配下の設定ファイルをいじる)
Hadoopエコシステムの整備(Hive、Sparkなど)
データ収集部分の構築
データカタログ
予算と並列処理性能を考慮したインフラ設計
まだ解像度低いので今後変わっていくかもしれないが、直近でやろうと思うのは1と2。Hadoopクラスタ(HDFS、YARN、MapReduce)の設定と認証を調べつつより良くしていこうと思う。
この記事が気に入ったらサポートをしてみませんか?