LoginSignup
16
8

More than 5 years have passed since last update.

EC2にHadoop/Hive/Presto突っ込んでS3にクエリ投げるまで

Last updated at Posted at 2017-01-05

Emrでのやり方は需要があったら書くかな。
といっても説明することほとんど無いけどね。細かい設定関係をどこでどうするのかってくらいか。

というわけで、タイトル通りEC2インスタンスにprestoセットアップして、s3に置いたデータファイル(orc)にクエリ投げるまでをざざっと。なお、Hadoopは擬似分散モード、prestoはcoordinator/workerが同じノードです。

何故か

作業時、途中までrootでやってたのでそれをここに記します。途中からec2-userでやりました。

sudo su -

Hive ローカルメタストアで使用するのでmysqlをいれよう

ぽすぐれでも良いですがmysqlのほうがラクです。
mysqlは大人の事情で5.7系使いたかったのでrpmで

yum -y install http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.7/mysql-community-common-5.7.16-1.el6.x86_64.rpm
yum -y install http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.7/mysql-community-libs-5.7.16-1.el6.x86_64.rpm
yum -y install http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.7/mysql-community-libs-compat-5.7.16-1.el6.x86_64.rpm
yum -y install http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.7/mysql-community-client-5.7.16-1.el6.x86_64.rpm
yum -y install http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.7/mysql-community-server-5.7.16-1.el6.x86_64.rpm
yum -y install http://ftp.jaist.ac.jp/pub/mysql/Downloads/MySQL-5.7/mysql-community-devel-5.7.16-1.el6.x86_64.rpm

service mysqld start
chkconfig mysqld on

いらないものも入ってるしなんで1個ずつやってんねんって思いはしますが作業メモにこう書いてあったので・・・
なお、rpmのurlは意外と頻繁に変わる気がするのでバージョン固定の観点からいってもs3かどっかに置いとくほうが良いでしょうね。

初期パスワードの変更とpluginの無効化

とりあえず初期パスを獲得します。

cat /var/log/mysqld.log | grep "temporary password"

↑でroot@localhost: XXXXXXX のXXXXXXXを使ってmysqlへログイン。
開発用の環境だしvalidate_passwordは闇に葬ります。

set password for root@localhost=password('passwordPASSWORD@999');
use mysql
uninstall plugin validate_password;
update user set authentication_string=PASSWORD('新しいパスワード') where User='root';
flush privileges;
exit

JDKの入手とインストール

とりあえず1.8系ならそれで良いことにします。

Linux x64のrpmをDL。

mv DLしたパス/jdk-8u111-linux-x64.rpm /usr/local/lib
yum -y localinstall /usr/local/lib/jdk-8u111-linux-x64.rpm
java -version
rm -f /usr/local/lib/jdk-8u111-linux-x64.rpm

JAVA_HOMEの設定

ここからec2-userで作業します。別にrootのままで良い人はそのままで。
user変えたら環境変数JAVA_HOMEを設定します。

echo "export JAVA_HOME=/usr/java/jdk1.8.0_111" >> ~/.bashrc
. ~/.bashrc

SSH設定

hadoopはssh使うので、パスワード入力無しでlocalhostにssh接続可能な状態にします。
ssh-keygen時の対話は全部ノールックenterでかまいません。
ついでにフィンガープリントも追加しておきます。

ssh-keygen
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
ssh localhost
exit

Hadoopのインストールと設定

インストール

http://www.apache.org/dyn/closer.cgi/hadoop/common/
に記載されてる適当なサイトから目的のversionのhadoopのURLを入手します。
自分は2.7.3でやりました。

wget http://[[上で入手したURL]]/hadoop-2.7.3.tar.gz
sudo mv DLしたパス/hadoop-2.7.3.tar.gz /usr/local/lib
cd /usr/local/lib
sudo tar zxf hadoop-2.7.3.tar.gz
sudo rm -f hadoop-2.7.3.tar.gz
sudo ln -s hadoop-2.7.3 hadoop

# ownerをec2-userにしておく
sudo su -
cd /usr/local/lib
chown ec2-user hadoop
exit

擬似分散モードHDFS設定

