๐ธ Instagram ID ์ค๋ฉ ์ ๋ต
Instagram์ด ๋๊ท๋ชจ ๋ถ์ฐ ์์คํ ์์ ๊ณ ์ ํ ID๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ
๐ข 64๋นํธ ID ๊ตฌ์กฐ
Shard ID
13 bits
์ค๋ ์๋ณ์
Sequence
10 bits
์๋ ์ฆ๊ฐ ์ํ์ค
| ๋ถ๋ถ | ๋นํธ ์ | ์ต๋ ๊ฐ | ์ค๋ช |
|---|---|---|---|
| ํ์์คํฌํ | 41 bits | 2^41 โ 69๋ | ์ปค์คํ epoch ์ดํ์ ๋ฐ๋ฆฌ์ด. ์๊ฐ ์ ์ ๋ ฌ ๊ฐ๋ฅ |
| ์ค๋ ID | 13 bits | 2^13 = 8,192 | ๋ ผ๋ฆฌ์ ์ค๋ ์๋ณ. ๋ฐ์ดํฐ ์์น ๊ฒฐ์ |
| ์ํ์ค | 10 bits | 2^10 = 1,024 | ์ค๋๋น ๋ฐ๋ฆฌ์ด๋น 1,024๊ฐ ID ์์ฑ ๊ฐ๋ฅ |
๐๏ธ ์ค๋ฉ ์ํคํ ์ฒ
ํต์ฌ ์์ด๋์ด: ๋ ผ๋ฆฌ์ ์ค๋๋ฅผ ์ฝ๋์์ ๋ฌผ๋ฆฌ์ ์๋ฒ๋ก ๋งคํ. ๋ฐ์ดํฐ ์ฌ๊ตฌ์ฑ ์์ด ์ค๋๋ฅผ ๋ค๋ฅธ ์๋ฒ๋ก ์ฝ๊ฒ ์ด๋ ๊ฐ๋ฅ!
๐ ID ์์ฑ ์์
์๋๋ฆฌ์ค
- ๋ ์ง: 2011๋ 9์ 9์ผ ์คํ 5์
- Epoch: 2011๋ 1์ 1์ผ
- ์ฌ์ฉ์ ID: 31,341
- ๋ ผ๋ฆฌ์ ์ค๋ ๊ฐ์: 2,000๊ฐ
1
ํ์์คํฌํ ๊ณ์ฐ
Epoch ์ดํ ๊ฒฝ๊ณผ ์๊ฐ: 1,387,263,000 ๋ฐ๋ฆฌ์ด
์ผ์ชฝ 23๋นํธ ์ํํธ: 1387263000 << 23
๊ฒฐ๊ณผ: ์ต์์ 41๋นํธ ์ฑ์ฐ๊ธฐ
2
์ค๋ ID ๊ณ์ฐ
์ฌ์ฉ์ ID๋ก ์ค๋ฉ: 31341 % 2000 = 1341
์ผ์ชฝ 10๋นํธ ์ํํธ: 1341 << 10
๊ฒฐ๊ณผ: ๋ค์ 13๋นํธ ์ฑ์ฐ๊ธฐ
3
์ํ์ค ๋ฒํธ ์ถ๊ฐ
PostgreSQL nextval() ํธ์ถ
์ํ์ค ๊ฐ % 1024
๊ฒฐ๊ณผ: ๋ง์ง๋ง 10๋นํธ ์ฑ์ฐ๊ธฐ
4
์ต์ข
ID ์กฐํฉ
ID = (timestamp << 23) | (shard_id << 10) | (sequence % 1024)
๊ฒฐ๊ณผ: 64๋นํธ ๊ณ ์ ID ์์ฑ ์๋ฃ!
๐ป PostgreSQL ๊ตฌํ
CREATE OR REPLACE FUNCTION insta5.next_id(OUT result bigint) AS $$
DECLARE
our_epoch bigint := 1314220021721; -- ์ปค์คํ
epoch
seq_id bigint;
now_millis bigint;
shard_id int := 5; -- ํ์ฌ ์ค๋ ID
BEGIN
-- 1. ์ํ์ค ๋ฒํธ ๊ฐ์ ธ์ค๊ธฐ (1024๋ก ๋๋ ๋๋จธ์ง)
SELECT nextval('insta5.table_id_seq') % 1024 INTO seq_id;
-- 2. ํ์ฌ ๋ฐ๋ฆฌ์ด ํ์์คํฌํ
SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000)
INTO now_millis;
-- 3. ID ์กฐํฉ
result := (now_millis - our_epoch) << 23; -- ํ์์คํฌํ
result := result | (shard_id << 10); -- ์ค๋ ID
result := result | (seq_id); -- ์ํ์ค
END;
$$ LANGUAGE PLPGSQL;
โจ ์ฃผ์ ์ฅ์
โฐ ์๊ฐ ์ ์ ๋ ฌ
ID์ ํ์์คํฌํ๊ฐ ํฌํจ๋์ด ์์ด ์ถ๊ฐ ์ฟผ๋ฆฌ ์์ด ์๊ฐ์ ์ ๋ ฌ ๊ฐ๋ฅ
๐ฏ ์ค๋ ์๋ณ
ID์์ ์ค๋ ์ ๋ณด๋ฅผ ์ถ์ถํ์ฌ ์ด๋ DB๋ฅผ ์ฟผ๋ฆฌํ ์ง ์ฆ์ ํ์
๐ ๋จ์์ฑ
๋ณ๋์ ID ์์ฑ ์๋น์ค ๋ถํ์. PostgreSQL ๋ด๋ถ์์ ๋ชจ๋ ์ฒ๋ฆฌ
๐ ํ์ฅ์ฑ
๋ฐ์ดํฐ ์ฌ๊ตฌ์ฑ ์์ด ๋ ผ๋ฆฌ์ ์ค๋๋ฅผ ์ ์๋ฒ๋ก ์ด๋ ๊ฐ๋ฅ
โก ๋์ ์ฒ๋ฆฌ๋
์ค๋๋น ๋ฐ๋ฆฌ์ด๋น 1,024๊ฐ ID ์์ฑ. ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ก ์ ์ฒด ์ฒ๋ฆฌ๋ ๊ทน๋ํ
๐พ ํจ์จ์ ์ ์ฅ
64๋นํธ๋ก ์ปดํฉํธ. Redis ๋ฑ์์ ํจ์จ์ ์ผ๋ก ์ ์ฅ ๊ฐ๋ฅ
๐ ๋ค๋ฅธ ์๋ฃจ์ ๊ณผ์ ๋น๊ต
| ์๋ฃจ์ | ํฌ๊ธฐ | ์๊ฐ์ ์ ๋ ฌ | ๋ณต์ก๋ | Instagram ์ ํ ์ฌ๋ถ |
|---|---|---|---|---|
| UUID | 128 bits | โ | ๋ฎ์ | โ ๋๋ฌด ํผ |
| Flickr (ํ์/์ง์) | 64 bits | โ | ์ค๊ฐ | โ ์๊ฐ์ ์ ๋ ฌ ๋ถ๊ฐ |
| Twitter Snowflake | 64 bits | โ | ๋์ | โ ๏ธ ๋ณ๋ ์๋น์ค ํ์ |
| Instagram ๋ฐฉ์ | 64 bits | โ | ๋ฎ์ | โ ์ ํ! |
๐ ์ฑ๋ฅ ์งํ
์ฒ๋ฆฌ๋ ๊ณ์ฐ
- ์ค๋๋น ์ฒ๋ฆฌ๋: 1,024 IDs/๋ฐ๋ฆฌ์ด = 1,024,000 IDs/์ด
- 2,000๊ฐ ๋ ผ๋ฆฌ์ ์ค๋: 2,048,000,000 IDs/์ด (์ด๋ก ์ ์ต๋)
- ์ค์ Instagram ๋ถํ: ์ด๋น ์ฌ์ง 25๊ฐ + ์ข์์ 90๊ฐ = 115๊ฐ/์ด
- ์ฌ์ : ์ด๋ก ์ ์ต๋์น์ 0.000006% ์ฌ์ฉ ์ค (์ถฉ๋ถํ ํ์ฅ ์ฌ๋ ฅ)
๐ ํต์ฌ ๊ตํ
- ๋จ์ํจ์ด ์ต๊ณ : ๋ณต์กํ ์ธ๋ถ ์๋น์ค ๋์ ๊ธฐ์กด DB ๊ธฐ๋ฅ ํ์ฉ
- ํ๋ช ํ ์ฐจ์ฉ: Twitter Snowflake ์์ด๋์ด๋ฅผ ์ฐจ์ฉํ๋ ์ํฉ์ ๋ง๊ฒ ๋ณํ
- ๋ ผ๋ฆฌ์ ์ถ์ํ: ๋ ผ๋ฆฌ์ ์ค๋์ ๋ฌผ๋ฆฌ์ ์ค๋ ๋ถ๋ฆฌ๋ก ํ์ฅ์ฑ ํ๋ณด
- ์ค์ผ์ผ๋ง ์ ๋ต: ์ ์ ์์ง๋์ด๋ก 1,400๋ง+ ์ฌ์ฉ์ ์ง์ ๊ฐ๋ฅ
๐ ์ฐธ๊ณ ์๋ฃ
- ์๋ฌธ: Sharding & IDs at Instagram
- Twitter Snowflake: ๋ถ์ฐ ID ์์ฑ ์์คํ ์ ์๊ฐ
- PostgreSQL Schemas: ๋ ผ๋ฆฌ์ ๊ทธ๋ฃนํ ๊ธฐ๋ฅ
- PL/PGSQL: PostgreSQL์ ๋ด์ฅ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด
๋ฐ์ํ
'์น๋ ์ฐ๋ค' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| stockcrypto-logs ๊ฐ๋ฐ (์์ฐ๊ด๋ฆฌ ๊ฐ๊ณ๋ถ) (0) | 2025.12.13 |
|---|---|
| Google Antigravity ์ถ์ ๋ฐ Gemini 3.0 pro (0) | 2025.11.19 |
| flowith.io with neo ์ agent mode ์ฌ์ฉํด๋ณด๊ธฐ (2) | 2025.05.28 |
| Goodbye, Yoda condition? (์๋คํํ์) (0) | 2023.10.10 |
| ์ฉ์ด์ ํต์ผ์ ์ค์ํ๋ค. (feat. ๊ธฐ๋ณธ์ ์ค์ํจ) (0) | 2023.08.28 |