Яка база даних може обробляти зберігання мільярдів / трильйонів записів?


75

Ми дивимось на розробку інструменту для збору та аналізу даних netflow, з яких ми збираємо величезну кількість. Щодня ми збираємо близько ~ 1,4 млрд записів потоку, які виглядатимуть у форматі json:

{
   "tcp_flags": "0",
   "src_as": "54321",
   "nexthop": "1.2.3.4",
   "unix_secs": "1352234521",
   "src_mask": "23",
   "tos": "0",
   "prot": "6",
   "input": "105",
   "doctets": "186",
   "engine_type": "0",
   "exaddr": "2.3.4.5",
   "engine_id": "2",
   "srcaddr": "9.8.7.6",
   "dst_as": "12345",
   "unix_nsecs": "752265174",
   "sysuptime": "2943529544",
   "dst_mask": "24",
   "dstport": "80",
   "last": "2943523241",
   "srcport": "52672",
   "dpkts": "4",
   "output": "111",
   "dstaddr": "6.5.4.3",
   "first": "2943517993"
}

Ми хотіли б мати можливість здійснювати швидкий пошук (менше 10 секунд) на наборі даних, швидше за все, протягом вузьких фрагментів часу (інтервали 10 - 30 хвилин). Ми також хочемо проіндексувати більшість точок даних, щоб ми могли швидко здійснювати пошук по кожному з них. Ми також хотіли б мати сучасний перегляд даних під час пошуку. Було б чудово залишатися у світі з відкритим кодом, але ми не проти дивитися на власні рішення цього проекту.

Ідея полягає в тому, щоб зберігати приблизно один місяць даних, що складе ~ 43,2 млрд записів. Приблизна оцінка, що кожен запис міститиме близько 480 байт даних, дорівнюватиме ~ 18,7 терабайт даних за місяць, а може, і втричі більше, ніж індексам. Врешті-решт, ми хотіли б збільшити потужність цієї системи для зберігання трильйонів записів.

Ми (в основному) оцінили диван, кассандру та монгоб, наскільки це можливо, кандидатів на цей проект, проте кожен пропонує свої завдання. З допомогою couchbase індексація проводиться з інтервалами, а не під час вставки даних, тому перегляди не є актуальними, вторинні індекси кассандри не дуже ефективні при поверненні результатів, оскільки вони зазвичай вимагають сканування всього кластеру для отримання результатів, і mongodb виглядає перспективно, але Мабуть, набагато складніше масштабувати, оскільки це господар / раб / шматок. Деякі інші кандидати, які ми плануємо оцінити, - це розширення пошуку, mysql (не впевнений, чи це взагалі можливо) та кілька реляційних баз даних, орієнтованих на стовпці. Будь-які пропозиції чи досвід у світі будуть вдячні.


Коментарі не для розширеного обговорення; ця розмова перенесена в чат .
Пол Білий

Відповіді:


57

У компанії, в якій я працюю, ми маємо справу з аналогічним обсягом даних (близько 10 ТБ даних у режимі реального пошуку). Ми вирішуємо це разом з Кассандрою, і я хотів би згадати пару ідей, які дозволять вам здійснити пошук O (1) у базі даних з декількома ТБ. Це не характерно для Cassandra db, однак ви можете використовувати його і з іншими db.

Теорія

  • Обробляйте ваші дані. Немає можливості жодного сервера надійно та реально зберігати такий об'єм даних.
  • Будьте готові до апаратних несправностей і відмов цілого вузла, дублюйте дані.
  • Почніть використовувати безліч резервних серверів з самого початку.
  • Використовуйте багато дешевших товарних серверів порівняно з високопродуктивними.
  • Переконайтесь, що дані однаково розподілені по черепках.
  • Витратьте багато часу на планування запитів. Витягніть API із запитів, а потім ретельно спроектуйте таблиці. Це найважливіше і тривале завдання.
  • У Кассандрі ви можете спроектувати складений ключ стовпця та отримати доступ до цього ключа в O (1). Проведіть час, працюючи над ними. Це використовуватиметься для доступу до записів, які можна шукати, а не вторинного індексу.
  • Скористайтеся широкими рядами. Вони корисні для зберігання позначених часом подій.
  • Ніколи не виконуйте повне сканування або фактично будь-яку операцію, більше ніж O (Log N) на такому рівні гучності. Якщо вам потрібна що-небудь більше, ніж O (Log N), перевантажте такі операції на алгоритми зменшення карт.

