それが僕には楽しかったんです。

僕と MySQL と時々 MariaDB

Builderscon に参加してきたから雑にまとめてみる

はじめに

どうも、最近 Redis はフェチとか訳わからんことを言っているけんつです。
今回、縁あって Builderscon に参加してきたので色々と雑に書き残していきます。

スカラシップ

今回 Builderscon に参加するにあたって Classi さんのスカラシップを利用させていただける事となりました。
北海道からの参加となったので正直すごく助かったのと、かなりいろんなことを勉強できる機会を得ることができたので
本当に感謝しか無いです。
classi-scholarship.connpass.com

特に面白かったセッション達

インフラや分散システム周りを中心にそれなりの数、セッションを聞いてみて特に面白かったこれ勉強になったセッション達を雑にまとめます。

Open SKT: メルペイ開発の裏側

トップバッターはメルカリさんの「Open SKT: メルペイ開発の裏側」というセッション
主に分散システムとして決済システムを構築する場合の勘所みたいなところを多く話していた気がする

speakerdeck.com


このセッションではメルカリさんがメルペイというサービスを提供する中でどうやって安心安全を担保していくかという部分にかなり焦点があたっていた。

まずはメルペイのアーキテクチャから触れられていて、マイクロサービスアーキテクチャを採用しているとのこと。
またそれに付随して、開発で重要視されているような事柄も紹介されていた。


このセッションの中で一番おもしろいと思ったところは決済システムないでの一貫性管理をどのようにやっていくかという問題をどう解決するかという所だった。
というのも、自身も大学の研究でマイクロサービスアーキテクチャを採用した機械学習プラットフォームを開発しているが
システム間の強調が難しく、分散システム内でどうやってデータの一貫性を管理しようかと迷っていたという所が大きい。

まず、分散システムにおいてシステム間の強調が難しい場合は中央に処理を集約してしまい
そこでトランザクションを一元管理するというのがよいみたい。
確かに、これは自分でも考えぬいて一箇所で管理した方がシステム全体が複雑になりにくいなどの副次的効果もあると考えてそうしているから納得した。

しかし、次に聞いた話は完全に度肝を抜かれた感じがある。
というのも、エラー処理を例外として扱わずリトライと冪等性の原則を適用するという方法がとても斬新に思えたから。

エラー処理を例外として扱うと確かに複数のコンポーネントが強調して動作している分散システムでは複雑性が増してしまう。
そのため、処理がエラーとなった場合はリトライをし、冪等性を担保して二重処理を防ぐ
その上で継続不可能な場合のみエラーとして検出する
これがかなり合理的に思えた。

というのも、分散システム内の必要なすべての要素において一度処理を行えるかどうかを確かめる(Try)し、
それが実行可能なら処理を確定させ(Confirm)、処理を実行できないのなら中止(Cancel)するという仕組みがあれば確かに
上記のことを満たせるし、システムの複雑性が増さないと思ったから。

これは実際に研究内でどうしようか迷っていたところで、確かにこうすることでエラー処理周りを複雑にしなくて済む一番いい方法だと思った。


この部分の話がかなり面白くて分散システム内で一貫性をどうやって担保するかという問題の解決策は自分の中でかなり斬新な上に衝撃で聞いてみて面白かった。

そのあとに登場した Kyash のアーキテクチャでもトランザクションについては類似した内容が展開されていたから多分これが一番都合のよい仕組みなんだと思う。

RDBのトラブルの現場を追え!

次はそーだいさんの 「RDB のトラブルの現場を追え!」
スロークエリ、不正データ、パフォーマンスチューニングの順番で追っていく。


speakerdeck.com


最初はスロークエリについて紹介されていた。
その中でも最初に来たのはサブクエリの問題。
以下のクエリがなぜ遅いかという問いから始まった。

REPLACE INTO hoge(id, name)
  SELECT id, name
    FROM foo AS f
    INNER JOIN bar AS b ON f.event_id = b.id
  WHERE f.id in (
    SELECT max(event_id)
    FROM f
    WHERE canceled_at IS NULL
    GROUP BY event_id, sheet_id
);

これはサブクエリが最高に良くないみたいで MySQL 5.5以下だとスロークエリになってしまう。
5.5 以下では実行計画を見ると「相関サブクエリ」扱いになる。
これによって SELECT id, name に対して、SELCT max(event_id) が走ってしまうためパフォーマンスが落ちるとのこと。

この記事を書くにあたって参考にした記事は以下の2つ

nippondanji.blogspot.com
dev.classmethod.jp

大きいバイナリは直接持たない方がいい
という話と
バルクインサートを利用する場合 MySQLでは LOAD を使った方が早い

といった話も展開された。


また、スロークエリは知らないため(上記のあれが相関サブクエリになってしまうなど)に起こるものと
そもそもどう頑張ってもテーブルの設計が悪いパターンがある。


どっちか判断するために
スロークエリログを見て->実行計画みて->テーブル設計を見直すと大体わかってくるらしい。


その次は、不正データについての話。
制約を守ればいいというだけでなく、INSERT, UPDATE などは処理に成功していても制約が守れているかどうかは判断しにくいため
制約を守れていないデータが入ってしまう場合があるとのこと。(わかる)


さらにその次はパフォーマンスチューニングの話
主にテーブルが絡んだ話だった記憶がある。例題は ISUCON 8 の問題。

特に面白かったのが InnoDBクラスタインデックスのため INDEX を利用したとき暗黙的にソートされるから GROUP BY などを利用する必要がないというもの。
これは InnoDB の挙動を知っているからできる話で、よく理解していないのなら利用するべきではないと仰っていたが
InnoDB の挙動を考えて SQL を書くとかは考えもしなかったから個人的にこれがめちゃくちゃ面白いなと思った。
InnoDB の挙動もっと追ってみたい。

おわりに

他にも色々なセッションを見に行ってすごく勉強になったのだけど全部まとめていると量が大変なことになるので特に面白かったセッション2つを雑にまとめてみた。
これから時間をみて少しずつ更新していきたい。

今回、初めてこういうカンファレンスに参加したけど、自分の興味ある分野でかなり深い話やめちゃくちゃ勉強になる話をたくさん聞くことが出来てかなり勉強になった。
また一番自分のなかで良かったと思えることは、普段から自分が分散システムに携わっているなかで「うーん、この構成で本当にやっていいのか」とか「この部分の一貫性をどうやって担保しようか」などといったベストアンサーやベストプラクティスは存在しない自分で考えなければならない問題と同じことを解決しようとしていたセッションが多くやっぱり自分だけでなくみんなこれは迷うのかみたいな気付きが得られた上に
それに対する多くな優秀な方が考えた現状ベストプラクティスに最も近い問題解決の手法とそこに至るまでのプロセスを学ぶことが出来たことだと思う。

そのうち聴講するだけでなく、こういうカンファレンスで登壇してみたい。