Найкраще сховище даних на мільярди рядків


86

Мені потрібно мати можливість зберігати невеликі біти даних (приблизно 50-75 байт) для мільярдів записів (~ 3 мільярди на місяць протягом року).

Єдина вимога - це швидкі вставки та швидкий пошук усіх записів з однаковим GUID та можливістю доступу до сховища даних із .net.

Я хлопець із SQL-сервера, і думаю, що SQL Server може це зробити, але з усіма розмовами про BigTable, CouchDB та інші рішення nosql, це все більше звучить, як альтернатива традиційному RDBS може бути найкращою через оптимізацію для розподілені запити та масштабування. Я спробував cassandra, а бібліотеки .net наразі не компілюються або всі вони можуть бути змінені (разом із самою cassandra).

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

Якби вам довелося зберігати 36 мільярдів невеликих плоских записів, щоб вони були доступні з .net, що б вибрати і чому?


Так, мої цифри правильні. На даний момент ми отримуємо стільки даних, що надходять у систему, але ми їх агрегуємо і зберігаємо лише загальний підрахунок, тому ми втрачаємо дані за запис і підтримуємо лише погодинні суми даних. Зважаючи на бізнес-вимоги, ми хочемо підтримувати кожен запис, як це було спочатку, і це 3Bil рядків на місяць.
Джоді Поулетт

Ви підняли кілька хороших питань. Відповіді такі: 95% часу вистачає - дані вже затримуються із змінною сумою, тому мені все одно доведеться синхронізувати їх після того, як це відбудеться, тож перебування на короткий час не є порушенням угоди. Втрата вставок або навіть тисяч вставок - це не кінець світу. Втратити дані на день, однак, було б досить погано. Послідовність теж не така важлива. В основному після вставки рядків 30 мільйонів на день мені потрібно отримати всі рядки з однаковим GUID (можливо, 20 рядків) і бути досить впевненим, що я поверну їх усі.
Джоді Поулетт

Ви скидаєте 30 мільйонів рядків на день щоденно / щогодинно за розкладом, або вони постійно змінюються один за одним?
Ремус Русану,

Дані надходять із сайту FTP ... файли надходять постійно, і у мене є процес, який аналізує файли, і в даний час він генерує агреговані дані та вставляє агреговані значення (можливо, 1000 рядків) як транзакцію. Новий процес повинен буде вставити сотні тисяч рядків з кожного надійшов файлу, ймовірно, використання масової вставки було б найбільш ефективним способом зробити це.
Джоді Поулетт

Це звучить як робота ETL для SSIS та SQL Server. Вони справді мають світовий рекорд ETL із швидкістю завантаження понад 2 ТБ / годину: blogs.msdn.com/sqlperf/archive/2008/02/27/etl-world-record.aspx
Ремус Русану

Відповіді:


102

Зберігання ~ 3,5 ТБ даних та вставка приблизно 1 К / с 24x7, а також запити зі швидкістю, не вказаною, можливо з SQL Server, але є ще питання:

  • які вимоги щодо наявності у вас для цього? 99,999% часу безвідмовної роботи, чи цього достатньо на 95%?
  • які вимоги до надійності ви маєте? Вам не вистачає вставки коштує 1 млн доларів?
  • яка вимога до відшкодування ви маєте? Якщо ви втратите один день даних, чи це важливо?
  • яка вимога до послідовності? Чи потрібно гарантувати, що запис буде видимим при наступному прочитанні?

Якщо вам потрібні всі ці вимоги, які я підкреслив, запропоноване вами завантаження буде коштувати мільйони апаратного забезпечення та ліцензування реляційної системи, будь-якої системи, незалежно від того, які трюки ви намагаєтесь (шардування, розділення тощо). Система nosql, за їх самим визначенням, не відповідала б усім цим вимогам.

Очевидно, ви вже послабили деякі з цих вимог. Існує приємний візуальний посібник, що порівнює пропозиції nosql на основі парадигми "вибрати 2 з 3" у Візуальному посібнику для систем NoSQL :

nosql порівняння

Після оновлення коментаря OP