Практика

  • Не витрачайте час на створення зображень ОС або встановлення серверів на фізичні машини. Використовуйте хмарні провайдери для швидкого прототипування. Я працював з Amazon EC2 і можу дуже рекомендувати його для його простоти, надійності та швидкості прототипування.
  • Машини Windows, як правило, повільніше під час завантаження і забирають значно більше ресурсів, перебуваючи в режимі очікування. Подумайте про використання ОС на базі Unix. Особисто я виявив, що сервер Ubuntu є надійною ОС, але крім того, в askubuntu є досить хороша спільнота
  • Подумайте про мережу, вузли в ідеалі повинні бути близькими один до одного, щоб забезпечити швидкий пліток та обмін мета-даними.
  • Не впадайте в крайні випадки: дійсно широкі рядки стовпців або виключно довгі сімейства стовпців (таблиці). Найкращі показники досягаються в межах розумних меж - якщо db підтримує стільки N рядків за дизайном, це не означає, що він працює добре.
  • Наш пошук займає близько 3-5 секунд, багато чого пов’язано з проміжними вузлами між інтерфейсом користувача та базою даних. Розглянемо, як наблизити запити до бази даних.
  • Використовуйте мережевий балансир навантаження. Виберіть усталену. Ми використовуємо HAProxy, який простий, але швидкий. Ніколи з цим не виникало проблем.
  • Віддайте перевагу простоті складних рішень.
  • Шукайте безкоштовні рішення з відкритим кодом, якщо ви не забезпечені бюджетом розміру корпорації. Після того, як ви перейдете на кілька серверів, витрати на інфраструктуру можуть зрости високими.

Я не працюю в Amazon і не маю стосунків з командами HAProxy та Ubuntu. Це особиста думка, а не будь-яка промоція.


5
Я впевнений, що пошук O (1) неможливий окрім надзвичайно тривіальних / марних випадків.
Fitzsimmons

2
Не будьте ображені, але повідомте це Google. O (1) пошук можливий за шкалою PB при ретельному проектуванні.
олексій

9
@oleksii Бюджети Google на мільярд доларів не є розумним порівнянням.
Марк Сторі-Сміт

4
Я можу зв'язати 3 попередні коментарі зO(1) search <=> unbounded storage space <=> unlimited supply of cash
ypercubeᵀᴹ

3
O (1) пошук одного запису можна здійснити за допомогою лінійної хеш-таблиці. . Однак це не дає вам ніякої ефективності в пошуку послідовно (для діапазонів). Для цього вам потрібен певний варіант структури BTree, який є O (log n) для одного елемента.
ЗанепокоєнийOfTunbridgeWells

41

Якби я збирався вкласти це в SQL Server, я запропонував би таблицю на кшталт:

