Work Records

日々の作業記録です。ソフトウェアエンジニアリング全般から、趣味の話まで。

エンジニア職と株式投資


エンジニアが株式投資を考えることについて

自分の観測範囲だけかもしれませんが、投資について話をするエンジニアは少ないように思います。最近の売り手市場感からいえば、一般平均以上は給与をもらっていると思うので、 単にそういった手の話を公にすることが憚れているだけかもしれませんが。

まあそれはどちらでもいいのですが、アメリカの時価総額ランキングの上位をほとんどがテック企業が占めている現在の状況で、エンジニア職であることは投資的観点においても非常に恵まれていると感じています。
具体的には、以下のような観点をエンジニアであれば持つことができるからです。

  • あるテクノロジーが何かの業界にブレイクスルーを起こしうるかどうか
  • 注目のサービスには実はあるコア技術が隠れている
  • 新興企業の技術力がどの程度なのか

また、別観点で言えばエンジニアは常にスキルをアップデートしていく必要があり、なんの技術を習得するか?ということがある意味では自身に対しての投資になるので、そこの技術選定を正しく行うためにもビジネスとテクノロジーの関連については敏感になっておく必要があるとも思います。


NVIDIA

テクノロジーと株価の関係が非常にわかりやすいのがNVIDIAだろうと思います。それこそ、テクノロジーを知らなければ謎の半導体メーカーなどと呼んでしまいます。

直近5年の株価を見てみると、素晴らしいくらいの右肩上がりと2018年の暴落になっています。
f:id:kenjiszk:20190114003207p:plain

右肩上がりなのは良いですが、肝心なのはテクノロジーを理解していれば、このNVIDIA株を値段が上がる前に買えるかどうか?という点になります。

第一参入期 AlphaGo

NVIDIAGPUの会社なので、もともとはゲームなどグラフィックを処理するための特殊なプロセッサを作っていました。ところが、このGPUディープラーニングにも利用できることがわかったのが最初の参入期になります。

詳細は省きますが、AI技術の実用化の一つのブレイクスルーがディープラーニングという手法が確立したことですが、このディープラーニングの計算を可能にしたのが、多重の行列計算を現実的な時間内で完了できるGPU、という関連です。

このディープラーニングが世間の注目を集め、実用化ができてきたなという出来事といえばAlphaGoではないかと思います。

Wikipediaより。

2016年3月、韓国棋界で「魔王」と呼ばれる世界トップ棋士の一人の李世乭と戦い、4勝1敗と勝ち越した。

gigazine.net

つまり2016年3月時点で以下の考察ができます。

特に技術が理解できる、技術について調べることができる能力があれば、三つ目以降の考察も可能ではないかと思います。
この時期に参入していれば将来$400近くまで上昇する株が$40程度で買えたことになります。

とはいえ、結果から考察しているだけなのでそんなに簡単な話ではないですが、技術を知っていれば確度が高くなることは間違い無いと思います。

第二参入期 仮想通貨

二度目の参入時期は、仮想通貨ブームではないかと思います。つまり、2017年の初頭から中頃まで。bitcoinの3年チャートを見るとこんな感じ。
f:id:kenjiszk:20190114185736p:plain

こんな感じで考えられていればこの時期にNVIDIA株に注目できていたと思います。

  • 仮想通貨がなんとなく流行っているっぽい
  • ほとんどの通貨はPoWという手法を利用している
  • PoWには多くの計算が必要でそこにGPUが利用されている

ということで、ここがNVIDIA株参入の第二期目だったかなと思います。

ちなみに面白いのは、bitcoinの価格ではなくPoWに費やされている計算量(hashrate)とNVIDIAの株価の方が相関があるという点ではないでしょうか。仮想通貨の価格が暴落した2018年1月ではまだNVIDIA株は落ちずに保っています。
f:id:kenjiszk:20190114192428p:plain

つまり、

  • 仮想通貨全体が冷え込む
  • マイニングによる利益が出ないラインまで価格が落ち込む
  • GPUの需要が減り、NVIDIA株が下がる

といったストーリーになります。

ただし大局も見ないといけない

一応触れておくと、アメリカ株は2017年から2018年末にかけて、特にテック系株は順調だったのでそういった影響もあったとは思います。
f:id:kenjiszk:20190114193252p:plain
こういった全体感はちゃんと押さえておかないと参入時期を間違えるので一応は押さえておいた方がいいです。


では次は?

NVIDIAの例を元に見てきましたが、結局大事なのは、じゃあ今何を買えばいいの?という点かと思います。

VR / Oculus Go

