Сканування мільярда рядків у надшвидкій базі даних


9

Фон

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

Використовуйте кейс

Проблема полягає в наступному:

  1. Користувач встановлює дату початку / закінчення та діапазон значень (наприклад, 100 - 105).
  2. Система збирає всі рядки, які відповідають заданій даті, згруповані за місцем розташування.
  3. Система виконує визначення локацій, які протягом цих дат мають статистичну ймовірність потрапляння у заданий діапазон значень.
  4. Система відображає користувачеві всі відповідні місця.

Це проблема швидкості та масштабу.

Питання

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

Поточна система

Навколишнє середовище зараз:

  • PostgreSQL 8.4 (можливе оновлення; комутація баз даних не є можливою)
  • R і PL / R
  • XFS
  • WD VelociRaptor
  • 8 ГБ оперативної пам’яті (Corsair G.Skill; 1,3 ГГц)
  • Чотириядерний GenuineIntel 7 (2,8 ГГц)
  • Ubuntu 10.10

Можливі оновлення обладнання.

Оновлення - Структура бази даних

Мільярди рядків знаходяться в таблиці, що нагадує:

id | taken | location_id | category | value1 | value2 | value3
  • id - Первинний ключ
  • прийнято - дата, призначена рядку
  • location_id - Посилання на широту / довготу
  • категорія - опис даних
  • value1 .. 3 - інші значення, які користувач може запитувати

takenКолона , як правило , послідовні дати , в location_id, іноді кожне місце має дані від 1800 до 2010 (близько 77000 місць, багато з них продубльовані , як кожне місце має дані в тому ж діапазоні дат).

Існує сім категорій, і таблиці вже розділені за категоріями (використовуючи дочірні таблиці). Кожна категорія містить ~ 190 мільйонів рядків. Найближчим часом кількість рядків на категорію перевищить мільярд.

Є приблизно 20 000 локацій та 70 000 міст. Місця розташування співвідносяться з містом за широтою та довготою. Призначення кожної локації до конкретного міста означає знаходження меж міста, що не є тривіальним завданням.

Ідеї

Деякі у мене ідеї включають:

  • Знайдіть хмарний сервіс для розміщення бази даних.
  • Створіть смугу нальоту SSD (чудове відео).
  • Створіть таблицю, яка об'єднує всі місця за містами (попередній розрахунок).

Дякую!


10
"комутація баз даних не є варіантом" добре, що значною мірою усуває більшість рішень. Щасти!
Стівен А. Лоу

1
Важко сказати без додаткової інформації про те, що саме ти робиш із цими записами. Крім того, чи шукаєте ви найгірший випадок на 5 секунд (що, мабуть, означає, що кожний досліджений запис та нульові місця відповідають)?
Гай Сіртон,

2
@Dave: Скільки часу займає поточна система? Чи використовує поточну систему PostGIS ? Є чи або , або відноситься до другої таблиці? Чи індексується стовпець? location_idgeographygeometrylocation_id
rwong

1
@ Thorbjørn & @Darknight - У розділі з ідеями я перераховую попередній розрахунок, який би зменшив дані до одного значення на місто в день (за категорією). Вирахування може повторюватися щорічно, а то й щомісяця. Це був мій план, якщо не було б інших можливостей (розрахунки, мабуть, займуть тижні).
Дейв Джарвіс

1
@Dave, безліч можливостей, але питання в тому, що для тебе актуально. Чи досліджували ви, де ще є вузькі місця?

Відповіді:


12

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

Якщо ви робите повне сканування таблиці, вам потрібні відповідні індекси.

Якщо ви чекаєте вводу / виводу, вам потрібно більше пам’яті для кешування (Jeff Atwood нещодавно згадував, що 24 Gb системи були доступні для настільних систем).

Якщо ви зачекаєте на процесорі, вам слід зрозуміти, чи можна оптимізувати ваші розрахунки.

Для цього потрібна чітка DBA-шапка та капелюх Операційної системи, але це варто, щоб переконатися, що ви гавкаєте потрібне дерево.


Як ніколи ви нарізаєте його і нарізаєте кубиками - навіть якщо кожен рядок займає лише 100 байт, 1,3 мільярди рядків = 121 ГБ. Зі всіма вашими індексами тощо, я впевнений, що цього буде набагато більше. На одному коробці ви будете повільними, якщо у вас не буде серйозного обладнання навколо SSD + тонн таран. Дешевший спосіб - масштабування по коробках.
Subu Sankara Subramanian

4
@Subu, ти хочеш розповсюджуватися? Тепер у вас є дві проблеми ...

Хе - з цим я згоден :) Але це дешевше!
Subu Sankara Subramanian

@ Thorbjørn: Дякую за ваш час та всю вашу допомогу. Я думаю, що я зменшу набір даних до 25 мільйонів рядків на категорію, а потім застосувати індекси на дату. Це повинно скоротити сканування до ~ 70000 рядків (на день, з обмеженням на два тижні для діапазону), що має бути досить швидко.
Дейв Джарвіс

