RSS Записей | RSS Комментариев
Ядоблог - Stay upwind

Архив ‘Apache’ Категории

MongoDB, хранение файлов в базе

февраля 13, 2012 | 5 комментариев

В интернетах бытует мнение, что хранить файлы в БД — школоло. Разрушаем стереотип с Mongo GridFS.

Введение:
MongoDB предоставляет возможность хранить файлы любого размера в Mongo GridFS
Для драйвера PHP — это обычная коллекция, в которой есть поле для хранения бинарных данных.
Бинарные данные в свою очередь разбиваются на чунки(небольшие куски).
Бинарные данные можно извлечь как целиком, так и почунково(это экономит память).

Плюсы хранения данных в БД MongoDB:
MongoDB может хранить миллионы файлов в БД, хранение такого объёма данных в файловой системе может вызвать проблемы(начиная с IO проблем, заканчивая проблемами доступа к данным из разных серверов).
MongoDB реплицирует данные на все сервера, что упрощает доступ к данным на отдельно взятом сервере.
Нет проблем с бекапами и целостностью данных на разных серверах. надёжность обеспечивается MongoDB.
К загруженному файлу можно прикрепить метаданные (описание, комментарии, лайки, и.т.д.)
Т.к. файлы хранятся в чунках — можно работать с любой частью файла.

Минусы:
Быстродействие ниже, чем nginx + файловая истема. Сравним:
nginx + файловая система, получаем 6559.31 операций в секунду
apache + файловая система: получаем 2625.37 операций в секунду
nginx + модуль nginx-gridfs, получаем 1083.88 операций в секунду

Вывод: nginx + fs на высоте, но это решение не даёт масштабируемости и гибкости.
nginx + nginx-gridfs даёт приличные результаты, которые существенно возрастут, при использовании нескольких серверов MongoDB.

Благодарность, http://tokarchuk.ru за тесты.

nginx, в случае отсутвтвия файла запросить апач

января 11, 2012 | 2 комментария

решение:

location / (
    error_page 404 @fallback;
)
 
location @fallback (
    proxy_pass http://backend;
)

В двух словах: эта штуковина позволит на слабом серваке иметь отдачу под 200 страниц в секунду, если правильно настроить бэкенд (кешировать, временно статические страницы в файлуху(ramfs)).

Apache, nginx IAD

Создаём сайт на PHP без использования расширения в именах файлов

сентября 7, 2011 | 1 Комментарий

nginx, upstream sent too big header while reading response header from upstream, client

августа 26, 2011 | Комментариев нет

subj лечится добавлением в конфиг нгинкса пары строчек в http секцию:
proxy_buffers 8 16k;
proxy_buffer_size 32k;

thanks to: http://phpsuxx.blogspot.com/2009/11/upstream-sent-too-big-header-while.html

Apache, nginx IAD

XCache. PHP. Сравнение быстродействия.

августа 3, 2011 | Комментариев нет

Тестируем WordPress сайт утилитой ab:

ab -c 20 -n 200 http://lenta.iadlab.ru/

Что эквивалентно 20 запросам в секунду. Общее число запросов 200. Перед Apache стоит nginx, который принимает запросы и проксирует на apache в очередь.

Принцип работы XCache: предварительно компилируем PHP файлы в объектный код и сохраняем в памяти. При выполнении запроса линкуем нужные файлы из памяти и выполняем запрос.

Результаты без XCache:

Concurrency Level:      20
Time taken for tests:   51.226 seconds
Complete requests:      200
Failed requests:        0
Write errors:           0
Total transferred:      10737600 bytes
HTML transferred:       10688600 bytes
Requests per second:    3.90 [#/sec] (mean)
Time per request:       5122.616 [ms] (mean)
Time per request:       256.131 [ms] (mean, across all concurrent requests)
Transfer rate:          204.70 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:   473 4935 1205.1   4900   10384
Waiting:      272 4544 1024.4   4588    9127
Total:        473 4935 1205.1   4900   10384

Результаты с XCache:

Concurrency Level:      20
Time taken for tests:   35.107 seconds
Complete requests:      200
Failed requests:        0
Write errors:           0
Total transferred:      10737600 bytes
HTML transferred:       10688600 bytes
Requests per second:    5.70 [#/sec] (mean)
Time per request:       3510.692 [ms] (mean)
Time per request:       175.535 [ms] (mean, across all concurrent requests)
Transfer rate:          298.69 [Kbytes/sec] received
 
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0       3
Processing:   418 3366 791.7   3310    6196
Waiting:      324 3015 625.8   3056    4991
Total:        421 3366 791.4   3310    6196

Вывод: время выполнения упало ~ вдвое.

MySQL vs MongoDB. Более сложный insert (для mongodb) часть 3.

марта 25, 2011 | Комментариев нет

В продолжение решения задачи: Реляционка или не реляционка

Пройдя первый этап: MySQL vs MongoDB. Сравнение скорости insert Создания пользователей.

Пройдя второй этап:MySQL vs MongoDB. Более сложный insert (для mongodb) Создания друзей.

Пройдя третий этап: MySQL vs MongoDB. Более сложный insert (для mongodb) часть 2. Создания фотографий у каждого пользователя

Теперь пометим у каждого френда (100 френдов у каждого из 1000 пользователей) по 50 фотографий из 100 просмотренными. Получается 1000*100*50=5000000 (пять миллионов записей):

Для MySQL это вставка в таблицу who_view_photo записи с id_photo и id_user просмотревшем его.

Для MongoDB это изменение существующих объектов в коллекции пользователей. Причём мы меняем 3-й уровень объекта в глубину:

Посмотрим насколько шустро отработает наш MongoDB. Ему уже приходится в каждом объекте содержать информацию о 100 друзьях и 100 фотографиях (1000 записей).

По оси Х-время, по оси Y-количество случаев с данным временем. На примере вставки первых 50000 элементов (просмотров фотографий):

Вывод: Объекты MongoDB разжирнев, обрабатываются дольше, чем банальная вставка значения в таблицу MySQL. Но даже содержа 1000 значений в объекте, выполняя фактически операцию update к объекту (меняя его содержимое) мы получаем все-лишь двукратное замедление, что радует.

MySQL vs MongoDB. Более сложный insert (для mongodb) часть 2.

марта 25, 2011 | Комментариев нет

В продолжение решения задачи: Реляционка или не реляционка

Пройдя первый этап: MySQL vs MongoDB. Сравнение скорости insert Создания пользователей.

Пройдя второй этап:MySQL vs MongoDB. Более сложный insert (для mongodb) Создания друзей.

Создадим фотографии пользователей. Каждому пользователю по 100 фотографий.

Для MySQL это обычное создание записи в таблице:

Для NoSQL это добавление в коллекцию пользователей из MySQL vs MongoDB. Более сложный insert (для mongodb) ещё одного поля photos, являющегося множеством элементов.

И сравниваем производительность выполнения вставки 100 фотографий каждому из 1000 пользователей (100000 элементов).

По оси Х-время в секундах, по оси Y-количество случаев с данным временем выполнения(основной кусок увеличен):

Вывод: нужно понимать, что для MySQL — создание фотографии лишь вставка новой записи в таблицу фотографий, а для MongoDB — изменение существующего объекта, в котором уже содержится 100 друзей, созданных в предыдущем этапе, и ещё добавляется 100 элементов фотографий. Но при всём этом MongoDB половину операций (~50000) отработало за 0.0001 секунды, а MySQL редко ранее 0.0005 секунды. И MongoDB пришлось проделать гораздо большую работу (обновить существующие объекты).

MySQL vs MongoDB. Более сложный insert (для mongodb)

марта 25, 2011 | Комментариев нет

В продолжение решения задачи: Реляционка или не реляционка

Пройдя первый этап: MySQL vs MongoDB. Сравнение скорости insert

Создадим для 1000 пользователей системы по 100 друзей каждому (1000*100=100000 записей).
В MySQL мы имеем структуру:

Таким образом для MySQL это будет вставка записи в таблицу friends.
В MongoDB мы имеем структуру сложнее. т.к. вся информация представлена в виде большого дерева.
Мы имеем коллекцию пользователей. В которой все наши 1000 пользователей как документы.
Каждый документ имеет структуру:

  1. поле id_user
  2. массив ifriends состоящий из элементов id_friend (ссылка на другой элемент этой же коллекции users)

Понять сложно, если вы до этого ни разу не делали nosql проект. Обязательно изучите.
Ну так вот, операция создания френдов, по времени (по оси Х-время в секундах, по оси Y-количество операций с этим временем выполнения):

Вывод: тут нужно понимать, что в mysql — обычная вставка данных в таблицу, а в MongoDB — обновление существующего объекта — создание в его поле ifriend ещё одного элемента, хоть и с одним значением id_friend, но всё-же это update. Ну и мы видим, что выполнив 100000 таких операций мы имеет сравнимо одинаковые затраты по времени.

MySQL vs MongoDB. Сравнение скорости insert

марта 25, 2011 | 2 комментария

Для решения задачи Реляционка или не реляционка

Вставим 1000 записей в таблицу. Для чистоты эксперимента в таблицах уже по 10000 записей.

UPD: переделал сбор статистики и запустил на нормальном сервере. Результаты разительно другие (по Х-время в секундах, по Y-количество случаев):

Вывод: видим явно более быструю работу insert в mongodb. Нужно понимать что операции происходят в памяти, никакого обращения к диску не происходит. В обоих случаях. =)

Реляционка или не реляционка

марта 25, 2011 | Комментариев нет

Попробуем решить интересную задачу двумя способами (реляционным и не реляционным).
Допустим есть социальная сеть.
В ней есть пользователи, которые помечают других пользователей френдами.
Пользователи выкладывают какие-либо фотографии.

Задача: Для текущего пользователя вывести список всех фотографий френдов, которые этот пользователь ещё не просмотрел. О_о

Бум использовать:
php фреймворк CodeIgniter
mysql для реляционки
MongoDB для NoSql

Начальные данные:
1. создадим 1000 пользователей
2. для каждого пользователя зададим 100 друзей
3. для каждого пользователя зададим 100 фотографий (получится всего 100,000 фотографий О_о)
4. каждым пользователем посетим случайные 50 фото каждого своего друга (50*100*1000=5,000,000 записей)
5. каждым пользователем посетим случайные 1000 фото (1,000*1,000=1,000,000 ненужных записей дополнительно)

Ну и область наших интересов — быстродействие
Пока в процессе проектирования — пишите что-нить =)

© 2010 Ядоблог. Все права защишены.
Powered by Лаборатория Яда. Написать администратору