|
| 1 | +# 📌 7장: 분산 시스템을 위한 유일 ID 생성기 설계 |
| 2 | + |
| 3 | +## ✅ 1. 문제 이해하고 설계 범위를 확정하기 |
| 4 | + |
| 5 | + |
| 6 | + |
| 7 | +<br><br> |
| 8 | + |
| 9 | +## ✅ 2. 개략적 설계안 제시 및 동의 구하기 |
| 10 | + |
| 11 | +- 다중 마스터 복제(multi-master replication) |
| 12 | +- UUID(Universally Unique Identifier) |
| 13 | +- 티켓 서버(Ticket Server) |
| 14 | +- 트위터 스노플레이크 접근법(twitter snowflake) |
| 15 | + |
| 16 | +<br> |
| 17 | + |
| 18 | +### 다중 마스터 |
| 19 | + |
| 20 | +- 특징 |
| 21 | + - DB의 `Auto Increment`기능을 활용함 |
| 22 | + - id값을 1씩 값을 증가시키지 않고 k만큼 증가시켜 서버마다 독립적인 id를 생성하도록 보장합니다. |
| 23 | +- 장점 |
| 24 | + - 간편함 |
| 25 | +- 단점 |
| 26 | + - 데이터 센터에 걸쳐서 규모를 늘리기는 어려움 |
| 27 | + - 서버가 추가된다면, `offset` 값이나 `increment` 값을 변경해야 합니다. |
| 28 | + - id의 유일성을 보장 하지만, 값이 시간 흐름에 맞추어 커지도록 보장하긴 어려움 |
| 29 | + 1. **서버 A에서 먼저 데이터가 삽입됨 (ID 1)** |
| 30 | + - 데이터 삽입 시각: `2024-12-05 12:00:00` |
| 31 | + 2. **서버 B에서 데이터가 나중에 삽입됨 (ID 2)** |
| 32 | + - 데이터 삽입 시각: `2024-12-05 12:00:05` |
| 33 | + 3. **다시 서버 A에서 데이터가 삽입됨 (ID 3)** |
| 34 | + - 데이터 삽입 시각: `2024-12-05 12:00:10` |
| 35 | + |
| 36 | + 이 경우 ID 순서는 **1 → 2 → 3**으로 보이지만, 데이터가 생성된 실제 시간 순서는 **1 → 3 → 2**입니다. |
| 37 | + |
| 38 | + - 서버를 추가 및 삭제할때 잘 동작하게 만들기 어려움 |
| 39 | + - 역시 `offset` 값이나 `increment` 값이 발목을 잡을 수 있음 |
| 40 | + |
| 41 | +<br> |
| 42 | + |
| 43 | +### UUID |
| 44 | + |
| 45 | +- 장점 |
| 46 | + - 생성이 단순하고, 서버와의 조율이 굳이 필요하지 않음 |
| 47 | + - 각 서버가 알아서 id를 생성하기에 규모 확장에 용이 |
| 48 | +- 단점 |
| 49 | + - id가 김 (128bit) |
| 50 | + - 시간순 정렬 불가능 |
| 51 | + - but, `uuid v6, v7`에선 타임스탬프를 기준으로 만들어지므로 시간 순 정렬을 좀 더 용이하도록 개선했다고 알고 있음 |
| 52 | + - id에 숫자가 아닌 값이 포함될 수 있다. |
| 53 | + |
| 54 | +<br> |
| 55 | + |
| 56 | +### 티켓 서버 |
| 57 | + |
| 58 | +티켓 서버를 만들어서 각 서버들이 티켓 서버에게 id 생성을 요구함 |
| 59 | + |
| 60 | +- 장점 |
| 61 | + - 숫자로만 이루어진 id를 쉽게 생성 가능하고 구현하기 편함 |
| 62 | +- 단점 |
| 63 | + - 티켓 서버 자체가 SPOF임 |
| 64 | + - 이를 위해 서버를 확장한다면 이 자체로도 데이터 동기화 문제가 발생할 수 있음 |
| 65 | + |
| 66 | +<br> |
| 67 | + |
| 68 | +### 트위터 스노우플레이크 접근법 |
| 69 | + |
| 70 | + |
| 71 | + |
| 72 | + |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | +- 시스템이 시작될 때 결정되는 요소(운영 중에 변경되지 않음) |
| 77 | + - 데이터센터 ID, 서버 ID |
| 78 | +- ID 생성기가 돌고 있는 도중에 만들어지는 값 |
| 79 | + - 타임스탬프, 일련번호 |
| 80 | + |
| 81 | +- 타임스탬프 |
| 82 | + - 41비트의 2진수를 10진수로 변경하여, 트위터 기원 시각을 더하고 UTC 시각으로 변환하여 시간을 구함 |
| 83 | + - 최댓값은 2^41 - 1로 69년에 해당됨 → 적어도 69년동안은 중복이 없음 |
| 84 | +- 일련번호 |
| 85 | + - 12비트 → 4096개의 값을 가짐 |
| 86 | + |
| 87 | +<br><br> |
| 88 | + |
| 89 | +## ✅ 마지막으로 |
| 90 | + |
| 91 | +- 결국 스노우 플레이크를 선택함 → 하지만 이 조차도 id 생성기를 만들다 보면 SPOF가 될 수 있지 않은가? |
| 92 | +- 그래서 이런 ID 생성기의 고가용성을 위해 분산 시킨다면 고려할 수 있는게 있음 |
| 93 | + - 시계 동기화 (여러 서버들의 시간을 동기화 시키는 방법) |
| 94 | +- 동시성 문제가 잦은 환경이 아니라면 |
| 95 | + - 각 section의 길이를 좀 더 바꿀 수 있음 (일련번호 길이를 줄인다거나 |
| 96 | + |
| 97 | +<br><br><br> |
| 98 | + |
| 99 | +# 📌 8장: URL 단축기 설계 |
| 100 | + |
| 101 | +## ✅ 1. 문제 이해하고 설계 범위를 확정하기 |
| 102 | + |
| 103 | + |
| 104 | + |
| 105 | + |
| 106 | + |
| 107 | + |
| 108 | + |
| 109 | +- 목표 |
| 110 | + |
| 111 | +  |
| 112 | + |
| 113 | + |
| 114 | +<br><br> |
| 115 | + |
| 116 | +## ✅ 2. 개략적 설계안 제시 및 동의 구하기 |
| 117 | + |
| 118 | +### API 엔드포인트 |
| 119 | + |
| 120 | +```java |
| 121 | +// 단축용 URL 생성 요청 |
| 122 | +POST /api/v1/data/shorten HTTP/1.1 |
| 123 | +Host: example.com |
| 124 | +Content-Type: application/json |
| 125 | + |
| 126 | +{ |
| 127 | + "longUrl": "https://www.example.com/very/long/url" |
| 128 | +} |
| 129 | + |
| 130 | +// 응답 |
| 131 | +HTTP/1.1 200 OK |
| 132 | +Content-Type: application/json |
| 133 | + |
| 134 | +{ |
| 135 | + "shortUrl": "https://short.ly/abcd1234" |
| 136 | +} |
| 137 | +``` |
| 138 | + |
| 139 | +```java |
| 140 | +// URL 디렉션용 엔드포인트 요청 |
| 141 | +GET /api/v1/shortUrl/abcd1234 HTTP/1.1 |
| 142 | +Host: example.com |
| 143 | + |
| 144 | +// 응답 |
| 145 | +HTTP/1.1 301 Permanently Moved // or 302 Found |
| 146 | +Location: https://www.example.com/very/long/url |
| 147 | +``` |
| 148 | + |
| 149 | +- 301 and 302 |
| 150 | + - `301 Permanently Moved` |
| 151 | + - URL에 대한 HTTP 요청의 처리 책임이 영구적으로 Location 헤더에 반환된 URL로 이전되었다는 응답 |
| 152 | + - 단축 URL이 캐시되어 있다면 라우저는 원본 URL로 요청을 보내게 됨 |
| 153 | + - `302 Found` |
| 154 | + - 주어진 URL로의 요청이 `일시적으로` Location 헤더가 지정하는 URL에 의해 처리되어야 한다는 응답 (클라이언트의 요청은 언제나 단축 URL 서버로 먼저 보내짐) |
| 155 | + |
| 156 | + 301을 쓰면, 서버 부하를 줄일 수 있음 |
| 157 | + |
| 158 | + 302를 쓰면, 클릭 발생률, 발생 위치 추적에 용이함 |
| 159 | + |
| 160 | +<br> |
| 161 | + |
| 162 | +### URL 단축 |
| 163 | + |
| 164 | +- 결국 URL을 단축시킬 수 있는 해시 값을 알아야 함 |
| 165 | +- URL이 다르면 해시값도 달라야 하며, 해시 값은 다시 원본 URL로 복원할 수 있어야 합니다. |
| 166 | + |
| 167 | +단축 URL은 0-9, a-z, A-Z를 사용할 수 있습니다. 따라서 총 62개의 문자를 사용할 수 있습니다. |
| 168 | + |
| 169 | + |
| 170 | + |
| 171 | + |
| 172 | +→ 대략 7글자 정도를 URL의 길이로 삼으면 적당함 |
| 173 | + |
| 174 | +- **해시 후 충돌 해소 기법** |
| 175 | + - 잘 알려진 해시 함수를 이용하면 됨(CRC32, MD5, SHA-1 등) |
| 176 | + - 다만 결과값이 7보다 길어진다면 첫 7글자만 사용합니다. 그럼에도 중복이 발생한다면 다음과 같은 절차로 충돌이 해소될때까지 진행함 |
| 177 | + |
| 178 | +  |
| 179 | + |
| 180 | + |
| 181 | + |
| 182 | + → 잦은 DB 조회가 발생할 수 있기 때문에 DB대신 `블룸 필터`를 사용하여 성능을 높일 수 있습니다. |
| 183 | + |
| 184 | + |
| 185 | +- **base-62 변환 법** |
| 186 | + - 62진법을 이용해 변환함 |
| 187 | + |
| 188 | +  |
| 189 | + |
| 190 | + |
| 191 | + |
| 192 | +- 차이점 정리 |
| 193 | + |
| 194 | +  |
| 195 | + |
| 196 | + |
| 197 | + |
| 198 | +- 62진법을 사용한다면 결과적으로 아래와 같은 flow로 흐름이 진행됩니다. |
| 199 | + |
| 200 | +  |
| 201 | + |
| 202 | + |
| 203 | +  |
| 204 | + |
| 205 | + |
| 206 | + - 8-7 그림의 4번의 id 생성은 이전 7장에서 언급한 분산된 환경에서의 id 생성기를 만드는 기법을 활용하면 좋음 |
| 207 | + - 8-8 그림의 캐시는 <단축 URL, 원래 URL>의 쌍을 저장함 |
| 208 | + |
| 209 | +<br><br> |
| 210 | + |
| 211 | +## ✅ 마지막으로 |
| 212 | + |
| 213 | +- 위 시스템에 엄청난 양의 단축 URL 요청이 폭주한다면 처리율 제한 장치를 고려할 수 있음 |
| 214 | +- 웹 계층은 무상태 이므로 웹 서버의 규모를 확장할 수 있음 |
| 215 | +- DB 다중화 및 샤딩을 통해 규모 확장 가능 |
| 216 | +- URL 단축기에 데이터 분석 솔루션을 두어 중요 정보들을 수집 |
| 217 | +- 가용성, 데이터 일관성, 안전성이 갖추어져야 안정적인 대규모 시스템을 만들 수 있음 |
0 commit comments