Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

● 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

Slide 3

Slide 3 text

今日はULIDの話をします Today, I’ll talk about ULID

Slide 4

Slide 4 text

ULID = Universally Unique Lexicographically Sortable Identifier
 ● グローバルに一意
 ● 辞書順にソート可能
 ● 識別子
 ULIDとは What is ULID 
 ● Universally Unique
 ● Lexicographically Sortable
 ● Identifier
 


Slide 5

Slide 5 text

仕様の抜粋
 ● 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
 


Slide 6

Slide 6 text

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)


Slide 7

Slide 7 text

なぜULIDを使いたいのか🤔 Why we want to use ULID🤔

Slide 8

Slide 8 text

こんなことがありました Something like this happened.

Slide 9

Slide 9 text

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次障害を起こ してしまった。
 


Slide 10

Slide 10 text

ダブルアクティブになったことで、どちら の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


Slide 11

Slide 11 text

こういった経緯からオートインクリメントIDの使用をや めるということになりました Due to these circumstances, we decided to stop using auto-increment IDs.

Slide 12

Slide 12 text

オートインクリメントIDからの乗り換え先候補 Candidates for switching from auto-increment IDs ● Snowflake
 ● ULID
 ● UUID ver4
 and others
 
 
 ● Snowflake
 ● ULID
 ● UUID ver4
 その他


Slide 13

Slide 13 text

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を払い出せる


Slide 14

Slide 14 text

ULIDを採用すると決めたら、 あとは実装あるのみ Once the decision is made to adopt ULID, the only task is to work hard on its implementation

Slide 15

Slide 15 text

まずライブラリ選定 First, select a library

Slide 16

Slide 16 text

ライブラリに求めたこと
 ちなみに、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


Slide 17

Slide 17 text

候補 (載せ替え当時)
 ● 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


Slide 18

Slide 18 text

候補 (載せ替え当時)
 ● 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...
 


Slide 19

Slide 19 text

結局自作しました
 
 ● 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


Slide 20

Slide 20 text

あとはひたすら置き換える Then it's just a matter of diligently replacing it

Slide 21

Slide 21 text

テストコードの修正が大変だった Modifying the test code was a lot of work

Slide 22

Slide 22 text

● 当時のテストデータがランダムデータに対して アサーションしてないので、 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

Slide 23

Slide 23 text

● 当時のテストデータがランダムデータに対して アサーションしてないので、 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.


Slide 24

Slide 24 text

● 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).


Slide 25

Slide 25 text

以上!! That’s all

Slide 26

Slide 26 text

No content