いくつかあると思いますが個人的に考えているのは、VRです。VRについては何年も前から実用化に向けて色々な取り組みがありましたし、色々なアイディアを耳にしてきましたが、相当実用化してきたなと感じたのが、Oculus Goでした。
gigazine.net

まず非常に価格が安いことと、実際使ってみると多少の画質の悪さはあるものの十分コンテンツとして楽しめるなという感じを受けました。
AlphaGoがプロ棋士に勝ったことや、仮想通貨が流行り始めた事と同種の出来事ではないかと思います。

ここからがエンジニア的に考えないといけないところだと思いますが、VRを実現するために大切なものは小型GPUと5Gかなと考えています。

小型GPU

Oculus Goを見てわかるようにVRバイス自体がかなり小型化していますし、今後普及するためにはもっと小型にしていく必要がありそうです。一方で、VRコンテンツは当然非常に多くのグラフィック処理が必要になるので、高性能で小型のGPUを作ることができる技術が重要になります。

5G

今後、VRバイスが単独でネットワーク接続できないことはあり得ないので、非常に大量のVRコンテンツを通信するための5Gも注目したいところです。5G技術自体はすでに確立していてどう広まっていくかの段階なので、必要なチップや、基地局系の企業が注目されるのではないでしょうか。

まとめ

エンジニアならではの視点で、成長する技術について着目できるのではないかと考えこのブログを書いてみました。

ただ、一方で技術に対するアンテナを高くキープする一つのインセンティブとしての株式の売買益ってのはありな気はします。どんな目的にしろ最新技術をキャッチアップし、技術と社会・ビジネスをしっかりと関連づけられる思考能力が一番重要です。

一人の力で日経平均を動かせる男の投資哲学

一人の力で日経平均を動かせる男の投資哲学

世界一やさしい 株の教科書 1年生

世界一やさしい 株の教科書 1年生

SRE風のインフラエンジニアにならないために

この記事は、SRE Advent Calendar 2018 - Qiitaの24日目として投稿しています。

SRE風のインフラエンジニア

ここ数年で、SREという言葉が注目されていて色々な組織でSREチームが立ち上がっています。
特に、インフラチームが名前を変えてSREチームとなるケースは多いのではないかと思います。私もそうです。
この投稿では、DevOpsに対する考え方を通してインフラエンジニアではなくSREエンジニアがどう考えて働いていけば良いかということをまとめていきたいと思います。


SREとDevOps

そもそもDevOpsとは

DevOpsという言葉が生まれて随分立っていると思うので本稿を読む方にとっては釈迦に説法かもしれませんが、一応振り返って見ます。
DevOpsはDev(開発者)とOps(運用者)の境界を無くしていくことにより、提供しているサービスの価値を上げていく取り組みです。

SRE本でも取り上げられている、DevとOpsの目的の差異

マクロで見るとサービスの価値を上げたいことで目的が一致しているものの、ミクロで見ればDevとOpsで思惑が異なってくることが問題になります。

ミクロなDevの目的

新しいコードをどんどんリリースしてサービスを発展させていきたい。そのため、可能な限りリリースサイクルを高速にしたい。

ミクロなOpsの目的

システムを安定化させることが第一命題。そのため、可能な限り、システムに変更を加えたくない。

この両者の矛盾を解決するのがSREとしての役割です。



Ops側の視点での安定性の考え方を改める

まず、ミクロなOpsの目的として挙げていた、可能な限り、システムに変更を加えたくない、は正しくありません。短期的にはそれで問題ないとしても、長期的には必ず問題を引き起こします。極端な例を挙げるとすれば、何年も新規リリースをせずに放置されていたシステムにはもう修正は入れられない、といった具合です。(しかも、そんな感じのシステムは意外に存在します)

次に考えるのは、100%安全なリリースを、ある程度の長すぎないスパンで行う、といった試みかもしれません。が、これもまた間違いの一つです。100%安全なリリースは存在せず、また、100%に近づけるためのコストは指数関数的に増加してしまうからです。

システムを高速に更新可能にしておくことで安定性を担保する

100%安全なリリースは存在しないし、未来永劫新規リリースを行わないプロダクトは存在しないので、なるべく高速に更新可能な状態をキープすることが重要になります。これが実現できていれば、コスト的に見合うだけのQAを行なった後はさっさとリリースして、問題があったら速攻でロールバックや修正のリリースを行えます。
これがシステムを安定させるための解です。

インフラエンジニアではなくSREとしてどう高速リリースを実現するか

