* Юрий Лосев <
kei...@gmail.com> [16/04/07 18:34]:
> Мне нет нужды хранить все сессии пользователя в памяти, хотелось бы хранить
> допустим последние 3 сессии, а остальные вытеснять на диск.
На диск - это куда? В другую базу, в sophia engine?
> 1. Есть ли некий аналог LPUSH + LTRIM redis`а. Или я должен реализовать это
> через lua процедуру? По сути нужен кольцевой буффер,только без удаления.
У таплов есть добавление поля в конец, и удаление из начала.
Только пока не понятно, как лучше представить отдельное событие -
как поле тапла, или как отдельный тапл. Какой размер события?
Сколько событий собираетесь хранить в памяти (3?)
> Стоит ли здесь использовать некий кастомный explorationd, или есть более
> подходящие инструменты.
Сейчас только в чате обсуждали как прикрутить expiraitond для
вытеснения в sophia engine. Так что это однозначно один из
вариантов.
Т.е. я вижу следующие принципиальные подходы:
1) Хранить только K последних событий. Всё в памяти, в момент
добавления K+1 события, самое старое удаляется. Хранимки на
Lua.
2) Хранить только K последних событий. Но чистку делать в
background, с помощью expirationd. Т.е. обходить все таплы в
background и удалять старые события.
3) То же самое что и 2), но старые события не удалять, а пушать в
sophia или в postgres/mysql.
2) и 3) делаются через expiraitond. Сделать ли индекс по id,
tstamp или только по id, зависит от размера события. Старайтесь
чтобы таплы в среднем были меньше 300-400 байт - это оптимально
для нас.
> 2. Я не нашел в документации операции move между space. Правильно ли я
> понимаю, что я должен сначала сделать insert в sophia-space, а потом
> удалить данные из памяти?
Да.
> 3. Правильно ли я понимаю, что есть только низкоуровневые операции с
> индексами. То есть я не могу сделать выборку "not equal", или не могу
> допустим выбрать по двум одиночным индексам(по составному естественно
> могу), либо мне нужно выбрать сначала 1 индекс, потом второй, и самому
> искать их пересечения.
Да.
> 4. Также, как я понимаю, нет оператора ИЛИ для индексов, то есть я не могу
> реализовать что-то типа: "SELECT * FROM radacct WHERE status="Start" or
> status="Update"", опять же нужна lua процедура?
Это в целом можно попробовать сделать с помощью bitset индекса.
Либо сделать чтобы update шёл после start и сделать status > x
> 5. Нет операции для выборки только уникальных значений индекса? Допустим
> пользователи постоянно повторяются, и я хочу сделать чтото типа: "SELECT
> DISTINCT(username) FROM radacct WHERE vlan=...". Опять же нужно
> реализовывать через lua, итерируя по индексу `username`?
Я бы сделал индекс vlan, username, т.к. WHERE vlan = есть. И вроде
этот индекс будет сам по себе уже уникальный. При поиске можно
задать частичный ключ (vlan).
> Хотелось бы также иметь какуюто статистику, её нельзя назвать realtime,
> скорее near-realtime, ибо задержка в несколько секунд неважна.
> Например: Количество пользователей online в конкретном вилане. Или
> количество уникальных пользователей в вилане за неделю.
Есть index:count().
> Не вижу смысла для этого хранить всех пользователей за неделю в памяти,
> ведь достаточно для этого сделать отдельный space, и заливать туда только
> vlan, username, timestamp допустим
>
> Здесь я не понимаю, как построить процессинг. У меня есть space с исходными
> записями сессий (raw_acct), а дальше мне нужно както обработать каждую
> приходящую в него запись, и собрать по ним.
> Что здесь лучше использовать? expirationd? И анализировать + перекладывать
> записи по нужным space`ам (online_users, 1week_users). Или есть что-то
> лучше?
Это зависит от характера нагрузки. expirationd подходит для
ситуаций когда можно что-то вычислить в background, и результат
сложить куда-то отдельно. Он экономит CPU в целом.
Если хватает CPU, можно всё вычислять в realtime, при обработке
входящего события - и такой код всегда проще поддерживать.
Вы сколько событий в секунду на инстанс хотите обрабатывать?
> Или здесь может быть лучше применить queue? Просто как я понимаю, в очередь
> ктото должен данные толкать. Не хотелось бы делать этого с радиус сервера,
> ибо он должен быстро записать данные, и обслуживать следующую запись.
> Нагрузка конечно копеечная, для таких систем (~1000 - 2000rps, может будет
> чуть больше, если мы сможем уменьшить таймаут, предыдущая система не
> справлялась с такими цифрами.), но не будет ли очередь тормозить этот
> процесс? Впринципе лаг в несколько секунд абсолютно не важен.
> И с использованием очереди придется еще прогонять через нее каждое событие
> аккаунтинга, а не оперировать одной сущностью "сессия", которая просто
> может быть в разном статусе.
Имхо при такой нагрузке можно пробовать все действия (кроме записи
в Софию-Постгрес) делать в реалтайме в хранимке обрабатывающей
событие.
> По-моему у меня еще были вопросы, но я получился по-моему и так чересчур
> многословен, за что прошу меня простить. Если прижмет, спрошу в дальнейшем.
> Просто нет ничего хуже, чем пытаться положить новую технологию на рельсы
> предыдущего опыта, поэтому я пытаюсь понять, правильно ли я подхожу к
> tarantool.
Очень похоже что мы как раз для вас. На чём-то ещё будете городить
адовый огород, у нас должно всё завестись в 300-400 строк на Lua.
> Можно тыкать моськой в документацию, где я что-то не нашел/пропустил.
Лучше конкретизировать вопросы. И нужно ещё понять сколько вообще
данных и каким железом хотите обойтись. Пока что видно только про
RPS, но неясно сколько всего users/vlan, сколько одно событие.
Надо бы оценить сколкьо памяти понадобится на хранение 1 события,
и за какой срок нужно хранить историю.
--
Konstantin Osipov, Moscow, Russia,
+7 903 626 22 32
http://tarantool.org -
www.twitter.com/kostja_osipov