2010-07-05 2 views
3

У нас есть приложение, которое принимает данные в реальном времени и вставляет их в базу данных. он работает в течение 4,5 часов в день. Мы вставляем данные второй раз в 17 таблиц. Пользователь может в любое время запросить любую таблицу для последних вторых данных и некоторые записи в истории ...Лучшая практика для вставки и запроса данных из памяти

Обработка кормов и вставка делаются с использованием C# консольное приложения ...

Обработка запросов пользователей является проведенных через службу WCF ...

Мы выяснили, что вставка - наше узкое место; большую часть времени там проводят. Мы потратили много времени на то, чтобы завершить работу таблиц и индексов, но результаты были неудовлетворительными.

Предполагая, что у нас есть достаточная память, лучше всего вставлять данные в память вместо базы данных. В настоящее время мы используем datatables, которые обновляются и вставляются каждую секунду. . Наш коллега предложил другую службу WCF вместо базы данных между обработчиком фида и обработчиком запросов пользователей WCF. Предполагается, что средний уровень WCF будет основан на TCP и хранит данные в собственной памяти. Можно сказать, что обработчик корма может иметь дело с пользовательскими запросами вместо того, чтобы иметь средний уровень между двумя процессами, но мы хотим разделить вещи, поэтому, если сбой обработчика кормов, мы хотим, чтобы все еще были в состоянии предоставить пользователю текущие записи

Мы ограничены во времени, и мы хотим переместить все в память за короткий промежуток времени. Имеет ли WCF в середине 2 процесса плохое дело? Я знаю, что запросы добавляют некоторые накладные расходы, но все эти 3 процесса (обработчик фида, база данных с памятью (WCF), обработчик пользовательского запроса (WCF) будут находиться на одной машине, а пропускная способность не будет такой из вопроса.

Пожалуйста помогите!

+0

Действительно хороший вопрос. – Kangkan

ответ

2

Я хотел бы изучить создание кеша данных (например, вы также можете уменьшить выбор базы данных) и недействить данные в кеше после его записи в базу данных. Таким образом, вы можете запускать вызовы, чтобы сделать большую вставку вместо многих более мелких, но хранить данные в памяти так, чтобы читатели могли ее прочитать. На самом деле, если вы знаете, когда данные устаревают, вы можете полностью не читать базу данных и использовать ее как хранилище резервных копий. Таким образом, производительность базы данных будет влиять только на размер вашего кеша.

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

Уровень кеша не должен быть сложным, однако он должен быть многопоточным для размещения данных и сохранения его в фоновом режиме. Этот уровень будет располагаться только за WCF-сервисом, средой соединения, а служба WCF должна быть улучшена, чтобы содержать логику консольного приложения + идею пакетной обработки. Затем консольное приложение может просто подключиться к WCF и выкинуть на него результаты.

Обновление: Единственное, что можно сказать, это инвестировать в профилировщик, чтобы узнать, представляете ли вы какие-либо проблемы с производительностью в замаскированном коде. Кроме того, профиль вашей базы данных. Вы упомянули, что вам нужны быстрые вставки и выбирает - к сожалению, они обычно компрометируют друг против друга ...

+0

Спасибо за ответ. Данные на самом деле не устаревают, так как каждая запись может быть выбрана в любое время (пользователь может указать вторую «запись», которую он хочет). Ваше решение по-прежнему предлагает вставлять в базу данных, но реже создавать кеш, но мне интересно, будем ли мы по-прежнему выбирать из базы данных (если данные не в кеше, что возможно, учитывая, что выбор полностью случайный для данных истории), а в результате coincedent вставлена ​​огромная таблица, не собирается ли это создавать тайм-ауты выбора? Разве мы не можем просто складывать все в память? – mustafabar

+1

Это действительно зависит - вставляет каждую секунду за 4,5 часа может быть много данных? Ваша проблема - это производительность вставки, которая может быть решена другими способами. Что вы можете сделать, так это удалить все индексы, тем самым адаптировав таблицу к производительности вставки и возьмите на себя затраты на выбор, возможно, используя кеш-выбор, чтобы удерживать больше в памяти. –

+1

Конечно, in-memory - это возможный путь, но память также нестабильна - выключение питания и все это исчезло. –

0

Какую базу данных вы используете? MySQL имеет двигатель MEMORY хранения, который, казалось бы, подходит для такого рода вещи.

+0

Мы используем базу данных SQL. Microsoft SQL Server 2008 – mustafabar

0

вы используете DataTable с DataAdapter? Если это так, я бы порекомендовал вам полностью их удалить. Вставляйте свои записи напрямую с помощью DBCommand. Когда пользователи запрашивают отчеты, считывают данные с помощью DataReader или заполняют объекты DataTable с помощью DataTable.Load (IDataReader).

Истощение данных в памяти может привести к потере данных в случае сбоев или сбоев питания.

+0

Мы создаем соединение SQLTransaction и используем его для вставки путем циклического прохождения через DataTable с помощью SQLBulkCopy. Нам нужна транзакция, чтобы обратить вспять эффект возможных сбоев. – mustafabar

Смежные вопросы