class SRE implements DevOpsGoogleが言っているように、DevOpsはインターフェースとしてシステムを高速に更新可能にしておくことで安定性を担保するということを定義しているが、SREはそれを実現するもの(実装)であると考えられます。
そのため、実装方法はプロダクトや組織によって多種多様になると思います。ここで、今までのインフラエンジニアという保守や管理がメインの立場から一歩踏み出し、DevとOps、もしかするとビジネスサイドなどの境界を飛び越えてどこを改善すれば、プロダクトの高速リリースの実現と安定化を達成できるか、ということを考えていく必要が出てきます。
いくつかの例をあげていきたいと思います。

プロダクトの高速リリースに効くところを見極める

ひとえにリリースの高速化といっても具体的に何を高速化するのか?は考え所です。インフラだけ担当していると割と見えにくいのですが、CI/CDの改善や、開発環境の充実、QA環境の充実、といったあたりがかなり重要ではないかと思います。これらの要素は、本番環境に比べれば軽視されがちだったりしますが、本番環境を安定させるためにも超重要な項目であるという認識を持ちましょう。

また、SREやインフラエンジニアの視点から見るDevはサーバーサイド開発者であることが多いと思いますが、もしモバイルアプリを提供しているサービスであればクライアントのエンジニアもDevであり、アプリケーションのリリースサイクルを考える一員であることを忘れないことも大事です。よく話して見ると意外とSREチームが解決できる問題を抱えていたりすることがあると思います。

リリースするにあたっての心配事を潰す

いざ新機能をリリースして見たら全サービスが落ちてしまった、なんて経験をした開発者であえば、リリースが怖くなります。こういった心理的な障壁も高速リリースに対する壁であると思います。これに対しての施策はいくつもあると思いますが、大きな修正を小さく試せるカナリアリリースや、一部の機能が落ちても全体としてはサービスが提供できるようになるためにサーキットブレイカーを導入するといったことが効果があります。

また、リリースに際して怖いものの一つに、プロダクション環境のデータでしか再現できないようなバグ、があります。これに関してもプロダクションと同等のデータを扱える検証環境が用意されていればかなり安心してリリースが行えるようになります。

もう一点大事なのが検知システムで、システムが正常に動作しているかをいち早く検知できる仕組みが整っているかどうか、という点も重要です。

Chaos Engineeingしてみるのも一つの解ではないでしょうか。

開発チームが自律して動ける仕組みやツールを提供する

SREチーム無しでも完結できる作業を増やすための仕組みやツールを提供することも重要です。全ての構成がコード化されていたり、クラウドサービスを利用しているのであれば十分可能だと思います。
また、監視アラートの対応についても事前に十分なドキュメントや対応ルールが決まっているのであればSREチーム無しでも十分対応可能なものは多いです。

ただし、注意したいのは、十分なコミュニケーションや準備無しでこれをしようとするとアラートの押し付け合いに発展したり、お見合いが発生します。



今の組織でやれていること

色々と偉そうに書いてきたものの、私が所属しているチームで全てやれているというわけでもありません。ですが、結構いい動きができているなあと思う点もあるので紹介したいと思います。

開発チーム出身の人がSREチームにジョインしてくれている

DevとOpsが融合するための一番手っ取り早い方法だと思います。

SREチームに入る新人のエンジニアさんもRails研修などを通して最低限の開発力を持っている

これも非常にいいことで、問題が起きた時にコードまでちゃんと読めるとか、そういった素地を最初に作ってもらっています。

SREチームのケツを叩いてくれる人がいる

やはりどうしても100%開発に従事しているわけではないので、Devチームが困っていることを十分理解することは困難です。そんな時にしっかり要望を投げつけてくれるDevチームがいることが一番大事ではないかと思います。DevとOpsはお互いに忖度無しに要望を投げつけあうくらいの方がうまくいくと思います。



今の組織でこれからやってみたいこと

SREチームからの短期留学

SREチームへの短期留学はたまに聞きますが、SREチームから開発チームへの短期留学ってあまり聞かないかなと思っています。
やっぱり身を以て他のチームがどんな苦労をしているかを理解することがチーム間の境界を無くすことに繋がるのでチャンスがあればやりたいと思っています。



まとめ

インフラエンジニアからSREエンジニアになって3年くらい経ちますが、色々と感じてきたことを書いて見ました。
私が経験してきたインフラエンジニアの考える安定性が守りの安定性であれば、SREとして考えるべき安定性は攻めの安定性と言えるんじゃないかと思います。



Site Reliability Engineering: How Google Runs Production Systems (English Edition)

Site Reliability Engineering: How Google Runs Production Systems (English Edition)

The Site Reliability Workbook: Practical Ways to Implement SRE