@Dave, ви все ще повинні знати, де ваші вузькі місця. Дізнайтеся це, поки не потрібно .

4

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

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


Дякую за ідеї. Можливо, 77,066 дат, і нові дати будуть додані вперед. У мене єдина машина. Є 20 000 локацій, але розділення за місцем розташування не допоможе, оскільки дані для аналізу охоплюють усі місця.
Дейв Джарвіс

і як використання хмари відрізняється від вищевказаного рішення?
Чані

Це я і думав. Якийсь горизонтальний розділ, щоб пошук міг відбуватися паралельно по всіх розділах.
davidk01

Розбиття на день, мабуть, було б найбільш корисним, що призведе до 2562 окремих таблиць (366 днів x 7 категорій).
Дейв Джарвіс

4

Найгірший сценарій - діапазон дат охоплює всі дати у вашій базі даних.

Ви хочете прочитати 1,3 мільярда записів і зробити якийсь аналіз для кожного запису проти введених значень на одній фізичній машині менше ніж за 5 секунд. Результатом можуть бути всі локації або жодні - ви заздалегідь нічого не знаєте.

З огляду на ці параметри, я б сказав, що це неможливо.

Подивіться на ваш жорсткий диск: швидкість максимальної тривалості менше 150 МБ / с. Читання 1,3 мільярда записів займе більше 5 секунд. CPU-мудро, ви не зможете за 5 секунд робити будь-який статистичний аналіз на 1,3 мільярда записів.

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

Можливо, можливо зберегти всі записи (або принаймні важливу частину) в пам'яті. Напевно, не в 8 Гб. Це принаймні усуне частину вводу / виводу диска, хоча навіть пропускна здатність пам’яті може бути недостатньою для перевірки всього за 5 секунд. У будь-якому випадку, це ще одна методика прискорення подібних програм (поєднати з моєю попередньою пропозицією).

Ви згадуєте про використання хмарного сервісу. Так, якщо ви платите за достатню кількість м'язів процесора та IO і розділіть вашу базу даних на багатьох серверах, ви можете змусити / розділити та перемогти її.


Дякую за відповідь. Оновлення обладнання - це врахування відповідно до перелічених вами ідей. Ідеальним є рішення, яке коштує 750 доларів США.
Дейв Джарвіс

2

Другий коментар rwong до питання: PostgreSQL пропонує відповідні типи та інструменти індексів (GIST-індекси, GIN-індекси, Postgis, Geometrical типи) таким чином, що дані геоданих та дати, пов'язані з датою, повинні шукати за цими критеріями без особливих проблем.

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


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

2
Індексація місцезнаходження на основі B-Tree не є найменшим корисним з огляду на тип пошуку, який ви шукаєте. Вам потрібен перевернутий індекс, який працює з необхідними операторами, що у випадку Postgis зазвичай означає GIST. Можливо, ви захочете виділити кілька повільних запитів ...
Денис де Бернарді,

1

Враховуючи, що ви використовуєте дані PostgreSQL та дані про широту / довготу, вам обов'язково слід використовувати і PostGIS, таким чином ви можете додати просторовий індекс GiST до вашої бази даних, щоб прискорити роботу.

У мене є така таблиця (з 350k рядками) з конфігурацією, значно меншою, ніж у вас (2 ядра і ледь 2 Гб оперативної пам’яті), але пошук займає менше однієї секунди.


0

Можливо, ви можете зламати реляційну модель, як Essbase, зі своєю архітектурою OLAP: Essbase Wikipedia

Що я маю на увазі - створити одну таблицю на місто, таким чином закінчившись 1000 таблицями. Не одна таблиця, як ви запропонували, але багато. Індексуйте кожну таблицю за датою та місцем розташування. Багато таблиць, багато індексів -> швидше.


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

@Dave: чи можете ви побудувати діаграму voronoi для міст та класифікувати значення lat / lon на tessellations? (тобто, якщо це звучить безглуздо, нехай буде.) Тоді під час пошуку ви шукатимете всі міста, чия тесселяція торкається діапазону lat / lon запиту. Якщо тестеляція voronoi занадто повільна, квадратні коробки (наприклад, 5 град. Х х 5 град.) Можуть спробувати спробувати.
rwong

0

Що стосується вашої ідеї знайти хмарний сервіс для розміщення бази даних, ви ще натрапили на SimpleGeo ? Вони просто перерізали стрічку на службі зберігання даних, яка, очевидно, "спеціально налаштована на зберігання та запит даних про місцевості дуже, дуже швидко" - хоча вартість зберігання та запиту на понад мільярд рядків може зробити цей підхід нездійсненним.


-2

вас очікує проїзд велосипеда по шосе. В даний час ви шукаєте рішення тільки для вирішення цієї проблеми, ви не передбачаєте проблеми, що робити, якщо у вас є 2 мільярди записів? Необхідно вирішити масштабність. відповідь - просто використання об'єктних баз даних. наприклад кеш Intersystems

і повірте мені, я не з міжсистем ;-)

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