CREATE TABLE tcp_traffic
(
    tcp_traffic_id bigint constraint PK_tcp_traffic primary key clustered IDENTITY(1,1)
    , tcp_flags smallint    /* at most 9 bits in TCP, so use SMALLINT */
    , src_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , netxhop bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , unix_secs bigint  
    , src_mask int      /* an assumption */
    , tos tinyint       /* values are 0-255, see RFC 791 */
    , prot tinyint      /* values are 0-255, see RFC 790 */
    , input int         /* an assumption */
    , doctets int       /* an assumption */
    , engine_type int   /* an assumption */
    , exaddr bigint     /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , engine_id int     /* an assumption */
    , srcaddr bigint    /* use a big integer for the IP address instead of storing
                             it as dotted-decimal */
    , dst_as int        /* Since there are less than 2 billion A.S.'s possible, use INT */
    , unix_nsecs bigint /* an assumption */
    , sysuptime bigint  /* an assumption */
    , dst_mask int      /* an assumption */
    , dstport smallint  /* ports can be in the range of 0 - 32767 */
    , [last] bigint     /* an assumption */
    , srcport smallint  /* ports can be in the range of 0 - 32767 */
    , dpkts int         /* an assumption */
    , output int        /* an assumption */
    , dstaddr bigint    /* use a big integer for the IP address instead of storing
                            it as dotted-decimal */
    , [first] bigint    /* an assumption */
);

Це призводить до загальної передбачуваної потреби в сховищі для єдиної таблиці, без подальших індексів 5,5 ТБ для 43,2 записів про біліонів (Ваша зазначена вимога). Це обчислюється як 130 байт для самих даних плюс 7 байт на рядок накладних даних, плюс 96 байт на сторінку накладних даних. SQL Server зберігає дані на 8 КБ сторінок, що забезпечує 59 рядків на сторінці. Це дорівнює 732 203 390 сторінок за один місяць даних.

SQL Server любить писати на диск у 8-сторінкових фрагментах (64 КБ), що дорівнює 472 рядкам на фізичний ввід / вивід. З 16,203 записів потоку, що генеруються щосекунди, вам знадобиться мінімальна швидкість вводу / виводу 34 IOps, гарантована щомісяця. Хоча це саме по собі не є величезною кількістю, інші введення / виведення в системі (SQL Server та інше) не повинні ніколи порушувати цю необхідну швидкість IOps. Тому вам знадобиться розробити систему, здатну принаймні на порядок більше IOps або 340 підтримуваних IOps - я б схильний підрахувати, що для гарантії пропускної спроможності вам потрібно на 2 порядки більш стійкі IOps.

Ви помітите, що я не зберігаю IP-адреси у їх крапково-десятковій формі. Це економить величезну кількість на сховищі (7 байт на адресу), а також робить індексацію, пошук, сортування та порівняння IP-адрес набагато ефективнішими. Недоліком тут є те, що вам потрібно перетворити пунктирно-десяткові IP-адреси в 8-байтові цілі числа, перш ніж зберігати їх, і повернутися до пунктирних десяткових IP для відображення. Код, який потрібно зробити, є тривіальним, однак ваша швидкість передачі рядків додасть значну кількість накладних витрат на кожну оброблювану рядок потоку - можливо, ви захочете зробити цей процес перетворення на фізично іншій машині від SQL Server.

Обговорення потрібних вам індексів - зовсім окрема справа, оскільки ви не перерахували жодних конкретних вимог. Конструкція цієї таблиці буде зберігати потокові рядки у фізичному порядку, який вони отримують від SQL Server, tcp_traffic_idполе є унікальним для кожного запису і дозволяє сортувати рядки за порядком, в якому вони були записані (в цьому випадку, швидше за все, стосуються один-до-одного до події потоку).


4
Я б, мабуть, використовував binary(4)або binary(16), відповідно. 4 байти / рядок збільшує велику кількість пам’яті при множенні на 1 000 000 000 000.
Джон Сейгель

2
І номери портів мають діапазон 0-65535, тому ви можете використовувати, SMALLINTале там також має бути звичайна програма перетворення.
ypercubeᵀᴹ

7
@MrTelly Я не згоден. Робити це в SQL Server дорого, лише якщо вам потрібні HA або великі аварійні речі. Для надійного сховища даних, з яким реально легко жити, SQL Server чудово підходить для цього. Усі системи виходять дуже дорогими (і складними), якщо потрібен HA.
Самсміт