The Site Reliability Workbook: Practical Ways to Implement SRE

  • 作者: Betsy Beyer,Niall Richard Murphy,David K. Rensin,Kent Kawahara,Stephen Thorne
  • 出版社/メーカー: O'Reilly Media
  • 発売日: 2018/08/04
  • メディア: ペーパーバック
  • この商品を含むブログを見る

ECSのTaskを同期的に実行するコマンドecs_task_executorを作った


ECSのTaskの実行について

ECSにはServiceとTaskという二つのコンテナの実行方法がある。
Serviceは主にwebサーバーなどに代表されるような常に一定数のコンテナを保つように管理されるもので、Taskの方は一回実行したらそれっきりで終了するバッチ的な利用を想定されている。

APIアクセスによるTaskの実行

awscliやecs-cliによりこのTaskはAPI経由で実行することができる。
awscliであればこんな感じ。

aws ecs run-task --cluster default --task-definition sleep360:1


困ること

API経由でのTaskの実行は非同期で行われる

どういうことかというと、awsコマンドが実行成功した時点で正常終了してしまうということが起きる。
つまり実際にコンテナ上で実行したタスクがしばらくした後に異常終了した場合でもAPIを叩いた側は気づく事が出来ない。

以下は、ecs-cliでの実行例だが、sleep 120を処理しているコマンドでも実行自体は13秒で終わっている事がわかる。

$ time ecs-cli compose --project-name kenjiszk-test --file docker-compose.yml run web "sleep 120"
    INFO[0000] Using ECS task definition                     TaskDefinition="kenjiszk-test:3"
    INFO[0000] Starting container...                         container=e6fece2d-6f6f-44ec-95b9-44f37c7c1205/web
    INFO[0000] Describe ECS container status                 container=e6fece2d-6f6f-44ec-95b9-44f37c7c1205/web desiredStatus=RUNNING lastStatus=PENDING taskDefinition="kenjiszk-test:3"
    INFO[0013] Started container...                          container=e6fece2d-6f6f-44ec-95b9-44f37c7c1205/web desiredStatus=RUNNING lastStatus=RUNNING taskDefinition="kenjiszk-test:3"
    
    real	0m13.105s
    user	0m0.129s
    sys	0m0.098s

で、何が困るか?

連続するタスクがあって、それぞれ直前のタスクが成功した場合のみだけ処理を進めたいような場合、デフォルトの挙動だと失敗しようがしなかろうが成功してしまうのでどんどん先に進んでしまう。
それどころか、タスクの終了も待たないので、タスク自体が重なって実行されてしまうことになる。

具体的な例をあげると、Railsのデプロイ処理の場合

  • db:migrateなどのdbの処理
  • コード(コンテナ)の入れ替え

という流れを経るので、db:migrateが失敗したとしても新しいコードをデプロイしてしまうというやばいことも起きかねない。
そういった処理をする場合には、同期的に実行する事が不可欠になる。


同期的に実行できるようなコマンドを作った

という事で、同期的にコンテナ状のタスクを実行できて、失敗した場合にはしっかり失敗するようなコマンドを作成した。
github.com

READMEを見てもらえるとだいたいどういった処理になっているかわかるが、内部でやっていることは

  • aws APIを叩いてtaskを実行
  • taskの実行結果をpollingして取得する
  • taskのstatusがSTOPPEDになったら終了状況を取得して終了する

といった単純な処理をしている。

run_and_fail.shというしばらくすると失敗するscriptを用意して実行しみた例。
以下のように終了まで待っているのと、異常終了コードをハンドリング出来ている。

$ ecs_task_executor --cluster Sample -t kenjiszk-test:1 -n web -c 'run_and_fail.sh'
Set timeout as 600 sec.
LastStatus=PENDING TimeElapsed=5.024269701s
LastStatus=PENDING TimeElapsed=10.045879005s
LastStatus=PENDING TimeElapsed=15.070078421s
LastStatus=RUNNING TimeElapsed=20.092714283s
LastStatus=RUNNING TimeElapsed=25.109575722s
LastStatus=RUNNING TimeElapsed=30.131358467s
LastStatus=RUNNING TimeElapsed=35.150669821s
LastStatus=RUNNING TimeElapsed=40.16816051s
LastStatus=RUNNING TimeElapsed=45.185257392s
LastStatus=RUNNING TimeElapsed=50.209708875s
{
  ContainerArn: "arn:aws:ecs:ap-northeast-1:000000000:container/df87b9cd-962f-4580-ad8d-f6b97446b9a2",
  ExitCode: 255,
  HealthStatus: "UNKNOWN",
  LastStatus: "STOPPED",
  Name: "web",
  NetworkBindings: [],
  NetworkInterfaces: [],
  TaskArn: "arn:aws:ecs:ap-northeast-1:00000000:task/de79a37c-4c51-4307-826c-f6a3c7d733cb"
}
$ echo $?
255


