Совместное использование большого массива со всеми пользователями в приложении rails - PullRequest
1 голос
/ 31 января 2012

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

Теперь я хочу как-то сделать одну копию, чтобы она не создавалась снова и снова.Я подумал о нескольких вариантах и ​​хотел получить информацию, чтобы определить, какая из них лучше:

1) Создайте модель и поместите данные в базу данных. 2) Создайте файл YAML, и приложение загрузит его, когда оноинициализирует.

Мне лично нравится идея модели, но некоторые инженеры на работе считают, что она не заслуживает того, чтобы быть полной моделью.В 97% случаев пользователи увидят одно и то же, но в 3% случаев пользователи получат немного другой массив (несколько элементов будут изменены).
Любые другие подходы, которые я должен учитывать .??..Благодарюзаранее.

Ответы [ 2 ]

1 голос
/ 31 января 2012

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

Если вы запускаете несколько серверных процессов (не потоков) и если содержимое массиваизменяется во время работы приложения, и изменения должны быть видны всем процессам, кэширование в памяти не будет работать.В этом случае вам придется использовать БД.

Исходя из информации в вашем комментарии, я предлагаю вам попробовать что-то вроде этого:

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

Каждый раз, когда вам нужно использовать массив, извлекайте соответствующую «обновленную» метку времени из БД.(Возможно, вам придется использовать кодированный вручную SQL и ModelName.connection.execute, чтобы избежать вытягивания всех данных в записи, что, вероятно, будет делать ActiveRecord.) Если временная метка позже, чем в последний раз, когда обновлялся ваш кэш, извлеките массив изБД и обновите кэш.

Используйте Mutex ('require thread') при получении / обновлении кэшированных данных, если в настройках вашего сервера могут использоваться несколько потоков.(Я не думаю, что это делает Passenger, но у меня были проблемы, похожие на проблемы с многопоточностью при использовании Passenger + RMagick, поэтому я все равно использовал бы Mutex для безопасности.)

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

Немноготестирования производительности на настройку кеша с использованием Benchmark.measure {}.Если ошибка в настройке фактически ухудшит, а не улучшит производительность, это будет грустно ...

0 голосов
/ 31 января 2012

Я бы выбрал вариант 2. Вы можете добавить две константы (для 97% и 3%), которые загружаются из файла YAML при инициализации приложения.Это должно значительно сократить ваш след памяти.

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

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