З SQL Server це було б прямою реалізацією:

  • одна кластерна клавіша (GUID, час) таблиці. Так, це буде фрагментовано , але чи впливає фрагментація на читання, і читання потрібне лише для значного сканування діапазону. Оскільки ви запитуєте лише конкретний GUID та діапазон дат, фрагментація не матиме великого значення. Так, це широкий ключ, тому нелистові сторінки матимуть низьку щільність ключів. Так, це призведе до поганого коефіцієнта заповнення. І так, можливі поділи сторінок. Незважаючи на ці проблеми, з огляду на вимоги, як і раніше є найкращим ключовим вибором.
  • розділіть таблицю за часом, щоб ви могли здійснити ефективне видалення прострочених записів через автоматичне розсувне вікно . Доповніть це за допомогою відновлення розділу онлайн-індексу за останній місяць, щоб усунути поганий коефіцієнт заповнення та фрагментацію, введені кластером GUID.
  • включити стиснення сторінки - -. Оскільки кластеризовані групи ключів спочатку GUID, усі записи GUID будуть поруч, що дає стисненню сторінок хороший шанс розгорнути стиснення словника.
  • вам знадобиться швидкий шлях вводу-виводу для файлу журналу. Вас цікавить висока пропускна здатність, а не низька затримка, щоб журнал не відставав від вставок 1 Кб / сек, тому зачистка є обов’язковою.

Для розділення та стиснення сторінок потрібен SQL Server Enterprise Edition, вони не працюватимуть у Standard Edition, і обидва вони дуже важливі для задоволення вимог.

Як додаткове зауваження: якщо записи надходять із ферми веб-серверів інтерфейсу, я ставлю Express на кожен веб-сервер, а замість INSERT на задній стороні я передаю SENDінформацію на задній кінець, використовуючи локальне підключення / транзакцію на Express, розміщеному разом із веб-сервером. Це дає набагато кращу історію доступності рішення.

Отже, я б це зробив у SQL Server. Хороша новина полягає в тому, що проблеми, з якими ви зіткнетесь, добре зрозумілі та відомі рішення. це не обов'язково означає, що це краще, ніж те, чого ви могли б досягти за допомогою Кассандри, BigTable або Динамо. Я дам комусь більше знань у речах, не пов'язаних зі sql-іш, щоб аргументувати свою справу.

Зауважте, що я ніколи не згадував модель програмування, підтримку .Net тощо. Чесно кажучи, вони не мають значення у великих розгортаннях. Вони роблять величезну різницю в процесі розробки, але після розгортання не має значення, наскільки швидкою була розробка, якщо накладні витрати ORM вбивають продуктивність :)


Я гаряче пов’язав сайт Натана, але це не перша сторінка;)
Ремус Русану,

@RemusRusanu: дивлячись на міграцію dba.se. Тільки для того, щоб підготувати вас :-) І +1
gbn

Починаючи з Microsoft SQL Server 2016, видання Enterprise більше не потрібне для розділення таблиць, оскільки розділення таблиць тепер доступне майже у всіх версіях SQL Server 2016.
TChadwick,

17

Всупереч поширеній думці, NoSQL не стосується продуктивності чи навіть масштабованості. Йдеться головним чином про мінімізацію так званого об’єктно-реляційного невідповідності імпедансу, але також про горизонтальну масштабованість порівняно з більш типовою вертикальною масштабованістю СУБД.

Для простої вимоги до швидких вставок та швидкого пошуку підходить майже будь-який продукт бази даних. Якщо ви хочете додати реляційні дані, або об’єднатись, або мати якусь складну логіку транзакцій або обмеження, які вам потрібно застосувати, тоді вам потрібна реляційна база даних. Жоден продукт NoSQL не може порівняти.

Якщо вам потрібні дані без схеми, ви хочете використовувати базу даних, орієнтовану на документи, таку як MongoDB або CouchDB. Розпущена схема є основним витягом з них; Мені особисто подобається MongoDB і я використовую його в декількох спеціальних системах звітності. Я вважаю це дуже корисним, коли вимоги до даних постійно змінюються.

Інший основний варіант NoSQL - це розподілені магазини Key-Value, такі як BigTable або Cassandra. Вони особливо корисні, якщо ви хочете масштабувати свою базу даних на багатьох машинах, на яких працює товарне обладнання. Очевидно, вони прекрасно працюють і на серверах, але не користуються перевагами обладнання високого класу, а також SQL Server або Oracle чи іншої бази даних, призначеної для вертикального масштабування, і, очевидно, вони не є реляційними і не підходять для забезпечення нормалізації або обмеження. Крім того, як ви помітили, підтримка .NET, як правило, є непомітною.

