LINUX.ORG.RU

Rails кеширование геоданных

 , , , ,


0

2

Доброго вечера, я вновь за советом.

Я проектирую приложение на Ruby on Rails и не знаю как лучше организовать хранение временных геоданных.

С мобильных клиентов на сервер отправляются данные (публичный ключ (хранится в соответствующей модели Rails приложения), и геоданные (longlat)). Частота отправки от 1 до 3 сек (для каждого клиента разная). Клиентов ожидается на первое время сотня, но тестироваться будет на больших объемах: 700-3000 одновременно подключенных клиентов.

Задача: организовать временное хранилище, которое по достижении некоторого времени, будет предоставлять накопленные данные Rails приложению (в котором, будет производиться поиск модели по публичному ключу и отображение данных).

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

Я в курсе про Redis, но я не знаю как заставить его создавать транзакцию и делать коммит в бд. Если лучшим выбором будет отказаться от коммитов в базу данных, и ограничиться только лишь кешем, то возникает сложность получения этих данных из Rails (получить нужно все данные, а они, очевидно, с различными ключами). Кроме того, после получения этих данных они должны остаться так же доступными для последующих подключений клиентов web-приложения.

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

P.S. Успокойтесь, ни за кем следить не собираюсь, приложение пишется для коммерческих целей для мониторинга движения служебного транспорта. Похождение простых смертных линуксоидов заказчику не интересны. :)

★★★★

храни в redis, если нужно временно, или же в redis и паралельно в дб. Хотя редиса думаю хватит.

Попробуй ssdb, при больших нагрузках у нас не взлетело. Но там более 3к

ggrn ★★★★★ ()
Последнее исправление: ggrn (всего исправлений: 2)
Ответ на: комментарий от ggrn

Redis то Redis, но как реализовать - непонятно. Чувствую я, что тянуть весь накопленный массив, а потом его обрабатывать в данном случае будет очень трудоемко. При хранении в бд проблема решается одним запросом, но как заставить Redis сохранять в бд? Третье средство (выполняющее эту операцию, например, по крону) хотелось бы всячески избежать.

comp00 ★★★★ ()
Ответ на: комментарий от dvrts

шило на мыло, только еще и с потерей фич, в виде типов Redis.

Кроме того, насколько я понял, и в Redis и в memcached все достаточно плохо с аутентификацией пользователей, при подключении из глобальной сети, что представляет собой потенциальную дыру.

comp00 ★★★★ ()

почему не складывать все в хэш в редисе? потом в одну команду получишь все данные вместе с ключами. если нужно разделять по юзерам - делаешь много хешей

staz ()
Ответ на: комментарий от staz

Я ничего не имею против redis, как кеш-хранилища.

Проблема в том, что большому количеству клиентов нужно обеспечить доступ к редису. Т.к. данные будут передаваться через публичные сети, хотелось бы иметь что-то по серьезнее метода AUTH у редиса, во избежании потери нарушения достоверности информации. А гугл показал, что redis ничего подобного не умеет.

Ну и опять же, к вопросу о дублировании/переносе кеша в бд: как заставить редис делать запросы к бд? Пока мне никто так и не дал ответа.

comp00 ★★★★ ()
Ответ на: комментарий от comp00

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

Тебе нужны данные про одного юзверя или всех? Если 1 то делай ключ типа geo_data_%userid%:data (данные упаковываются pickle'ом)

Ну и опять же, к вопросу о дублировании/переносе кеша в бд: как заставить редис делать запросы к бд?

Никак. Редис это не умеет. У нас кладуться данные и в redis и в бд, но в бд пишем через celery

ggrn ★★★★★ ()
Последнее исправление: ggrn (всего исправлений: 2)
Ответ на: комментарий от ggrn

Тебе нужны данные про одного юзверя или всех?

От всех, информация о которых есть в кеше. Вытаскивать ее нужно при каждом обращении к веб-странице с картой.

У нас кладуться данные и в redis и в бд, но в бд пишем через celery

Коммит в дб выполняется по таймингу? И как организована передача данных (аутентификация) в redis?

comp00 ★★★★ ()

А если рассмотреть вариант с укладыванием в реляционную БД сразу, без редиса?

Быстродействия не хватит?

Потому как по всем остальным параметрам твои задачи реляционная БД решает замечательно. И даже можно БД периодически чистить от устаревших записей.

P.S. Хотя да... если сотня клиентов и выше, это может быть напряжненько.

hobbit ★★★★★ ()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

Вся суть этого кеша - делать не тысячу подключений, а одно. В идеале - не делать вообще. Честно сказать, уже думаю о создании своей «очереди», которая бы принимала данные и по таймингу открывала транзакцию к бд.

comp00 ★★★★ ()
Ответ на: комментарий от comp00

Вся суть этого кеша - делать не тысячу подключений, а одно. В идеале - не делать вообще.

Опять-таки - в плане быстродействия или в плане безопасности? Если второе - во всяких форумных движках, например, не заводят для 500 пользователей по аккаунту в БД, заводят один служебный. А аккаунты для пользователей самого интерфейса делают уже как надстройку, средствами самого движка.

Я с реляционными БД работал не так уж мало (Oracle, PostgreSQL), но к сожалению, почти всегда это были ненагруженные системы. Случай, когда в одну БД довольно часто лазили больше сотни клиентов, попадался ровно один раз и вполне успешно разруливался самим Ораклом. Правда, там клиенты всё же не каждую секунду INSERT делали.

Вот, кстати, интересная статья, автор которой использует Redis в качестве кэша к PostgreSQL. Самому хотелось бы что-то подобное попробовать, но в последнее время я от БД несколько отошёл. Так что в этой теме я скорее, читатель, чем писатель :)