なお、複数ノード用意してちゃんと分散しようとするともうちょっと設定が必要なそうです。
今回は擬似分散で。

まず環境変数HAOOP_HOME/HADOOP_CONF_DIRを設定します。

echo "export HADOOP_HOME=/usr/local/lib/hadoop" >> ~/.bashrc
echo "export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop" >> ~/.bashrc
. ~/.bashrc

HDFS格納先となるディレクトリを生成します。パスはお好みで良いかと。

mkdir -p ~/var/hdfs/{name,data}

core-site.xml/hdfs-site.xml/yarn-site.xmlを編集します。

sudo vi /usr/local/lib/hadoop/etc/hadoop/core-site.xml


<configuration>
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://localhost:9000</value>
  </property>
</configuration>

sudo vi /usr/local/lib/hadoop/etc/hadoop/hdfs-site.xml


<configuration>
  <property>
    <name>dfs.name.dir</name>
    <value>/home/ec2-user/var/hdfs/name</value>
  </property>
  <property>
    <name>dfs.data.dir</name>
    <value>/home/ec2-user/var/hdfs/data</value>
  </property>
  <property>
    <name>dfs.replication</name>
    <value>1</value>
  </property>
</configuration>

sudo vi /usr/local/lib/hadoop/etc/hadoop/yarn-site.xml
(s3アクセスのため)

<configuration>

<!-- Site specific YARN configuration properties -->
  <property>
    <name>fs.s3a.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
  </property>
  <property>
    <name>fs.s3a.access.key</name>
    <value>AWSアクセスキー</value>
  </property>
  <property>
    <name>fs.s3a.secret.key</name>
    <value>AWSシークレットアクセスキー</value>
  </property>
</configuration>

namenodeの初期化をします。
なお、namenodeはdatanodeがどういった情報を記録しているかを管理してるらしいです。

/usr/local/lib/hadoop/bin/hadoop namenode -format

最後に起動と確認をします。

/usr/local/lib/hadoop/sbin/start-dfs.sh
/usr/local/lib/hadoop/bin/hadoop fs -ls /

ファイルをまだ生成していないので、とりあえずエラーが出たりしなければ問題なし。

S3へ触るために追加設定

org.apache.hadoop.fs.s3a.S3AFileSystemを利用可能にするため、Hadoopにclasspath追加します。
なお、特にどこかから持ってこなくてもデフォルトでjarそのものはshare/hadoop/tools/lib/にもってます。

sudo vi /usr/local/lib/hadoop/etc/hadoop/hadoop-env.sh
ファイル末尾に