Всі продукти реляційних баз даних підтримують розділення обмеженого сорту. Вони не настільки гнучкі, як BigTable або інші системи DKVS, вони не легко розподіляють сотні серверів, але насправді не схоже, що це те, що ви шукаєте. Вони досить добре справляються з підрахунком записів у мільярдах, доки ви правильно індексуєте та нормалізуєте дані, запускаєте базу даних на потужному обладнанні (особливо твердотільних накопичувачах, якщо ви їх можете собі дозволити) і розділяєте 2 або 3 або 5 фізичних дисків, якщо необхідний.

Якщо ви відповідаєте вищезазначеним критеріям, якщо ви працюєте в корпоративному середовищі і маєте гроші, щоб витратити на гідну оптимізацію обладнання та баз даних, наразі я б дотримувався SQL Server. Якщо ви стискаєте копійки і вам потрібно запустити це на низькоякісному обладнанні хмарних обчислень Amazon EC2, ви, мабуть, захочете замість цього вибрати Кассандру або Волдеморт (припускаючи, що ви можете отримати будь-яку з них для роботи з .NET).


11

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

36 мільярдів, 3 мільярди на місяць, це приблизно 100 мільйонів на день, 4,16 мільйона на годину, ~ 70 тисяч рядків на хвилину, 1,1 тисячі рядків на секунду, що надходить у систему, стабільно протягом 12 місяців, не передбачаючи часу простою.

Ці цифри не є неможливими з великим відривом, я зробив більші системи, але ви хочете ще раз перевірити, що це справді ті величини, які ви маєте на увазі - дуже мало додатків дійсно мають цю кількість.

Що стосується зберігання / отримання та досить важливого аспекту, про який ви не згадували, це старіння старих даних - видалення не є безкоштовним.

Звичайна технологія, яку розглядають, - це розділення, проте пошук / пошук, заснований на GUID, призведе до низької продуктивності, якщо припустити, що вам потрібно отримувати кожне збіжне значення протягом усього 12-місячного періоду. Ви можете розмістити кластеризовані індекси в стовпці GUID, щоб отримати відповідні кластеризовані дані для читання / запису, але при таких кількостях і швидкості вставки фрагментація буде занадто високою для підтримки, і вона впаде на поверх.

Я б також запропонував, що вам знадобиться дуже пристойний апаратний бюджет, якщо це серйозне додаток із швидкістю відповіді типу OLTP, тобто за деякими приблизними припущеннями, припускаючи дуже незначні накладні витрати, розумно індексуючи, близько 2,7 ТБ даних.

У таборі SQL Server єдине, на що вам може сподобатися, - це нове видання паралельного сховища даних (Madison), яке призначене більше для виділення даних та запуску паралельних запитів до нього, щоб забезпечити високу швидкість проти великих знаків даних.


3
У біоінформатиці набори мільярдів рядків даних - не рідкість. Але з ними часто працюють чисто потоково з плоских файлів.
Ерік Гаррісон,

3
@Erik: для обробки потоку (тобто просто потрібно виявити певні умови, але немає необхідності зберігати дані для подальших запитів) щось на зразок StreamInsight краще будь-якої бази даних microsoft.com/sqlserver/2008/en/us/r2 -complex-event.aspx
Ремус Русану,

2

"Мені потрібно мати можливість зберігати невеликі біти даних (приблизно 50-75 байт) для мільярдів записів (~ 3 мільярди на місяць протягом року).

Єдина вимога - це швидкі вставки та швидкі пошуки всіх записів з однаковим GUID та можливістю доступу до сховища даних із .net. "

Я можу сказати вам з досвіду, що це можливо в SQL Server, тому що я зробив це на початку 2009 року ... і це все ще працює до цього дня і досить швидко.

Таблиця була розділена на 256 розділів, майте на увазі, це була версія SQL 2005 ... і ми зробили саме те, що ви говорите, а саме зберігати біти інформації за GUID і швидко отримувати за GUID.

Коли я пішов, у нас було близько 2-3 мільярдів записів, і отримання даних все ще було досить хорошим (1-2 секунди, якщо пройти через інтерфейс користувача, або менше, якщо на RDBMS), хоча політика збереження даних збиралася створити інстанцію.

