?

Log in

No account? Create an account

Previous Entry | Next Entry

У нас имеется вот такая практическая задача по хранению как бы журналов, которую мы что-то никак не решим. Может, она давно уже решена, и мы зря мучаемся?

Имеется некоторое число агентов, числом порядка десятков. Каждый агент вступает, скажем, в разговор, и в процессе записывает некоторый журнал, текстовую информацию. Для каждой строки мы записываем время, целое число — код события и, собственно, текст, до 1000 символов (в среднем 150). За 2 минуты эксперимента агент выдает где-то таких строк 200-300. Кроме того, записывается код агента и код разговора. Информация хранится 2 месяца, затем ее можно стирать. Собственно, вот и все — один последовательный файл на всех или одна таблица в базе данных.

В части запросов к хранилищу: нам хочется получать весь журнал одного агента (один агент производит единицы или десятки разговоров, и исчезает навсегда), одного разговора или запрашивать информацию по тому самому коду события. Некоторые из кодов «более важны» (они известны заранее, и их коды отрицательные); более важные записи всегда просматриваются человеком, ежедневно, несколько раз в день. Однако, запросы по другим кодам тоже приходится делать, но реже.

Сейчас это все записывается в таблицу в БД. К сожалению, вставлять записи мы успеваем (BULK INSERT), а вот удалять уже не всегда получается, DELETE просто не успевает их удалять с нужной скоростью, и эта зараза растет. Сейчас она живет на отдельном диске в 1ТБ на машине с 2 зеонами и 32 ГБ оперативной памяти. Мы добавим SSD для tempdb, но это, пожалуй, все, что мы смогли придумать по части железа. Сервер MS SQL Server 2008 на OS Windows Server 2008 R2. Все это как бы работает, только медленно немного: запрос на один журнал агента выполняется минуту-другую, а, например, всех отрицательных («важных») кодов за сегодня — минут от 8 до 25, в зависимости от погоды в Атлантике и личного расположения сервера к запрашивающему (других факторов не пока выявлено). Файлы занимают где-то 200-300 ГБ на диске, если сложить индексы, данные и database logs вместе. И пухнет потихоньку: мы и машин с агентами добавляем, и, как я уже говорил, не за два месяца там данных, а уже за 3, и все больше делается.

Надо сказать, что, когда мы эту страхолюдию запускали, в больших базах данных мы не очень понимали, но теперь понимаем куда больше — многие простые решения уже сделаны. Это чтобы показать уровень владения предметом: совсем не специалисты, изучивших всю эту напасть на своем горбу.

Возможно, существуют более эффективные решения, чем СУБД, учитывая простоту хранимых данных (нет модификации, только вставка/удаление; нет реляций, одна-единственная таблица), но мы их не нашли. Не думаю, что с такой проблемой столкнулись мы одни. Если знаете, как такие вещи решают — научите витающих в облаках теоретиков, как с ними справляются, а?

Доб. Кто-нибудь имел дело с Apachе Cassandra или Hypertable? Это то, что мы ищем, или нет?

Comments

pilot_pirx
Sep. 7th, 2010 09:32 am (UTC)
Приходит в голову пара общеупотребительных вариантов:
1. Partitioning - у Oracle это встроенная возможность, про SQL Server надо уточнять, наверняка тоже что-то похожее есть.
2. Как вариант предыдущего - "буферная" таблица или база: создаем 2 таблицы с одинаковыми атрибутами. В первой храним "оперативную" информацию(например данные за последний час), при этом не строим на ней никаких индексов(отсутствие индексов увеличит скорость добавления-удаления записей), условий целостности и т.п. Из "буферной" таблицы регулярно переносим информацию в "основную" таблицу - на ней можно строить индексы в соответствии с теми запросами, которые нужно делать для анализа данных.
fregimus
Sep. 7th, 2010 09:36 am (UTC)
Partitioning есть — можно разбить на многие «сегменты», но их тогда надо хранить на разных дисках, да? Кажется, что это решение не совсем радикальное, ведь дисков в корпус можно насовать только ограниченное количество. В этом конкретном еще одно, кажется, осталось — 1U. Насчет буферной таблицы — все как раз наоборот: проблем со вставкой никаких как раз нет, даже с индексами; проблемы только с запросами и с удалением старых записей, так что не понятно, как это поможет.
pilot_pirx
Sep. 7th, 2010 11:33 am (UTC)
Partitioning с хранением на разных дисках напрямую не связан, он позволяет структурировать хранение строк в таблице. Например, можно разбить все данные на сегменты по 2 месяца(это ускорит удаление и запросы, если все данные попадают в 2х-месячный интервал). Или сделать 2 сегмента - в одном строки с отрицательными кодами, в другом - с положительными(это, вместе с соответствующими индексами, должно ускорить выборки, затрагивающие только отрицательные и только положительные коды).

Про буферную таблицу - отсутствие индексов удалению тоже должно помочь.

А вообще, чтобы размышлять более предметно, я бы посоветовал посмотреть планы выполнения запросов, которые у вас тормозят.

Кстати, на скорость работы может влиять выбранный уровень изоляции транзакций.
fregimus
Sep. 7th, 2010 04:55 pm (UTC)
Спасибо, partitioning попробуем. По поводу изоляции — там все уже выкрутили, что сервер позволяет. Кажется.

Profile

oak
fregimus
L. Fregimus Vacerro

Latest Month

June 2018
S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930

Page Summary

Powered by LiveJournal.com
Designed by Tiffany Chow