Upgrade to Pro — share decks privately, control downloads, hide ads and more …

マネーフォワード クラウドの 基盤プロダクトにおける設計・実装ガイドラインで ID生成機にUL...

ogawa
September 26, 2024
140

マネーフォワード クラウドの 基盤プロダクトにおける設計・実装ガイドラインで ID生成機にULIDを推している理由 / Why we recommend ULID in the design and implementation of core products

ogawa

September 26, 2024
Tweet

Transcript

  1. • Carrer
 ◦ 2007: SIer
 ◦ 2011: SIer(Due to a

    merger)
 ◦ 2017: toG SaaS
 ◦ 2022.05 -: Money Forward
 • Workflow Domain Tech Lead
 • X: @kroyeeg
 小川 昌吾 Ogawa Shogo / Ogawan
  2. ULID = Universally Unique Lexicographically Sortable Identifier
 • グローバルに一意
 •

    辞書順にソート可能
 • 識別子
 ULIDとは What is ULID 
 • Universally Unique
 • Lexicographically Sortable
 • Identifier
 

  3. 仕様の抜粋
 • 128ビットデータ
 • 1msecごとに1.21e+24個のユニーク なキーを持てる
 • 辞書順ソート可能
 • 26文字


    • 使用する文字はCrockford base32
 ULIDとは What is ULID Excerpt from the specifications
 • 128-bit data
 • Capable of having 1.21e+24 unique keys every 1 millisecond
 • Lexicographically sortable
 • 26 characters long
 • Uses Crockford's base32 alphabet
 

  4. ULIDとは What is ULID データフォーマット
 • タイムスタンプとランダムパートで構成 する
 • 文字列はすべて大文字


    (Crockford base32で規定)
 Data format
 • Composed of a timestamp and a random part
 • All characters are uppercase (as specified by Crockford's base32)

  5. One day, a network failure occurred in the database of

    a certain product.
 We switched the writer instance to recover, but it was not the ideal method.
 As a result, after the network was restored, the database became double-active, causing a secondary failure.
 ある日、あるプロダクトのDBでNW障害 が発生
 
 ライターインスタンスを切り替えて復旧し たがやり方がよくなかった
 
 この結果、NW復旧後にDBがダブルア クティブになってしまい、2次障害を起こ してしまった。
 

  6. ダブルアクティブになったことで、どちら のDBへアクセスするかがランダムな状 態になった。
 さらに、RDBのオートインクリメントIDを 使ってID採番を行っていたため、本来 起こるはずがない「異なる事業者で同一 IDのデータ」ができてしまった。
 Due to the

    double-active state, the application started accessing both DB instances randomly.
 Furthermore, because we were using auto-increment IDs in the RDB, we ended up creating data in each instance for different merchants having the same ID, which should never have happened.
 
 Table name: users
 DB instance-A
 DB instance-B

  7. オートインクリメントIDからの乗り換え先候補 Candidates for switching from auto-increment IDs • Snowflake
 •

    ULID
 • UUID ver4
 and others
 
 
 • Snowflake
 • ULID
 • UUID ver4
 その他

  8. ULIDにした理由 The reasons for choosing ULID • The probability of

    generating trillions of IDs at the same time without any sign of overlap
 • The specification is lightweight and clear
 • Unlikely to have updates to the specification
 • Timestamp-based IDs are compatible with RDB
 • IDs can be generated on the application layer
 • 同一時刻に数兆個のIDを生成してぶ つかる気配のない確率
 • 仕様が軽量で明確
 • 仕様の更新がなさそう
 • タイムスタンプベースのIDのため、 RDBと相性が良い
 • アプリケーションでIDを払い出せる

  9. ライブラリに求めたこと
 ちなみに、Kotlinです
 • ULIDを型レベルで生成できる
 
 • Maven Centralに上がっている
 • ランダムパートの仕様を満たしている


    ライブラリ選定 Select a library Requirements for the library (p.s. we use Kotlin):
 • Capable of generating ULID at the type level
 • Uploaded on Maven Central
 • Meets the specifications for the random part

  10. 候補 (載せ替え当時)
 • JonasSchubert/kULID
 • Aallam/ulid-kotlin
 • kobil-systems/ulid-kt
 ULIDのライブラリは更新の必要がほぼな いので、大体最終コミットが5年前とかです


    ライブラリ選定 Select a library Candidates (At that time)
 • JonasSchubert/kULID
 • Aallam/ulid-kotlin
 • kobil-systems/ulid-kt
 ULID libraries generally do not require updates, so the last commit is usually about five years ago

  11. 候補 (載せ替え当時)
 • JonasSchubert/kULID
 • Aallam/ulid-kotlin
 • kobil-systems/ulid-kt
 ライブラリ選定 Select

    a library 上2つが痒いところに手が届かず、
 一番下のは機能的には理想だったけど、 Maven Centralに上がってなかった。。。
 Candidates (At that time)
 • JonasSchubert/kULID
 • Aallam/ulid-kotlin
 • kobil-systems/ulid-kt
 
 The top two options didn't quite meet the needs, and while the bottom one was functionally ideal, it wasn't available on Maven Central...
 

  12. 結局自作しました
 
 • ULIDを型レベルで生成できる
 
 • Maven Centralに上がっている
 • ランダムパートの仕様を満たしている


    ライブラリ選定 Select a library I ended up creating it myself.
 
 • Capable of generating ULID at the type level
 • Uploaded on Maven Central
 • Meets the specifications for the random part

  13. • 当時のテストデータがランダムデータに対して アサーションしてないので、 ULIDを1つずつ割 り当てる地獄(まだ一部残っている) 
 • ID系のメンバー変数をULID型に置き換えな いといけない(単に置き換えるのがめんどい) 


    
 • At the time, the test data did not assert against random data, so there was the tedious task of assigning ULIDs one by one (some of which still remain)
 • Member variables related to IDs had to be replaced with ULID types (simply replacing them was tedious)
 ULIDへの移行で大変だったこと Problems faced during the transition to ULID
  14. • 当時のテストデータがランダムデータに対して アサーションしてないので、 ULIDを1つずつ割 り当てる地獄(まだ一部残っている) 
 • ID系のメンバー変数をULID型に置き換えな いといけない(単に置き換えるのがめんどい) 


    
 • At the time, the test data did not assert against random data, so there was the tedious task of assigning ULIDs one by one (some of which still remain)
 • Member variables related to IDs had to be replaced with ULID types (simply replacing them was tedious)
 ULIDへの移行で大変だったこと Problems faced during the transition to ULID • テストデータはランダムで生成して具体的な値 を自分たちでは一切書かないでテストしてれ ば楽だった。
 
 • 例えLongでもID抽象型を付けておけば良 かった
 
 
 • It would have been easier if the test data was generated randomly and we tested without writing specific values ourselves.
 • For example, even with Long, it would have been better to have an abstract ID type in place.

  15. • IDをDBに依存しない形に実装すれ ば、不用意に異なるデータと紐づくこと はなくなる
 • ULIDは単方向増加でRDBとの相性が よい
 
 • アプリでID生成をすることで、バックエ

    ンドの処理性能が上がる
 • 移行はめんどいので、最初から使うと 良いよ(心の声)
 まとめ Conclusion • If the ID is made independent of the database, it will no longer inadvertently be associated with different data.
 • ULID is monotonically increasing, which makes them well-suited for compatibility with RDB.
 • Generating IDs in the app improved backend processing performance.
 • Migration is a hassle, so it's better to use it from the start (from the bottom of my heart).