hobbit ★★★★★ ()
Последнее исправление: hobbit (всего исправлений: 1)
Ответ на: комментарий от hobbit

Опять-таки - в плане быстродействия или в плане безопасности?

В плане быстродействия. Время жизни максимум 5 секунд, есть смысл хранить это в реляционной бд? Да и каждые 5 сек. обращаться к бд - не очень радостное занятие. Хотя, конечно, попробую.

Если второе - во всяких форумных движках, например, не заводят для 500 пользователей по аккаунту в БД, заводят один служебный.

Не совсем понял... Под подключениями я подразумевал физическое подключение, создание транзакции, INSERT_OR_UPDATE всех собранных данных, COMMIT. Естественно в один аккаунт БД, которым и пользуется Rails, для доступа к таблице из него.

За ссылку спасибо, обязательно прочту.

comp00 ★★★★ ()
Ответ на: комментарий от hobbit

К сожалению, материал в статье, все же жестко привязан nginx, а у меня apache.

Но почему бы мне не реализовать подобным образом, используя Rails? Создать контроллер mysite.dom/geodata и слать туда JSON'ы обычным HTTP запросом. В контроллере аутенфицировать данные, и отправлять в асинхронную очередь resque, которая поместит данные в redis. При обращении к странице с картой, в контроллере Rails обращается к redis, обрабатывает данные и отображает. Вроде все логично.

Из плюсов получу обратную связь при отправки геоданных: в случае невалидных данных отправлять соответствующее сообщение на устройство, а так же сохранится централизованность стека приложений вокруг Rails.

Стоит попытаться, или же я упускаю важные подводные камни, сводящие на нет всю схему передачи данных?

comp00 ★★★★ ()

получить нужно все данные, а они, очевидно, с различными ключами

Какими ключами?

special-k ★★★ ()
Ответ на: комментарий от special-k

как вариант - тот самый public_key для конкретного юзера

comp00 ★★★★ ()
Ответ на: комментарий от comp00

Ты же для одного юзера выбираешь - один ключ - один запрос.

special-k ★★★ ()
Ответ на: комментарий от special-k

Из Rails я как используемые ключи получу? Загрузить ключи всех моделей и запросить в Redies, в надежде что хотя бы половина будет в кеше?

comp00 ★★★★ ()
Ответ на: комментарий от comp00

Из Rails я как используемые ключи получу?

Что за странный вопрос...
К примеру, ты выводишь комменты на экран - ты выбираешь из базы (например) 20 комментов - вот ты знаешь их ключи.

ключи всех моделей и запросить в Redies

Заведи поле, указывающее есть запись в редис, или нет.

special-k ★★★ ()
Ответ на: комментарий от special-k

Неужели так сложно прочитать пост? Я не использую пагинацию. Мне нужно отобразить на карте положение всех передатчиков, не 10 или 20, а всех. Понятно, что с ростом нагрузки придется это оптимизировать, но на текущем этапе заказчик явно дал ограничение в 100 элементов.

Заведи поле, указывающее есть запись в редис, или нет.

эм... что? У меня есть модель Entity с полем public_key. После авторизации, это Entity шлет запросы в Redis с содержимым public_key и геоданными. при обращении к контроллеру, мне нужно получить все геоданные всех public_key`ев, но rails не знает какой из Entity присылает данные в текущий момент, а значит public_key неизвестен. Куда я должен добавить флаг?

Читай внимательно пост, пожалуйста.

comp00 ★★★★ ()
Ответ на: комментарий от comp00

Неужели так сложно прочитать пост?

Да ты хрень какую-то пишешь.

публичный ключ (хранится в соответствующей модели Rails приложения)

В модели ничего не хранится, модель - это класс реализующий доступ к БД, какая используются БД, только редис, или еще реляционная?

После авторизации

Авторизация (вернее аутентификация) - это когда ты получаешь id (а как правило еще и объект) текущего пользователя. В объекте текущего пользователя могут быть какие угодно поля.

rails не знает какой из Entity присылает данные в текущий момент

Почему не знает? Что не знает? Что значит «Entity присылает».

special-k ★★★ ()

Опиши задачу в общем, безо всяких энтитис: что делает пользователь. Разбирать что ты там по чем понимаешь нет особого желания.

special-k ★★★ ()

Если ты просто, каждые 3 секунды хочешь обновлять значение (координаты) по соответствующему ключу, а потом просто выводить текущие значения, то используй http://redis.io/commands/hset В качестве значения устанавливай примерно следующее:

PUB_KEY;lonlat;creation_datetime

Получай все с помощью http://redis.io/commands/hvals

На сервере фильтруй значения по устаревшей дате и удаляй (если требуется).

special-k ★★★ ()
Ответ на: комментарий от special-k

В модели ничего не хранится, модель - это класс реализующий доступ к БД,

Спасибо за экскурс в паттерн MVC.

какая используются БД, только редис, или еще реляционная?

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

Короче, не парься, я уже знаю как это реализовать.

comp00 ★★★★ ()
Ответ на: комментарий от comp00

Коммит в дб выполняется по таймингу?

В celery добавляется задача в очередь.

И как организована передача данных (аутентификация) в redis?

0_0 ещё раз? Что не ясно? Просто кладу данные в редис и всё

ggrn ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.