isucon2019予選 1日目の参加記録
イントロダクション
9/17(土)にisuconに会社の同僚2名(以下 Aさん、Bさんで表記)と参戦してきました。 結果は、あえなく失敗でしたが、集まってわいわい言いながら問題に向かっていく、というのはとても楽しかったです。
また、問題も今までとは傾向の違うところがあったり、なるほどーと思わされるところがあったりと、とても楽しませていただきました。 運営の皆様、そして一緒に出場してくれた同僚の2名、どうもありがとうございました!
isucon9予選の問題
isucariという椅子を売りたい人と買いたい人をつなぐサービス UIや画像からマイクロサービスでのサーバーサイドのアプリケーションまで、すごくしっかり作り込まれていました。
同僚と振り返りで出た話でも、今までの問題と比べて改善ポイントが見つけづらかった、というのが出ていました
当日の記録メモ
AM10:00〜
会社の会議室に集合して準備。公式で10分ほど遅れるとのアナウンスがあり、おっとトラブルかー、という気持ちと、「10分で直すってすごいな。。大丈夫かな」とか考えていましたが、 本当に10分もかからず対応完了で10:10から競技開始。
早速マニュアルの確認から。 isucari...、あ、本当にメルカリで来たのか。 け、決済、、QR、、ここまで、対応しているのかと思いながら、マニュアルを眺めていました。
その間に、AさんがAlibabaCloudでインスタンスの作成。 自分はAWSとかもちゃんと触ったことなかったので、ふむふむと見させてもらいつつ自分一人だったら絶対ハマってたなぁと思ったりしていた。
無事にインスタンスが作成されてIPが共有されたので各自sshの設定をしてログイン。 その後、サーバのプロセスや確認してnginx,mysqlが動いていて初期実装でgoのアプリが動いていることを確認。
自分はそれと並行して、運用スクリプトをいじったりansibleの設定を直したりしていた。
Bさんはgoの設定やリポジトリへのpushをしたり、schemaSpyというツールでスキーマ構成を把握したり、アプリのコードを追いかけたりとしてもらっていた。 これのおかげでローカルでのコンパイルやインスタンスへのデプロイも手軽に出来て効率的に進められたように思う。
AM11:00くらい?
ここらで、まずはベンチを動かしてみることに。 nginxのログ設定とmysqlのスロークエリログの設定をしてベンチを開始、だが、スロークエリが出ない。。 設定を確認してみたらスロークエリOFF、ロングクエリタイム=1になっていた(逆にしたつもりでいた)という感じで、初っ端からミス・・
気を取り直して、設定を修正して再度ベンチを実施。 インデックスちょっと張ってみるかーといった話が出てきたり、ログやコードからN+1クエリ直さないとね、という話をしたり、 categoriesあたりはメモリに載せちゃおうかという話をしたりしていた。
ここで分担しつつ作業を進めていくが、ローカルでアプリがうまく動かせず、それと並行しつつ対応。 とりあえずローカルでコンパイルして問題なければ、サーバにデプロイして確認するかーという感じなり、それぞれの担当作業に着手。
Bさんがものすごい勢いでN+1クエリを解消。あとでコミットログ見ると凄まじい発想力と実装力。。まじで神・・ 自分はcategoriesのキャッシュ化に着手。 Aさんはクエリのインデックス作成や問題のありそうなクエリや実装の調査を対応。
go力や把握力が低くて、まずなぜかMapでのキャッシュ化を試みて、時間をかけて対応したものの、全然使えないことに気づく。。マジで使えないやつ。。 その後に、構造体でちゃんと持てばいいじゃんと気づき、対応するものの、既存のクエリでは全件、取得のところしか切り替えられず、 他のところはフィルタリングなどがうまくいかずつまる・・
そんなこんなしているうちに、BさんがN+1を解消した実装でベンチを回すが、あれ、、あんまり負荷が上がっていかない?という話が出てきた。 Aさんがマニュアルをチェックしてくれて、ここでキャンペーンの設定があることに気づく。
ここの変更と自分の中途半端な実装を混ぜて一旦デプロイして再度、ベンチを回してみることに。 まずはレベル4で、当然のように落ちる。。
スロークエリを見てみてもあまりそれらしいものは出てこないのでDB問題ではなさそう。 nginxのログから新着一覧の取得あたりが遅そう?という話になり、とりあえずそのあたりも含めてがっつりコードを追ってみることに。 自分はAPIのコードや呼び出し部分もしかして改善必要?と思って見てみたり、/buyが怪しそうということで、処理の流れを見ていたりした。
PM0:00~2:00くらい
確かこの辺りで、カテゴリのparent_id引いているところ決めてうちで固定値で何とかなりそうでは、という話がAさんから出て対応してもらったり、改善できそうなクエリを直してもらったりした。 途中、/buyのuserのロックいらないのでは?と思い、FOR UPDATE外してみたり、不要なロックしている箇所がなさそうか見ていじってみたりしたが改善が見られず・・ 思い返してみると、この辺でnetdataやプロファイルとか入れられればよかったかも。
途中nginxが1コアしかつかっていない事に気づいて設定を修正してもみるが、改善は見られず。
PM2:00くらい
いったん昼飯を挟みつつ、goのnet/httpが同一の最大接続数のデフォルト設定が2であることを発見。 32まで増やしてみるが変わらず・・いま思えばもっと前で止まっているので当然・・
お昼食べつつ、みんなでマニュアルを見返して、あー、ちゃんと更新や登録は即座に反映しないとって明記されているね。って話をしたり、 カテゴリ新着一覧はやたら「即座に」って書いているのに、新着一覧がないのは即座に返さなくていいってこと?インデックスページなのでキャッシュ使って改善した方がいいのでは?どうしようかー という話が出て、主眼は新着一覧ページをどう改善するかに変わってきた
PM3:00くらい
ここでAさんが高い商品を買ってもらえるようにすればスコア出るのでは?クエリのORDER変えてみては?という話から、それやってみようとなり、対応してもらうものの、どうやらここはいじってていけない的なエラーが発生。 この辺り、AさんとBさんのお二人が色々トライ&エラーで対応してくれていて、自分はAPI呼び出し部分なんとか出来ないかなー、もしくはロック減らせないか、とか考えいていたが何も出てこず。。
pprofでプロファイル取ってみたのは、この辺だったはず。 やっぱり新着一覧がって話とログイン周り時間かかっているねって話になり、ログイン周り見てみるが怪しげなところが見つけられず。 プロファイルでログイン周りのロジックで負荷が高そうというのは出ていたものの、ハッシュ化のところで、ん?ってなったが、ここはいじれないかーと思い、手を出さなかったのは、後悔ポイントの一つ。せめてcostいじっておくべきだったよ・・
この辺でnetdataも入れてみる。ポートが開いておらず試行錯誤。AlibabaCloudのコンソールでポートを開けてもらいやっと見れる状態に。 この辺でハマる自分のレベルの低さを痛感。。
トライ&エラーでログをみながら、ロックってログが出てるなんだろ?/buyだね、という話になり、同僚がロックエラーが出ているIDをログに出してみようと提案。 早速、対応してもらいベンチ回してみると同じ商品に対する購入処理が集中して、落ちていることが判明。 神エンジニアが排他制御を入れてくれ、ベンチを回してみると、5,000くらい?(記憶が怪しい)がスコアが出てくれるようになり、光が見えてきた。 その後、数回、ベンチを回してみてちゃんとスコアが出るようになったことを確認しつつ、同僚二人が諸々、修正を実施してくれて5,000くらい?で一時的に30位以内(たしか、そのくらい)に入った。
PM4:00
CPUがボトルネックであることはわかっていたので、よし、これを複数台構成にすれば、もっと改善するのでは?ということで、この辺りか複数台構成への変更に着手開始。 排他制御はこのままだと複数台構成にできないということで、redisを使って排他制御をする事に。これを同僚がサクッと実装、マジで神。
redis自体は自分が用意していたansibleで入れるつもりがエラー連発。 結局、同僚が見つけてくれた対応方法を実施したり、同僚が対応入れてくれたりで解決。
ここから自分はnginxの複数台構成の設定に着手。
PM5:00
間違えてグローバルIPで接続しようとしたりするなどショボいミスをしつつもとりあえず設定完了して、ベンチ開始。 ちゃんと振り分けができていることは確認できたが、どうにもすぐ落ちる。 ここで、画像が複数台対応してないじゃん、と気づき/uploadの場合、自サーバのみを見るように変更。 しかし、それでもまだ落ちるし、IPエラーみたいなログも出るし、時間もないしで調査。 ここで、/sellも画像、関係していると気づき対応しtベンチを回す。これが確かPM6:00前くらい。
ギリギリで間に合ったかと思ったがFAILし、結局、このまま解決せずタイムアップ。
タイムアップ後
ログを確認していると、なぜかhttp301が出ている事に気づく、これに気づきnginxのlocation設定が間違っている可能性が浮上。 手元の環境で設定を直して、画面から確認してみるとエラーになるところが解消。"/sell"とすべきところを"/sell/"にしていたせいという、痛恨のミス。 これは本当に申し訳ないことをしてしまった・・ マジでちゃんとnginx勉強しとけよ自分、と切に、切に思いました。
p.s 帰宅後、同僚が入れてくれた修正などを見て、あの短時間でここまでの修正を、、これをFAILにしてしまって本当に申し訳ない気持ちでいっぱいになりました
全体振り返りなど
- ansibleやログローテスクリプトなどを事前に用意していたが、色々ツメが甘くログローテスクリプト以外はあんまり役に立たなかった気がする
- ansibleはubuntuでの設定ファイルの構成に合わせておくべきだった(isucon8のcentosの構成に合わせていたため勉強不足もありハマった)
- goでのロジックがさらっと書けなかったのは、単純に力不足と練習不足だったのでここはちゃんと勉強しておく
- newrelicなどマイクロサービスでのボトルネックなどを可視化出来るようなツールにも慣れておく
- nginxとmysqlは基本なので定期的に勉強しておく
来年も機会があれば参加したいです。なので、それまでの今回の反省点を少しでもつぶせるようにしたい
Could Native Days Tokyo 2019/Openstack Days Tokyo 2019に行ってきた(2日目)
Could Native Days Tokyo 2019/Openstack Days Tokyo 2019に7/22・23の2日間参加させてもらったので、2日目に参加したセッションのメモと簡単な感想などをまとめました。
keynote
楽天モバイルの世界初完全仮想化クラウド型モバイルネットワーク
MNO算入などで話題になっている楽天モバイルの話。 OpenStackを使っているんだな以外のことは、自分には難しくてほとんど理解出来なかったが、 色々な挑戦や工夫を凝らされたサービスがどうなっていくのかは非常に楽しみだと感じた。
メモ
- OpenStackを使って仮想ネットワークプラットフォームを構築
- 主な構成はvRAN, EPC CODE, IMS
- generic vNet manager
- 楽天の基地局はvBBUを利用しているためアンテナとpower board,バッテリーだけで設置
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発(鈴木順也さん from SBペイメントサービス)
決済システムでSpringを利用しているということや、cloud foundryは自分自身も利用経験があったので、個人的にとても興味深いキーノートだった。 決済代行というプラットフォーム提供側ということで、運用やObserverbilityの取り組みはすごくしっかりしているんだなと思わされた。
内製化に至る道程
- 元々は内部のエンジニアがいなかった
- マニュアルオペが多くてミスも多かった
- spring-boot+seleniumで運用自動化
- マニュアルオペが多くてミスも多かった
- モダンな開発・運用の実現のためにspring-bootを導入
- 加盟店数は約11万
- PCFとConcorseCIを利用
PCFを選んだ理由
- リリース改善
- ゼロダウンタイム
- ワンクリックリリースetc.
- クラウドのフル活用
- オートヒーリングetc
- k8sは学習コストや導入コストが高そうなのでPaaSを選択
- 決済で高いセキュリティも求められるためprivate cloud PaaSを選定
アーキテクチャ
- Java+Spring-bootのマイクロサービス
- GWを通って決済機関ごとのマイクロサービスとやりとり
- 決済会社とのやり取り部分はCircuit breakerを利用
- 他のサービスへの障害の伝搬を起こさないように
- 決済会社とのやり取り部分はCircuit breakerを利用
Observerbility
- metrics -> Grafana(micrometer), Prometheus
- CPU,ヒープ,GCなど
- logging -> Elastic, Kibana
- tracing -> zipkin
- サービスのモニタリング、ダッシュボード化も実施
- 決済手段ごとのOK数、NG数などもモニタリング
- 決済高、取扱高などもモニタリング
- どう実現しているのだろう?
金融領域におけるOpensStackの導入事例の紹介(佐藤優典さん、斎藤光さん from YJFX)
自分たちのニーズにあったものを選ぶという事が実際の開発、経験を元にお話をされていて、他のセッションとは違う観点で、 アーキテクチャや組織の話をされていて面白いなと感じたセッション。
YJFXについて
- 外貨ex -> トレーダーと銀行の仲介をYJFXが行う
- 1銀行の1通貨につき5,000 トランザクション/sで頻繁にやり取りが発生する
クラウドの導入事例について
- ここ数年で内製化を始めた。それまでは完全外注
- ノード数500+, システム10+でモノリシックなアプリケーション
アーキテクチャ
- channels -> トレーダーとのやりとり
- customer -> ビジネスロジック?
- front -> 銀行とのやりとり
- Analyze system -> 分析
なぜOpenStackを導入?
- 元々はパブリッククラウドだったが、アクセス・トランザクションが増えていく一方でコスト面の問題があった
- クラウドを使っていてもサービスの立ち上げなどで稟議を上げる必要があるなど手続きが全然、簡略化されていなかった
- 現状は開発/STGで利用だが、今後は本番環境(物理サーバ)にも展開したい
導入時のgoodポイント
- ansibleの活用で低コストでオペレーションできた
導入時に苦労したポイント
- ansible導入できていないレガシーシステムの以降が大変だった
- トラブルシューティング
今後
- Agliityの強い基盤を構築する -> 変化に強くする
- 組織文化の醸成
Change the Game, Change the World(北山晋吾 from Redhat)
k8sとは?いま注目されている事とは?などについての話から、そこに追随、対応していくためのRedHatさんでの取り組みを紹介されていて、 タイトルもさることながら、スライド、話し方も分かりやすく、今後の展開に非常に興味を持たせられるキーノートだった。 前職の同期なので、本の出版やこのような大舞台でのキーノートを任せられるなど、活躍ぶりがすごいなと思った。
イントロ
- k8sはプラットフォームのためのプラットフォーム
- プラットフォーマー 勝者の法則 -> 本
- k8sを利用するとクラウドリソースが抽象化され運用工数を下げられる可能性がある
- 運用工数を下げるためのポイントが既存のシステム運用と大きく変わるという意識改革 -> これが+Nativeでは?
Operatorとは?
- 今回はOperatorの話が多い
- 監視するコンテナ?
- アプリ運用における運用の知見をコード化してパッケージ化したもの
- インストール、スケーリングなどを自動化
OpenStackを用いたパブリッククラウドの国内事例と課題(中里さん from GMO)
転職したらKubernetesだった件(ZLab)
今回、参加したセッションの中で一番、面白かったと個人的に感じたセッション。 kubernetesが内部的にどんなことをやっているのか、各コンポーネントがどういうことをやっているのかを、非常に分かりやすく解説されていたセッション。 なるほどと思うこと、やっぱり難しくて理解しきれないところ、もっと詳しく知りたいと思ったところなど内容も盛りだくさんで、セッションだけでは持ち帰れなかった事が多かったのでスライドを見て、手を動かしたりしつつ復習して理解を深めたい。 説明の着眼点や発表の仕方、準備など、すごくスムーズで非常にレベルの高いセッションだと感じた。
このセッションについて
- kubernetesがやっていることは人間の手作業で実施できる
- 各コンポーネントの責務、具体的な動きをしておくことは大切
クラスタにワーカーノードをジョイン(worker)
- ネットワーク設定の追加
- コンテナランタイムの確認
- pod networkの設定
- nodeへの追加
- ノード設定情報の更新?
- kubeletは自身のNodeオブジェクトのステータスを定期的に更新(ハートビート)
- ノードが健全でなくなったら、k8sは他の健全なノードでアプリケーションを実行するように切り替える -> 死んだノードにはデプロイさせない
コマンド
- ip route -> ルーティング確認
podの実行(master&worker)
- マスターがpodのスケジューラが実行準備が出来ているワーカーノードに実行をお願いする
- podにnodeを割り当てる -> Bindingリソースで割当て
ワーカーは自身のノードに割あたっているpodが無いかを定期的に確認してあれば実行
- pauseコンテナの呼び出し?
- ネットワークの設定
- CNIのbridgeプラグインの実行?
- CNIのloopbackの実行?
- コンテナの起動 -> dockerコマンド
- podが起動したことをmasterに通知
- podのステータスを更新
podは複数のコンテナで構成されている
- pod間のコンテナはlocalhostで通信 -> そのやり取りをスのがpauseコンテナ?
ReplicaSetを処理(master)
- レプリカセットで管理しているpodを確認 -> ラベルで一致するものがあるか確認?
- (なければ)必要な数のpodを作成
- レプリカセットのステータスを更新してapi-serverに通知
Scheduler設定?(master&worker)
- masterからpodの実行依頼
- wokerはリクエストに応じてpodを起動する
- masterはworkerがちゃんとpodを作ったかを確認する
(確認出来たら)レプリカセットのステータスを更新してapi-serverに通知
Serviceの処理
- serviceの機能はワーカーノードのkube-proxyが責任を持つ
- 定義と状態で差分があればreconcile loopで調整される
主な処理フロー
- dummy interfaceの作成
- iptablesの作成
- EndPointsオブジェクト -> service作成時に自動で作られる。負荷分散先のIPのリストをまとめる
- IP、負荷分散などの設定(ipset, ip addr add, ipvsadm)
Rancherで実現するKubernetes Everywhere(進藤さん from Rancher labs)
メモ
- Rancherはいろいろなkubernetesを一元管理
- オンプレの機械学習基盤での利用に関する問い合わせが増えている
- Anthos -> googleが提供するオンプレ上でk8sを使う仕組み?
Understanding Envoy(小野さん from tetrate)
envoy, service meshについてのセッション。envoyがどういう役割をしていて、どのように利用できるのかという事が知りたくて参加したセッション。 実際に参加してみて、その辺りについて少し知る事が出来た反面、色々な使い方・活用法があるからこそ、envoy/service meshについての説明というのは難しく、一言ではかTれなかったり、利用側によっても使い方の幅があるんだなということも知れたセッションだった。
Envoyのデザイン
- L3/L4(tcp/IP)層でのフィルター
- L7(http)層でのフィルター
- observabilityの情報がたくさん取れる
- AuthN/AUthZ
- edge proxy
Envoyの設定
- API経由で設定の変更が可能 -> XXDiscoveryServiceという名前になっている
- Envoyとしては全体で使うGlobal configだけセットし、それ以外はプロジェクごとなどでAPI経由などで設定する
Envoyのユースケース
1.SmartStackからの置き換え(Yelp)
- SmartStackとは?
- ServiceMeshの元祖的なもの
- アプリケーションのリクエストは全部HA Proxyに行く
- サーバーの増減があった場合にHA Proxyの設定などを自動更新
- アプリケーションのリクエストは全部HA Proxyに行く
- ServiceMeshの元祖的なもの
- EnvoyにはFailure recoveryの機能もある
- statsで取れるmetricsが多い
2.HW LBsの置き換え(eBay)
- HW LBをSW LBに置き換え、そのSW LBとしてEnvoyを利用
- L7 proxyにenvoyを利用
- k8sを利用して定義・管理
3.コンテナとVMのハイブリッド環境での利用(cookpad)
- S3で設定を管理し、設定に変更があったらenvoyに流し、envoy経由で各アプリケーションに反映?
- EnvoyをVMで動かす3rd partyパッケージも存在している
Microservicesを支えるInfrastructure as a code(坂部広大さん from Wantedly)
課題・問題をサービス開発でどう解決するのか?求められているサービスレベルを常に提供し続けるためにどういう取り組みをしているのか?とサービスの本質、求められるものをどう定義し、定義されたサービスの運用をしているのかといったお話。 今までに対応し解決された事例だけではなく、いまも継続して取り組んでいる課題や過去の失敗談など、かなり深部にわたってまでの共有もなされていたセッションだった。 アプリケーション側のエンジニアとして、Webサービスを開発・運用するエンジニアとして非常に学びの多かったセッションでした。
これまで出てきた課題と解決
- 一貫性ある基盤
- マイクロサービスの責務の再定義、cloud pub/sub
- ネットワークエラー
- IstioによるObservability向上
- kube-dnsのscale-up/outの相関による問題?
- データ更新によるイベント伝搬
未解決の課題
- Datasoreがボトルネック
- ロードテストをして最適解を見つけて対応している
- Fault Isolation
- マンパワーでしのいでいる部分が残っているので、サーキットブレーカー、Retry, Timeoutなど取り組むべき課題がある
課題の対応
- 課題の見極め
- 何が課題で、それをどう解決するのかをステークホルダーにもしっかり説明して理解を得る
- まずはPOCをやって効果などを検証する
- 実際にそれを導入して効果があったのか?
- スケーラビリティ、キャパシティプランニング、自動化可能化なども重要
メモ
- チェックポイント
- production ready
- ストレステストは必要だとおもったらやる -> それ以外はベンチのみ
リリース事例
- OpenCensusでトレーシング -> レイテンシ。スループットの可視化
- サービスメッシュで統計的なエラー数の取得 -> telemetryの機能を利用
- Canary deployはCRDを利用した自社ツール
- spinnakerはフルスタックすぎる感があった・・
- Argoで暗黙的に存在する依存関係のあるJobをWorkflowとして実現
継続的に取り組む課題
- 同期と非同期の選択による運用の複雑化
- マイクロサービス間のN+1問題
- インフラ起因の問題
- thread leak
- hostのpid-maxが超過すると新しいスレッドの作成時にエラーetc.
- memory leak
- thread leak
技術的投資
- SLI(Service Level Indicator)をプロダクト単位で定めてmetricsを取る
- SLIが守られていない場合はロールバックするなど
- 技術レベル向上への投資
紹介されたスライド資料
マイクロサービスにおける最高のDXを目指して(すずきけんじさん from FINC)
マイクロサービスで有名なFINCさんのセッション。「DX」という言葉を初めて知ったが、普段、自分たちがやっている取り組みが言葉で表されることで非常に納得感を持って内容が入ってきたセッションだった。開発部・開発の一括りの中にも色々な立場の人たちがいて、その中での最大公約数を見つけ出して取り入れる事が重要という、当たり前のようでいて非常に難しい課題にしっかり取り組まれているのだなという印象を受けた。
DXとは?
- 開発者体験。気持ちよく開発ができているかどうか?
- DXが良いとは?
- システムの見通しが良い。最新のドキュメントが揃っている
- スムーズに開発できる環境が整っている etc.
- 結果、開発に余裕が生まれ非機能要件やリファクタなどの対応ができる
DXで大事なのは継続的な活動を維持すること
開発に関わるのはDev以外にQAやMainterarやSecurityなどもある
Microserviesについて
- なぜFINCはmicroservices?
- 1つのアプリの中でいろいろな機能あg入っているのでマイクロサービスと相性が良いため
- マイクロサービスが大規模であればCI/CDは各アプリで管理するのが良さそう
MicroservicesとDXについて
- DEV視点で見ると良さそう
- システムが小さくキープできるので見通しが良い
- テストやデプロイが高速に行える etc.
- 新規機能の立ち上げもしやすい
MicroservicesのDXを良くする取り組み
ツールの導入
組織的な取り組み
- 段階的な取り組み
- 可視化
- みんなで見れるようにして問題を共有するところから始める
- できるところから対応
- FINXでは週1ペースで有志で集まってできる人、ところから対応していく
- ドメイン知識がいらないセキュリティアップデートなどはチームにこだわらず、できる人がやる
- 分散化
- ある程度体制が出来てきたら分散化を目指す
- 組織としてDX悪いところにフォーカスして回復してきたら、各チームに任せる
- ある程度体制が出来てきたら分散化を目指す
- 可視化
その他
- cloud nativeとは?
- cloudを利用することで人間がやっていた構築や設定などの作業を自動化すること
- Kubernetes Operator
- 運用の自動化に使えるk8sのコントローラー?
- loki -> k8sのロギングサービス
2日目全体の感想
初日に比べてアプリケーションエンジニアとしてどうk8s,クラウドと付き合っていくか、活用していくかといった内容も多かったように感じました。 特にk8s+マイクロサービスという構成は、少しずつ事例も出てきているので、参考にすべきところ、気をつけるべきことなどをしっかり整理し取り入れていけばと思った。 あとは" 転職したらKubernetesだった件"の内容を復習し、k8sの概要や基本の仕組みの理解を深めることはサービス運輸おをしていく中でも非常に大事だと思うのでやっていきたい
Could Native Days Tokyo 2019/Openstack Days Tokyo 2019に行ってきた(1日目)
Could Native Days Tokyo 2019/Openstack Days Tokyo 2019に7/22・23の2日間参加させてもらったので、初日に参加したセッションのメモと簡単な感想などをまとめました。
keynote
1日目のkeynoteは海外企業などの発表も多く、初っ端から豪華だなと思った。 特にAirbnbのk8s環境はよく記事やブログなどでも話題になるので、とても興味があったし、あれだけの規模でのマイグレーションについての話はとても興味深い内容だった。
イントロダクション(はせがわさん)
- cloud native trail map
- クラウドネイティブを学んでいくためのロードマップ的なもの
- クラウドネイティブの本番利用は今回の来場者の46%。開発環境では80%以上
CNCF Just now(ふくやすさん)
- CNCFには40+のProjectがあり、Graduated(k8s, prometheusなど)、Incubating(linkerd, etcdなど), Sandboxなどのカテゴリがある
- スポンサー企業は400いじょうでappleなども最近プラチナスポンサー入りしている。日本では富士通など
- cloud native landscape
- cloud native関連のサービス、プロダクト、企業などが記載されているもの
- certified k8s application developer -> 受講して受かると認定される
Collaboration Without Boundaries(Mark from Openstack foundation)
- 9年前に最初のカンファレンスを開催して世界中に広めていった
- 国境や企業を超えてコラボレーションをすることで次々に良いものを生み出せていけた
- 最近はVMだけではなくベアメタルも対応している
- IRON(ベアメタルで使うためのもの?), NEUTRIC?
Peforming Infrastructure Migration at Scale(Melanie from Airbnb)
- 72%がk8s(本番)
- マイグレーションはtech debtをなくしていくために必要なもの
- 年数が立つに連れて効率が悪くなっていった状態 = tech debt
マイグレーションをうまくやっていくための戦略 -> マイグレーションがどのレベルのものなのかを整理する
- componenet -> security patchなど
- system -> CI/CDなど
- infra -> cloud native環境にうつすなど
sequence migration
- 簡単に対応できるものから、段階的に移行していく
prioritized migration
- やることに優先順位を付けて対応していく
abstraction層で内部をうまく隠して扱えるようにするつもり
- validation phase -> このテクノロジーが使えるものであるということ検証するフェーズ
- 本当にこのProjectが使えるといういうことを確認できるまでIterationを回す
- プロトタイプを使って検証
- 資料やabstarction層での検証、ツールなどを使う
- 本当にこのProjectが使えるといういうことを確認できるまでIterationを回す
The 10 new rules of open source infrastructure(Stephen from canonical)
10 new rules
- consume unmodified upstream -> オリジナルのソースコードをそのまま使えるようにする
- Infrastructure-is-a-Product -> インフラは製品。導入初年度のコストが一番かかる
- Automate for day 1826
- Run at capacity on-orem.Use public cloud for overflow. -> 用途に合わせて、例えば一時的に必要なものはpublic cloudを使うけど、通常稼働はオンプレなど、規模や用途に合わせる
- Upgrade.don't backport -> バックポートをすると手作りのインフラになり、他環境への移行などがしづらくなる
- Workload placement matters -> アプリ層で起きていること、インフラ層で起きていることの相関関係をしっかり把握する
- Plan for transition -> k8sでの環境はあくまで一過性のもの。今後の変化にもたいおうできるような俊敏性、柔軟性が大事
- Security shoould not be special -> 環境が大方、揃ってきたところでセキュリティに問題にぶち当たると作り直しが必要になる。セキュリティも設計の段階で取り入れ、はじめからしっかり考える。
- Embrace shiny objects -> 革新的な技術に積極的に使っていく?
- . Be edggey,go Micro! -> とんがっていく、マイクロでいく? => マイクロエッジ??
- microk8s
Demand Less Choices! (Davis from IBN, Knative)
BareMetal -> VM -> Container -> Functions Serverless
- PaaS -> cloud foundryなど。すべてをやってくれる
- シンプルなUX
- Container
- マイクロサービス
- ステートレス
- エンドポイント、 LB
- ビルド
- ロードや粒度によってスケールを調整できる
- Caas -> k8sなど。ビルドなどは自分でやらないといけない
- FaaS -> OpenWhiskなど
- シンプルなUX
- Container
- マイクロサービス
- ステートレス
- エンドポイント、 LB
- ビルド
- イベント駆動
- ゼロにもスケールできる -> 使わなければまったく課金は発生しない
- PaaS -> cloud foundryなど。すべてをやってくれる
k8sではリソースの定義、管理やツールの理解・利用などを自分でやらないといけない
- そういった問題に対処して、コードに集中するためするためにknativeが出てきた
- githubのduclin/helloworldでもっと細かい情報を見れる
Rancherセッション
GCPでVMを立てて、Dockerを使ってRancherインストール。 その後にRancherからWordPress, Prometheusをインストールして設定するというハンズオン。
冒頭でRancherやk8sの近況や最新事情について知ることが出来たのは、とてもよかったと思う。 また、現在の業務でRancherを少し使っているが、実際にインストールや設定はしていないので、そこを一度、体験出来たのは良い機会だった。
資料
Rancherとは?
- k8sクラスタの構築・運用などを行うためのツール
- helmベースのカタログ機能によるアプリケーション管理
- Gitlab, Prometheus, FluentdなどのOSS連携
- Anthos -> googleのrancher的なツール
- 2.2.X系からprometheus, grafanaはrancher同梱になった
- rancher自体もk8sでデプロイ、管理するのが推奨されている -> helmでインストール、管理できる
- githubとかとのCI/CDのパイプライン機能もあるが、現段階ではまだ使いづらいかも・・
- rancher cataloggを使ってミドルウェアのインストールなども手軽に行える
- DisneyでハイブリッドクラウドをRancherを使って管理している
SMIというServiceMeshの標準化にも力を入れている
2.3系ではService Mesh & Observerbility -> IstioやJaegerでのトレースなど。あとキアリ?
- R!O -> マイクロPaaS。k8sをdocker runみたいに手軽に構築、実行できるようにしたツール
- IoTなどを見据えたk3sや地理的分散DB(?)のSUBMARINERなどもRancherLabsでやっている
学習資料
KubernetesでJVMアプリを動かすための実践的ノウハウ集
Oracleの方のセッション。 今までJavaのモジュールやクラウド環境でJavaを利用するために気をつける、意識することというのがあまり分かっていなかったので、 なぜクラウドで使うJDKの話がよく話題に上がるのか、Javaのモジュールを使ってどんな事が出来るのかなどが、このセッションを通して理解する入り口にやっと立てたような気がする。
JVM on k8sノウハウ集
1.ローカル開発
- jib + skaffoldでローカル開発を効率化 -> dockerイメージのビルド&k8sにデプロイ
- jibでビルド&pushを効率化
- jibは変更箇所のみ反映してくれるので無駄な処理をおさえられるらしい
- skaffoldはdokcerのbuild/push/deployまでを自動化してくれる
- jibでのビルド&pushとkubectl apllyでのデプロイを1コマンドで実行
- Projectの直下にskaffold.yamlを用意して設定を記述
- jibでビルド&pushを効率化
2.ビルド
公式のベースイメージを利用
- JVMコンテナをビルドする上での指針
発展的な方法した対応方法について
- jibとカスタムJREを組み合わせ
- GraalVMのNative image生成機能を利用
- SubstrateVM -> 黒魔術的なものなのでおすすめしない
3.デプロイ
- コンテナのリソース制限機能を考慮して、適切なJVMパラメータを設定
- ロールアウトで気にすべきこと
- ServiceMeshによるトラフィック制御
- 追加したばかりのpodには少量のトラフィックを流すようにして暖機運転させるなど
4.監視
Mackerelチームのコンテナ開発における戦略とこれから(今井隼人さん)
Mackerelを使っていないので詳しいことは理解出来なかったが、監視の際に気をつけるポイントや監視用のシステムを作る際に工夫したことなどの知見が得られればと思い参加。 コンテナの監視ならではのポイントの話などはなるほどと思うところもあったが、AWSについての話なども多く、自分には理解出来ないところもちらほらあった。
makerelとは?
- mackerelはserver, agent, pluginの構成
- pluginはメトリックを収集してagent向けの形式に変換する役割
コンテナ監視について
- Dockerプラグイン
- DockerAPIからメトリックを取得
- ECSプラグイン
ECSインテグレーション
上記ではコンテナ監視に向かないため、mackerel-container-agentを開発・リリース
- kubernetesクラスタの監視は課題があり次フェーズ以降
- サイドカーとして稼働する仕組み
- 今後はDaemonSet型での提供も検討中
- 方針
- k8s podをホストとして扱う
- コンテナの基本的なメトリックをシステムメトリックとする
- ロールの割当を可能とする
詳細
- k8sについてはkubeletが提供するAPIを利用
- PODのメタデータやメトリック、ログの取得、コマンドのローカル実行のためのAPI
- kubelete-portとread-only-port -> 監視ではread-only-port経由でのアクセスで充分?
- kubelet APIのAuthN/AuthZ
- RBACで設定
- 今後はプロファイリング、トレーシングなどとのツールとの連携も検討
紹介された記事など
メルペイにおけるマイクロサービスの構築と運用(Takagi Junichiroさん)
この日に参加予定のセッション中で一番楽しみにしていたセッション。 業務で決済に関わっていることやマイクロサービスを採用していることもあるのと、メルペイのブログ記事は色々と学びや情報も多く、このセッションで話される内容がとても楽しみだった。 参加した感想としては、メルカリという大きな会社のサービスかつ決済ということ側面も大きいのだろうけど、サービスを運用していく中での仕組み作り、ルール定義がすごくしっかりしていると感じた。 もちろんサービス規模や特性に合わせて変わってくる面もあるのだろうけど、仕組み作り、特にObservabilityについては、個人的には参考にすべきところも多いなと感じた。 あとは失敗談についての共有もあったのは、大きな学びだったと思う一方、アプリケーションエンジニアとして関われる部分で持ち帰れたものはどの程度だろうという現実的な部分とのギャップによるもやもやは少し感じてしまった。 ともあれ、良いセッションに参加できてよかったです。
なぜマイクロサービスか?
- 短期間でのリリースを可能にするために採用
- goとspannerを各マイクロサービス共通のアーキテクチャとしている
- 共通のライブラリやツールの導入がしやすい
- チーム間での情報共有や人の流動性を高めるため
メルペイのマイクロサービス
- 共通のGKEクラスタ
- 個別のProject
- Spanner(DB?)やMQなど
- レイヤードアーキテクチャ
- マイクロサービスのテンプレートを利用して立ち上げ
- 社内の共通ライブラリ -> logging, tracing, クライアントサイドLB
マイクロサービスの階層構造
- Gateway -> 共通処理、ルーティングを担当。GoのMSNとCloud Load Balancer実現
- Authマイクロサービスを利用したAuthN/AuthZ
- API -> アグリゲーションなどを行う
- BEサービス -> 個別のロジック?
- 共通サービス
気をつけていること
一貫性と信頼性
- データの一貫性
- リトライと冪等性 -> リトライしても二重処理されずに正しく動く
- リコンサイル
- 本当にデータ整合性が取れているのか?
- 不整合を見つけて修正する必要がある
- バッチ処理によるリコンサイル
- 非同期なイベント通知によるリコンサイル
マイクロサービスのレビュ−
- DesignDoc -> Devspec的なもの
- ProductionReadinessChecklist
Kuberenetes
- Clusterはプラットフォームチームが担当
- namespace内を各チームが開発・運用
- DBやMQなどはteraformで管理。権限設定したアカウントをk8s secretsで管理
- デプロイはSpinnaker経由で実施
共通プラットフォーム
運用を減らす仕組み
- マイクロサービスの構成をできるだけ揃える -> 共通処理など
- k8sによるオートスケールや自己修復による自動化
- Managedサービスの利用
運用で気をつけていること
- SLO(Service Level Objectuve)を設定
- Observability
監視体制
- DATA DOGに集約しslackやpager dutyに流す
開発・運用で出てきた課題
- マイクロサービスのモノリス化
- QAが難しい
- どのバージョンの組み合わせで、どこが原因でエラーが出ているのか?
- 運用と開発のリソースの調整
失敗談
Deploy時にエラーが出る
- Graceful shutdownをちゃんとやりましょう -> ぶつっと切らない
- Probeを適切に設定
- Rolling Updateの改善
- 設定値の調整
Ingressの再作成に失敗
- GKEのバグによるものだった
- いっぱい作ってうまくいったものを使う作戦で対応。。
Ingressを追加したら元からあったIngressが壊れた
- 追加したあとに既存のingressの証明書に違うものが適用されていた
紹介されたブログ記事
初日を終えての感想
初日はインフラ・SRE的な内容でのセッションが多く、自分の勉強・理解不足もあり、あまり理解出来なかったことも多かったように感じた。 ただ、KubernetesやCloud周りの最新事情や、各社の取り組みをはじめとして、今まで自分があまり得ていなかった情報を知る事ができたの大きな収穫の一つだと感じた。 それと同時に、多くのセッションで言われていた事だがKuberenetesについて学ぶべき事が多く、学習コストも高いので、サーバサイドエンジニアとしての自分に必要なもの、自分が学ぶべき事の的をしっかり絞って、うまく付き合っていく事が非常に大事だと感じられたのが、この日の一番の学びだったと思いました。
その他気になった用語
- webhook conversion -> 詳細は後日、調査する
DDD実践の現場に参加してきた
DDD(Domain Driven Design)実践の現場
- 2019/5/29@pixiv
ドメイン駆動設計の正しい歩き方
https://www.slideshare.net/masuda220/ss-148093123
- なぜDDDで作るのか?
Evansが求めた設計について
- 設計の一般論ではない
- ビジネスルールの複雑さがソフトウェアの複雑さの根本原因
ドメインロジック
- ビジネスルールをコードで表現したもの
- コアを整理していけば周辺が整理され、それが全体に波及して、シンプルなものが作れる
- 開発者がビジネス活動について継続的に学び続ける
ドメイン駆動設計を実践するための6つの問い
- ビジネスの活動を継続的に学んでいるか?
- コアドメインに集中しているか?
- 全てを同じにしようとする必要はない。コアに集中する。そこを徹底的に綺麗にする
- ビジネスを深く洞察しているか?
- ドメイン層を独立させているか?
- ロジックを画面やテーブル構造と一緒にする必要はない
- モデルと実装を密に結合しているか?
- 実装に役立たないモデリングはどこか間違っている可能性がある
- システム間の秩序の改善を続けているか?
- もっと良い方法がないかを検討し改善し続ける。もっとシンプルなIFに出来ないか、など
ドメインロジックを独立させる
- まず料金を計算するのにはどう(メモリ上で)表現いいのかを考える -> 画面やDBのことは一旦忘れる
- 料金計算ロジックを独立させる
- モデリング
- ルール、攻勢要素とその関係を自然言語やすい式などで表せるようにする
- モデリングは仮説を立てる<->コードで表現するを行き来して作り上げる
コアドメインに集中する
- 中核となるルールは、繰り返し出てくる部分
- どこを軸にとるか?
- どこを軸にしてコードを書くとシンプルになるか? => 抜粋版みたいなコードを書いてモデリングの妥当性を検証する
- 歯抜けの仕様書を渡された時に、歯抜けの部分がさぐり当てられるか? -> ビジネスに対して深く理解していないとこれが出来ない
DDDを現場に導入する
- 体験的に習得する -> ハンズオン、OJTなど
- エヴァンス本をちゃんと読む
- 28ページの抜粋版を読む
- 要点を重点的に読む
- 9,10章あたりはビジネスを深く洞察する、ということがどういうことなのかに触れている
DDDをできるようになるには?
- 増田さんの本:現場で役立つシステム設計の原則
- isolating-the-domain -> サンプルコード
- jig -> 設計可視化ツール
- オブジェクト指向設計 -> ドメイン駆動設計本格入門 スライド => VOなどの具体的な設計
この辺りを理解すればEvans本の想定読者の要件をクリアできるはず
質問にあがっていたこと
- ドメインエキスパートの説明がうまくない場合は?
- 期待しない・・自分の質問したいことの具体例を持って質問する。わざと間違えた質問をぶつけて話してもらうのもあり
- ビジネスルールの複雑さに立ち向かう -> ここにビジネスルールが複雑になる原因などについて書かれている
モデル駆動型開発によるビジネスをソフトウェアに落し込む1つのやり方
- 複雑なものをシンプルに
- ユビキタス言語はチームやドメインエキスパートとの対話で生み出す
- 対話をするためには一般業務知識や専門用語の理解なども必要
- ユビキタス言語を値オブジェクト(or エンティティ)で表す
- ドメインモデル貧血症
- ビジネスルールがほとんどなくデータの入れ物のようになってしまっているドメインモデル
まとめなど
- 最近、進化的アーキテクチャの本を読んでいたこともあり、ドメインを育てる、進化させるということがまさに進化的アーキテクチャを実践する方法の1つになるんだということを感じた
- 今までスライドや本でしか増田さんの話を聞いたことがなかったが、現場での説明や小話を交えてで得られる情報は貴重だなと改めて感じた
- システム間の秩序の改善の話については、個人的には頭をガンと打たれたくらいの衝撃だった。外部とのやりとりのインターフェースがイマイチなことのせいにしてあきらめている自分がいたが、自分でできることはなにか、ここから改善できることはないのかを常に考え改善していくというマインドを持ってことに当たるということが欠けていたなと気付かされた
豚バラ肉と春キャベツの塩蒸し
豚バラ肉と春キャベツの塩蒸しに挑戦してみたのでその記録
作ったもの
- 豚バラ肉(ではなく、正確には豚の薄切り肉)と春キャベツの塩蒸し
成果・結果
- 今回はさほど難易度が高くなかったこともあり食べれるものが作れた。
- 材料や調味料も白ワイン以外は普段、家においてあるものでさっと作れるので、今後も御飯作る時のレパートリーに一つにしたい
感想・反省
自分のゴハンを作ってみる
自分のゴハンを作ってみる 今日は妻が遅めの美味しいご飯にお呼ばれされて夕飯がいらないということで、自分のゴハンを用意するべく出来ない料理について挑戦しました。
今日、挑戦してみたのは以下の2品
1.ほうれん草とニンジンのナムル
結果としては基本的に野菜を切って、温めて、タレと絡める。 なので、大きな失敗のしようもなく、何とか出来ました。 ただ、味が少々薄めな気が・・
分量について
ほうれん草1袋、とあったので素直にその通りにしていたが、
自分が買ってきたほうれん草はちょっと多めだったように感じていたので、切る前に多いいかな、と思った時点で減らすべきだったと思う。
この結果、タレも分量通りだと全然足りなく、最後の味の調節でミスったと思う
ニンジンの千切り
レシピを見ていた時は、ハイハイ、千切りね。と余裕こいていたのですが・・
自分が野菜の切り方すら分かっていないレベルであることを、ニンジンを前にするまで忘れており、ここは妻に教えてもらいながら対応。
ウチのやり方では、
* ニンジンを適度な長さに分割
* 分割したニンジンを立てて薄切りにする
* 薄切りにしたニンジンを重ねて線状に切る
なんか、基本、太めになってしまうので、色々やり方や工夫はあるのかもしれないけど、とりあえずこの方法をできるようにしないことには始まらない。。
タレ作り
これは美味しいだろう、というようなものばかり混ぜているので、間違えるとすれば濃すぎるか、薄すぎるかのどちらからで今回は後者だったように感じる。 ただ、味見の時点ではしょっぱかったので、多分、混ざり切っていない。が正解なんだと思う。
今回の敗因としては、まずど初心者なので分量をちゃんと量りながらやるべきだった。適当なスプーンでなくて計量スプーンでちゃんとやる。
あと今回感じたのは、ゴマって彩り、見た目や味を多少ごまかす的な要素で使っているもんだと思っていたが、今回みたいに何かをませる時の混ざり具合の目安としても役立つという発見があった。
2.たらのムニエル
もうこれは結果から言って大失敗。
身が崩れ、味のつき方もイマイチで、まあ残念なものとなってしまった。ごめんなさい・・
小麦粉少なかったか
小麦粉が少なかったように思う。ただ、あくまでそんな感じがした、と言う程度なので定かではない
最初の焼きが足りなかった
最初にしっかり焼いておかないといけないのだが、焼きが甘く、結果として火の通りが甘い感じで出来上がってしまった。ここは大反省の1つ
タラを半分に切っておくべきだったっぽい
身が崩れてしまって、見た目もよろしくない感じになってしまった。妻のアドバイスでは身を半分にするなどしておけば崩れなかったのでは?と言うことだったので次回気をつける
フライパン選びが良くなかった
家にはサイズ的に小・中・大のフライパンがあって、今回は中を選んだが結果、これが大きな失敗だったと思う。 最後は焼いたタラの身をタレで煮詰める感じになるのだが、フライパンが大きく煮詰める感じにできず、うまく味が付かなかったのが大反省の2つ目。
ただ、ここには前述の小麦粉の分量や、タレの分量の甘さ、火加減をちゃんとしてなかった、など色々とよろしくない点があっての結果だと思うので、フライパンはあくまで要因の1つだと思うけれど、せめて小を選んでいればもうちょっと何とかなったかも、と思うと残念でならない・・
全体
とりあえず簡単なおつまみ的なものは今後もちょっとずつ挑戦して、包丁の使い方や料理を進めていく上での手際、整理の術を身につけて行こうと思った。
また、小麦粉を使う料理やムニエル自体が初挑戦だったので、失敗はしたが良い経験だったと思うので、今回の反省を生かしてまた挑戦したい。
コードで理解するDDDの戦略的設計・戦術的設計のつながり勉強会メモ
だいぶ経ってしまったが8/4(土)にDDDの勉強会に参加してきたのでその時のメモまとめ 講師は現在ビズリーチに在籍されている松岡さんで、自分も本人とは気づかぬうちにDDD関連の調べ物をしている際にブログを拝見させていただいたことがある方でした。 当初の予定よりも30分延長してくださり3時間半の長丁場で内容の濃い勉強会でした
DDD
まずは原典にあたってみるのが良い https://domainlanguage.com/ddd/reference/
設計したモデルとコードを一致させる モデルと実装の変更に耐えられる設計でないといけない -> これを実現するのが戦術的設計
モデルとは
対象領域の特定の側面を表現し、関連する問題を解決するために使用する対象物 ユビキタス言語でモデルを表現する
知識
問題領域の知識(Why,What)
お客さんの業務 ユーザのニーズ 市場 ->聞く、情報収集をする、フィードバックをもらう
解決領域の知識(How)
ツール、ライブラリの使い方 コード文法 ->実際に試して得る
境界づけられたコンテキスト
特定のモデルが適用される境界
戦略的設計
コンテキストを定義、再配置するなど?
戦術的設計
構成的にやりやすい形にするための設計?
アーキテクチャ
レイヤードアーキテクチャ
3層アーキテクチャなど Infra層がAppやDomainに依存する -> DBを差し替えたりなど出来ない
ヘキサゴナルアーキテクチャ
オニオンやクリーンはこれの派生 ポートとアダプターで外部サービスとやりとり? 外側は交換可能だが、中心はそんなに変わらない
オニオンアーキテクチャ
infra層が一番上に持ってこられるアーキテクチャ -> infra層がAppやDomainに依存しない マイクロサービスなどで用いられている(サービス同士のhttp通信などはinfra層同士のやりとり) https://dzone.com/articles/onion-architecture-is-interesting
クリーンアーキテクチャ
ドメイン層
ドメインサービス
ドメインサービス
個体で扱えない、集合体で扱うものなどに利用(部屋の空き時間を知る場合は各予約単体では分からないため予約の集合体から空き時間を確認する必要がある) ただ、極力使わないようにするべき
ファクトリ
ドメインモデル
エンティティ
可変 IDを持つ IDで比較する 1テーブルに相当
値オブジェクト
不変 IDを持たない 値で比較する テーブルの値に相当
ドメインイベント
集約
整合性を保つ単位? -> トランザクションで整合性を保証する単位? 1repository1集約 1つのコンテキストの中に複数の集約がある
マイクロサービス
マイクロサービスはコンテキスト単位