コネヒト開発者ブログ

コネヒト開発者ブログ

Papertrail + Amazon CloudWatchでアプリケーション監視の幅を広げる

こんにちは、サーバーサイドのお仕事してます金城(@o0h_)です。
今更ながら「映画大好きポンポさん」(の2巻)を読みました、めっちゃ良くないですか・・・

映画大好きポンポさん2 (MFC ジーンピクシブシリーズ)

映画大好きポンポさん2 (MFC ジーンピクシブシリーズ)

本日は、サービスの監視の話です。
コネヒトではエラートラッキングにSentryを用いていますが、CloudWatch Alarmによる定量的なエラー観測も併せて行っています。
「どう使い分けるの」「どうやって観測しているの」というお話をさせていただきます。

https://cdn.mamari.jp/authorized/amana_5bbb0ea4-8550-4449-ba79-002aac120002.jpg

続きを読む

チームに「効く」ダッシュボードを考える

Creating Effective Dashboards

こんにちは、サーバーサイドのお仕事してます金城(@o0h_)です。
つい先日、なんか気分が乗らないぜ〜〜って時にスピナーベイトを読み直してみたんですけど、気分の悪さが・・・上塗りされました・・・気をつけましょう。

スピナーベイト (1) (バーズコミックス)

さて、今回は抽象的な話になります。
「チームで毎日見るようなプロダクトの成長のためのダッシュボードってどういうのを作るんだっけ」という内容です。

https://cdn.mamari.jp/authorized/5b7ed6a6-dbc4-4548-a9f5-0017ac120002.jpg

続きを読む

ランサーズさんとランチLT大会を行いました

こんにちは。 Free! が終わってしまい夏の終わりを感じている @super_mannerです。2020年までは頑張って生きようと思いました。

さて、今回は先日開催されました、ランサーズさんとのランチLT大会についてお伝えできればと思います!

なぜ開催されたのか

コネヒトでは先日、コネヒトーク というイベントを開催いたしました。
ありがたいことにビジネスサイド、デベロッパーサイド共にたくさんのゲストの方にお越しいただき、楽しんでいただけるイベントとなりました。
そんなコネヒトークの懇親会で出会ったのがまなみんさんです。
同じサーバーサイドエンジニアということもあり、話が盛り上がり

「実はCakePHPを使っている会社の方とゆっくりお話できる機会って結構貴重なのかも?!」
「最近、コネヒトでも社内勉強会、社外勉強会を開催する事が増えてきたし、このあたりで一つ一緒に勉強会を実施するのもおもしろいのかも?!」

というその場の思いつきを口にしたところ、とても良い反応をいただきまして、あれよあれよと合同勉強会の開催決定しました🎉

折角共通の知識ですので、今回のLTテーマは「CakePHPに関すること」として実施することに決定。
また、ランサーズさんは時折ランチでゲストを招いて勉強会を行っているとのことでしたので、今回もその形式でお邪魔することになりました。

LT大会当日の様子

コネヒトでもこういった形式での勉強会は初めてなので、当日は発表者である弊社のサーバーサイドエンジニア陣はドキドキしながら伺ったのですが(私が一番ドキドキしていたのは秘密)、明るく迎え入れてくださりランサーズの皆さんの素敵なお人柄をうかがい知ることができました(^^) まずはランチを取りながら自己紹介等でアイスブレイクをした後に、いよいよLTのお時間です。

発表にのぞむ弊社エンジニアの金城
発表にのぞむ弊社エンジニアの金城

今回の勉強会は、コネヒトから3名、ランサーズさんから3名の合計6名のLTで執り行いました。 発表者以外にもたくさんのエンジニアの方にご参加いただくことができ、 質疑応答でも毎回何かしら手が挙がる等いい感じに盛り上がり、あっという間にお開きの時間を迎えてしまいました。
私個人といたしましても、扱っているバージョンが違うことや、アプリケーションを取り巻く環境の違いから、私も勉強になることが大変多く楽しませていただきました。
なお、コネヒト側が行ったLTの資料はこちらに上がっておりますので興味がある方は見てみてください! *1

最後に

今回開催するに当たり、お声がけをいただいたまなみんさんをはじめ、広報の宮田さんにも大変尽力いただきました! 重ねて、LTをしてくださった皆様も本当にありがとうございました 🙏 こうした取り組みも今後増やしていきたいと思いますので、今後共コネヒトをよろしくお願いいたします!

*1:対象の資料タイトルはそれぞれ、 「よいOSSを支える3C」「Bye Bye Magic Number」「雰囲気で使わないjoinメソッド」

社内のGoogle Apps Scriptを整理しはじめた

f:id:dachi023:20180921153427p:plain

こんにちは。エンジニアの安達 (@ry0_adachi) です。

先週くらいから社内に散らかった大量のGoogle Apps Script (以降GAS) の管理をすることにしたので1週間でやったこと、これからやっていきたいことを本記事でまとめます。

そもそも何で管理が大変なのか

GASって散らかってる感がすごいけど、なんでそう思うんだろうね?
を考えてみたのですが、だいたいこの3つが悪い気がしました。

  • コードの一覧性が低い、権限問題により全体像がつかめない
  • 同じようなコードが量産される (共通化されない)
  • トリガーがどのアカウントに紐付いているか分からない

誰でもカジュアルにコードを書けるし便利だけど、しっかり管理しないと気づいた頃には大変なことに...ということなんだと思います。