export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:$HADOOP_HOME/share/hadoop/tools/lib/*

アクセスできるか確認します。

/usr/local/lib/hadoop/bin/hadoop fs -ls s3a://[[bucket名]]/

fs.s3.implも試しましたが、-lsでエラーになってしまい断念。

Hiveのインストール

http://www.apache.org/dyn/closer.cgi/hive/
hadoopと同じように、上のURLから目的のversionのhiveのURLを入手します。
今回はapache-hive-2.1.1-bin.tar.gz。

wget http://[[上で入手したURL]]/apache-hive-2.1.1-bin.tar.gz
sudo mv DLしたパス/apache-hive-2.1.1-bin.tar.gz /usr/local/lib
cd /usr/local/lib
sudo tar zxf apache-hive-2.1.1-bin.tar.gz
sudo rm -f apache-hive-2.1.1-bin.tar.gz
sudo ln -s apache-hive-2.1.1-bin hive

# owner変更
sudo su -
cd /usr/local/lib
chown ec2-user hive
exit

環境変数HIVE_HOMEを設定します。

echo "export HIVE_HOME=/usr/local/lib/hive" >> ~/.bashrc
. ~/.bashrc

# インストール確認
/usr/local/lib/hive/bin/hive -H

JDBC

metastoreにmysqlを使用するため、ドライバを設置します。
http://dev.mysql.com/downloads/connector/j/
ここのTAR ArchiveのほうをDL。
今回はmysql-connector-java-5.1.40.tar.gzでした。

これを解凍してhiveで利用できるようにします。

tar zxf DLしたパス/mysql-connector-java-5.1.40.tar.gz
sudo mv mysql-connector-java-5.1.40/mysql-connector-java-5.1.40-bin.jar /usr/local/lib/hive/lib

metastore用DBとuser作成

metastoreのDBとuserを作ります。なお、char setをlatin1にしないとhiveがmetastoreデータ作る時に
ユニークインデックスの合計文字長の制約に引っかかってエラーになるようです。

mysql -uroot -p

create database hive_metastore default character set 'latin1';
use hive_metastore;
create user 'hive'@'localhost' identified by 'パスワード';
grant select, insert, update, delete, alter, create, index, references on hive_metastore.* to 'hive'@'localhost';

metastore設定

hive-site.xmlを作成します。

sudo vi /usr/local/lib/hive/conf/hive-site.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value><![CDATA[jdbc:mysql://localhost/hive_metastore?autoReconnect=true&useSSL=false]]></value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>hive</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>パスワード</value>
  </property>
  <property>
    <name>datanucleus.fixedDatastore</name>
    <value>false</value>
  </property>
  <property>
    <name>hive.exec.local.scratchdir</name>
    <value>/tmp/hive</value>
  </property>
  <property>
    <name>hive.downloaded.resources.dir</name>
    <value>/tmp/hive</value>
  </property>
  <property>
    <name>hive.querylog.location</name>
    <value>/tmp/hive</value>
  </property>
  <property>
    <name>hive.server2.enable.doAs</name>
    <value>false</value>
  </property>
</configuration>

初期化と接続確認

/usr/local/lib/hive/bin/schematool -dbType mysql -initSchema
/usr/local/lib/hive/bin/hive

ORCテーブルデータ作成

テキストデータ

接続できたらサンプルデータを作ります。
2017/01/01から03までと見立てて

10000,1,AAA
10001,2,BBB
20000,3,CCC
20001,4,DDD
30000,5,EEE
30001,6,FFF

こんな感じに3ファイル作ってs3へ配置。
その際のロケーションは
[[bucket]]/dir/2017/1/1
[[bucket]]/dir/2017/1/2
[[bucket]]/dir/2017/1/3

こんな感じで。

生データテーブル生成

ファイルを配置したらhiveデータを作ります。

/usr/local/lib/hive/bin/hive

でhive接続したら

CREATE DATABASE test_orc;

use test_orc;

CREATE EXTERNAL TABLE tmp1
(
  time BIGINT,
  id INT,
  name STRING
)
  ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
  LINES TERMINATED BY '\n'
  LOCATION 's3a://[[bucket]]/dir/2017/1/1';

CREATE EXTERNAL TABLE tmp2
(
  time BIGINT,
  id INT,
  name STRING
)
  ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
  LINES TERMINATED BY '\n'
  LOCATION 's3a://[[bucket]]/dir/2017/1/2';

CREATE EXTERNAL TABLE tmp3
(
  time BIGINT,
  id INT,
  name STRING
)
  ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
  LINES TERMINATED BY '\n'
  LOCATION 's3a://[[bucket]]/dir/2017/1/3';

色々やり方はありますがとりあえず手っ取り早く3テーブル作ってしまいます。
なお、この時点でクエリ発行すればちゃんとデータ取れます。

ORCテーブル生成とinsert

最後にORCデータテーブルを作成し、データを入れます。

CREATE EXTERNAL TABLE test
(
  time BIGINT,
  id INT,
  name STRING
)
  PARTITIONED BY (ts BIGINT)
  ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
  LINES TERMINATED BY '\n'
  STORED AS ORC
  LOCATION 's3a://[[bucket]]/orc';
  tblproperties("orc.compress"="zlib");
INSERT INTO TABLE test PARTITION (ts=10000) SELECT time,id,name FROM tmp1 ORDER BY time;
INSERT INTO TABLE test PARTITION (ts=20000) SELECT time,id,name FROM tmp1 ORDER BY time;
INSERT INTO TABLE test PARTITION (ts=30000) SELECT time,id,name FROM tmp1 ORDER BY time;

これでORC形式データテーブルが出来ます。
ORDERをつけている理由はsmall files problem対応です。

ThriftMetastore

prestoからhive metastoreを触ることになるため、hiveをメタストアモードで起動させる必要があるようです。

nohup /usr/local/lib/hive/bin/hive --service metastore &

presto-server

公式資料。上のほうにserverプログラムがtar.gz形式でリンク貼られているため例によってDLして解凍します。
今回はpresto-server-0.161.tar.gzでした。

wget http://[[上で入手したURL]]/presto-server-0.161.tar.gz
sudo mv DLしたパス/presto-server-0.161.tar.gz /usr/local/lib
cd /usr/local/lib
sudo tar zxf presto-server-0.161.tar.gz
sudo rm -f presto-server-0.161.tar.gz
sudo ln -s presto-server-0.161 presto

# owner変更
sudo su -
cd /usr/local/lib
chown ec2-user presto
exit

あとは公式に従って設定していきます。

mkdir -p ~/var/presto/data
cd /usr/local/lib/presto
mkdir etc
cd etc

vi node.properties

node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/home/ec2-user/var/presto/data

vi jvm.config
Emrを使用するとこの設定は変更できません。
Emrの場合は-Xmxはインスタンスのメモリ量の大体90%が設定されているようです。

-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:OnOutOfMemoryError=kill -9 %p

vi config.properties
パブリックDNSでも動作はするはずです。
query.max-memory-per-nodeはjvmのXmxの40%までしか設定できません。
設定するとサーバ起動時にエラー出ます。

coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8889
query.max-memory=5GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://[[coordinatorノードのプライベートDNS]]:8889
query.queue-config-file=/home/ec2-user/presto-queues.json

vi log.properties

com.facebook.presto=INFO

query.queue-config-file

クエリの最大同時実行数と最大実行待ち数を決める設定値を定義します。
https://prestodb.io/docs/current/admin/queue.html
公式資料。

{
  "queues": {
    "user.${USER}": {
      "maxConcurrent": 100,
      "maxQueued": 200
    }
  },
  "rules": [
    {
      "queues": ["user.${USER}"]
    }
  ]
}

この例でいくと、実行ユーザが誰であっても最大同時実行数は100で最大実行待ち数は200です。

Hiveカタログの生成

今回はHiveデータに触りたいのでHive用のcatalogを作ります。

mkdir catalog
cd catalog

vi hive.properties
hive.s3.use-instance-credentialsはデフォルトtrue。
IAMを設定していない場合trueだとawsのmetadataが取得できないってことでエラー出ます。
またこちらもパブリックDNSでも動作するはずです。

connector.name=hive-cdh5
hive.metastore.uri=thrift://[[hive-metastoreが起動してるサーバ/今回は同じノードなのでcoordinatorノードのプライベートDNS]]:9083
hive.config.resources=/usr/local/lib/hadoop/etc/hadoop/core-site.xml,/usr/local/lib/hadoop/etc/hadoop/hdfs-site.xml
hive.s3.use-instance-credentials=false
hive.s3.aws-access-key=AWSアクセスキー
hive.s3.aws-secret-key=AWSシークレットアクセスキー
hive.s3.endpoint=エンドポイント

presto-client

https://prestodb.io/docs/current/installation/cli.html
例によって公式資料に従ってclientをセットアップします。

wget http://[[上で入手したURL]]/presto-cli-0.161-executable.jar
sudo mv DLしたパス/presto-cli-0.161-executable.jar /usr/local/lib/presto/bin/
cd /usr/local/lib/presto/bin/
sudo mv presto-cli-0.161-executable.jar presto
chmod +x presto

起動とクエリ

あとは起動してクライアントからクエリ投げるだけです。

/usr/local/lib/presto/bin/launcher start
/usr/local/lib/presto/bin/presto --server localhost:8889 --catalog hive --schema test_orc

もし起動時にエラーが出る場合は、この設定通りにやっている場合は

/home/ec2-user/var/presto/data/var/log/server.log

にログが出ていると思います。

めちゃめちゃ長くなりましたが以上でセットアップ完了です。
workerをちゃんと立てたい場合はhadoopの分散設定をする必要がありそうなのでそれはまたいずれということで・・・

16
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
8