夏休みブログ移住計画
今日はあくまで宣言だけするよ。
そろそろお盆がきますね。
自分の会社も例にもれずお盆休みなるものがあります。
こういう長期的な休みの前になると、どこに遊びに行こうかとか、
誰とご飯食べにいこうかと考えるのもあるのですが、
その一方でなにか勉強しようかなーと考えるのも結構好きなんです。
で、普段はどちらかというとインプットよりでひたすら技術書含め本を読むことが多いのですが、
たまにはこれまでのアウトプットをやりたいなと思い、いろいろ考えた結果、このブログを移住させようと考えました。
(といってもそんなにこのブログであれこれ書いてないですけど・・・)
移住計画概要
- 概要
- WordPressにブログを移住
- 目的
- 目標
- ひとまず夏休み中(19日まで)に移住完了させたい
- 今年中にデータの基盤やら分析やらできたらいいな
- 手順
とこんな感じ。
ま、とりあえず書けば自分の重い腰もあがるやろうということで今日はあくまで宣言のみ。 明日からやってみる。
Ubuntu16にCDH6(Beta)をManagerなしでインストール
最近Clouderaの動向をウォッチしていなかったのですが、 知らぬ間にCDH6がリリースされていました。
https://www.cloudera.com/documentation/enterprise/6/release-notes/topics/rg_cdh_6_release_notes.html
※まだベータ版らしいです。
CDH6はHadoop3.0.0やSparkも2系がデフォルトで入っているようで、 新しい機能を試してみるのにサクサク入れられるディストーションとしても使えそうです。
というわけで、ひとまずデフォルトでインストールしてみました。 CDH5版インストール方法はこちらの記事から
というより前記事とほとんどインストール方法は変わりません。
ちなみにCloudera Managerを使ったのインストールはこちらから(めっちゃ簡単)
環境
Javaのインストール
ひとまず、java8を先に入れて、PATHを通しておきます。
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get -y install oracle-java8-installer cat << EOF >> ~/.bashrc JAVA_HOME=/usr/lib/jvm/java-8-oracle PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME export PATH EOF source ~/.bashrc
cdh.listファイルの作成
/etc/apt/sources.list.dの中にcdh.listというファイルを作成
cd /etc/apt/sources.list.d sudo touch cdh.list ## vimやEmacsなどでcdh.listの中に以下のコマンドを入力 deb [arch=amd64] https://archive.cloudera.com/cdh6/6.0.0-beta1/ubuntu1604/apt xenial-cdh6.0.0-beta1 contrib deb-src https://archive.cloudera.com/cdh6/6.0.0-beta1/ubuntu1604/apt xenial-cdh6.0.0-beta1 contrib
Hadoopのリポジトリ登録
sudo wget https://archive.cloudera.com/cdh6/6.0.0-beta1/ubuntu1604/apt/archive.key sudo apt-key add archive.key
Hadoopインストール&起動
あとは素直にHadoopを入れて動かすだけ。
sudo apt update sudo apt-get install -y hadoop-conf-pseudo sudo -u hdfs hdfs namenode -format sudo systemctl start hadoop-hdfs-namenode hadoop-hdfs-datanode hadoop-hdfs-secondarynamenode sudo /usr/lib/hadoop/libexec/init-hdfs.sh sudo systemctl restart hadoop-hdfs-namenode hadoop-hdfs-datanode hadoop-hdfs-secondarynamenode sudo systemctl start hadoop-yarn-resourcemanager hadoop-yarn-nodemanager
結論
やっぱりCloudera ManagerとCloudera Directorは正義。
なるべくお金をかけずにお手軽運用でサーバを扱う(検証、テスト用)
なるべくお金をかけずにお手軽運用でサーバを扱う(検証、テスト用)1,2年前にまとめていたけど、
下書きで残しっぱなしだったので、今更載せておきます。
前ふり
AWS等クラウドでサーバを立てる時に気になるお金。
なるべく課金を減らすために必要なときだけ立てて、
いらなければ落とすなんてことをしますよね。
でも落とした後に起動するとやっかいなのがIPアドレスの変更。
毎回毎回アドレスが変わってしまうとssh config等の設定を変えないといけなかったりして面倒なんですよね。
かといってElasticなIPを使うとそれでもお金がかかってしまうので嫌だ。。。
というわけで、なるべくお金をかけずにかつ設定をなるべく変えないでサーバを扱う方法を自分なりに試行錯誤してみたやつです。
※今回の例はあくまで検証や遊びでサーバを立てて使う人用の方法です。本番システムでの利用は推奨しません。
やること
- VPCを作成
- パブリックサブネットとプライベートサブネットを立てる
- インターネットからパブリックサブネットにアクセスさせる設定
- パブリックサブネットに踏み台サーバを立てる
- プライベートサブネットに検証サーバを立てる
- ssh configで踏み台経由でサーバにアクセスする設定を行う
- ssh <設定名>でいつでもアクセスできる やっていることのほとんどはAWSEC2のデザインパターンとかでよくみるやつです。
VPCの作成
まずは、VPCを作成します。
AWSのユーザーコンソールからVPCに移動
設定項目 | 設定値 |
---|---|
名前タグ | 適当な名前で |
IPv4 CIDRブロック | なんでもいいけどVPCにいっぱいサーバを立てるなら10.0.0.0/16が順当かと |
IPv6 CIDRブロック | ブロックはなしで |
テナンシー | デフォルトでOK |
パブリックサブネットとプライベートサブネットを立てる
続いてサブネットを作ります。
ユーザーコンソールからVPC -> サブネットに移動。
サブネットではインターネット経由でアクセスできるパブリックサブネットとプライベートサブネットを設定します。
- パブリックサブネット側
設定項目 | 設定値 |
---|---|
名前タグ | 適当な名前で |
VPC | さっき作成したVPC名を指定 |
アベイラビリティーゾーン | 今回は特に指定なしでOK |
IPv4 CIDRブロック | VPCで設定したブロック内で範囲を指定。今回は10.0.1.0/24としておく。 |
- プライベートサブネット側
設定項目 | 設定値 |
---|---|
名前タグ | 適当な名前で |
VPC | さっき作成したVPC名を指定 |
アベイラビリティーゾーン | 今回は特に指定なしでOK |
IPv4 CIDRブロック | VPCで設定したブロック内で範囲を指定。今回は10.0.2.0/24としておく。 |
インターネットからパブリックサブネットにアクセスさせる設定
ここは大事なところ。
2つサブネットを作成した後に、パブリックサブネットのみ選択して、サブネットのアクション-> 自動割り当てIPの設定変更 に飛ぶ
そこで、 パブリックIPv4アドレスの自動割り当てを有効にする にチェック。
これをやっとかないと踏み台サーバ立てても外部からサーバにアクセスするための外部IPを発行してくれません。
次にやるのはインターネットとパブリックサブネットをつなぐゲートウェイ(窓口みたいなもの)の設定
- VPC -> インターネットゲートウェイに移動
- インターネットゲートウェイの作成を押して文字通り作成(名前は適当に)
- さっき作ったゲートウェイを選択して、 アクション->VPCのアタッチを選択
- VPCでさっき作ったVPCを選択してアタッチ
- VPC -> ルートテーブルに移動
- 作ったVPCに紐づくルートテーブルを選択。
- 下部にあるルートタブを選択して編集。
- 別のルートを追加を選択。以下のように設定
送信先 | ターゲット |
---|---|
0.0.0.0/0 | さっき作ったゲートウェイの名前 |
これでできました。
パブリックサブネットに踏み台サーバを立てる
ここから踏み台サーバを立てます。
サーバの立て方は基本的な方法と同じなので割愛。
一般的な立て方と違うのは以下の点。
- インスタンスのタイプはt2.nano(踏み台用途なので and 24時間稼働を想定してなるべくお金がかからないように)
- インスタンスの詳細の設定にて
- ネットワーク -> 作ったVPCの名前
- サブネット -> パブリックサブネットの名前
プライベートサブネットに検証サーバを立てる
今度はプライベート側に実際に使用するサーバを立てます。
こちらも基本的な立て方は同じ。
変更点は以下の点
- インスタンスの詳細の設定にて
- ネットワーク -> 作ったVPCの名前
- サブネット -> プライベートサブネットの名前
- セキュリティグループは基本的に全開放でも問題ないが、気にされる方は必要なポートをパブリックサブネットのIPに指定するとよし。
ssh configで踏み台経由でサーバにアクセスする設定を行う
サーバが立てられたので、sshでつなぐ設定をします。 今回はmacを想定し、macの.ssh/configに設定をします。
# ~/.ssh/config Host humidai HostName <踏み台サーバのパブリックIP> User ubuntu #サーバによって変化 Port 22 #sshポート GatewayPorts yes IdentityFile ローカルマシン内で踏み台サーバの公開鍵が置いてある場所 Host server HostName <10.0.2.xxとなるIP> User ec2-user #サーバによって変化 Port 22 GatewayPorts yes ProxyCommand ssh -CW %h:%p humidai #humidaiは上記設定したHostの名前を指定 IdentityFile ローカルマシン内で検証サーバの公開鍵が置いてある場所 # ProxtCommandが踏み台サーバ経由でsshサクセスさせるためのコマンド
この設定をした後、
ssh server
とコマンドを入力すると、踏み台経由でアクセスできます。
しかも、検証サーバを一旦落として再度あげてもプライベートIPは変わらないので、そのままsshコマンドで入れます。
また、ポートフォワーディングしたい場合は、
# ~/.ssh/config #踏み台側 LocalForward 5432 localhost:5432 LocalForward 8080 localhost:8080 #サーバ側 LocalForward 5432 <サーバのプライベートIP>:5432 LocalForward 8080 <サーバーのプライベートIP>:8080
と設定すればOK
懸念事項
1 この構成にすると、サーバ側からインターネットにつなぐことができないので、wgetとかでファイルを落としたりすることはできません。
これについては別途NATインスタンスとかNATゲートウェイが必要になるのですが、いずれにしてもお金がかかる。。。。
なので、しょっちゅうインターネットにアクセスしないのであれば、ローカルマシンに対象ファイルを落としてscpコマンドで移動がよいかなと。
実際scpコマンドで移動させる場合でも
scp <移動させるファイル> server:/home/ec2-user
みたいな感じで簡単に移動できます。
2 この構成は踏み台サーバは常時稼働を想定しています。踏み台サーバはt2.nanoの最小構成なので、
$0.0058 /1 時間 -> 500円くらい/1ヶ月
が必要経費になります。
ただ、毎回毎回IPアドレスを変える手間とか、めんどくさくてサーバをずっと起動させることによる課金等を考えると決して高い値段ではないかなと。
終わりに
今回は最近良くやるAWSでの検証サーバ構築用のシステムを紹介しました。
上述したように、この構成は本番構成でもやるような部分も含まれていますので、特にAWS初心者の方はぜひチャレンジしてみるといいかもしれません。
ホントの最後に
間違いとか、わからないとこがあればコメントとかしていただければ!!
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その6)
第7問(ABC 085 B - Kagami Mochi)の類題を解いていきます。
#include <iostream> #include <algorithm> #include <string> #include <set> using namespace std; int main() { string str; int length,i; set<char> alphabets; cin >> str; length = str.length(); for(i = 0; i<length; i++){ alphabets.insert(str[i]); } set<char>::iterator it; for(i = 'a';i <= 'z'; i++) { it = alphabets.find(i); if(it == alphabets.end()){ cout << (char)i << endl; return 0; } } cout << "None" << endl; return 0; }
- 各都市(数値で表される)を配列のキーとして用意しておき、2行目以降、その数値が出るたびにキーの値をインクリメントさせる
- 今思えばmap使わなくても普通の配列でできたかなと思うけど、、、まあいいか。
#include <iostream> #include <algorithm> #include <string> #include <map> using namespace std; int main() { int number_of_cities,number_of_roads,i,j,k; map<int,int> road_to_city; cin >> number_of_cities >> number_of_roads; for(i = 0 ; i< number_of_cities; i++) { road_to_city[i] = 0; } for(i = 0; i < number_of_roads;i++) { cin >> j >> k; road_to_city[j-1]++; road_to_city[k-1]++; } for(i = 0; i<number_of_cities;i++){ cout << road_to_city[i] << endl; } return 0; }
ABC 047 B - Snuke's Coloring 2 (ABC Edit)
- 一旦xとy座標を変数にした後、4象限(x軸の上側、下側、y軸の上側、下側)で隠される面積を割り出して、引き算する。
- 多分もっといい解法があるんだろうとは思うけど、今の実力ではこれがいっぱいいっぱいでした。
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int x,y,i,j,k,l,number_of_coloring; int left_coloring_x = 0; int right_coloring_x = 0; int upper_coloring_y = 0; int lower_coloring_y = 0; cin >> x >> y >> number_of_coloring; for(i = 0; i < number_of_coloring;i++){ cin >> j >> k >> l; switch(l){ case 1: if(left_coloring_x < j){ left_coloring_x = j; } break; case 2: if(right_coloring_x < abs(x - j)){ right_coloring_x = abs(x - j); } break; case 3: if(lower_coloring_y < k){ lower_coloring_y = k; } break; case 4: if(upper_coloring_y < abs(y - k)){ upper_coloring_y = abs(y - k); } break; } } x = x - left_coloring_x - right_coloring_x; y = y - lower_coloring_y - upper_coloring_y; if(x <= 0 || y <= 0) { cout << 0 << endl; } else { cout << x * y << endl; } return 0; }
ABC 091 B Two Colors Card Game
- mapを用意
- 青いカードのときは文字列を見るたびににその文字をキーとして数値をインクリメント
- 赤いカードのときはその逆でその文字キーで数値をデクリメント
- あとはmapを上からキーを走査して、もっとも大きい数値を出力する
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int i,number_of_bluecard,number_of_redcard; map<string,int> strs; string str; int max_yen = 0; cin >> number_of_bluecard; for(i = 0; i< number_of_bluecard; i++){ cin >> str; if(strs.find(str) == strs.end()){ strs[str] = 1; } else { strs[str]++; } } cin >> number_of_redcard; for(i = 0;i<number_of_redcard; i++){ cin >> str; if(strs.find(str) != strs.end() && strs[str] != 0 ){ strs[str]--; } } for(auto itr = strs.begin(); itr != strs.end(); itr++){ if(max_yen < itr->second) { max_yen = itr->second; } } cout << max_yen << endl; return 0; }
- 入力される数値をキーとして、各数値の出現回数をカウント
- 出現回数が多い順にキーをソート
- 規定されている数値の種類までカウントし、超えた場合は各キーに紐づく値を足し算していく
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int i,ball,balls,num_ball_type; int ball_type[210000] = {0}; int counter = 0; int number_of_changed_type = 0; cin >> balls >> num_ball_type; for(i = 0; i < balls; i++){ cin >> ball; ball_type[ball]++; } sort(ball_type,ball_type+210000,greater<int>()); for(i = 0; i < 210000; i++){ if(ball_type[i] == 0){ break; } if(counter >= num_ball_type) { number_of_changed_type += ball_type[i]; } else { counter++; } } cout << number_of_changed_type << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その5)
最近サボってた。 ABC 083 B - Some Sumsの類題を解く。
ABC 080 B - Harshad Number + 与えられた数値を10で割っていきながら各位の値を足し算していく。 + その後、足し算した値で割り切れるかどうかを判定。
#include <iostream> using namespace std; int main() { int N,i,sum; cin >> N; i = N; while(i > 0){ sum += i % 10; i /= 10; } if(N % sum == 0){ cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; }
ABC 090 B - Palindromic Numbers
- 与えられた数値の範囲内でループを回す
- ループごとに各位の値を分解して配列にわたす
- 一の位と一万の位、ならびに十の位と千の位の値が同じかどうか判定する
#include <iostream> using namespace std; int main() { int i,j,k,first,last,digits[10]; int counter = 0; cin >> first >> last; for(i = first; i <= last; i++){ j = i; k = 0; while(j > 0) { digits[k] = j % 10; cout << digits[k] << endl; j /= 10; k++; } if(digits[0] == digits[4] && digits[1] == digits[3]){ counter++; } } cout << counter << endl; return 0; }
続いて第6問(ABC 088 B - Card Game for Two )の類題。
- とりあえずソートさせて終わり。
- もうちょっとだけ補足すると、数値を大きい順番に並べ替えて順番に足し算していきます。
#include <iostream> #include <algorithm> using namespace std; int main() { int i,N,rods; int rod[60]; int maxlength = 0; int length = 0; cin >> N >> rods; for(i = 0; i < N; i++){ cin >> rod[i]; } sort(rod,rod+N,greater<int>()); for(i = 0; i < rods;i++){ length += rod[i]; } if(maxlength <= length) { maxlength = length; } cout << maxlength << endl; return 0; }
ABC 064 B - Traveling AtCoDeer Problem
- 最初は問題文を読んで??となったのですが、要するに与えられた値から最小と最大の値を抜き出してその差をとることだとわかってからはそこまで苦労しなかった。
- ソートしたほうが早かったかも。
#include <iostream> #include <algorithm> using namespace std; int main() { int i,N,coodinates[1100]; int maxcoodinate = 0; int mincoodinate = 0; cin >> N; for(i = 0; i < N; i++) { cin >> coodinates[i]; } mincoodinate = coodinates[0]; maxcoodinate = coodinates[0]; for(i = 1; i < N; i++) { if(coodinates[i] <= mincoodinate) { mincoodinate = coodinates[i]; } if(coodinates[i] >= maxcoodinate) { maxcoodinate = coodinates[i]; } } cout << maxcoodinate - mincoodinate << endl; return 0; }
ABC 042 B - Iroha Loves Strings
- 文字列のソート処理
- ソートさせたあと、順番に文字列連結させてます。
#include <iostream> #include <algorithm> #include <string> using namespace std; int main() { int i,N,L; cin >> N >> L; string str[110]; string concat = ""; for(i = 0; i < N ; i++) { cin >> str[i]; } sort(str,str+N); for(i = 0; i < N; i++) { concat += str[i]; } cout << concat << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その4)
続き。ABC 087 B - Coinsの類題です。
- 複数あ座標を線分で結んだ時にその線分の距離が最大になる距離を求める
- 距離の公式を使う。
- かつ全ての線分を探索するため2重forループを使用。
#include <iostream> #include <cmath> using namespace std; int main() { int N,x[110],y[110],i,j,k; double maxdistance = 0; double xd,yd,distance; cin >> N; for(i = 0; i < N; i++) { cin >> x[i] >> y[i]; } for(j = 0;j < N;j++) { for(k = j; k < N; k++) { xd = pow(x[j] - x[k],2.0); yd = pow(y[j] - y[k],2.0); distance = sqrt(xd + yd); if(maxdistance <= distance) { maxdistance = distance; } } } cout << maxdistance << endl; return 0; }
- 指定された文字列が全て異なる文字で形成されているかどうかを判別
- 制約上全探索しても問題ないので単純にforループを回して同じ文字があるかどうかを判定
#include <iostream> #include <string> using namespace std; int main() { int i,j; string str; cin >> str; for(i = 0; i<str.length(); i++){ for(j = i + 1; j < str.length(); j++){ if(str[i] == str[j]){ cout << "no" << endl; return 0; } } } cout << "yes" << endl; return 0; }
ABC 051 B - Sum of Three Integers
- ある数値の範囲内におさまるx,y,zがある
- x + y + z = Sとなるx,y,zの組み合わせの数を算出する
- x,y,zを全てループで回してもよいが、時間的制約も気になるので、以下のようにプログラムを組んでみた
- x,yの値はforループ
- zの値はSからxとyを引いた値とする
- このzが決められた数値の範囲内でかつ0以上かどうかを判定
#include <iostream> using namespace std; int main() { int k,s,x,y,z; int counter = 0; cin >> k >> s; for(x = 0; x <= k;x++) { for(y = 0;y <= k; y++){ z = s - x - y; if(z >= 0 && z <= k) { counter++; } } } cout << counter << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その3)
前回の続き。
ABC 081 B - Shift Onlyの類題を解きます。
ABC 068 B - Break Number
- 指定された数値を1ずつループで処理しながら2で割り切れる数をもとめる。
- max値とmaxカウンターを用意しておいて、そのカウンター以上割り切れる回数が多い数がでてきたら更新する。
#include <iostream> using namespace std; int main() { int i,j,input,counter; int max = 0; int maxcounter = 0; cin >> input; for(i = 1;i <= input; i++) { j = i; counter = 0; while(j > 1) { if(j % 2 == 0) { j /= 2; counter++; }else { break; } } if(counter >= maxcounter) { max = i; maxcounter = counter; } } cout << max << endl; return 0; }
ABC 073 B - Theater
- 団体客毎にループで処理
- 各ループ毎の人数を足し算していって、結果を出力
#include <iostream> using namespace std; int main() { int i,j,first,last,groups,counter,num_people; cin >> groups; for(i = 1; i <= groups; i++) { cin >> first >> last; counter += last - first + 1; } cout << counter << endl; return 0; }
ABC 072 B - OddString
- 入力された中から奇数番の文字のみ取得
- C++だとStringを配列としてもてるので、配列の番号で偶数番(配列は0からはじまるので)を文字列結合させる
#include <iostream> #include <string> using namespace std; int main() { string input; string output = ""; int i; cin >> input; for(i = 0; i < input.length(); i+=2) { output += input[i]; } cout << output << endl; return 0; }
ABC 053 B - A to Z String
- 文字列の中からAを見つけて、そこからZまでの長さの最大値をもとめる
- 何も考えずにAを見つけたら文字列の最後まで調べてZを見つけるなんてことをやったら時間オーバーになった
- よく考えれば最初にAを見つけたらその後にAがきたとしてもそれが最大の長さになるわけじゃないので、見つけ次第Zまでの長さを求めた後、break文を挟んだら通った。
#include <iostream> #include <string> using namespace std; int main() { string input; int i,j; int stringlength = 0; cin >> input; for(i = 0; i < input.length(); i++) { if(input[i] == 'A'){ for(j = i; j < input.length(); j++) { if(input[j] == 'Z') { stringlength = j - i + 1; } } break; } } cout << stringlength << endl; return 0; }