それぞれの問題に対してとった対策

コードの一覧性

f:id:dachi023:20180921130944p:plain

今まではGASのダッシュボードからしか見る術がなかったのですが今はGitHubにコードをPushするようにしました。最初はGoogle Apps Script GitHub アシスタントというChromeの拡張を使っていたのですが、今はclaspというツールでやっています。

claspの詳細な使い方については触れませんが、GASのコードをローカルでpullしたりpushできるようにするためのCLIツールです。claspでプロジェクトを作成して好きなエディタでコードを書いてpushして反映、といった感じでローカルで作業できる範囲が広がるのでだいぶ効率はよくなりました。

Command Line Interface using clasp  |  Apps Script  |  Google Developers

権限ない問題

権限ない問題は個別に招待や共有をするのではなく「XXXの全員が閲覧or編集可能」など組織ごとに権限を付与するようにお願いするしかない気がします、大変そうです。とはいえ社員全員から見えたらまずいもの (個人情報とかそういうの) とかもあるので全部キッチリやる必要はないかなと思います、この辺は完璧を目指さないほうがいいのかもしれません。

同じようなコードの量産

共通化するのにはGASの機能で公開APIとして社内向けに公開するか、ES Modulesを使って書いたコードをBabelとGAS用のプラグインで変換すれば良さそうです。この辺は特に難しいことを考えずにコードをキレイにするだけだったので重複するコードが大量にあった、ということ以外は特に大変ではなかったです。

公開API

f:id:dachi023:20180921160359p:plain

webpack, BrowserifyのPlugin

トリガーを設定したアカウントがわからない

GASに設定したトリガーは設定したアカウントでしか表示されないのでかなり厄介です。離職などによってアカウントを停止すると今まで実行されてた処理が止まってしまった、ということも前にありました。トリガーを紐付けておくために専用アカウントを作ってはみたのですがアカウント切り替えるのが面倒というのもあってあまり進捗は良くないです。いい方法があればブコメなどで教えてもらえると嬉しいです。

今後やりたいこと

  • 今閲覧できているコードを全部GitHubにpushする
  • 便利そうなものはAPI化して他の人も使えるようにしておく
  • 周りを巻き込んでいってこれをちゃんと標準のやり方にする

このあたりでしょうか。
結構泥臭い作業が多いし、GSuiteの権限との絡みで制御できないものもあり辛いことも多々あるんですが、GASを今より簡単に使えるようにしたら会社の中がもっと便利になりそうだなぁと思っているのでそれを糧にもうちょっと頑張ってみようと思ってます。

ECSのバックエンドをEC2からFargateに変更するにあたり知っておくとよさそうな事

こんにちは。インフラエンジニアの永井(shnagai)です。

これまでEC2バックエンドでECSを運用してきたが、Fargateを採用するにあたり、EC2バックエンド時と比べた差分についてまとめてみました。

内容は、ざっくり下記5項目について。

  • NW(awsvpc)
  • タスク定義
  • サービス
  • AutoScalling
  • メトリクス/ログ

Fargateをやってみたというのは出たての頃にやったので、今回は本番運用を考えるにあたり知っておいたほうがよさそうな点についてまとめてます。

tech.connehito.com

NW(awsvpc)

アーキテクチャ的に一番大きく変わるのは、NWの部分だと思う。 EC2上で、タスクを動かすときはデフォルトだと「bridge」が指定されるので、ホスト経由で外部と通信を行っていた。同一タスク(コンテナのリッスンポートが同じもの)を効率的にEC2上で動かすために、動的ポートマッピングを使うのが通例となっていた。

Fargateになると、EC2の存在は隠蔽されるが、当然VPC内にタスクを立てたかったり、セキュリティグループを指定したいのでそれを実現するために、awsvpcネットワークモードを使うことになる。 ちなみに、awsvpcはEC2バックエンドの時でも使えるので、Fargate用の機能ではない。

awsvpcネットワークモード

  • タスクネットワーキング機能により、Amazon EC2 インスタンスと同じネットワーキングプロパティが Amazon ECS タスクに提供される。
  • awsvpcの指定は、タスク定義で行う
  • タスクが、独自のENI(Elastic Network Interface)を持つ。(プライマリプライベート IP アドレス、内部 DNS ホスト名)
  • ENIに対して、VPCフローログ使えるので通信キャプチャ出来る
  • 同じタスクに属するコンテナは、localhost インターフェイス経由で通信できる

タスクネットワーキング機能

ECSのタスクに対して、独自のネットワークNameSpaceを提供する機能(EC2バックエンドの時は、EC2のネットワークをbridgeだったりhostマウント形式で使っていたので使わなくてもよかった)

  • Amazon ECS コンテナインスタンスには、タスクネットワーキングを有効にするために、コンテナエージェントのバージョン 1.15.0 以上が必要
  • 現時点では、Amazon ECS 対応 AMI またはその他の ecs-init パッケージの Amazon Linux バリアントだけがサポート
  • Application Load Balancer および ネットワークロードバランサーのみサポート(CLBは使えない)
  • awsvpc 上で動くfargateタスクをELBにぶら下げる際は、ターゲットタイプとして instance ではなく、ip を選択する必要がある。これは大事。つまり、EC2で運用していたALBだったりにぶら下げる時は、新しくALBのターゲットグループを作りipタイプのターゲットで作ってあげる必要がある。

タスク定義

