Какая база данных может обрабатывать хранилище миллиардов / триллионов записей?

75

Мы смотрим на разработку инструмента для сбора и анализа данных сетевых потоков, из которых мы собираем огромное количество. Каждый день мы собираем около 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, cassandra и mongodb в качестве возможных кандидатов для этого проекта, однако каждый из них предлагает свои собственные задачи. С помощью couchbase индексация выполняется с интервалами, а не во время вставки данных, поэтому представления не обновляются, вторичные индексы cassandra не очень эффективны при возвращении результатов, так как обычно для них требуется сканирование всего кластера, а mongodb выглядит многообещающе, но кажется, что его гораздо сложнее масштабировать, поскольку он является главным / подчиненным / осколочным. Некоторые другие кандидаты, которые мы планируем оценивать, являются эластичный поиск, MySQL (не уверен, если это даже применимо), и несколько ориентированных на столбцы реляционных баз данных. Любые предложения или опыт реального мира будут оценены.

somecallmemike
источник
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
Пол Уайт

Ответы:

57

В компании, в которой я работаю, мы имеем дело с аналогичным объемом данных (около 10 ТБ данных, доступных для поиска в режиме реального времени). Мы решаем это с Кассандрой, и я хотел бы упомянуть пару идей, которые позволят вам выполнить O (1) поиск в базе данных с несколькими ТБ. Это не относится к Cassandra db, вы можете использовать его и с другими db.

теория

  • Осколки ваших данных. Ни один сервер не сможет надежно и реально хранить такой объем данных.
  • Будьте готовы к аппаратным сбоям и сбоям всего узла, дублируйте данные.
  • Начните использовать много внутренних серверов с самого начала.
  • Используйте много более дешевых обычных серверов, по сравнению с топовыми высокопроизводительными.
  • Убедитесь, что данные равномерно распределены по осколкам.
  • Потратьте много времени на планирование ваших запросов. Извлекайте API из запросов, а затем тщательно проектируйте таблицы. Это самая важная и длительная задача.
  • В Cassandra вы можете создать составной ключ столбца и получить доступ к этому ключу в O (1). Проведите время, работая над ними. Это будет использоваться для доступа к доступным для поиска записям вместо вторичного индекса.
  • Используйте широкие ряды. Они полезны для хранения событий с метками времени.
  • Никогда не выполняйте полное сканирование или вообще никакую операцию больше, чем O (Log N) на таком томе. Если вам требуется что-то большее, чем O (Log N), перенесите такие операции в алгоритмы Map-Reduce.

практика

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

Я не работаю на Amazon и не имею отношений с командами HAProxy и Ubuntu. Это личное мнение, а не какое-либо продвижение.

алексей
источник
5
Я почти уверен, что поиск O (1) невозможен, за исключением крайне тривиальных / бесполезных случаев.
Фитцсиммонс
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).
ConcernedOfTunbridgeWells
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 записей beeellion (ваше указанное требование). Это рассчитывается как 130 байтов для самих данных, плюс 7 байтов на строку служебных данных, плюс 96 байтов на страницу служебных данных. SQL Server хранит данные на страницах размером 8 КБ, что позволяет использовать 59 строк на страницу. Это соответствует 732 203 390 страницам за один месяц данных.

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

Вы заметите, что я не храню 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 Существует два расхода: а) Дисковое хранилище (на 5-8 ТБ, в зависимости от места, используемого индексами), б) ОЗУ (для поддержки запросов, кэширования индекса). Обычно это делается с помощью большого массива RAID10 или SAN. Тем не менее, обратите внимание, что разделение, безусловно, может быть выполнено и может позволить вам использовать логику уровня приложения для разделения нагрузки на несколько SQL-серверов. Это может позволить вам использовать дешевые серверы по 0,5-2 ТБ каждый и, возможно, даже использовать бесплатную версию 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 марта 12:00 до 27 марта 00:01, вы можете выполнить сканирование диапазона с указанием начальной и конечной строк.

ИМХО, дизайн ключа строки является наиболее важной частью использования HBase - если вы спроектируете его хорошо, вы сможете выполнять быстрые запросы и хранить большие объемы данных.

Суман
источник
3

Сказал это:

... мы не против искать собственные решения для этого проекта

Я предлагаю рассмотреть IBM Informix базы данных + TimeSeries Datablade. Вопреки тому, что говорят некоторые люди, Informix жив и работает очень хорошо. Последняя версия была выпущена в прошлом месяце (март / 2013, версия 12.10).

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

Здесь вы можете проверить PDF с эталоном, который можно использовать в качестве справочного материала. Здесь две презентации с более техническими примерами: руководство по манекенам и другие советы

У меня нет личного опыта работы с TimeSeries , поэтому я не могу согласиться с тем, что это будет «решением», просто предложением оценить.

ceinmart
источник
2

Я рекомендую взглянуть на Informix TimeSeries. В литературе IBM утверждается, что TimeSeries может хранить такую ​​информацию в 1/5 пространства и работать в 5 раз быстрее, чем традиционные реляционные таблицы.

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

Андрей
источник