SLIDE 1 Как мигрировать 50Пб в 32ПБ
Андрей Сумин, CTO of Mail Services at Mail.ru
SLIDE 2 Из чего состоит почта
50ПБ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 15% 85% файлы
SLIDE 3
Структура базы
SLIDE 4
FileDB
SLIDE 5
FileDB sha1 (от содержимого файла)
SLIDE 6
FileDB sha1 counter
SLIDE 7
letters index store | |
SLIDE 8
letters index store | | delete letter → | | | delete file → | crash
SLIDE 9
letters index store | | delete letter → | | | delete file → | crash restore | delete file → | | ← ok | delete letter
SLIDE 10
letters index store | | delete letter → | | | delete file → | crash restore | delete file → | | ← ok | delete letter
SLIDE 11
FileDB sha1 counter magic # в индексах писем лежит sha1 и magic
SLIDE 12
counter = 1 magic = 345
SLIDE 13
counter = 1 magic = 345
SLIDE 14
letters index store | | counter = 1 | | magic = 345 add letter → | | | |
SLIDE 15
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → |
SLIDE 16
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → | 345 + 123 = 468 2
SLIDE 17
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → | 345 + 123 = 468 2 | | remove letter → | | | delete file (sha1, 123) → | 468 – 123 = 345 1
SLIDE 18
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → | 345 + 123 = 468 2 | | remove letter → | | | delete file (sha1, 123) → | 468 – 123 = 345 1 | delete file (sha1, 345) → | 345 – 345 = 0 0
SLIDE 19
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → | 345 + 123 = 468 2 | | remove letter → | | | delete file (sha1, 123) → | 468 – 123 = 345 1 | | | delete file (sha1, 123) → | 345 – 123 = 222 0
SLIDE 20
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → | 345 + 123 = 468 2 | | remove letter → | | | delete file (sha1, 123) → | 468 – 123 = 345 1 | | | delete file (sha1, 123) → | 345 – 123 = 222 0
SLIDE 21
letters index store | | counter = 1 | | magic = 345 add letter → | | | upload file (sha1, 123) → | 345 + 123 = 468 2 | | remove letter → | | | delete file (sha1, 123) → | 468 – 123 = 345 1 | | | delete file (sha1, 123) → | 345 – 123 = 222 0 | delete file (sha1, 345) → | 222 – 345 = -123 0
SLIDE 22
FileDB sha1 counter magic flags
SLIDE 23
FileDB sha1 counter magic flags IP0 disk0 IP1 disk1
SLIDE 24
FileDB sha1 counter magic flags pair_id → IP0 disk0 IP1 disk1
SLIDE 25
PairDB id IP0 disk0 IP1 disk1
SLIDE 26
PairDB id IP0 disk0 IP1 disk1 flags
SLIDE 27
PairDB id IP0 disk0 IP1 disk1 flags free0 free1
SLIDE 28
FileDB sha1 20 counter 4 magic 4 flags 4 pair_id 4
SLIDE 29 36 (данные)
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
SLIDE 30 36 + 5 (длина полей)
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
SLIDE 31 36 + 5 + 16 (заголовки)
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■■
SLIDE 32 36 + 5 + 16 = 57 байт
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■■
SLIDE 33
57 * 12 * 10^9 = 637 GB
■■■■■ ……………………… ■■■■■■■
SLIDE 34
12 * 12 * 10^9 = 179GB
■■■■■ ……………………… ■■■■■■■
SLIDE 35
637 GB 179 GB
■■■■■■■■■■■■■■■■■■■■
SLIDE 36
637 GB 179 GB
■■■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■■■ 1600 GB
SLIDE 37
PairDB содержит 14000 записей
SLIDE 38
Loader API
SLIDE 39
inc (sha1, magic)
SLIDE 40
inc (sha1, magic) upload (sha1, magic)
SLIDE 41
inc (sha1, magic) upload (sha1, magic) dec (sha1, magic)
SLIDE 42
inc (sha1, magic) upload (sha1, magic) dec (sha1, magic) GET /sha1
SLIDE 43
iproto
|sync cmd len|
SLIDE 44
iproto
|sync cmd len|flags|origin-len|sha1|magic|
SLIDE 45
Выбираем пару для заливки файла
|---1---|----------2----------|-----3-----|--------4--------|
SLIDE 46
Проблема чистой пары
|--1--|-----------------------2-----------------------|--3--|--4--|
SLIDE 47
Проблема чистой пары
|--√1--|-------------√2-------------|--√3--|--√4--|
SLIDE 48
Пара выбрана
|--√1--|-------------√2-------------|--√3--|--√4--|
SLIDE 49
Пара выбрана
|--√1--|-------------√2-------------|--√3--|--√4--| Отправляем небольшой файл на эти диски.
SLIDE 50
|sync cmd len|flags|origin-len|sha1|magic|filecontent.................|
sha1 считаем на лету
SLIDE 51
nginx + webdav
SLIDE 52 loader store | | | PUT (sha1) → |
SLIDE 53 loader store loader | | | | PUT (sha1) → | ←PUT (sha1) |
SLIDE 54 loader store loader | | | | PUT (sha1) → | ←PUT (sha1) | /60/07/600710b0a5cfa...5a97b98ea355c.inprogress.random.ts | ← 201 | | |
SLIDE 55 loader store loader | | | | PUT (sha1) → | ←PUT (sha1) | /60/07/600710b0a5cfa...5a97b98ea355c.inprogress.random.ts | ← 201 | | | | MOVE → | /60/07/600710b0a5cfa...5a97b98ea355c | ← 204 |
SLIDE 56 loader store FileDB | | (space0) | PUT (sha1) → | | | ← 201 | | | | | | MOVE → | | | ← 204 | |
SLIDE 57 loader store FileDB | | (space0) | PUT (sha1) → | | | ← 201 | | | | | | MOVE → | | | ← 204 | | | | | increment_or_upload (pair_id, sha1, magic)→ |
SLIDE 58 loader store FileDB | | (space0) | PUT (sha1) → | | | ← 201 | | | | | | MOVE → | | | ← 204 | | | | | increment_or_upload (pair_id, sha1, magic)→ | loader | increment_or_upload (pair_id, sha1, magic)→ |
SLIDE 59 Удаление файла
- Гарантированно записать файл
- Быстро отдать файл
- Держать метаданные консистентными
SLIDE 60 Удаление файла
- Гарантированно записать файл
- Быстро отдать файл
- Держать метаданные консистентными
Удалять можно в offline
SLIDE 61 Удаление файла
- Гарантированно записать файл
- Быстро отдать файл
- Держать метаданные консистентными
Удалять можно в offline При удалении только уменьшаем счетчик
SLIDE 62
decrement (sha1, magic)
counter-- current_magic –= magic
SLIDE 63
decrement (sha1, magic)
counter-- current_magic –= magic If (counter == 0 && current_magic== 0){ move(sha1, space1) }
SLIDE 64
Valkyrie
SLIDE 65 Valkyrie FileDB | | | | | get ( sha1, space1) → | | ← found ( sha1 ) | | |
SLIDE 66 Valkyrie FileDB loader | | ← set (sha1) | | | | get ( sha1, space1) → | | ← found ( sha1 ) | | |
SLIDE 67 Valkyrie FileDB loader | | ← set (sha1) | | | | get ( sha1, space1) → | | ← found ( sha1 ) | | | | get ( sha1, space0) → | | ← found ( sha1 ) |
SLIDE 68 Valkyrie FileDB | | | | | get ( sha1, space1) → | | ← found ( sha1 ) | | | | get ( sha1, space0) → | | ← found ( sha1 ) | rename sha1 → sha1.deleted.ts (карантин)
SLIDE 69 Valkyrie FileDB Valkyrie (disk0) | (disk1) | | | | get ( sha1, space1) → | ← | | ← found ( sha1 ) | → | | | | | get ( sha1, space0) → | ← | | ← not found ( sha1 ) | → |
SLIDE 70 Valkyrie FileDB Valkyrie (disk0) | (disk1) | | | | get ( sha1, space1) → | ← | | ← found ( sha1 ) | → | | | | | get ( sha1, space0) → | ← | | ← found ( sha1 ) | → | Когда удалять запись из space1?
SLIDE 71 Решим кто мастер
SLIDE 72 Решим кто мастер 600710b0a5cfa...5a97b98ea355c | | | первый бит | 1 | | disk0 disk1
SLIDE 73 Разнесем по времени magic (space0) → проверка консистентности magic (space1) → timestamp удаления
SLIDE 74 Valkyrie FileDB Valkyrie (master) (space1) (slave) | | | | ← | | | | | | | | | | | | | | | | → | | | ← |
SLIDE 75 Valkyrie находит на диске файл sha1: 1. Записи о нем нет в FileDB — на карантин через sha1.deleted.ts
SLIDE 76 loader store loader | | | | PUT (sha1) → | ←PUT (sha1) |
SLIDE 77 loader store1 store2 loader | | | | | PUT (sha1) → | | ←PUT (sha1) |
SLIDE 78 loader store1 FileDB | | (space0) | PUT (sha1) → | | | MOVE → | | | | | increment_or_upload (pair_id1, sha1, magic)→ | loader store2 | PUT (sha1) → | | | MOVE → | | | | | | increment_or_upload (pair_id2, sha1, magic)→ |
SLIDE 79 loader store1 FileDB | | (space0) | PUT (sha1) → | | | MOVE → | | | | | increment_or_upload (pair_id1, sha1, magic)→ | loader store2 | PUT (sha1) → | | | MOVE → | | | | | | increment_or_upload (pair_id2, sha1, magic)→ |
SLIDE 80 Valkyrie находит на диске файл sha1: 1. Записи о нем нет в FileDB — на карантин через sha1.deleted.ts 2. Запись есть, но указывает на другую пару — проверить на другой паре и удалить
SLIDE 81 Valkyrie находит на диске файл sha1: 1. Записи о нем нет в FileDB — на карантин через sha1.deleted.ts 2. Запись есть, но указывает на другую пару — проверить на другой паре и удалить 3. В FileDB запись указывает на текущую пару — сходить HEAD на второй диск, на текущем диске проверить целостность.
SLIDE 82 Disk1 — оказался проблемным Disk2 — readonly + размув
SLIDE 83 Из чего состоит почта
50ПБ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 15% 85% файлы
SLIDE 84 Из чего состоит почта
50ПБ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 15% 85% файлы 32ПБ 18ПБ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 25% 75% файлы