元々EC2で動かしていたタスク定義を、Fargate対応に切り替える想定で変更点を記載

ネットワークモード

  • awsvpc選ぶ

Requires Compatibilities(互換性が必要)

  • FARGATEを選ぶ

タスクサイズ

組み合わせがあるので、例えばメモリ2GBだと0.25vCPUから1vCPUまでの間から選ぶようなイメージ

  • タスクメモリ 0.5〜30GB
  • vCPU 0.25〜4

コンテナの定義

  • ホストポートマッピングは使えない
  • メモリ、CPUの総量がタスクサイズを超えないように調整
  • ログドライバとして選べるのは、awslogsのみ

サービス

タスク定義でawsvpcネットワークモードを指定しているタスクを動かす場合に、VPCとセキュリティグループを指定することが出来る。

EC2バックエンド時は、EC2側に設定していた項目がここに来たイメージ。

  • クラスタVPC
  • サブネット
  • せキュリティグループ
  • パブリックIPの自動割当
  • ALB・NLB使う際は、ターゲットグループがIPになっているものを選ぶ(なければ作っておく)

デプロイ(サービス更新)時は、EC2インスタンスの時と同じで、タスク起動数が最小数を満たすようにタスク新規作成が始まり、ALB(NLB)ターゲットのdraining期間が過ぎるのを待って旧タスクは落ちる

AutoScalling

Fargateにする一つの大きなメリット。これまでは、EC2(ASG)のスケールアウト+サービスのスケールアウトのつじつま合わせながら組まないといけなかったので障壁高かったが、Fargateならリソース負荷ベースで気軽にスケールアウトが組める

  • スケールの単位は、CPU,Memory,ALBのリクエスト数もしくはCloudWatchアラーム
  • スケジュール単位のスケールがほしいがなさそう(CloudwatchEventsとLambda組み合わせれば出来るかな)

メトリクス/ログ

メトリクス周りが若干弱いけど、これはせっかくEC2管理から逃れられるんだから、リソースとかあまり気にせずAutoScallingをうまく組んで自動で運用していくって流れがいいのかなと思ったり。 ログは、コンテナに直接ログイン出来ない点埋めるべく標準出力は簡単に見れるような仕組みが提供されている。

内部にはログ溜めずにツール使って外に飛ばしたり、標準出力をうまく使って状況把握出来るように運用していくのが吉。 デバッグは、コンテナなんだからローカルで動けば基本OKなはずで、どうしてもってときは同じイメージをEC2バックエンドで動かすしかないかなと思ったり。

  • メトリクスはクラスタとしては出てこなくて、ECSサービス単位でCPUとmemoryが見れる
  • 標準出力は、ECSコンソール上から閲覧可能
  • ecs-cliコマンドから叩くことで tail -f 的にリアルタイムでみることも出来る(awslogsを使ってCloudwatchLogsから同じように取得も可能)

ecs-cli logs - Amazon Elastic Container Service

ecs-cli logs --follow --task-id task-id

[Tue Sep 04 04:03:41.332650 2018] メッセージ
[Tue Sep 04 04:03:41.391128 2018] メッセージ

最後に

検証しながら気付いた点

  • やはり、EC2バックエンド時と違い、ホスト側で行われていたdocker pull時のキャッシュがきかないので起動時間は長かった
  • キャッシュでごまかされていたので、webの運用ではあまり気にならなかったが、デプロイ時間に直接響くのでDockerイメージを小さくしていくことが必要になってくる

コネヒトではコンテナ周りの基盤を整備したりサービス改善を行うエンジニアを募集しています。 少しでも興味もたれた方は、是非気軽にオフィスに遊びにきていただけるとうれしいです。

www.wantedly.com

Kotlin Fest 2018に行ってきました!

f:id:tommy_kw:20180830093312p:plain

こんにちは、Androidエンジニアの富田です。先日KotlinFest 2018というKotlinカンファレンスに参加してきましたので簡単に内容を共有したいと思います。

Kotlin Fest 2018とは

kotlin.connpass.com

KotlinFestとは「Kotlinを愛でる」をテーマに、Kotlinに関する知見の共有と、Kotlinファンの交流の場を提供する技術カンファレンスです。海外ではKotlinConfという約1300名規模のKotlinカンファレンスがありますが、それに負けないくらいの熱量を持ったカンファレンスでした。有難いことにこんな可愛いトートバッグも頂きました!

f:id:tommy_kw:20180826160254j:plain

発表内容

オープニングトーク(長澤太郎さん、藤原聖さん)

内容

  • Kotlinを愛でるをテーマに
    • 日々の開発、業務を楽しむ
    • Kotlinを盛り上げ
    • Kotlinは可愛い言語
    • みんなでKotlinを愛でる
  • 長澤太郎さんとKotlin
    • 6年前にKotlinと出会う
    • イベント、勉強会、執筆活動でKotlinに貢献
    • 日本Kotlinユーザグループの代表を務める
  • なぜKotlinFestを開催したのか
    • 「Kotlinのカンファレンスいつやるの?」とよく聞かれていた
    • 「俺がやらなきゃ誰がやる!!!」という思いに駆られ、昨年のDroidKaigiでKotlinFest開催をサプライズ発表した
    • 日本Kotlinユーザグループとして開催することを決定
    • コミュニティは生き物であり、スピーカー、スタッフ、運営、参加者などが支えるもの
  • Kotlinの哲学
    • 実用主義
    • 簡潔
    • 安全
    • 相互運用性
  • Kotlinを知るリソース

