canonical_id について#

canonical_id の生成と割り当て#

Unification Algorithm 実行後、最終 graph に対して canonical_id を割り振る処理が +canonicalize タスクで行われる。各ユーザーに対して leader の値をベースにして canonical_id が生成され、それを follow する全ての followerに同じ ID が配布されることになる。

leader key の値 (graph.leader_id) をベースに、以下の計算で導出する:

to_base64url(
  to_big_endian_64(
    bitwise_xor(
      from_big_endian_64(
        substr(
          sha256(to_utf8(graph.leader_id)), 1, 8
        )
      ), leader_keys.key_mask_low64i
    )
  ) || leader_keys.key_mask_high8b
)
_images/4-7-1.png

Fig. 24 canonical_id の生成と割り当て#

上の例では、User1 と User2 は、leader となった td_client_id に基づいて canonical_id が生成されるのに対して、User3 は td_client_id が存在しなかったために leader が (merge_by_keys の次の優先度であった) td_global_id となり、その値に基づいて canonical_id が生成されることになる。 生成された canonical_id は、接続する全ての follower にも割り振られ、1人の leader と全ての follower に同じ canonical_id を持っている状態となる。出力される lookup テーブルでは、この情報が記録されており、全ての key ごとに割り振られている canonical_id を知ることができるテーブルとなっている。

canonical_id は不変か?#

実は、canonical_id は毎回の Unification WF の実行に対して (同じユーザーに対して) 常に同じ値が生成されるとは限らない。

_images/4-8-1.png

Fig. 25 canonical_id が変わってしまうケース#

次回の更新時、User1 には “aaa_00” という元よりも小さい値の leader が出現したとする。 その際、User1 の leader は (最小の値の leader が最終的に唯一の leader となるため) “aaa_00” となり、 前回とは異なる canonical_id が生成されることになる。異なる canonical_id は別人を意味するので、新しいユーザーが出現したことを意味する。例えば、この canonical_id を利用しているオーディエンススタジオ上では、User1 の cdp_customer_id が変わってしまうことを意味する。

merge_by_keys: の順番の決め方#

できるだけ canonical_id を Unification WF 更新に対して変わらないように心がけることが重要である。そして canonical_id の不変性に大きく関わっているのが merge_by_keys: の key の順番である。

Unification Algorithm は、merge_by_keys: に設定された key の中で、できるだけ先頭の、つまり優先度が高い key を優先的に leader に設定するものだった。これは各ユーザーに最終的に選ばれる1つの leader は多くは merge_by_keys: の先頭の key になるということである。

つまり、merge_by_keys: では、将来に対してできるだけ値が変わらない key から順に設定すべきである。1番目の優先度の key を持たないユーザーに対しては2番目の優先度の key が leader となるので、先頭だけでなく2番目、3番目…つまり順番が非常に重要になる。

merge_by_keys: の設定例#

  • ⭕️ merge_by_keys: [email, td_global_id]

    • email は個人に対して変更したり増えたりしにくいので、いつの更新でも同じ値が選ばれる (つまり canonical_id も常に同じになる)

  • ⭕️ merge_by_keys: [member_id, email, td_global_id]

    • member_id や customer_id は個人に対して変更したり増えたりしにくいので、いつの更新でも同じ値が選ばれる (つまり canonical_id も常に同じになる)

  • ❌ merge_by_keys: [td_client_id, email, td_global_id]

    • td_client_id は時間が経てば値が異なる。新しく生成された値が過去の最小値より小さい値をとった場合には、それが leader となるため、前回と canonical_id が異なるものになる。