今後

自前でコマンドを作って見たが、実は同期的にTaskを実行できるオプションがあるんじゃないかとちょっとヒヤヒヤしている。


WEB+DB PRESS Vol.105

WEB+DB PRESS Vol.105

  • 作者: 小笠原みつき,西村公宏,柳佳音,志甫侑紀,池田友洋,木村涼平,?橋優介,大塚雅和,飯塚直,吉川竜太,末永恭正,久保田祐史,浜田真成,穴井宏幸,大島一将,桑原仁雄,牧大輔,池田拓司,はまちや2,竹原,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/06/23
  • メディア: 単行本
  • この商品を含むブログを見る
合格対策 AWS認定ソリューションアーキテクト - アソシエイト

合格対策 AWS認定ソリューションアーキテクト - アソシエイト

ALISのICOスマートコントラクトを読んでALISベータ版にまとめ記事を投稿してみた

ALISとは

公式サイトより。

ALISは信頼性の高い情報・人に素早く出会えるソーシャルメディアプラットフォームです。 信頼できる記事を書いた人、それをいち早く見つけた人が報酬を獲得することで信頼できる情報を蓄積するプラットフォームの実現を目指します。 従来のメディアにありがちな広告のためのコンテンツ、ステルスマーケティング、信頼性の低い情報にうんざりしている人々を解放することがALISの目的です。

alismedia.jp

ブロックチェーンを用いたメディアを作成していて、ICOも成功しているプロジェクトです。
このメディアに記事を書いて高く評価されるとトークンがもらえ、いい記事を誰よりも早く評価してもトークンがもらえるシステムになっています。

何をかく?

ALISのプロジェクトは全てgithubとtrelloで進捗が確認できます。すごい。
ということで、せっかく公開されているコードの一部を読んでみることにしました。
ALISトークンのICOコントラクト部分を読み面白い部分をALISに投稿してみました。
全5回分になります。
ALISのICOスマートコントラクトを読む① | ALIS
ALISのICOスマートコントラクトを読む② | ALIS
ALISのICOスマートコントラクトを読む③ | ALIS
ALISのICOスマートコントラクトを読む④ | ALIS
ALISのICOスマートコントラクトを読む⑤ | ALIS

ALISトークンの実装が気になる方はぜひ記事の中をみてください。
この記事は実際にALISを使ってみた感想を書いてみます。

書いてみた結果

何ALIS獲得できたか

一番気になるのが結果どのくらいのトークンを獲得できたかだと思いますが、2018/05/20の時点で5 記事書いて、全89 いいねをもらい、49.513 ALISを獲得しました。
現在1トークンが$0.186173なので$9.2くらいの価値になります。
1記事200円くらいですね。高いのか安いのかよくわかりません。

どんな記事がいいねを獲得している?

現在、メディアの画面が、新着記事と人気記事のタブしかないので新着記事として出ている期間にどのくらい一気にいいねを獲得できるかがいいねを稼ぐ鍵なのかなあと感じました。
新着期間にたいしていいねを稼げなければ人気記事にも出てこないのでそのまま埋もれていきます。
アイキャッチ画像を工夫していたり、短い記事を量産したりするのもそのあたりの事情なのかなあと思います。

今後

普通のメディアの機能が追加されていく?

お気に入りのブロガーのブックマーク機能とか、過去記事の検索機能とか、普通のメディアにはある機能が実装されていくのではないかと思います。
今は、ブロックチェーンと仮想通貨のテーマしか投稿できないですが、将来は全ジャンル解放になるでしょうからタグ付けなどの機能も出そうですね。

個人的には、daily、weekly、monthlyのランキング機能とか出てくれるといい記事が見つけやすくていいなあと思っています。
トークンによる評価システムはいい記事の見つけやすさが前提で成り立つものだと思いますので。

ウォレット機能が出た時にどうなる?

ベータ版の現在では獲得したALISトークンを移動することができないので特に何も起きていませんが、ウォレットが実装されてトークンを移動できるようになったタイミングが気になります。
その時までにトークンを長く保持している方が得するというインセンティブがしっかりはたらく状況にしておくことが運営側としては重要になります。
white paperによるとトークンを多く持っている方がよりトークンを獲得しやすいといったモデルになっていてそこで担保しているようですが、それをユーザーに実感させる必要はありそうです。
ただ記事を書いてお金を稼ぐというモチベーションの人は貯め続けるというモチベーションはないと思うのでウォレットが実装されたタイミングが非常に注目だと思います。