感想

今回のKotlinFestのテーマは「Kotlinを愛でる」。これは、Kotlin in Action本の原著に「Embracing Kotlin」と表現されていた箇所をわかりやすく日本語訳した意味になります。しかしKotlinを愛でるためには、Kotlinを知る必要があるため、KotinFestでKotlinを知って、さらに愛でようという思いが込められていました。「KotlinってAndroidで使うもの?」というイメージがあるかもしれませんが、Androidエンジニア以外の方にもKotlinを知ってもらうため、サーバサイドやKotlinを知るためのセッションが多く盛り込まれていました。昨年サンフランシスコで開催されたKotlinConfを見に行き熱量の高さに圧倒されましたが、KotlinFestもそれに負けないくらい高い熱量を持ったイベントでした。

Kotlinもう一歩(森洋之さん)

内容

  • Kotlinのタイプシステム
    • クラスとタイプがある。val s: String? = "string" // class:String、type:String?と必ずしも同じ訳ではない
    • タイプによってできる操作(例えば文字列を加算)が決まるため、val s: String? = "string"; s.hashCode() // NGとなる
    • つまり安全!
  • タイプとサブタイプ
    • あるタイプが期待される全ての箇所で使えるタイプをサブタイプ
    • Any?は全てのタイプのスーパータイプ
    • Nothingは全てのタイプのサブタイプ
  • ジェネリクス
    • 異なる型を表現するときにジェネリクスを使う
    • Type Erasureがあり型情報は実行時に消える
    • 不変、共変、反変の3種類の変位がある
  • Type Projection
    • val nums: MutableList<in Int> = mutableListOf<Number>(1.0,2.0,3.0)定義する場所ではなく、使う箇所でout/in修飾子を使う
  • Star Projection
    • ジェネリクスな型タイプが実際にわからないときに使う
    • Javaは?マーク型で、Kotlinは*を使う
    • val list: MutableList<*> = mutableListOf<Int>(1,2,3); list.add(4.0) // 追加できない 値を取り出すことはできるが安全ではないため追加できない

感想

タイトルの通りKotlinをさらに知るためのタイプシステムやジェネリクスについてのお話でした。ジェネリクスはAndroidアプリ開発だと利用する箇所が限られるため不変、共変、反変周りがちょっと難しかったです。長澤太郎さんが公開している初学者向け「Kotlinでジェネリクスを学ぼう」こちらの資料も併せて読むとスッと理解できるかもしれません。また冒頭で紹介がありました「基本からしっかり身につくAndroidアプリ開発入門」を購入しましたので、これから読んでみたいと思います!

How to Test Server-side Kotlin(鈴木健太さん、前原秀徳さん)

内容

  • レガシーシステムで試したテスト方法
    • 10年くらい前の技術スタックで実装されたレガシーシステムをサーバサイドKotlinにリプレイス。そこで培ったテスト方法を紹介
    • テーブル数は100個から200個くらい
    • 独自Javaフレームワーク、XSLT、テストなし
    • テストのあるシステムにリプレイス。フロントはRails、Nuxt.js。SprintBoot + Kotlinで実装されたAPIサーバ
    • 今回はあくまで単体テスト、DBのインテグレーションテストについて紹介
  • サーバサイドKotlinの有用なテストライブラリ
    • テスティングフレームワークは、JUnit4、JUnit5、Spek、KotlinTest、TestNG、Spock。spring-boot-starter-testのデフォルトに従い、JUnit4を採用
    • アサーションライブラリはHamcrest、AssertJ、KotlinTestなどたくさんあるが、AssertJを採用。sprint-boot-starter-testのデフォルトに従う
    • モックライブラリは、Mokito、Mokito-Kotlin、Mockkがある。Mockito-Kotlin、Mockkのany()を使えばMockito.any()問題は起きない。Mockito-Kotlinを採用
    • DBセットアップライブラリは、DBUnit、DBSetupなどがあり、DbSetup-kotlinを採用
  • サーバサイドKotlinのテスト方法
    • presentation、domain、application、infrastructure構成
    • テスト方針は基本的にapplication層のテストを書く。domain層もテストするがロジックが複雑なところに限る
    • applicationを厚めに書くことによって仕様の正しさを担保する。それによって下のdomain層のリファクタリングもしやすくなる
    • データベースはモックにしない。DbSetup-kotlinでDBのセットアップをした
    • AssertJ-DBでDB状態(DBの変更)をチェック
    • JSON APIはSpringのMockMVCを利用
  • テストツールの紹介
    • Factlin。既存のデータベーススキーマからDbSetup用のコードを生成するライブラリ
    • Kotlin Fill Class。引数の多いコンストラクタを簡単に記述できるIntelliJ Plugin

感想

知見が多く大変参考になりました。ママリで使用しているライブラリは、KotlinTestとMokitoでMockitoのwhenがKotlinの予約語と被るので紹介していただいたMockkライブラリを使ってみます。加えて単体テストに纏わるお話でしたが、機能テスト、探索的テスト、パフォーマンスなどのアジャイルテストもぜひ聞いてみたいです。最後にIntelliJ Plugin Kotlin Fill Classがとても便利で早速利用させていただきました。ソースコードも勉強になるので是非興味のある方はご覧ください。

start from Convert to Kotlin(望月美帆さん)