2
IMO, SQL Server, безумовно, можуть зберігати дані; Я все ще не впевнений, чи це правильне рішення для вирішення аналітичної частини проекту, в основному тому, що я недостатньо знайомий з іншими системами, які розглядаються.
Джон Сейгель

3
@MrTelly Є дві витрати: a) Зберігання диска (за 5-8 tb, залежно від місця, яке використовується індексами) b) RAM (для підтримки запитів, кешування індексів). Зробити це монолітно, як правило, можна зробити з великим масивом RAID10 або SAN. Однак зауважте, що шардинг, безумовно, можна зробити, і це може дозволити вам використовувати логіку рівня програми для розподілу навантаження на декілька серверів SQL. Це може дозволити вам використовувати дешеві сервери з 0,5-2tb кожного, а можливо, навіть використовувати безкоштовне видання SQL Server. (Зауважте, що шардинг - це загальна концепція, часто робиться на рівні додатків і стосується будь-якого методу стійкості)
samsmith

5

Я рекомендував би HBase . Ви можете зберігати всі необроблені дані в одній або декількох таблицях HBase, залежно від того, що потрібно запитувати. HBase може обробляти великі набори даних та виконувати автоматичне загострення через область розбиття.

Крім того, якщо добре розробити клавіші рядків, ви можете отримати надзвичайно швидкі, навіть запити O (1). Зауважте, що якщо ви отримуєте великий набір даних, це все ще буде повільним, оскільки отримання даних є операцією O (n).

Оскільки ви хочете проводити запит у кожному полі, я рекомендую створити унікальну таблицю для кожного з них. Прикладом даних src_address є таблиця, яка виглядає приблизно так:

1.2.3.4_timestamp1 : { data }
1.2.3.4_timestamp2 : { data }

Отже, якщо ви хочете запитувати всі дані через 1.2.3.4, починаючи з 27 березня 00:00 до 27 березня 12:01, ви можете виконати сканування діапазону із вказаними рядками початку та зупинки.

IMHO, дизайн ключових рядків є найважливішою частиною використання HBase - якщо ви добре спроектуєте її, ви зможете робити швидкі запити І зберігати великі обсяги даних.


3

Сказав це:

... ми не проти дивитися на власні рішення цього проекту

Пропоную розглянути базу даних IBM Informix + блок даних DataSeries. Навпроти того, що кажуть деякі люди, Informix живий і йде дуже добре. Остання версія була випущена минулого місяця (березень / 2013, версія 12.10).

TimeSeries - це як «плагін» (без витрат), здатний вирішувати такі ситуації, як ваша.
І ви можете використовувати його у виробництві з безкоштовною версією бази даних Informix ( видання Innovator-C ). (поза курсом, лише для оцінки технічних частин, оскільки безкоштовна версія має багато обмежених ресурсів)

Тут ви можете перевірити PDF-орієнтир, що може бути використане в якості посилання. Ось дві презентації з більш технічними прикладами: путівник манекенів та інші поради

У мене немає особистого досвіду роботи з TimeSeries , тож я не можу погодитися, що це буде "рішення", просто пропозиція оцінити.


2

Я є другою рекомендацією подивитися на Informix TimeSeries. Література IBM стверджує, що TimeSeries може зберігати подібну інформацію в 1/5-му просторі та виконувати в 5 разів швидше, ніж традиційні реляційні таблиці.

Додатковими перевагами будуть інтерфейс віртуальної таблиці, який може зробити дані TimeSeries кінцевим користувачем як традиційні реляційні таблиці (спрощуючи розробку додатків, отримуючи при цьому переваги TimeSeries), простий HA з вузлами HDR, які тепер підтримують дані TimeSeries у версії 12.1 та інтеграція даних TimeSeries в прискорювач складів Informix, який можна використовувати для прискорення складних звітів про сховища даних та можливості прототипувати рішення TimeSeries в Informix за допомогою безкоштовних версій Informix Developer або Innovator-C.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.