まとめ

個人的には予想していたよりも1記事あたりに獲得できるALISの量が多かったので継続的に何か記事を書いてみてもいいかなあという感じです。

アフター・ビットコイン: 仮想通貨とブロックチェーンの次なる覇者

アフター・ビットコイン: 仮想通貨とブロックチェーンの次なる覇者

10年後の仕事図鑑

10年後の仕事図鑑

slackに飛んでくるアラートの統計を取る

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム

slackに色々なアラートを飛ばしている

slackに色々なアラート通知を飛ばしている人は多いと思います。

例えばDatadogと連携すればこのような感じで。
f:id:kenjiszk:20171220025043p:plain



アラートの統計情報を取りたい

そこでこう言った需要が出て来ます。

  • なんか最近アラート多くないか?半年前と比べてどうなってんだろ。
  • ちょっと無駄なアラートが増えて来たかもしれない。
  • この半年でアラートの件数を半分に減らそう!

アラートの件数の推移を取りたくなってくるわけです。

slackの機能

当初、slackにそう言った機能くらいあるだろ、とたかをくくっていたわけですが、
slackには特定のchannelの特定のbotが発言した回数の統計情報、くらい細かいものは見せてくれませんでした。。。
まあ当たり前か。。。

APIを使って取得してみる

ただし、便利なAPIはたくさん用意してくれているので、サクッとやりたいことは実現できそうです。
api.slack.com

サンプルスクリプト

ということで、サクッとGoでslackのapiを叩いて、mysqlにデータを保存するスクリプトを作りました。
主要部分だけ抜粋。

slackのchannels.historyからデータを取得
/* パラメータのセット、slackのtokenは環境変数から、idはデータを取得したいchannelのchannel id*/
values := url.Values{}
values.Add("token", os.Getenv("SLACK_ACCESS_TOKEN"))
values.Add("channel", id)

resp, err := http.Get("https://slack.com/api/channels.history" + "?" + values.Encode())
if err != nil {
        return err
}
defer resp.Body.Close()

/* レスポンスをよみこんでjsonに変換 */
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
        return err
}
jsonStr := string(body)
jsonBytes := ([]byte)(jsonStr)
rInfo := new(RespInfo)
if err := json.Unmarshal(jsonBytes, rInfo); err != nil {
        return err
}

必要なデータだけ受け取るので、構造体は以下のように定義

type RespInfo struct {
        Ok       bool      `json:"ok"`
        HasMore  bool      `json:"has_more"`
        Messages []Message `json:"messages"`
}

type Message struct {
        BotID string `json:"bot_id"`
        TS    string `json:"ts"`
}
MySQLに突っ込む

rInfo.Messagesに取得して来たメッセージが入っているので必要なものをMySQLに突っ込む
テーブル定義はこのように。