内容

  • AndoridプロジェクトにおいてまだJavaのアプリが多い
    • Androidは10年続いている世界だが、Kotlinは公式言語としてサポートされたのはまだ1年
    • 1年ちょいのためやはりJavaアプリの方が多い
    • 今までのJava資産を使うことが多い
  • Kotlinをプロジェクトに導入して良いことだらけなんだっけ
    • 開始3年のサービスは最初にテストから導入
    • 開始1年のサービスはKotlin Beta版だったのでJavaを選択する。新しく作る部分にはKotlinを導入
    • 開始5年のサービスは完全Javaレガシーだったので積極的にKotlinにリプレイス
    • 今までKotlinを導入しなかったことがない。Kotlinを選択しない理由がない
    • Javaのコードで不足がない、パフォーマンスをカリカリにするなどの時はJavaを選択
  • Androidアプリにて上手にKotlin化するには?
    • テストでKotlinを使う
    • 新しい機能追加などで部分的に導入する
    • 既存のJavaコードをKotlinにConvertする
  • Convert to Kotlin
    • Android Studioにて「Convert Java File to Kotlin File」で一発変換
    • Convertだけでは読みやすいコードにするのは難しい部分もあるので手動である程度直す必要がある
    • 「Kotlinらしい」だけではなく、「読みやすいコード」、「壊れないコード」を目指す

感想

セッション終了後「帰ってからKotlinしたい!」という気持ちになりました!冒頭であった「Javaのアプリの方がまだ多い」について普段Kotlinを使っていることが多いので感覚としてKotlinアプリが多いのかなと錯覚していましたが、Kotlinが正式言語採用されてまだ1年。まだまだJavaアプリが多いのでConvert to Kotlinは有用な機能だと改めて感じました。Covnert to Kotlinはママリでもよく利用していて、説明にもあった通りそれだけではまだ読みやすいコードにならないケースがあります。Covnert to Kotlinってどうやって処理しているのか気になったのでコードをみてみたいと思います!

Kotlin コルーチンを理解しよう(八木俊広さん)

内容

  • コルーチンとは?
    • メルヴィン・コンウェイの1963年の論文が初出
    • 継続状況を持つプログラムを簡単に記述できる
    • サブルーチンは普通の関数で呼び出しから最後まで実行。一方コルーチンはある途中で止まって後から再開できるインスタンス
    • コールバックスタイルと違ってフラットにかける
  • Kotlinはどのようにコルーチンを表現しているのか
    • Javaのバイトコードから実装方法を探る
    • コルーチンの中断と再開をステートマシンとして表現している
    • コルーチンを再開するためにステートマシン内でキャプチャする
    • 内部状態を変化させながら実行する
    • Kotlinではsuspend修飾子を使っていて、コンパイル時に自動で継続インターフェースの引数が付加される
    • コルーチンビルダーと継続的インターフェースを使って簡単に実装できる
  • Kotlinコルーチンの基本的な使い方
    • Kotlin1.1 experimentalでコルーチンを利用可能
    • コルーチンを利用するには、kotlinx.corutinesの各種ライブラリから利用できる
    • Kotlin1.3でStableになり、今触ってもそんなに変更はないはず
    • launch関数は、コルーチンを生成している訳ではない。JOBを返すがコルーチンではない。ちょっとコルーチンに関与できる
    • AndroidでUIを触る際にlaunch関数だけではなく、継続的インターセプターをセットする必要がある
    • async関数はDeferredを返すメソッド
  • まだまだあるKotlinコルーチンの使い方
    • Retrofitでコルーチンを利用するにはJakeWhartonさんのretrofit2-kotlin-coroutines-adapterを使うとDeferredを返してくれる
    • EventBusとしても使える
    • すでにコルーチンに対応したサードパーティ製のライブラリも増えている

感想

コルーチンはステートマシンとして表現されているんですね!内部実装までちゃんと理解されて本当に圧倒されました!さらにとてもわかりやすいコルーチンの説明でサードパーティ製のライブラリでもコルーチンサポートしているものが増えてきたので、Androidアプリでもコルーチンを使ってもいいかなと素直に思いました。あとJavaコードに変換したコルーチンのコードを読むの面白そうだったので、理解を深めるという意味でもデコンパイルを利用してコードを見てみたいと思います!

How to Kontribute (v4 JP) しらじさん

photos.google.com

内容

  • Ubieの福利厚生
    • 長澤太郎さんがいること!
  • Kontributeするための環境構築
    • JDK1.6、JDK1.7、JDK1.8、JDK9(or 10)
    • Intelij Idea Communication(or Ultimate)
    • Github Kotlin Repositoryセットアップ
    • Idea Pluginsセットアップ
  • 困った時のコミュニケーション手段
    • Slack Kotlinlang #kontributorsにジョインして分からないことがあれば質問できる
    • YoutrackでIssue管理を行い、Issueについてディスカッションできる
    • Github KotlinではPRのやり取りをする
  • 誰でも簡単に取り組めるKontribute
    • Readmeなどのタイポやコメントの修正
    • サンプルコードを提供する
  • 少しステップアップしたKontribute(IDE Plugin)
    • Inspectionファイルの作成
    • Inspectionとは特定のコードに対してワーニングやエラーとして表示してくれる機能
    • PSI(Program Structure Interface) Viewerを使うとPSI構造が可視化できる

感想