Отже, коротенько кажучи, я взяв 8-й символ (тобто десь посередині) із рядка GUID, і SHA1 хешував його і відтворив як крихітний int (0-255) і зберігав у відповідному розділі і використовував той самий виклик функції при отриманні дані назад.

напишіть мені, якщо вам потрібна додаткова інформація ...


2

У наступній статті розглядається імпорт та використання таблиці рядків 16 мільярдів у Microsoft SQL. http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

Зі статті:

Ось кілька дистильованих порад з мого досвіду:

  • Чим більше даних у вас у таблиці з визначеним кластерним індексом, тим повільніше стає імпорт несортованих записів до неї. У якийсь момент стає надто повільним, щоб бути практичним.
  • Якщо ви хочете експортувати свою таблицю до найменшого можливого файлу, зробіть її рідним форматом. Це найкраще працює з таблицями, що містять переважно числові стовпці, оскільки вони більш компактно представлені у двійкових полях, ніж символьні дані. Якщо всі ваші дані буквено-цифрові, ви не отримаєте багато, експортуючи їх у власному форматі. Якщо не допустити нульових значень у числових полях, це може ще більше ущільнити дані. Якщо ви дозволите поле бути нульовим, двійкове представлення поля буде містити 1-байтовий префікс, який вказує, скільки байт даних буде слідувати.
  • Ви не можете використовувати BCP для більш ніж 2147483347 записів, оскільки змінна лічильника BCP є 4-байтовим цілим числом. Мені не вдалося знайти посилання на це в MSDN чи Інтернеті. Якщо ваша таблиця складається з
    понад 2 147 483 647 записів, вам доведеться експортувати її шматками
    або написати власну процедуру експорту.
  • Визначення кластерного індексу в попередньо заповненій таблиці займає багато місця на диску. У моєму тесті мій журнал вибухнув до 10 разів від початкового
    розміру таблиці до завершення.
  • Під час імпортування великої кількості записів за допомогою оператора BULK INSERT включіть параметр BATCHSIZE і вкажіть, скільки
    записів слід фіксувати одночасно. Якщо ви не включите цей параметр,
    увесь ваш файл імпортується як одна транзакція, що
    вимагає багато місця в журналі.
  • Найшвидший спосіб потрапляння даних у таблицю з кластерним індексом - це попереднє попереднє упорядкування даних. Потім ви можете імпортувати його за допомогою
    оператора BULK INSERT із параметром ORDER.

1

Є незвичайний факт, який, здається, не помічається.

" В основному після вставки рядків 30 мільйонів на день мені потрібно отримати всі рядки з однаковим GUID (можливо, 20 рядків) і бути впевненим, що я поверну їх усі "

Потрібно лише 20 стовпців, щоб некластеризований індекс на GUID працював чудово. Ви можете кластеризуватися в іншому стовпці для розподілу даних між розділами.

У мене питання щодо вставки даних: як воно вставляється?

  • Це об'ємна вставка за певним графіком (за хвилину, за годину тощо)?
  • З якого джерела беруться ці дані (плоскі файли, OLTP тощо)?

Я думаю, що на них потрібно відповісти, щоб допомогти зрозуміти одну сторону рівняння.


1

Amazon Redshift - чудова послуга. Він не був доступний, коли питання було опубліковано в 2010 році, але зараз він є головним гравцем у 2017 році. Це база даних на основі стовпців, роздвоєна від Postgres, тому стандартні бібліотеки сполучників SQL та Postgres будуть працювати з нею.

Його найкраще використовувати для звітності, особливо для агрегування. Дані з однієї таблиці зберігаються на різних серверах у хмарі Amazon, розподіляються на визначених дистрибутивах таблиць, тому ви покладаєтесь на розподілену потужність процесора.

Отже, SELECTS та особливо агреговані SELECTS швидко блискають. Завантаження великих даних бажано здійснювати за допомогою команди COPY із файлів csv Amazon S3. Недоліками є те, що ВИДАЛЕННЯ та ОНОВЛЕННЯ працюють повільніше, ніж зазвичай, але саме тому Redshift використовується не в першу чергу в транснаціональній базі даних, а більше в платформі сховища даних.


0

