Лучший способ создать временную базу данных hightraffic, в памяти или SQL? - PullRequest
0 голосов
/ 08 февраля 2011

В этом проекте будет создан сервер NAT-T

.

Это список серверов в каком-либо порту, куда клиенты отправляют свой идентификатор, IP, порт и сервер сохраняют свое время последнего контакта для клиентов очистки.

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

Проблема в том, что он должен обрабатывать 15 000 транзакций в секунду. База данных не нуждается в хранении.

Среднее число отслеживаемых клиентов должно составлять 200 тыс.

Как может быть лучший способ реализовать это, с помощью сервера SQL или со структурой данных? Структура данных ведьмы?

1 Ответ

2 голосов
/ 08 февраля 2011

Таким образом, вам нужна возможность вставлять элементы, находить, обновлять и удалять их по идентификатору. Вам также необходимо удалить клиентов, к которым не обращались в течение некоторого периода времени. Допустим, время определяется константой: OldClientRemovalInterval.

Структура данных клиента будет содержать идентификатор, IP, порт и время последнего доступа.

Вот один из способов сделать это:

Ведение ассоциативного массива клиентских записей, ключом которого является идентификатор. Стандартная библиотека шаблонов C ++ имеет несколько различных структур данных ассоциативных массивов (map, hash_map и т. Д.). A hash_map дает очень быстрое время доступа. Вы можете вставлять, обновлять или удалять элементы очень быстро.

Для удаления ведите очередь FIFO, которая содержит идентификаторы клиентов и ожидаемое время удаления. Всякий раз, когда клиентская запись вставляется или обновляется, создайте вторую структуру { ClientID, RemovalTime }, с вычислением RemovalTime путем добавления OldClientRemovalInterval к текущему времени.

Элементы в очереди упорядочены по увеличению времени удаления. Периодически проверяйте очередь, удаляя любые элементы, время удаления которых истекло.

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

ClientID = RemoveItemFromQueue();
Client = GetClientRecord(ClientID);
ClientRemovalTime = Client.LastAccess + ClientRemovalInterval;
if (ClientRemovalTime <= CurrentTime)
    RemoveClient(ClientId);

Это фактически потребует, чтобы структура данных поддерживала 30K транзакций в секунду (для каждой вставки / обновления будет соответствующий поиск и возможное удаление). Но hash_map должен справиться с этим без проблем.

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

InsertOrUpdateClient();
// now remove up to 2 items
for (int i = 0; i < 2; ++i)
{
    if (queue.Peek().RemovalTime >= CurrentTime)
    {
        // Remove item from queue,
        // and potentially remove client from associative array.
    }
    else
    {
        break;
    }
}

Это позволит не тратить слишком много времени на удаление, но в среднем не позволит старым клиентам засорять структуру данных. Единственный недостаток заключается в том, что удаление не происходит, если нет вставок / обновлений. Таким образом, после длительного периода бездействия стол может быть полон старых клиентов. Если это важно, у вас может быть таймер, который периодически отправляет нулевой запрос (например, со специальным идентификатором клиента, равным -1), который не обновляет ассоциативный массив, но выполняет удаление.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...