しらじさんの「How to Kontribute」はバージョンv4で、こちらの資料やしらじさんの登壇内容に感化されてKontributorになった方は20人くらいいるのではないでしょうか?(すみません、めちゃくちゃざっくりです)。現在Kontributorは248名でこの登壇をきっかけにさらにKontributorが生まれると僕も嬉しく思います。Kontributeすることによって、JetBrainsのエンジニアさんからフィードバックをいただけて学びが深いですし、PRがマージされるとKotlinブログにも名前が載るのでモチベーション向上に繋がります。しらじさんがお話していた通り、ハードルは高くないと思うので是非ご興味のある方は資料を見ながらKontributorにチャレンジしてみてください!

まとめ

初めて日本でこれほど大きな規模のKotlinカンファレンスが開催されて、本当に関係者の皆さんに感謝しております。当日「#kotlinfest」がtwitterのトレンド入りをして注目度も高く、参加者の拍手や暖かいフィードバックがとても印象的でした。さらに登壇者の皆さんの資料がとてもわかりやすく資料を見るだけでも勉強になることが多かったです。今回のカンファレンスをきっかけにKotlinを好きになった方やさらに好きになった方もたくさんいらっしゃると思います。

KotlinFest 2018は終了しましたが、Kotlinイベントはまだまだ続きます!今年の10月にKotlinConf 2018がオランダで開催されます。そこでは、KontributorのKirill Rakhmanさんによる「Kotlin JSによるWebブラウザ拡張」、KotlinFestでも少しだけ紹介があったΛrrowについて、ΛrrowメンテナーのRaúl Raja Martínezさんによる「Arrowライブラリによる関数プログラミング」、GoogleのKevin Mostさんによる「Kotlinコンパイラプラグイン作り」など面白いセッションが盛りだくさんです!気になるセッションがあれば資料など公開されると思いますのでチェックしてみると良いかもしれません。来年もKotlinFestが開催されるのを心待ちにしております!!

RDS for MySQLからAuroraへの移行 〜Auroraリードレプリカを利用した低コスト移行方式〜

こんにちは。インフラエンジニアの永井(shnagai)です。

今回は、メインサービスで使っているDBを、RDS for MySQLからAmazon Auroraへ移行した話について書こうと思います。

Auroraの良さについては、一つ前のブログにまとめているので気になる方はこちらをご覧ください。

tech.connehito.com

なぜAurora移行を行ったのか

可用性を担保しながら、コストメリットが享受できる

RDS for MySQL時代は可用性を確保する為に、マスター、レプリカ全て MultiAZ構成で組んでいました。しかし、MultiAZだとアクティブ-スタンバイ構成なので、スタンバイ機はトラフィックを捌かず寝ている状態になります。

Auroraにすることで、マスター - レプリカ間のフェイルオーバーが可能になり、全てのRDSインスタンスをアクティブに運用することで、同じマスタとレプリカの台数で運用した場合に、コスト削減が図れます。

運用面のメリットを享受したかった

下記にあるような、Auroraが提供している機能を使うことでDBA的な仕事を出来るだけ減らし運用負荷なくサービス運用が可能になります。

  • リーダエンドポイントでの、リードレプリカへのヘルスチェック付きLB機能
  • アプリケーションからのセッション切断なく行われる、ゼロダウンタイムパッチ
  • パフォーマンス劣化の少ない AuditLogでの監査(MySQLだとパフォーマンス 1/3程になるという話で使いづらかった)
  • 最近GAされたパフォーマンスインサイトやCloudWatchでDBエンジン関連のものが見れることで、何もしなくても詳細なモニタリングが可能になる

Aurora移行後のアーキテクチャ f:id:nagais:20180828130021j:plain

Aurora移行でのメイン検証

メインデータベースの移行だったので、慎重な検証を重ねた末に移行を行いました。 時系列での、移行プロセスは後述するので、ここでは検証時に特に注力した2点について書こうと思います。

①DBエンジンがMySQL5.6からAuroraに変わることで、アプリケーション側で予期せぬエラーや性能劣化が発生しないか

AuroraはMySQL5.6互換で、移行前はコネヒトでもMySQL5.6を使っていました。 AWS SAに聞いたり公式ドキュメントを見ながら、ある程度Aurora自体枯れてきていて、他社での移行実績もあるので、Aurora移行対策でのアプリケーション修正は不要だろうと踏んでいました。

しかし、やはり不安はあったので、事前検証として、ステージング環境のAurora化・本番環境での読み取りトラフィックへのAuroraのカナリアリリースを通して、実際のトラフィックを裁く中で、もしエラーを検知した場合は、アプリケーションを修正するというスタンスを取りました。

結果として、Aurora導入にあたりアプリケーション側の改修は0でした。アプリケーション起点で工数をかけて調査するのではなく、カナリアリリースで本番トラフィックを受けるこの方法は、クラウドネイティブな考えに通ずるところがあり個人的には気に入っています。もちろんユーザに迷惑をかけないために、ステージングである程度試験してからカナリアリリースは行っていますが。

②MySQLからAuroraへのマスター(書込トラフィック)切替時のオペレーション

今回の、Aurora移行は、オンライン中に行いました。(ユーザへのメンテナンス周知等はもちろん行ってます) メインDBの切替ですので、書込トラフィックをいかに短時間でRDS for MySQLからAuroraに切替られるのかが移行の肝でした。当日作業でのダウンタイムを小さくすることを重要視しプランを練り、ステージング環境の切替時に実際のオペレーションを行いつつ、時間計測も行いました。