Ви можете спробувати використовувати Cassandra або HBase, хоча вам доведеться прочитати, як створити сімейства колонок відповідно до вашого випадку використання. Кассандра надає власну мову запитів, але для безпосереднього доступу до даних потрібно використовувати Java-API API HBase. Якщо вам потрібно використовувати Hbase, тоді я рекомендую запитувати дані за допомогою Apache Drill від Map-R, який є проектом з відкритим кодом. Мова запитів Drill відповідає SQL (ключові слова в drill мають те саме значення, що і в SQL).


0

З такою кількістю записів на рік у вас з часом закінчиться простір. Чому б не сховище файлової системи, як xfs, яке підтримує 2 ^ 64 файли та використовує менші поля. Незалежно від того, наскільки фантастичні люди хочуть отримати або на суму грошей, в кінцевому підсумку ви витратите на отримання системи з будь-якою базою даних SQL NoSQL .. залежно від того, що ці багато записів зазвичай роблять електричні компанії та метеостанції / провайдери, такі як Міністерство охорони навколишнього середовища, які контролюють менші станцій по всій країні. Якщо ви робите щось на зразок накопичення тиску .. температури .. швидкості вітру .. вологості тощо ..., а керівництво - це місце розташування .. ви все одно можете розділити дані за роком / місяцем / днем ​​/ годиною. Припускаючи, що ви зберігаєте 4 роки даних на жорсткому диску. Потім його можна запустити на меншому Nas з дзеркалом, де це також забезпечить кращу швидкість читання та мати кілька точок монтування. заснований на році, коли він був створений. Ви можете просто створити веб-інтерфейс для пошуку. Так що місце скидання1 / 2001/06/01 // температура та місцезнаходження1 / 2002/06/01 // температура лише скидала б вміст погодинної температури за 1-й день літа за ці 2 роки (24 години * 2) 48 невеликих файлів проти пошуку в базі даних з мільярдами записів і, можливо, витраченими мільйонами. Простий спосіб дивитись на речі. 1,5 мільярда веб-сайтів у світі, бо Бог знає, скільки сторінок кожна. Якби такій компанії, як Google, довелося витратити мільйони на 3 мільярди пошуків, щоб заплатити за це суперкомп’ютери, вони були б зламані. Натомість у них є рахунок за електроенергію ... пара мільйонів дерьмових комп'ютерів. І індексація кофеїну ... стійкий до майбутнього .. продовжуйте додавати більше. І так, де індексація, що працює під керуванням SQL, має сенс, тоді як чудова Побудова суперкомп’ютерів для безглуздих завдань з виправленими речами, такими як погода ... статистика тощо, щоб техніки могли хвалитись, що їхні системи хрустять xtb за х секунд ... марнотратство грошей, яке може бути провели десь ще ..


-2

Зберігання записів у простих двійкових файлах, по одному файлу на GUID, не буде швидшим за це.


5
Ви справді очікуєте, що це буде добре?
ChaosPandion

3
Так, створення мільярдів файлів у файловій системі може бути руйнівним для деяких файлових систем. Я зробив помилку, зробивши щось подібне, але маючи лише 1 мільйон, і я майже збив систему, намагаючись відкрити оболонку в одній з цих папок. Крім того, якщо ви шукаєте на основі керівництва, як повинен працювати механізм запитів?
Роб Гудвін,

Важко здогадатися, як це буде працювати, не знаючи, скільки унікальних GUID очікується :) Але це не стає простішим, ніж просто запис у звичайні файли. І швидкі вставки разом із пошуком за GUID були єдиною вимогою.
Томас Кьорнес

Це може працювати, але ви повинні обмежити кількість файлів у папці. Вам потрібно створити нову папку для n файлів. В якості імені папки ви можете використовувати підрядок керівництва.
TTT

1
так, існує обмеження на кількість inode для багатьох файлових систем, і я пам’ятаю, що натиснув це обмеження на файлову систему redhat за замовчуванням .... обмеження становило близько 1000000 файлів або близько того.
Дін Хіллер

-3

Ви можете використовувати MongoDB і використовувати Guid як клавішу різкості, це означає, що ви можете розподіляти свої дані на декількох машинах, але дані, які ви хочете вибрати, є лише на одній машині, оскільки ви вибираєте клавішею шардування.

Шардінг в MongoDb ще не готовий до виробництва.

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