ćœŹć–‡ä¸ťčŚäť‹çťĺœ¨ä¸€ä¸Şĺˆ†ĺ¸ƒĺźçłťçťŸä¸, ć€Žäšˆć ˇç”Ÿćˆĺ…¨ĺą€ĺ”Żä¸€çš„ ID
一, é—Žé˘˜ćčż°
ĺœ¨ĺˆ†ĺ¸ƒĺźçłťçťŸĺ˜ĺœ¨ĺ¤šä¸Ş Shard çš„ĺœşć™Żä¸, ĺŒć—śĺœ¨ĺ„个 Shard ć’ĺ…Ľć•°ćŽć—ś, ć€Žäšˆçť™čż™äş›ć•°ćŽç”Ÿćˆĺ…¨ĺą€çš„ unique ID?
ĺœ¨ĺ•ćœşçłťçťŸä¸ (䞋匂一个 MySQL 厞䞋), unique ID 的生ćˆć˜Żéžĺ¸¸çŽ€ĺ•çš„, ç›´ćŽĽĺˆŠç”¨ MySQL 自希的自增 ID ĺŠŸčƒ˝ĺ°ąĺŻäťĽĺŽžçŽ°.
ä˝†ĺœ¨ä¸€ä¸Şĺ˜ĺœ¨ĺ¤šä¸Ş Shards çš„ĺˆ†ĺ¸ƒĺźçłťçťŸ (䞋匂多个 MySQL 厞䞋睄ćˆä¸€ä¸Şé›†çž¤, ĺœ¨čż™ä¸Şé›†çž¤ä¸ć’ĺ…Ľć•°ćŽ), čż™ä¸Şé—Žé˘˜äźšĺ˜ĺž—ĺ¤ć‚, ć‰€ç”Ÿćˆçš„全幀的 unique ID čŚćťĄčśłäťĽä¸‹éœ€ćą‚:
- äżčŻç”Ÿćˆçš„ ID 全幀唯一
- 䝊ĺŽć•°ćŽĺœ¨ĺ¤šä¸Ş Shards 䚋间čżç§ťä¸äźšĺ—ĺˆ° ID 生ćˆć–šĺźçš„é™ĺˆś
- 生ćˆçš„ ID ä¸ćœ€ĺĽ˝čƒ˝ĺ¸Śä¸Šć—śé—´äżĄćŻ, 䞋匂 ID çš„ĺ‰ k ä˝ć˜Ż Timestamp, čż™ć ˇčƒ˝ĺ¤Ÿç›´ćŽĽé€ščż‡ĺŻš ID çš„ĺ‰ k ä˝çš„排ĺşćĽĺŻšć•°ćŽćŒ‰ć—śé—´ćŽ’ĺş
- 生ćˆçš„ ID ćœ€ĺĽ˝ä¸ĺ¤§äşŽ 64 bits
- ç”Ÿćˆ ID çš„é€ŸĺşŚćœ‰čŚćą‚. 䞋匂, ĺœ¨ä¸€ä¸ŞéŤ˜ĺžĺé‡çš„ĺœşć™Żä¸, 需čŚćŻç§’生ćˆĺ‡ 万个 ID (Twitter ćœ€ć–°çš„ĺł°ĺ€źĺˆ°čžžäş† 143,199 Tweets/s, äšŸĺ°ąć˜Ż 10万+/ç§’)
- 整个ćœĺŠĄćœ€ĺĽ˝ć˛Ąćœ‰ĺ•炚
ĺŚ‚ćžœć˛Ąćœ‰ä¸Šé˘čż™äş›é™ĺˆś, é—Žé˘˜äźšç›¸ĺŻšçŽ€ĺ•, 䞋匂:
- ç›´ćŽĽĺˆŠç”¨ UUID.randomUUID() 掼ĺŁćĽç”Ÿćˆ unique ID (http://www.ietf.org/rfc/rfc4122.txt). ä˝†čż™ä¸Şć–šćĄˆç”Ÿćˆçš„ ID ćœ‰ 128 bits, ĺŚĺ¤–, 生ćˆçš„ ID ä¸äšŸć˛Ąćœ‰ĺ¸Ś Timestamp
- ĺˆŠç”¨ä¸€ä¸Şä¸ĺżƒćœĺŠĄĺ™¨ćĽçťŸä¸€ç”Ÿćˆ unique ID. 但这ç§ć–šćĄˆĺŻčƒ˝ĺ˜ĺœ¨ĺ•ç‚šé—Žé˘˜; ĺŚĺ¤–, čŚć”ŻćŒéŤ˜ĺžĺçŽ‡çš„çłťçťŸ, čż™ä¸Şć–šćĄˆčż˜čŚĺšĺžˆĺ¤šć”ščż›ĺˇĽä˝œ (䞋匂, ćŻćŹĄäťŽä¸ĺżƒćœĺŠĄĺ™¨ć‰šé‡čގĺ–一扚 IDs, ćĺ‡ ID äş§ç”Ÿçš„ĺžĺ率)
- Flickr çš„ĺšćł• (http://code.flickr.net/2010/02/08/ticket-servers-distributed-unique-primary-keys-on-the-cheap/). ä˝†äť–čż™ä¸Şć–šćĄˆ ID ä¸ć˛Ąćœ‰ĺ¸Ś Timestamp, 生ćˆçš„ ID ä¸čƒ˝ćŒ‰ć—śé—´ćŽ’ĺş
ĺœ¨čŚćťĄčśłĺ‰é˘ 6 炚čŚćą‚çš„ĺœşć™Żä¸, ć€ŽäšˆćĽç”Ÿćˆĺ…¨ĺą€ unique ID 呢?
Twitter çš„ Snowflake ć˜Żä¸€ç§ćŻ”čžƒĺĽ˝çš„ĺšćł•. 下é˘ä¸ťčŚäť‹çť Twitter Snowflake, 䝼ĺŠĺŽƒçš„ĺ˜ç§
äşŒ, Twitter Snowflake
https://github.com/twitter/snowflake
Snowflake 生ćˆçš„ unique ID çš„çť„ćˆ (ç”ąéŤ˜ä˝ĺˆ°ä˝Žä˝):
- 41 bits: Timestamp (母秒级)
- 10 bits: 节炚 ID (datacenter ID 5 bits + worker ID 5 bits)
- 12 bits: sequence number
一兹 63 bits (ćœ€éŤ˜ä˝ć˜Ż 0)
unique ID 生ćˆčż‡ç¨‹:
- 10 bits çš„ćœşĺ™¨ĺˇ, ĺœ¨ ID ĺˆ†é… Worker ĺŻĺŠ¨çš„ć—śĺ€™, 䝎一个 Zookeeper é›†çž¤čŽˇĺ– (äżčŻć‰€ćœ‰çš„ Worker ä¸äźšćœ‰é‡ĺ¤çš„ćœşĺ™¨ĺˇ)
- 41 bits çš„ Timestamp: ćŻćŹĄčŚç”Ÿćˆä¸€ä¸Şć–° ID 的旜候, éƒ˝äźščŽˇĺ–一下当ĺ‰çš„ Timestamp, 焜ĺŽĺˆ†ä¸¤ç§ćƒ…ĺ†ľç”Ÿćˆ sequence number:
- ĺŚ‚ćžœĺ˝“ĺ‰çš„ Timestamp ĺ’Œĺ‰ä¸€ä¸Şĺˇ˛ç”Ÿćˆ ID çš„ Timestamp ç›¸ĺŒ (ĺœ¨ĺŒä¸€ćŻŤç§’ä¸), 尹用ĺ‰ä¸€ä¸Ş ID çš„ sequence number + 1 ä˝œä¸şć–°çš„ sequence number (12 bits); ĺŚ‚ćžœćœŹćŻŤç§’ĺ†…çš„ć‰€ćœ‰ ID ç”¨ĺŽŒ, ç‰ĺˆ°ä¸‹ä¸€ćŻŤç§’çť§çť (这个ç‰ĺž…过程ä¸, ä¸čƒ˝ĺˆ†é…出新的 ID)
- ĺŚ‚ćžœĺ˝“ĺ‰çš„ Timestamp 比ĺ‰ä¸€ä¸Ş ID çš„ Timestamp 大, éšćœşç”Ÿćˆä¸€ä¸Şĺˆĺ§‹ sequence number (12 bits) ä˝œä¸şćœŹćŻŤç§’ĺ†…çš„çŹŹä¸€ä¸Ş sequence number
整个过程ä¸, ĺŞć˜Żĺœ¨ Worker ĺŻĺŠ¨çš„ć—śĺ€™äźšĺŻšĺ¤–éƒ¨ćœ‰äžčľ– (需čŚäťŽ Zookeeper čŽˇĺ– Worker ĺˇ), äš‹ĺŽĺ°ąĺŻäťĽç‹ŹçŤ‹ĺˇĽä˝œäş†, ĺšĺˆ°äş†ĺŽťä¸ĺżƒĺŒ–.
ĺź‚ĺ¸¸ćƒ…ĺ†ľčŽ¨čŽş:
- ĺœ¨čŽˇĺ–ĺ˝“ĺ‰ Timestamp ć—ś, ĺŚ‚ćžœčŽˇĺ–ĺˆ°çš„ć—śé—´ćˆłćŻ”ĺ‰ä¸€ä¸Şĺˇ˛ç”Ÿćˆ ID çš„ Timestamp čż˜čŚĺ°ć€ŽäšˆĺŠž? Snowflake çš„ĺšćł•ć˜Żçť§çťčގĺ–当ĺ‰ćœşĺ™¨çš„ć—śé—´, ç›´ĺˆ°čŽˇĺ–ĺˆ°ć›´ĺ¤§çš„ Timestamp ć‰čƒ˝çť§çťĺˇĽä˝œ (ĺœ¨čż™ä¸Şç‰ĺž…过程ä¸, ä¸čƒ˝ĺˆ†é…出新的 ID)
äťŽčż™ä¸Şĺź‚ĺ¸¸ćƒ…ĺ†ľĺŻäťĽçœ‹ĺ‡ş, ĺŚ‚ćžœ Snowflake 所čżčĄŒçš„é‚Łäş›ćœşĺ™¨ć—śé’Ÿćœ‰ĺ¤§çš„ĺ塎旜, 整个 Snowflake çłťçťŸä¸čƒ˝ćŁĺ¸¸ĺˇĽä˝œ (ĺ塎垗蜊多, ĺˆ†é…ć–° ID ć—śç‰ĺž…的旜间蜊䚅)
䝎 Snowflake çš„ĺŽ˜ć–šć–‡ćĄŁ (https://github.com/twitter/snowflake/#system-clock-dependency) ä¸äšŸĺŻäťĽçœ‹ĺˆ°, ĺŽƒć˜ŽçĄŽčŚćą‚ “You should use NTP to keep your system clock accurate”. č€Œä¸”ćœ€ĺĽ˝ćŠŠ NTP é…罎ćˆä¸äźšĺ‘ĺŽč°ƒć•´çš„樥ĺź. äšŸĺ°ąć˜ŻčŻ´, NTP çş ćŁć—śé—´ć—ś, ä¸äźšĺ‘ĺŽĺ›žć‹¨ćœşĺ™¨ć—śé’Ÿ.
三, Snowflake 的兜䝖ĺ˜ç§
Snowflake ćœ‰ä¸€äş›ĺ˜ç§, ĺ„个应用睓ĺˆč‡Şĺˇąçš„ĺŽžé™…ĺœşć™ŻĺŻš Snowflake ĺšäş†ä¸€äş›ć”šĺЍ. čż™é‡Œä¸ťčŚäť‹çť 3 ç§.
1. Boundary flake
http://boundary.com/blog/2012/01/12/flake-a-decentralized-k-ordered-unique-id-generator-in-erlang/
ĺ˜ĺŒ–:
- ID é•żĺşŚć‰Šĺą•ĺˆ° 128 bits:
- ćœ€éŤ˜ 64 bits ć—śé—´ćˆł;
- 焜ĺŽć˜Ż 48 bits çš„ Worker ĺˇ (ĺ’Œ Mac ĺœ°ĺ€ä¸€ć ˇé•ż);
- ćœ€ĺŽć˜Ż 16 bits çš„ Seq Number
- ç”ąäşŽĺŽƒç”¨ 48 bits ä˝œä¸ş Worker ID, ĺ’Œ Mac ĺœ°ĺ€çš„é•żĺşŚä¸€ć ˇ, čż™ć ˇĺŻĺŠ¨ć—śä¸éœ€čŚĺ’Œ Zookeeper é€ščŽŻčŽˇĺ– Worker ID. ĺšĺˆ°äş†ĺŽŒĺ…¨çš„ĺŽťä¸ĺżƒĺŒ–
- ĺŸşäşŽ Erlang
ĺŽƒčż™ć ˇĺšçš„ç›Žçš„ć˜Żç”¨ć›´ĺ¤šçš„ bits 厞现更ĺ°çš„冲çŞćŚ‚çŽ‡, čż™ć ˇĺ°ąć”ŻćŒć›´ĺ¤šçš„ Worker ĺŒć—śĺˇĽä˝œ. ĺŒć—ś, ćŻćŻŤç§’čƒ˝ĺˆ†é…出更多的 ID
2. Simpleflake
http://engineering.custommade.com/simpleflake-distributed-id-generation-for-the-lazy/
Simpleflake çš„ć€čˇŻć˜Żĺ–ćśˆ Worker ĺˇ, äżç•™ 41 bits çš„ Timestamp, ĺŒć—śćŠŠ sequence number ć‰Šĺą•ĺˆ° 22 bits;
Simpleflake 的牚炚:
- sequence number ĺŽŒĺ…¨é éšćœşäş§ç”Ÿ (čż™ć ˇäšŸĺŻźč‡´äş†ç”Ÿćˆçš„ ID ĺŻčƒ˝ĺ‡şçްé‡ĺ¤)
- ć˛Ąćœ‰ Worker ĺˇ, äšŸĺ°ąä¸éœ€čŚĺ’Œ Zookeeper 通莯, ĺŽžçŽ°äş†ĺŽŒĺ…¨ĺŽťä¸ĺżƒĺŒ–
- Timestamp äżćŒĺ’Œ Snowflake 一致, 䝊ĺŽĺŻäťĽć— çźĺ‡çş§ĺˆ° Snowflake
Simpleflake çš„é—Žé˘˜ĺ°ąć˜Ż sequence number ĺŽŒĺ…¨éšćœşç”Ÿćˆ, äźšĺŻźč‡´ç”Ÿćˆçš„ ID é‡ĺ¤çš„ĺŻčƒ˝. čż™ä¸Şç”Ÿćˆ ID é‡ĺ¤çš„挂率éšç€ćŻç§’生ćˆçš„ ID ć•°çš„ĺ˘žé•żč€Œĺ˘žé•ż.
所䝼, Simpleflake çš„é™ĺˆśĺ°ąć˜ŻćŻç§’生ćˆçš„ ID ä¸čƒ˝ĺ¤Şĺ¤š (ćœ€ĺĽ˝ĺ°äşŽ 100揥/ç§’, ĺŚ‚ćžœĺ¤§äşŽ 100揥/ç§’çš„ĺœşć™Ż, Simpleflake ĺ°ąä¸é€‚用了, ĺťşčŽŽĺˆ‡ć˘ĺ›ž Snowflake).
3. instagram çš„ĺšćł•
ĺ…ˆçŽ€ĺ•äť‹çťä¸€ä¸‹ instagram çš„ĺˆ†ĺ¸ƒĺźĺ˜ĺ‚¨ć–šćĄˆ:
- ĺ…ˆćŠŠćŻä¸Ş Table ĺˆ’ĺˆ†ä¸şĺ¤šä¸Şé€ťčž‘ĺˆ†ç‰‡ (logic Shard), é€ťčž‘ĺˆ†ç‰‡çš„ć•°é‡ĺŻäťĽĺžˆĺ¤§, 䞋匂 2000 ä¸Şé€ťčž‘ĺˆ†ç‰‡
- 焜ĺŽĺˆśĺŽšä¸€ä¸Şč§„ĺˆ™, 规厚ćŻä¸Şé€ťčž‘ĺˆ†ç‰‡č˘Ťĺ˜ĺ‚¨ĺˆ°ĺ“Şä¸Şć•°ćŽĺş“厞䞋上é˘; ć•°ćŽĺş“厞䞋ä¸éœ€čŚĺžˆĺ¤š. 䞋匂, ĺŻšćœ‰ 2 个 PostgreSQL ĺŽžäž‹çš„çłťçťŸ (instagram 使用 PostgreSQL); ĺŻäťĽä˝żç”¨ĺĽ‡ć•°é€ťčž‘ĺˆ†ç‰‡ĺ˜ć”žĺˆ°çŹŹä¸€ä¸Şć•°ćŽĺş“厞䞋, ĺść•°é€ťčž‘ĺˆ†ç‰‡ĺ˜ć”žĺˆ°çŹŹäşŒä¸Şć•°ćŽĺş“ĺŽžäž‹çš„č§„ĺˆ™
- ćŻä¸Ş Table ćŒ‡ĺŽšä¸€ä¸Şĺ—ćŽľä˝œä¸şĺˆ†ç‰‡ĺ—掾 (䞋匂, ĺŻšç”¨ćˆˇčĄ¨, ĺŻäťĽćŒ‡ĺŽš uid ä˝œä¸şĺˆ†ç‰‡ĺ—掾)
- ć’兼一个新的数ćŽć—ś, ĺ…ˆć šćŽĺˆ†ç‰‡ĺ—掾的借, 决厚数ćŽč˘Ťĺˆ†é…ĺˆ°ĺ“Şä¸Şé€ťčž‘ĺˆ†ç‰‡ (logic Shard)
- 焜ĺŽĺ†ć šćŽ logic Shard ĺ’Œ PostgreSQL 厞䞋的寚应关糝, 祎厚这ćĄć•°ćŽĺş”诼袍ĺ˜ć”žĺˆ°ĺ“Şĺ° PostgreSQL 厞䞋上
instagram unique ID 的睄ćˆ:
- 41 bits: Timestamp (母秒)
- 13 bits: ćŻä¸Ş logic Shard çš„äťŁĺˇ (ćœ€ĺ¤§ć”ŻćŒ 8 x 1024 个 logic Shards)
- 10 bits: sequence number; ćŻä¸Ş Shard ćŻćŻŤç§’ćœ€ĺ¤šĺŻäťĽç”Ÿćˆ 1024 个 ID
ç”Ÿćˆ unique ID ć—ś, 41 bits çš„ Timestamp ĺ’Œ Snowflake çąťäźź, čż™é‡Œĺ°ąä¸çť†čŻ´äş†.
丝čŚäť‹çťä¸€ä¸‹ 13 bits çš„ logic Shard äťŁĺˇ ĺ’Œ 10 bits çš„ sequence number ć€Žäšˆç”Ÿćˆ.
logic Shard 䝣ĺˇ:
- ĺ‡čŽžć’兼一ćĄć–°çš„ç”¨ćˆˇčŽ°ĺ˝•, ć’ĺ…Ľć—ś, ć šćŽ uid ćĽĺˆ¤ć–čż™ćĄčŽ°ĺ˝•ĺş”čŻĽč˘Ťć’ĺ…Ľĺˆ°ĺ“Şä¸Ş logic Shard ä¸.
- ĺ‡čŽžĺ˝“ĺ‰čŚć’兼的莰录䟚袍ć’ĺ…Ľĺˆ°çŹŹ 1341 ĺˇ logic Shard ä¸ (ĺ‡čŽžĺ˝“ĺ‰çš„这个 Table ä¸€ĺ…ąćœ‰ 2000 个 logic Shard)
- ć–°ç”Ÿćˆ ID çš„ 13 bits 掾čŚĺĄŤçš„ĺ°ąć˜Ż 1341 这个数ĺ—
sequence number ĺˆŠç”¨ PostgreSQL ćŻä¸Ş Table 上的 auto-increment sequence ćĽç”Ÿćˆ:
- ĺŚ‚ćžœĺ˝“ĺ‰čĄ¨ä¸Šĺˇ˛çťćœ‰ 5000 ćĄčŽ°ĺ˝•, é‚Łäšˆčż™ä¸ŞčĄ¨çš„ä¸‹ä¸€ä¸Ş auto-increment sequence ĺ°ąć˜Ż 5001 (ç›´ćŽĽč°ƒç”¨ PL/PGSQL ć䞛的斚法ĺŻäťĽčގĺ–ĺˆ°)
- 焜ĺŽćŠŠ 这个 5001 寚 1024 ĺ–ć¨Ąĺ°ąĺž—ĺˆ°äş† 10 bits çš„ sequence number
instagram čż™ä¸Şć–šćĄˆçš„äź˜ĺŠżĺœ¨äşŽ:
- ĺˆŠç”¨ logic Shard ĺˇćĽć›żć˘ Snowflake 使用的 Worker ĺˇ, ĺ°ąä¸éœ€čŚĺˆ°ä¸ĺżƒčŠ‚ç‚ščŽˇĺ– Worker ĺˇäş†. ĺšĺˆ°äş†ĺŽŒĺ…¨ĺŽťä¸ĺżƒĺŒ–
- ĺŚĺ¤–ä¸€ä¸Şé™„ĺ¸Śçš„ĺĽ˝ĺ¤„ĺ°ąć˜Ż, ĺŻäťĽé€ščż‡ ID ç›´ćŽĽçŸĽé“čż™ćĄčŽ°ĺ˝•č˘Ťĺ˜ć”žĺœ¨ĺ“Şä¸Ş logic Shard 上
ĺŒć—ś, 䝊ĺŽĺšć•°ćŽčżç§ťçš„旜候, äšŸć˜ŻćŒ‰ logic Shard 为ĺ•ä˝ĺšć•°ćŽčżç§ťçš„, 所䝼这ç§ĺšćł•䚟ä¸äźšĺ˝ąĺ“ĺˆ°äťŠĺŽçš„ć•°ćŽčżç§ť
ĺˆ†ĺ¸ƒĺźçłťçťŸä¸ĺ”Żä¸€ ID 的生ćˆć–šćł•ďźŒéŚ–ĺ‘äşŽć–‡çŤ - 䟯äšĺœ¨çşżă€‚