一番迷ったのは、切替時の書込データロストを防ぐ為の書込トラフィック遮断の方法です。ダウンタイムを小さくする事を最優先したので、RDSマスタをリードオンリーモードにするのが正攻法なところですが、SecurityGroupを使い、L4レイヤでMySQLへの通信を遮断する方法を選択しました。

以下が、検証の結果書込トラフィック移行の最終的な流れです。やること自体はとてもシンプルな内容になりました。

MySQLへの書込トラフィックを遮断(Route53の切替)
 - Route53の書込用DBレコードを、Auroraのリーダエンドポイントに切替(アプリケーションは書込トラフィックのみエラー検知)
 - アプリケーション側でセッションを使い回す可能性があるので、セキュリティグループにてMySQLマスターへのMySQL通信遮断
↓
最終書込のAuroraへのレプリケーション確認
↓
Auroraマスター昇格
↓
書込トラフィックをAuroraへ切替(Route53)

時系列で見たAurora移行の流れ

ここからは、実際にコネヒトで行った、RDS for MySQL5.6からAmazon Auroraへの移行について手順を、時系列で解説しようと思います。作業を出来る限り分解して、④までの作業は事前作業として、実際の深夜の切替作業は、⑤の書込トラフィックの切替のみで済むように設計しました。

【移行ステップ】

①Auroraリードレプリカを本番の読み取りトラフィックにカナリアリリース

②ステージング環境を、Aurora構成に切替

③本番の読み取りトラフィックを100%Aurora化

④サービス用途以外のレプリカDBを、Auroraをマスターとするbinlogレプリにて作成

⑤書込トラフィックのAuroraへの切替

ざっくり言うと、RDS for MySQLから作成出来るAuroraリードレプリカを使ったAurora移行形式です。RDS for MySQLからの移行だと、DMS(AWS Database Migration Service )を使うまでもなく、手軽にAurora移行が実現出来ます。

移行前の状態

まずは、Aurora移行前のアーキテクチャを簡単に紹介しておきます。

  • サービスで使っているRDS for MySQLは、可用性を確保するために全てMultiAZ構成
  • アプリケーションからのread only通信は、Route53で負荷分散(ヘルスチェックは使えないので、MultiAZ構成で可用性担保)
  • データ分析等に使うため、別サブネットにもRDSレプリカを配置し、社内から直接参照

f:id:nagais:20180828130053j:plain

以下、各ステップについて解説していきます。

①Auroraリードレプリカを本番の読み取りトラフィックにカナリアリリース

便利なことに、RDS for MySQLのレプリカとしてAuroraリードレプリカを作成することが出来ます。(異なるデータベースエンジンでデータの同期が出来るってすごい活気的だなと思います) アプリケーション側で予期せぬ挙動が発生しないかを確認するため、2週間程Auroraリードレプリカを本番の読み取りトラフィックにカナリアリリースしました。

カナリアリリースは、Route53の重み付けレシオ(Weight)を利用して行っています。 徐々に比率を上げていき、50%ずつ振り分けている時に、DBエンジンとしての性能差やホスト側の負荷状況も比較を行いました。コネヒトでは、潤沢なメモリのインスタンスを利用しているので、ほぼバッファキャッシュで返しており、Auroraによる大幅な性能向上は計測されませんでしたが、AuditLogを有効化した状態でもレイテンシ悪化しない事を確認出来ました。 このステップで、アプリケーション側で予期せぬエラー等何も問題が起きなかったのでAurora移行の実施を決定しました。

f:id:nagais:20180828130104j:plain

②ステージング環境を、Aurora構成に切替

次に、RDS for MySQLで稼働していたステージング環境を、Auroraに切替えました。 ここでの切替の目的は下記2つです。

1.カナリアリリースでは確認出来なかった、書込系処理でアプリケーション側の予期せぬエラーが出ないかのチェック

2.本番同等の手順で実施し、手順に漏れがないかのリハーサル的役割

問題なくステージング環境の移行は成功し、ここでも2週間程意図せぬ問題が出ないかウォッチを続けました。

③本番の読み取りトラフィックを100%Aurora化

Auroraに切り替えても、アプリケーション的に問題が発生しないことがわかったので、本番の読み取りトラフィックを全てAuroraレプリカで処理する構成にしました。これは、移行当日のオペレーションを少しでも少なくするという意図があります。 Route53で振り分けるエンドポイントとしては、インスタンスのエンドポイントではなく、Auroraクラスタの[cluster endpoint]と[reader endpoint]に50%ずつの割合で振り分けました。

f:id:nagais:20180828130123j:plain

④サービス用途以外のレプリカDBを、Auroraをマスターとするbinlogレプリにて作成

コネヒトでは、サービス用途以外でもレプリカDBを使っています。 ですが、Auroraレプリカは、起動時点でAuroraクラスタの[reader endpoint]のメンバになります。[reader endpoint]は、アプリケーションからの読み取りトラフィックを処理させるエンドポイントに使っているため、Auroraレプリカをサービス以外の用途で使うことは仕組み上出来ません。

この状況を回避するために、Auroraライターからbinlogレプリを手動で組み、RDS for MySQLのインスタンスを運用する構成にしました。2台必要でしたので、Auroraライターの2スレッドとbinlogを有効にすることのオーバーヘッドが懸念されましたが、特に負荷的な問題はありませんでした。

