2ファイル間で重複する / しない 行を出力する方法
こちらの操作をするときに、セットで、ファイル内の改行を置換するコマンドを調べることがあるので、
メモ程度に残しておく。
$ cat hogehoge.text 1 2 3 4 5
上記のファイルを1,2,3,4,5
と出力したい場合のコマンド
cat hogehoge.text | sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g'
2ファイル間で重複する / しない 行を出力する方法
こちらの操作をするときに、セットで、ファイル内の改行を置換するコマンドを調べることがあるので、
メモ程度に残しておく。
$ cat hogehoge.text 1 2 3 4 5
上記のファイルを1,2,3,4,5
と出力したい場合のコマンド
cat hogehoge.text | sed -e :loop -e 'N; $!b loop' -e 's/\n/ /g'
タイトルの通り、何気に結構使う処理だけど都度調べているからメモとして残す。
a.text と b.textが以下の内容の時、1と 2,3,4,5を出力したい場合
$ cat a.text 1 2 3 4 5 $ cat b.text 2 3 4 5
$ sort {a,b}.text | uniq -u
# ユニークな行を出力
$ sort {a,b}.text | uniq -d
# 重複行を出力
Ansibleでmacの環境構築する際、id:t-wada さんの上記の記事を参考したのですが、 Ansible Best Practicesに沿っていなかったので、書き直してみました。
こちらは、t_wadaさんの記事のままです。
sudo xcodebuild -license xcode-select --install ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" brew doctor brew update brew install python brew install ansible
hoshinaoshi/macbook-provisioning
本家とforkしたリポジトリを比較しながら、修正した点を挙げていきます。 階層構造も修正しています。
【本家】
. ├── LICENSE ├── README.md ├── hosts ├── localhost.yml
【修正後】
. ├── LICENSE ├── README.md ├── ansible.cfg ├── group_vars ├── hosts ├── localhost.yml ├── roles │ ├── homebrew │ │ ├── defaults │ │ ├── files │ │ ├── handlers │ │ ├── meta │ │ ├── tasks │ │ │ └── main.yml │ │ ├── templates │ │ └── vars │ │ └── main.yml │ ├── homebrew-cask │ │ ├── defaults │ │ ├── files │ │ ├── handlers │ │ ├── meta │ │ ├── tasks │ │ │ └── main.yml │ │ ├── templates │ │ └── vars │ │ └── main.yml │ ├── oh-my-zsh │ │ ├── defaults │ │ ├── files │ │ ├── handlers │ │ ├── meta │ │ ├── tasks │ │ │ └── main.yml │ │ ├── templates │ │ └── vars │ └── ricty │ ├── defaults │ ├── files │ ├── handlers │ │ └── main.yml │ ├── meta │ ├── tasks │ │ └── main.yml │ ├── templates │ └── vars └── site.yml
ベストプラクティスではsite.ymlをmaster playbookとします。 また、プロビジョニング対象の役割(production, stagingなど)ごとに実行するroleをまとめたplaybookも作ります。 今回はlocalhost.ymlのみですね。*2
これらのファイルはroleをincludeするだけに留め、ここに細かいタスクを書いていくことはしません。(後述)
元々のlocalhost.ymlのタスクは大きく4つの処理をしています。
今回はローカル環境のみが対象ですが、複数のプロビジョニング対象があった場合に、個別に差し込めるようにするため、 これらのタスクをrolesディレクトリ配下にそれぞれの役割ごとに分割します。 directory-layout
loclhost.ymlにhomebrew_taps, homebrew_packages, homebrew_cask_packagesの3つが定義されていましたが、 これらはhomebrewとcaskで使用するので、
./roles/homebrew/vars/main.yml
.roles/homebrew-cask/vars/main.yml
に記述します。
./roles/hogehoge/vars/main.yml
に変数を記述すると
./roles/hogehoge/tasks/main.yml
の実行時に自動で変数を読み込み、タスク内で使用することができます。
localhost.ymlに記述されているhandlerは、よく見るとRicty用の処理であるため、Rictyロールのhandlerとして定義します。 こちらは、varsと同様にhandlerも同role内のhandlerディレクトリに記述していれば、notifyをした際に呼び出されます。
- name: run fc-cache shell: fc-cache -vf
これらのファイルはロールをインクルードするだけに留め、ここに細かいタスクを書いていくことはしません。(後述)
ここまでの書き換えで、各ロールにvars, tasks, handlerを分けることができたので、 localhost.ymlではロールをインクルードするだけにします。
--- - name: Setup my MacBook hosts: localhost connection: local gather_facts: no roles: - { role: homebrew, tags: [ homebrew ] } - { role: homebrew-cask, tags: [ homebrew-cask ] } - { role: oh-my-zsh, tags: [ oh-my-zsh ] } - { role: ricty, tags: [ ricty ] }
だいぶスッキリしましたね。
また、tagを切っておくと、指定したタグだけ実行 / 指定したタグをスキップなどができるので、追加しておきます。
ansible-playbook site.yml --tags "homebrew,ricty"
ansible-playbook site.yml --skip-tags "oh-my-zsh"
HOMEBREW_CASK_OPTS="--appdir=/Applications" ansible-playbook -i hosts -vv localhost.yml
実行時にhostsの設定をしたり、HOMEBREW_CASK_OPTSを設定したりするのはめんどくさいので、
ansible.cfgを作成し、デフォルトの動作を設定をします。
[defaults] hostfile = ./hosts
環境変数については、homebrew-caskのタスクの一部として実行するようにします。
- name: HOMEBREW_CASK_OPTS設定 shell: export HOMEBREW_CASK_OPTS="--appdir=/Applications" ...後続の処理がずらずら〜
ここまでの設定で、実行時のコマンドが
HOMEBREW_CASK_OPTS="--appdir=/Applications" ansible-playbook -i hosts -vv localhost.yml
↓
ansible-playbook -vv site.yml
となりました。
シンプル!
以上でAnsible ベストプラクティスを適用した、Mac の開発環境構築を自動化する (2015 年初旬編)です。
"mac ansible"などで検索すると、localhost.ymlにtasksがばーーーーーっと書かれたplaybookをよく目にする印象があります。
複数のプロビジョニング対象が存在する場合は、ベストプラクティスが有効だと思いますが、 構築する対象がローカル環境のみで、処理(や、ロール)が少ないのであれば、1ファイルにゴリゴリ書いても良いのではないかと感じました。
ただ、実際は、開発スタートをするまでにrbenvの設定をしたり、ミドルウェアの設定をしたりなんだりすると、localhost.ymlが肥大化してしまうのではないかと考えられるため、早め早めにロールだけでも分けて記述するのが落とし所かと思います。
こちらにコードを置いておきます。
https://github.com/hoshinaoshi/macbook-provisioning
今回Ansibleを初めて触ってみたのですが、ymlで書くのが地味に楽でした。
Ansibleの処理も「Ansible {{やりたいコマンド}}」で検索 => 1つ目の記事ではい理解〜というような感じでした。
自分は、初めての技術に触れるときは、初心者用の書籍を購入して、一読するのですが、Ansibleにおいては下記の書籍を買いました。
Rubyを初めて触ったときに、(当時の自分が触っていた)C#とJAVAではコロンが使われておらず、 これはどのような意味なのかがよく話からたかったので、まとめてみました。
:symbol "symbol"
こちらの違いについてまとめます。
Rubyにおけるコロンは、シンボルといいます。
:symbol
一見文字列と同種に見えるが、内部的には数値として扱われます。
そのため、比較や検索などの速度面が文字列と比べると高速になります。
などについては、はシンボルを使用したほうが良いでしょう。
リファレンスを引用します。
Rubyの内部実装では、メソッド名や変数名、定数名、クラス名など の'名前'を整数で管理しています。これは名前を直接文字列として処理するよりも 速度面で有利だからです。そしてその整数をRubyのコード上で表現したものがシンボルです。 シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。 名前を管理するという役割上、シンボルと文字列は一対一に対応します。 また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。
文字列と見せかけて、内部の実装では整数として扱っている。といったところでしょうか。
つまり、メソッド名や変数名、定数名、クラス名を定義した瞬間にシンボルができるという意味です。 実際にやってみましょう。
class SymbolTest end symbol_var = 0 SYMLBOL_CONSTANT = 0 def symbol_method end p Symbol.all_symbols.include?(:SymbolTest) => true p Symbol.all_symbols.include?(:symbol_method) => true p Symbol.all_symbols.include?(:symbol_var) => true p Symbol.all_symbols.include?(:SYMLBOL_CONSTANT) => true
見事に全てtrueを返しましたね。
文字列と数値なので、そりゃ高速になるだろうと反射的に思いましたが、こちらも検証してみます。
benchmark
というモジュールを使用して計測してみます。
実際のやり方はこちらを参考にしました。
Ruby でベンチマークを取る方法 - Qiita
require 'benchmark' Benchmark.bm 10 do |r| str = "0123456789" str_hash = { "0123456789" => 1 } r.report "String" do 9999999.times { str_hash[str] } end sym = :"0123456789" sym_hash = { "0123456789" => 1 } r.report "Symbol" do 9999999.times { sym_hash[sym] } end end user system total real String 1.190000 0.000000 1.190000 ( 1.190577) Symbol 0.810000 0.000000 0.810000 ( 0.815450)
文字列に比べて、シンボルは30%前後早くなっていますね。 すごいぞシンボル。
同じ名前のシンボルであれば、いくつ生成してもオブジェクトIDが1つという意味ですかね。
hoge1 = "hoge" hoge2 = "hoge" puts hoge1.equal?(hoge2) => false puts hoge1.object_id => 70281989413340 puts hoge2.object_id => 70281989361520 sym1 = :hoge sym2 = :hoge puts sym1.equal?(sym2) => true puts sym1.object_id => 539048 puts sym2.object_id => 539048
こちらもリファレンス通りですね。
冒頭でも書きましたが、Rubyにおけるコロンは、"シンボル"と呼びます。 一見文字列と同じように見えますが、内部的には整数と同様に扱われます。 そのため
また、クラス、メソッド、変数、定数を定義すると、その名前のシンボルも生成されます。
文字列とシンボルの使い分けとしては、
などは、文字列ではなく、シンボルを使用したほうが良いでしょう。
こちらの本はRubyについて、今でもリファレンス的に使用している本なので、オススメします。
※今回のシンボルについては、ここまで詳細には書かれていませんが、全範囲を網羅的に書かれています。
homebrewでinstallしたTLS 1.2 接続できるcurlがbrew installでTLS1.2接続しなければならないパッケージのinstall時に、OSX標準のcurlを見に行ってしまい、うまくinstallできなかったので、その対処方法を書きます。
具体的には、brew cask install sourcetree
をした際に、curl https://downloads.atlassian.com/software/sourcetree/SourceTree_2.3.2.zip
を叩くのですが、
そこでssl handshake failed
となり失敗していました。
確認に使用したコマンドなども含めつつ説明していきます。
まずは、curlでTLS1.2で接続していないことを確認します。
$ curl --dump-header - https://www.example.com --tlsv1.2 --verbose * Trying nnn.nnn.nnn.nnn... * Connected to www.example.com (nnn.nnn.nnn.nnn) port 443 (#0) * SSL peer handshake failed, the server most likely requires a client certificate to connect * Closing connection 0 curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect
次に、最新のOpenSSLでTLS1.2が使用できることを確認します。
$ openssl s_client -connect www.example.com:443 -tls1_2 CONNECTED(00000003) ...
既存のcurlにOpenSSLが使われていないことを確認します。
$ which curl /usr/bin/curl $ curl --version curl 7.43.0 (x86_64-apple-darwin14.0) libcurl/7.43.0 SecureTransport zlib/1.2.5 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: AsynchDNS IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz UnixSockets
上記の通りOpenSSLが含まれていません。
homebrewで改めてcurlをinstallします。
$ brew install --with-openssl curl $ brew link curl --force
OpenSSLが使用できているか確認します。
$ which curl /usr/local/bin/curl $ curl --version curl 7.51.0 (x86_64-apple-darwin14.5.0) libcurl/7.51.0 **OpenSSL/1.0.2j** zlib/1.2.5 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets
OpenSSL/1.0.2jが適用されていることが確認できました。
念のために、TLS1.2で接続できるかも確認してみます。
$ curl --dump-header - https://www.google.com --tlsv1.2 --verbose * Rebuilt URL to: https://www.google.com/ * Trying 216.58.200.196... * TCP_NODELAY set * Connected to www.google.com (216.58.200.196) port 443 (#0) ... ... * Curl_http_done: called premature == 0 * Connection #0 to host www.google.com left intact
問題なくTLS1.2接続できていますね。
この時点で、brew cask install sourcetree
を実行してもssl handshake failed
になります。
前回の記事同様パスの影響を受けているのではないかと考えましたので、
brew cask install
で見ているcurlをシンボリックリンクで無理やりbrew installしたcurlを参照させます。
$ sudo mv /usr/bin/curl /usr/bin/curl_back $ sudo ln -s /usr/local/bin/curl /usr/bin/curl $ brew cask install sourcetree ==> Caveats Cask sourcetree installs files under "/usr/local". The presence of such files can cause warnings when running "brew doctor", which is considered to be a bug in Homebrew-Cask. ==> Downloading https://downloads.atlassian.com/software/sourcetree/SourceTree_2.3.2.zip Already downloaded: /Users/user_name/Library/Caches/Homebrew/Cask/sourcetree--2.3.2.zip ==> Verifying checksum for Cask sourcetree ==> Moving App 'SourceTree.app' to '/Applications/SourceTree.app' ==> Symlinking Binary 'stree' to '/usr/local/bin/stree' 🍺 sourcetree was successfully installed!
うまくいきました。 シンボリックリンクで無理やり変更しているので、ワークアラウンド感がハンパないですね。 うまいやり方があれば是非教えていただきたいです。
OSX標準のOpenSSLが古く、tls1.2で通信できず、curlが失敗する事案が発生してしまいました。 対処方法を調べても、
`brew update brew upgrade openssl brew link openssl --force
で治りました^^
という記事が多かったのですが、上記の対応でもopenssl version
が古いままだったので、その対処方法を書きます。
手順は下記の通りです。
この記事にたどり着いた人は、既に実行済みかつ、5,000万回は同じことを見ていると思いますが、 念のため記載しておきます。
$ which openssl #opensslのパスを確認 /usr/bin/openssl となってるはず $ openssl version #バージョンの確認 $ brew update #brewのアップデート $ brew list #opensslがインストールされているか確認 $ brew info openssl #最新版の情報取得 $ brew upgrade openssl #アップグレード $ brew link openssl
だいたいの記事では、これで治りました報告が多かったのですが、自分の場合は、
この時点でopenssl version
をやっても古いままでした。
今一度、パスを確認してみると
$ openssl version OpenSSL 0.9.8zg 14 July 2015 $ which openssl /usr/bin/openssl $ brew info openssl openssl: stable 1.0.2j (bottled) [keg-only] ずらずら〜〜 /usr/local/Cellar/openssl/1.0.2j (1,695 files, 12M)
OSX 標準のOpenSSLのパスが/usr/bin/opensslだったのに対して homebrewでinstallしたOpenSSLが/usr/local/Cellar/openssl/1.0.2jなのが分かります。
これまでの結果から、読み込まれる順番が問題なのではないか?と推測し、 $PATHの設定を疑いました。
$ echo "export PATH=/usr/local/Cellar/openssl/1.0.2j/bin:$PATH" >> ~/.bash_profile $ source ~/.bash_profile $ which openssl /usr/local/Cellar/openssl/1.0.2j/bin/openssl $ openssl version OpenSSL 1.0.2j 26 Sep 2016
予想通りでした。
brew link openssl
だけでは正常に反映されておらず、基本的なパスなどの確認を怠っていたがために小一時間ハマってしまいました。
以前からクラウド破産クラウド破産と耳に入ってはいたが、個人で利用しているAWSアカウントはほぼノーガードでした。
また、ピクスタの来期AWS予算を策定していく中で、こんな金額がいきなり身に降りかかってきたら生命保険に入ることを考えてしまうだろうと思ったため、
個人のアカウントも最低限セキュリティ対策をすることにしました。
ここまで箇条書きにしてみたものの、クラスメソッドさんの記事を参考にしました。
個人で使用する分には、IAMグループでAdministratorAccessを設定するのは、やむなしかと思ったのですが、 組織で使用する場合には、適切にグループの権限設定をした方が吉だと思いました。
アカウント全般もさることながら、EC2インスタンスもAmazonLinuxのAMIをまんま使用していたので、
稼働中のインスタンスに対してもセキュリティ向上のために下記を参考に諸々実施しました。
大きくは、
がセキュリティ上、有用ってところでしょうか。
特に自分の場合は、個人で開発を進めているとアクセスキーとシークレットキーを誤ってcommitしてしまう事案が多発しているので、
git-secretsは入れておくべきだと感じました。
実際にやってみて感じたのは、項目は多少多いものの、設定自体は簡単でした。 今更ながらですが、デフォルト設定のままだと不正利用された時に何も言えなくなるので、最初に締めべきとこは締めた方が良いと思います。
前回までの記事で
と、Webサービスのデータ解析をする上で必要なデータソースから取り込む手順を書きました。
今回は、それを定期的に実行する設定の手順を書きます。
また、Re:dashはクエリで取得するデータはページにアクセスする度に取得するわけではなく、内部に保存することで高速に情報を取得するようになっています。
取得するのに時間がかかるクエリは、深夜に実行しておくのが賢い使い方かもしれません。
以上で定期実行の設定は終わりです。
GoogleスプレッドシートとRe:dashの設定は、多少互いの実行時間を気にする必要はありますが、
ここまでできれば、自動でデータが取得できるので、Re:dashでダッシュボードを設定したり、
良い感じにグラフを組み合わせることで、データ可視化 & 共有プラットフォームの構築が可能になります。
個人的には、
これまでRailsのActiveRecordでデータ取得して〜
Viewでhtml書いて〜
Google Chartsでグラフ描画して〜
あ、そうだそうだ、絞り込みも追加して〜
と、自分でゴリゴリ書いていくのではなく、閲覧系の機能はRe:dashにお任せして、
更新系機能やRe:dashで実現しきれない部分だけは自分で作っていた方が良いと思いました。
また、難しいと感じる点は2点あります。
1点目は
GoogleスプレッドシートやSQLの出力イメージをRe:dashで使えるように考えるは難しいのではないかと感じています。
特に、非エンジニアに運用を展開するときは、そこを厚めにサポートしなければ組織根付いていかないのかなと思っています。
2点目は
ダッシュボードに属させるクエリの管理です。
ここのカテゴライズを考えておかなければ、結局「あのデータどこに行ったっけ?エンジニアに聞いたろ」
ということが発生してしまうので、エンジニアの手間があまり軽減しない可能性があると思いました。
Re:dashがここまでデータ抽出 => 可視化を簡単に出来るとは思いませんでした。
難しいと感じる点で書いた2点、すなわち組織への展開と運用方法の確立さえうまくいけば、
エンジニアやディレクターの工数軽減できるサービスだと思います。
前回の記事では、Googleスプレッドシートの値をRe:dashに取り込む方法を紹介しました。 今回は、GoogleAnalyticsのデータをGoogleスプレッドシートに取り込む手順を紹介しようと思います。
1. Googleスプレッドシートのアドオンを取得する。 GoogleスプレッドシートのアドオンにGoogleAnalyticsががあるので、それを取得します。
2. メニューバー > アドオン > GoogleAnalytics > Create new reportで取得情報を設定する
Create new reportを選択すると右側に情報入力欄が表示されます。 そこの、 1) Name Your Report(これは好きな名前でOK) 2) Select Account Information - Account - Property - View (Profile) を設定してください。 上記の設定は、情報取得元になります。
入力が完了したらCreate Reportボタンを押下します。
3. 取得したい情報を入力する。 2の手順が完了するとReport Configurationというシートが追加されます。 そのシートの下記項目を埋めていきます。
今回は、下記の内容を記入して実行してみます。
項目名 | 入力値 |
---|---|
Metrics | ga:sessions |
Dimensions | ga:date,ga:medium |
Sort | -ga:sessions |
上記は直近7日間を日ごとに、参照元別のセッション数を出すための切り口を設定しています。
4. 実行する メニューバー > アドオン > GoogleAnalytics > Run reportsで値を取得します。
取得した値を元にRe:dashに適用できるようにピボットテーブルなどで加工すると、Google AnalyticsのデータをRe:dashで表示できるようになります。
Re:dashではDataSourceにGoogleスプレッドシートを指定することができます。 Googleスプレッドシートからデータを取り込む場合、 GoogleAPIConsoleからAPI Keyを発行するなど、手順が多かったので、今回の記事でまとめようと思います。
1. GoogleAPIConsoleにアクセス
2. 新規プロジェクト作成 Re:dash用のプロジェクトを作成します。
3. API Keyを作成
画面左のサイドナビより認証情報をクリック
認証情報を作成 > サービス アカウントキーを選択
サービスアカウント種別を新しいサービスアカウントを選択し、各項目を入力。キーのタイプはJSONを選択
画面左のサイドナビよりダッシュボードをクリック > APIを有効にするをクリック
検索フォームに"Drive"と入力すると出てくるGoogle Drive APIを選択
有効にする をクリック
これで、Googleスプレッドシートを操作するAPIキーの取得と、APIの有効化が終わりました。
5. Re:dashでDataSourceを追加
Re:dash側でデータソースを追加します。
typeはGoogleSpreadSheetを選択し、API Keyを取得する際にDLしてきたjsonをファイル選択して、作成します。
6. クエリ作成
クエリ作成は少し、注意する必要があります。
取り込みたいGoogleスプレッドシートのURLが
https://docs.google.com/spreadsheets/d/10fdasFMDSjige4dfsaOMGF0asfmm1/edit#gid=2008635114
というURLで、左から2番目のシートを取り込みたい場合のクエリは
10fdasFMDSjige4dfsaOMGF0asfmm1|1
となります。
注意することは2つあります。
1. スプレッドシートのURLとシートの番号は|で区切る
2. シートの番号は左から0,1,2...となる。
10fdasFMDSjige4dfsaOMGF0asfmm1|1
この方法を参考に、自身のクエリを作り、実行すると、GoogleスプレッドシートのデータをRe:dashに取り込むことができます
saitou.hatenablog.com 前回の記事でRe:dashを使えるようにしましたので、今回はDataSourceとしてMySQLを追加してみます。
1. ログインする 初期ユーザーのログインidとpassは下記の通りです。 ID: admin PASS: admin
2. 画面右上のDBマークをクリックする
3. New DataSourceをクリック
4. 項目を埋めていく
5. DBが作成されたことを確認
6. クエリを実行してみる http://作成したインスタンスのIP/queries/new 上記にアクセスし、DataSourceを作成したDBを選択すると、 画面左側にスキーマ情報が表示されました。 スキーマが表示されれば接続自体できていますので、クエリを作成-実行してみてください。
Re:dashはスキーマを確認できるだけではなく、クエリの整形や、 グラフのpngダウンロード, 数値のCSV, Excelダウンロードまでサポートしています。
また、作成したグラフは範囲を指定することで、特定の日付に絞り込んだりすることができるので、 いちから自分で画面を作るより、だいぶ楽です。
うちの会社では
ということが数多くあります。
正直Railsで実装するとなると、viewまで書かなければならなくしんどいのと、 GAからデータ取得し、スプレッドシートに貼り付けという作業をdailyでやり続けるめんどくささがありました。
これらの作業を自動で取得からグラフ作成できる良いツールはないかと探していたところ、 Re:dashと言われるデータ可視化, 共有プラットフォームツールがあるということで、試してみました。
今回はAWS EC2を使用してログインするところまでの手順を書こうと思います。
Re:dashとは、DataSource*1*2にクエリを投げ、返って来た結果を簡単にグラフ化、共有、ダッシュボードに登録することで、
データ可視化や共有プラットフォームとして機能することが期待できるツールです。
また、クエリは定期実行*3させたり、クエリをForkして使いまわせたりできます。
データやグラフについても、CSV, ExcelでDLや、iframeでhtmlに組み込み、png画像としてDLできたりします。
なので、セキュリティグループで22(ssh), 80(http), 443(https)を開けておく必要があります。
また、AMIのOSはubuntuですので、ssh接続する際のユーザーはubuntuを指定する必要があります*5
ssh -i ~/.ssh/public.key ubuntu@ip-adress
AWS EC2のAMIを使用すれば、少しの時間でRe:dashを使えるようになります。
AWS以外にも
Qtがないとcapybara-webkitをinstallできないって毎回怒られるんだけど、
毎回やりかた忘れちゃうのでメモ
# qt4 $ wget https://download.qt.io/official_releases/qt/4.8/4.8.7/qt-everywhere-opensource-src-4.8.7.tar.gz $ tar xzvf qt-everywhere-opensource-src-4.8.7.tar.gz $ rm qt-everywhere-opensource-src-4.8.7.tar.gz $ cd qt-everywhere-opensource-src-4.8.7 $ ./configure -opensource -nomake examples -nomake tests $ sudo gmake -j2 # 2並列で1時間くらいかかる $ sudo gmake install $ sudo ln -s /usr/local/Trolltech/Qt-4.8.7/bin/qmake /usr/bin/qmake # qt5 $ more /etc/yum.repos.d/cent6.repo [CentOS6riken] name=Extra Packages for Enterprise Linux 6 - $basearch baseurl=ftp://ftp.riken.jp/Linux/centos/6/os/x86_64/ #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-6&arch=$basearch failovermethod=priority enabled=1 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 $ sudo yum install qt5-qtwebkit-devel $ sudo ln -s /usr/lib64/qt5/bin/qmake /usr/bin/qmake
Qtをインストールした後にbundle installをするとHeadless::Exception: Xvfb not found on your system
と怒られるので、Xvfbをインストールする。
sudo yum install -y libXcomposite.x86_64 xorg-x11-server-Xvfb.x86_64
最近はコードより人とやりとりすることが多くなってきたので、TeadmGeekを読んでみました。
今回はその感想を書きたいと思います。
TeadmGeekは、チームで仕事をするプログラマーに向けた本です。
また、他人とうまく仕事をするということにフォーカスを当てているので、プログラムの話は一切出てきません。
この本は6章立てです。
一人のエンジニアとしての心構えとして有名な3本柱、HRT(謙虚、尊敬、信頼)の重要性や、
チーム文化の重要性、組織に対しての行動の仕方などが書いています。
チームで開発を進めていくと衝突する、あらゆる人間関係は、謙虚、尊敬、信頼の欠如により、発生するものだと書かれています。
謙虚、尊敬、信頼とだけ聞くと、自らの意見を殺た方がよいのか?と思ったのですが、そういうことではなく、
チームとしてよりよい成果を得るための効率的なコミニュケーション方法だと学ぶことができます。
本のなかでは、実際の事例を基に、テクニックを活かすとこうなる!というような構成で書かれています。
この本を読んだ後に思ったのは、
HRTを知らない人(例えば超絶自分勝手な人)に対峙した場合に、一歩引いた視点で接することができるのではないかと思いました。
本書の狙い通り、なるべく衝突を回避すべく、落ち着いて誠実に対応できるでしょう。
開発チームが共有する文化(経験・価値・目標)は、効率的なコミニュケーションや、エンジニアリングに必要ということはなんとなくわかっていて、本にも書いていたのですが、
発見があった点は、新しく入ってきたメンバーに対しての抵抗力にもなるというところでした。
文化がないチームに新しくメンバーが入ってきた場合、入ってきたばかりのメンバーの声が強ければ、
一瞬にしてその人価値観が文化になってしまう恐れがあると書かれていました。
発足してから時間が経ったチームには、文化を明文化する必要性が見えてきたのは良かったです。
この本では、リーダーに"なってしまった"人のための行動のコツについても書いてあります。 具体的には下記のことが書かれています。
リーダーは、チームの触媒になるよう、目標を掲げたり、メンバーやチームの成功と幸せを考えたりと、
コードを書いていた時とは違う時間の使い方をしなければならないと、この本でも書いていました。
マネージャー向けに書かれた本でも書かれていたのは、以前のエントリでも学びましたが、
エンジニア向けに書かれたこの本でも同様のことが書かれていたので、妙な納得感がありました。
リーダーからもう一歩上の視点になったことについても書かれていました。
良くない振る舞い(行動的な意味)を排除する方法*1と、
開発チームが属している組織に対しての行動についてです。
基本的には、HRTの精神で臨むことを前提として書かれています。
良くない振る舞いに対しては、相手の想いと伝え方を最大限考え、対処するのがベストプラクティスだと学べます。
また、良くない振る舞いをしている人であったとしても、基本的には自分の中での正義があるので、
そのベクトルを揃えるために、チームの文化も必要だと感じました。
エンジニアは、より良いコードを書くことばかりに集中していてはダメだと書いています。
組織でうまく働くことについても書かれています。
本を読んで感じたのは、入社した瞬間の信頼貯金0の状態から、組織に信頼され、自分の意見や運命をコントロールできるポジションにつくまでの行動について書かれていると思いました。
エンジニアとしては、リリースよりもリファクタリングや技術的な解決に目が行きがちだが、
組織としては、サービスのローンチやユーザーに与えるインパクトの方が圧倒的に価値があることを、認めるべきと書かれています。
エンジニアは開発するだけが全てではなく、客観的(会社やビジネス側から見る視点)に見た事実を理解した上で、技術を活かすアプローチではないと、苦しくなると、だいぶ生々しいことが書かれています。
この本はエンジニア版の人を動かす*2だと思いました。
HRTを基本原則として、チームで成果を出すための知見が詰まった本なので、ほぼ全てのエンジニアにお勧めできる本だと思います。
また、リーダーとしての視点や、エンジニア個人として組織内での動き方についても書かれているので、"チームで成果を出す"という点以外でも十分学びを得られる本だと思います。
ピクスタの開発部で開発合宿を開催したので、
Solr4からの新機能であるSolrCloudを試してみました。
前回の記事はこちらです。
また参考にした書籍は↓こちらです
前回の記事では、インデクシング時の偏り、エラーによる単一障害によるシステム全体のダウンなどを挙げました。
SolrCloudは、分散インデクシングやレプリケーションのメリットを活かしつつ、
これらの問題を回避できる分散環境の仕組みを提供します。
具体的にはZooKeeper
というものが組み込まれており、それがnodeのステータス管理、分散検索時のフェイルオーバー、単一障害点などをなくす仕組みになっています。
今回は、シャード数2, レプリケーション数2の4台構成のシステムを想定して、環境を構築していきます。
まずは各nodeの基となるデータを作成します。
$ cd ~/solr-4.10.4/ $ cp -R example/ node1 $ cp -R example/ node2 $ cp -R example/ node3 $ cp -R example/ node4
node1を立ち上げる際にzookeeperの起動と設定も同時に行います。
$ cd ~/solr-4.10.4/node1 $ java -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=myconf -DzkRun -DnumShards=2 -jar start.jar
注意する点が一点あります。
書籍では
java -DzkRun -DzkHost=http://localhost:9983 -Dbootstrap_conf=true -DnumShards=2 -jar start.jar
と書いてあるのですが、bootstrap_conf=true
だけでは、zookeeperがconfigファイルを読み込めないので、
bootstrap_confdir
を設定する必要があります。
続いて、node2, node3, node4をzookerrperの管理下で起動します。
$ cd ~/solr-4.10.4/node2 $ java -Djetty.port=8985 -DzkHost=localhost:9983 -jar start.jar $ cd ~/solr-4.10.4/node3 $ java -Djetty.port=8987 -DzkHost=localhost:9983 -jar start.jar $ cd ~/solr-4.10.4/node4 $ java -Djetty.port=8989 -DzkHost=localhost:9983 -jar start.jar
node4まで立ち上げたらSolrCloud(zookeeper)が起動しているhttp://localhost:8983
にアクセスしてみましょう。
zookeeperを立ち上げた状態であれば、サイドバーにCloudというタブがあるはずなので、表示してみましょう。
設定した通り、シャード数2, レプリケーション数2の構成が出来上がりました。
ここまで簡単に環境ができるとはあっぱれ。
また、SolrCloudではRest APIを提供しており、管理画面からだけではなく、CLIで設定を変更できます。
一覧や詳細はこちらを参照してみてください
CLIを使用しても、レプリケーション数やシャード数を変更することができるので、
サーバー監視ツールからのalertなどで、状況に応じて柔軟にスケールすることができます。
今回の開発合宿では手元の書籍がSolr4系だったので、それで進めてきたのですが、
今後は5系でも同様の構成が作成できるように学んで行こうと思います。