CREATE DATABASE slack_stats;
USE slack_stats;
CREATE TABLE `alerts` (
  `timestamp` varchar(256) DEFAULT NULL,
  `bot_id` varchar(256) DEFAULT NULL,
  `slack_channel` varchar(256) DEFAULT NULL,
  UNIQUE KEY `i1` (`timestamp`,`bot_id`,`slack_channel`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

突っ込む側の処理は以下。
apiから取れるslack idはただの文字列なので人が読めるような文字列に変換する処理を入れてあります。

dbStr := fmt.Sprintf("root:%s@tcp(%s:3306)/slack_stats", os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_HOST"))
db, err := sql.Open("mysql", dbStr)
if err != nil {
        return err
}
defer db.Close()

stmtIns, err := db.Prepare("INSERT IGNORE INTO alerts (timestamp, bot_id, slack_channel) VALUES (?, ?, ?)")
if err != nil {
        return err
}
defer stmtIns.Close()

_, err = stmtIns.Exec(timestampe, bot_id, slack_channel)
if err != nil {
        return err
}
結果

こんな感じで突っ込めました。

mysql> select * from alerts where slack_channel = 'infra' limit 10;
+-------------------+------------------+---------------+
| timestamp         | bot_id           | slack_channel |
+-------------------+------------------+---------------+
| 1513606245.000070 | Datadog          | infra         |
| 1513606374.000311 | Datadog          | infra         |
| 1513607148.000258 | incoming-webhook | infra         |
| 1513607148.000663 | incoming-webhook | infra         |
| 1513607209.000354 | incoming-webhook | infra         |
| 1513607210.000247 | incoming-webhook | infra         |
| 1513607270.000409 | incoming-webhook | infra         |
| 1513607271.000133 | incoming-webhook | infra         |
| 1513607333.000085 | incoming-webhook | infra         |
| 1513607333.000509 | incoming-webhook | infra         |
+-------------------+------------------+---------------+
10 rows in set (0.00 sec)



redashによる可視化

可視化するためのSQL

データを突っ込んでいるだけなので、時間単位のアラート件数を出すように以下のクエリを発行します。

  • timestampの小数点以下を切って
  • JSTにするためにoffsetつけて
  • formatを時間単位にする
mysql> SELECT DATE_FORMAT(FROM_UNIXTIME(CAST(timestamp AS UNSIGNED) + 32400), '%Y-%m-%d %H') AS time, COUNT(*) FROM alerts WHERE slack_channel = 'infra' AND bot_id = 'Datadog' GROUP BY time LIMIT 10;
+---------------+----------+
| time          | COUNT(*) |
+---------------+----------+
| 2017-12-18 23 |        4 |
| 2017-12-19 00 |        3 |
| 2017-12-19 01 |        3 |
| 2017-12-19 02 |        1 |
| 2017-12-19 03 |        1 |
| 2017-12-19 04 |        1 |
| 2017-12-19 05 |        1 |
| 2017-12-19 06 |        4 |
| 2017-12-19 07 |       14 |
| 2017-12-19 08 |       13 |
+---------------+----------+
10 rows in set, 111 warnings (0.00 sec)

クエリがかけたらredashでグラフ化

redashの使い方とかはここでは説明しませんが、MySQLにデータが入ってしまえば何か使い慣れたグラフ化ツールで可視化してあげるといいと思います。
f:id:kenjiszk:20171220043656p:plain
こうやって可視化してみると、朝と夜にアラートが多いということがわかります。



今後

最初に書いたように、以下のような観点でのアラートマネジメントを進めていこうと思っています。

  • なんか最近アラート多くないか?半年前と比べてどうなってんだろ。
  • ちょっと無駄なアラートが増えて来たかもしれない。
  • この半年でアラートの件数を半分に減らそう!

Slack入門 [ChatOpsによるチーム開発の効率化]

Slack入門 [ChatOpsによるチーム開発の効率化]

Scriptの実行環境を保証するためにDockerfileを使う

Scriptの実行環境

最近golangを使ってちょっとしたscriptを書く機会が何度かあったが、そこにDockerfileを置いておいてビルド環境や方法を固定する方法がいいなあと思ったので、メモ程度に。
goの場合は実行ファイルはコンパイル後のバイナリで依存がOS(linux or window or mac)くらいしかないと思うが、rubyやらperlやら実行環境にも依存するような場合にはサクッと動作環境をDockerfileに書いておくと簡単で良いなあと感じた。


Dockerfileを一緒に作る

例えば、sampleX.go というのがscript達だとして

┬ sample1.go
├ sample2.go
├ sample3.go
├ libs/
└ configs/

こんな感じで、scriptを作ったとする。
golang wayはよくわからないが結構こんな感じでバラバラとscriptを気軽に量産しまくっている。
(サブコマンドとか使ってmainは一つにしたほうがいいのかもしれないが。)

ここに、Dockerfileをおく

┬ sample1.go
├ sample2.go
├ sample3.go
├ libs/
├ configs/
└ Dockerfile

Dockerfileの中身はこんな感じで。

FROM golang:alpine AS build-env
RUN apk add --update git
ADD . /work
WORKDIR /work
RUN go get "github.com/go-sql-driver/mysql" && \
    GOOS=linux GOARCH=amd64 go build -o sample1 sample1.go && \
    GOOS=linux GOARCH=amd64 go build -o sample2 sample2.go && \
    GOOS=linux GOARCH=amd64 go build -o sample3 sample3.go

FROM alpine
COPY --from=build-env /work/sample1 /usr/local/bin/sample1
COPY --from=build-env /work/sample2 /usr/local/bin/sample2
COPY --from=build-env /work/sample3 /usr/local/bin/sample3

Multi Stage Buildを使っていますが、buildの環境を定義しているのはbuild-envの方。
もし特定のgoのバージョンにしたかったり自前で作ったdocker imageでやりたい場合にはFROMにそれを指定すればいいし、
必要なライブラリはRUNで実行して入れてしまえばok。

実際の手順としては、

  • scriptを修正&テストを行う
  • `Docker build . -f Dockerfile -t xxxx/yyyy` を実行する
  • 適当なレジストリにdocker push xxxx/yyyy
  • 実行したい環境で、`docker run -it --rm xxxx/yyyy /usr/local/bin/sample1`

と言った感じ。

なので基本的にはdockerエンジンだけ実行側に入って入れば全てはちゃんと整った環境で実行される、ということになる。
これで、共通のcronサーバーにあれやこれや死ぬほどinstallしなくてもよくなる!

ちなみにだいたい同じようなscriptだったのでまとめて一個のDockerfileにしているが、
かなり毛色が違って使うライブラリも違うようなものは別 Dockerfileにしたほうが良いと思う。



まとめ

dockerを使い始めると構成管理がすごい楽になるなあと実感する。
必要最低限の範囲に必要最低限のライブラリだけ入れて、それが毎回同じ状況ですぐに立ち上がる、素晴らしい!

マイクロサービス入門 アーキテクチャと実装

マイクロサービス入門 アーキテクチャと実装

WEB+DB PRESS Vol.98

WEB+DB PRESS Vol.98

クラウドマイニングのススメ (genesis mining編)

クラウドマイングって?

自前でマイニングリグを作る場合

この記事で書きましたが、仮想通貨をマイニングするには最低でこのくらいの初期投資が必要になります。
kenjiszk.hatenablog.com

GPUの枚数によりますが、ある程度の利益を得たいなら50~100万くらいは初期コストが必要です。
また、自作PCの組み立て経験がない場合には多少組み立てに苦労するかもしれませんし、
自宅の電力の契約次第だとブレーカーが落ちるかもしれません。
また、GPUや電源が故障したりした場合にプラスでお金と労力がかかる可能性もあります。
適切な部品を購入して組み立てていないと火事になったり、といったケースもgoogle検索すると出てきます。

クラウドマイニングだと

そのあたりの一切の面倒を見てくれるのがクラウドマイニングです。
ユーザーはハッシュパワーを購入するだけ、後は勝手にマイニング業者がマイニングしてくれます。
当然手数料は取られますが、上記に書いたような手間を考えれば納得です。
また、マイニングリグを作った場合でも多くの場合はマイニングプールに参加するでしょうから
結局、多かれ少なかれ手数料はどこかに引かれることにはなるかと思います。


genesis mining

ということで、1年ほど前から細々と少額を試して見ていましたが、
2017年の夏に仮想通貨の価格が高騰したタイミングで、BTCの無期限マイニングが売りに出ていたので
買い足してみることにしました。


どのくらいの利益があるか?

現在のハッシュパワー

計5.6 TH/s を$787.3で購入しています。

月々の利益

大体、3日に1回くらいのペースで だいたい0.0025BTCくらいがウォレットに送られてきます。
2017/12時点でBTCは200万円くらいなので、大体月に5万円くらいの計算になります。

11月~12月にかけての急激な高騰のおかげで原価が一気に回収できた形です。
実は購入当時の試算では回収に1年くらいはかかる計算だったので、これは嬉しい誤算になりました。

ただし、マイニングのdifficultyの調整が入って来るのでこのレートが常に続くわけではありません。
当然価格が上がってマイナーが増えればdifficultyが上がるので、今がたまたま景気がいい、くらいに考えています。


2017/12時点で買えるハッシュパワー

いつでも好きなハッシュパワーが買えるわけではないようです。
おそらくgenesis mining側でも大量の発注待ちや設備投資を行なっていてその準備が整い次第売り出しが始まる感じです。

現在確認したところ、今買えるのはモネロの2年間契約のみでした。
f:id:kenjiszk:20171217072904p:plain

スクショは一番安いプランの値段をさしてますが、
$830で1000H/sとのこと。
今のdifficultyで計算すると、1年も待たずに回収できるようです。
f:id:kenjiszk:20171217073313p:plain

genesis miningに会員登録だけしておくと、BTCやETHなどの売り出しが始まったタイミングでメールが来ると思うので、
買いたいコインが出るまで会員登録だけしておいて寝かしておくのもありではないかと思います。


リスク

当然リスクはありますが、これは仮想通貨以外の投資でも同じかなあとは感じます。

  • ハッシュパワーを買っているコインの暴落
  • genesis miningが倒産する


割引コード

最後に、私のアフィリエイトコードを貼っておきます。
rK9eYc

購入時にこのコードを使うと3%割引されるそうなので、もしよろしければ。
genesys miningはこちらから => https://www.genesis-mining.com/a/615255

Happy mining!

小さく始めて大きく稼ぐ 「仮想通貨投資」入門

小さく始めて大きく稼ぐ 「仮想通貨投資」入門