本当は、複数の[reader endpoint]を作り用途毎に分散出来ると最高なのですが、現時点ではそのような機能はありませんでした。(先にも出来るかわからないですがほしい)

移行方法については、下記公式リファレンスに丁寧にまとめられておりこちらを参考に特につまづきポイントなく行えました。(通常のMySQLの非同期レプリとほぼ同じ手順です)

Aurora と MySQL との間、または Aurora と別の Aurora DB クラスターとの間のレプリケーション - Amazon Aurora

このステップが終わった段階で、残るはアプリケーションの書込トラフィックを司る、MySQLマスターをAuroraに切り替える作業だけとなりました。

f:id:nagais:20180828130137j:plain

⑤書込トラフィックのAuroraへの切替

いよいよ移行当日です。 当日は、サービスのトラフィックが最も少ない時間を狙ってメンテナンス通知を出して移行作業を行いました。

1. MySQLへの書込トラフィックを遮断

まず、MySQLマスタへの書込トラフィックを遮断しました。

  • route53で、書込エンドポイントの向け先をAuroraクラスタの[reader endpoint]に変更
  • セキュリティグループを編集し、MySQLマスタへの3306通信を遮断
2. 最終書込のAuroraへのレプリケーション確認

Auroraライターで、レプリカラグが0になり全てのMySQLマスタのトランザクションが伝搬されたことを確認。

3. Auroraマスター昇格

Auroraライターを昇格させて、Auroraクラスタのロールをマスターに変更します(1分かからないくらい)

4. 書込トラフィックをAuroraへ切替

route53で、書込エンドポイントの向け先をAuroraクラスタの[cluster endpoint]に変更

これで、切替は済んだので、アプリケーションの試験やエラーのウォッチに入り、全ての項目をパスした段階でMySQLマスタはスナップショットを取得した後、削除しました。

※VPCフローログを使って、MySQLマスターへのMySQL通信がDenyされていることを気軽に確認出来るのも作業短縮に大いに役立ちました。

当日は3分強のダウンタイムでAurora移行が実現出来ました。

※段階的に検証を重ねていたので、まぁないだろうとは思いつつ、もちろんロールバックプランも用意しました。この形式だと、MySQLマスタからレプリを全て組み直し、Auroraライターに書き込まれた差分データを確認してMySQLに書き戻すような地獄のような作業です。。。

f:id:nagais:20180828130223j:plain

RDS for MySQLから移行する時の注意点

  • パラメータグループが、クラスタとインスタンスに別れているので注意

RDS for MySQLからの移行だったので、既存のパラメータグループをAurora用のパラメータグループにコピーする必要がありました。その際に、Auroraのパラメータグループには、クラスタパラメータグループとインスタンスパラメータグループに分かれており、項目毎に分割されているので注意が必要です。

こちらに詳しくまとまっています。

Amazon Aurora MySQLリファレンス - Amazon Aurora

  • バックトラックは、binlogレプリを組んでいる場合は使えない。

Auroraのうれしい機能であるバックトラック機能(オペミス時等に巻き戻しが可能)ですが、binlogレプリを組んでいると使えません。仕組み的にそれはそうだなと思うのですが、binlogレプリは、機能別リーダエンドポイント的なものが出来れば捨てられるので進化に期待だなというところです。(バックトラックは、クラスタ作成時しか有効に出来なかったはずなので、この先導入は難しいですが。。)

Auroraへの要望

移行や検証している中で、Auroraに今後出来たら更に楽になるなと思うところがあったので書き留めておきます。

複数のリーダエンドポイントを設けたい

再三書いてはいますが、役割別にリーダエンドポイントを作れるとAuroraレプリカの自由度が増すので出来たらうれしいなと思っています。

binlogレプリだと、レプリケーションのステータスを自前で監視する必要が出てきますが、全てAuroraに出来ればそれもCloudWatchでまかなえるので。

新規レプリカ作成時に、別レプリカからキャッシュをロードしてくれるとうれしい

Auroraはキャッシュ層をDBエンジンと分離してもつアーキテクチャなので、インスタンス再起動時にシャットダウン前のページキャッシュを保存し、再起動時にそれをロードしてくれるため、俗にいうあたため行為(キャッシュ作り)が不要です。

Aurora自体、Auto Scalling機能をもっており、新規レプリカ作成時も何らかの方法でキャッシュをロードするような仕組みがあると更にDB運用が楽になると思っています。

さいごに

メインDBのAurora化というインパクトの大きな緊張感ある作業でしたが、AWSが提供してくれている機能をうまく使うことで、作業を分割しながらリスクヘッジして進めることが出来ました。特に、MySQL5.6互換であることとAuroraリードレプリカの存在が大きかったです。 何もなさすぎて本当に大丈夫なのか?というくらい、何のエラーや障害もなくメインDBのAurora化が終わり現在も元気に動いてます。

Auroraにすることで、性能面・運用面・コスト面(構成次第)で様々なメリットが享受出来、移行自体もMySQL5.6を使っている環境であればそれほど大変ではないのでおすすめです。 このブログがAurora移行を検討している方の何らかの助けになれると幸いです。

コネヒトではコンテナ周りの基盤を整備したりサービス改善を行うエンジニアを募集しています。 少しでも興味もたれた方は、是非気軽にオフィスに遊びにきていただけるとうれしいです。

www.wantedly.com