• Главная
  • » SQL
  • » Выдача картинок с mysql с помощью nginx

#1 2015.10.31 15:38

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Выдача картинок с mysql с помощью nginx

Есть ли такая возможность что бы не вмешивать в эту задачу php.
Перерыл интернет что то ничего не нашел на эту тему. Находил там работу nginx с mysql но совсем не понятно как реализовать данную задачу

Неактивен

#2 2015.11.01 16:29

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

Уточню задачу. Нужно хранить картинки в базе так как при хранении просто на фс то сильно перегружается винт постоянно нагружен по максимуму и в следствии висит сайт.
Вот только как это реализовать что бы не давать еще нагрузку на php я хз. Хотя может и стоит это сделать через php. Хоть так хоть так изображение будет полностью выгружатся в память

Неактивен

#3 2015.11.01 19:26

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Выдача картинок с mysql с помощью nginx

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

Неактивен

#4 2015.11.07 03:20

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

В обьщем там кроме картинок на диске кешировались еще много файлов. И нагрузка на винт была постоянно на максимум. Переписал кеш на mysql плюс подключил memcache сайт начал летать.
Добавлено спустя   7 минут  55 секунд:
Кстати был прикол с этим хешем. Хотел удалить папку кеша >20млн. файлов(Дождался при подсчете этой цыфры потом полюнул может там и 100 лямов) и тупонул выполнив несколько раз удаление папок через nohup. В общем почему то решил ребутнуть сервер но после ребута при запуске вообще подвис так как кеш хранился в папке tmp и система начала ее чистить. Пришлось загружатся в режиме востановления и переименовывать папку))
Досихпор не могу вычистить /tmp2. Поспешил я с хранением кеша в файлах. Решил секономить время

Неактивен

#5 2015.11.07 11:56

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Выдача картинок с mysql с помощью nginx

думаю, тут и mysql не лучшее решение. возможно, подошла бы какая-нибудь nosql база. например, couchdb. там можно сразу ссылку на файл в БД давать (встроенный http сервер), минуя nginx.

Неактивен

#6 2015.11.07 20:51

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

Gemorroj написал:

думаю, тут и mysql не лучшее решение. возможно, подошла бы какая-нибудь nosql база. например, couchdb. там можно сразу ссылку на файл в БД давать (встроенный http сервер), минуя nginx.

Я так понял речь идет о картинках или весь кеш сайта предлагаешь хранить на этой базе?
Кеш картинок пока что не трогал. Сейчас винт нагружен примерно на 5-10%. Сейчас задача выдачи картинок стоит такова:
Получаем ссылку на оригинал картинки с базы данных далее загружаем ее через курл в память + imagecreatefromstring($data) пошаманим немного и сохраняем в файл после выдаем в браузер.
Далее этим занимается nginx смотрит есть ли картинка в кеше если есть выдает в браузер, нет перенаправляет на данный скрипт. Пока что там 240т. картинок. работает быстро. Просто тогда было очень много операций чтения записи

Неактивен

#7 2015.11.08 12:18

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Выдача картинок с mysql с помощью nginx

так проблема в плохо оптимизированном php коде? ну так блин, с этого и начинал бы)

Неактивен

#8 2015.11.08 15:15

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

Gemorroj написал:

так проблема в плохо оптимизированном php коде? ну так блин, с этого и начинал бы)

Не понял с чего ты взял что проблема в php. Была проблема из-за хранения данных на винте. вот функция кеша (старая)

Код:

1
span style="color: #0000BB"><?php private function _cacheVideoSet ($data, $id) { $fp = fopen($this->_dirInfoCache . $id . '.txt', 'c+'); if (!$fp) { file_put_contents($this->_errorLogFile, 'cacheVideoSet failed no open file['.__LINE__.']'."\n", FILE_APPEND); return false; } $old_data = ''; while (!feof($fp)) { $old_data .= fread($fp, 8192); } rewind($fp); if (!$old_data) { $data['expire'] = $_SERVER['REQUEST_TIME']; fputs($fp, serialize($data)); } else { $old_data = unserialize($old_data); if (!is_array($old_data)) { file_put_contents($this->_errorLogFile, 'cacheVideoSet unserialize ['.__LINE__.']: '. $str . "\n", FILE_APPEND); fputs($fp, serialize($data)); } else { if (@$data['title']) $old_data['title'] = $data['title']; /* if ($data['description']) $old_data['description'] = $data['description']; */ if ($data['img']) $old_data['img'] = $data['img']; if ($data['localIp']) { $old_data['localIp'] = $data['localIp']; } $old_data['errno'] = @$data['errno']; $old_data['expire'] = $_SERVER['REQUEST_TIME']; if (@$data['downLinks']) $old_data['downLinks'] = $data['downLinks']; fputs($fp, serialize($old_data)); } } fclose($fp); }

А вот новая

Код:

1
span style="color: #0000BB"><?phppublic function setVideosInfo($arrayData) { $insert = "INSERT INTO `$this->_INFO_TABLE_NAME` " . "(`id`, `title`, `description`, `duration`, `img`, `errno`, `expire`, `data`, `relative_ids`)\n"; $values = []; foreach ($arrayData as $data) { $id = "'{$data['id']}'"; $title = "'" .$this->_mysqli->real_escape_string($data['title']) . "'"; $description = "'" . $this->_mysqli->real_escape_string(@$data['description']) . "'"; $duration = $data['duration']; $img = "'" . $data['img'] . "'"; $errno = (int)@$data['errno']; $otherData = @$data['data'] ? "'".$this->_mysqli->real_escape_string(serialize($data['data']))."'" : "''"; if (@$data['data']['downLinks']) $expire = $_SERVER['REQUEST_TIME']; else $expire = 0; $relative_ids = "'" . $this->_mysqli->real_escape_string(@$data['relative_ids'])."'"; $values[] = "($id, $title, $description, $duration, $img, $errno, $expire, $otherData, $relative_ids)"; } $insert .= 'VALUES '. implode (",\n", $values) . "\n" . "ON DUPLICATE KEY UPDATE\n" . "`title` = COALESCE(VALUES(title), description),\n" . "`description` = COALESCE(VALUES(description), description),\n" . "`img` = COALESCE(VALUES(img), img),\n" . "`errno` = VALUES(errno),\n" . "`expire` = VALUES(expire),\n" . "`data`= COALESCE(VALUES(data), data)\n"; if ($result = $this->_mysqli->query($insert)) { //$result->close(); } else { //echo $this->_mysqli->error; //echo $insert; } //echo $insert; }

Добавлено спустя   5 минут  24 секунды:
Просто когда все данные хранились на тупо по файлах. То увеличивалось время доступа к каждому файлу по мере их накопления.
Сейчас работает все гораздо быстрее. А если ты имеешь в виду за получение картинок то вот функция.

Код:

1
span style="color: #0000BB"><?phppublic function previewAction($m, $id, $type) { $path_cache = '/tmp/previews/'; $path = "{$path_cache}{$m}_{$id}"; if (!is_dir($path_cache)) { if (mkdir($path_cache)) { log(__FILE__ . ': '. __LINE__); return $this->errorAction(Response::HTTP_INTERNAL_SERVER_ERROR); } chmod($path_cache, 0777); } $video = new \Video\Video($m .'_'.$id); $video->initById(); \CurlMulti::exec(true); if (@$video->getOriginalImg() == '/images/x_null.gif') { return $this->_getDefaultImage($type); } if (!$video->getOriginalImg()) { return $this->errorAction(Response::HTTP_NOT_FOUND); } $ch = curl_init($video->getOriginalImg()); $headers = array( 'Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language:ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4,uk;q=0.2,und;q=0.2', 'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.90 Safari/537.36', 'Connection: close'); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_ENCODING ,""); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch); $info = curl_getinfo($ch); $error = curl_error($ch); if ($info['http_code'] != 200 || $error || $info['content_type'] != 'image/jpeg') { log(__FILE__ . ': '. __LINE__); return $this->_getDefaultImage($type); } $src_img = imagecreatefromstring($data); $src_w = imagesx($src_img); $src_h = imagesy($src_img); // исходное соотношение //$src_rate = $src_w / $src_h; // необходимое соотношение $dst_rate = 1.777777777777778; // ширина нового изображения $dst_w = $src_w < 320 ? $src_w : 320; // высота результата $dst_h = round($dst_w / $dst_rate); // новая высота оригинала $src_h_new = $src_w / $dst_rate; // отступы вырезаемой части $src_indent = round(($src_h - $src_h_new) / 2); $src_x = 0; $src_y = $src_indent; // отступы результата $dst_x = 0; $dst_y = 0; $img_hq = imagecreatetruecolor($dst_w, $dst_h); // копируем прямоугольник imagecopyresampled($img_hq, $src_img, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h_new); imagedestroy($src_img); imagejpeg($img_hq, "{$path}_HQ.jpg"); // create mq image $mq_w = 128; $mq_h = $mq_w/$dst_rate; $img_mq = imagecreatetruecolor($mq_w, $mq_h); imagecopyresampled($img_mq, $img_hq, 0, 0, 0, 0, $mq_w, $mq_h, $dst_w, $dst_h); imagejpeg($img_mq, "{$path}_MQ.jpg"); $response = new Response(); switch($type) { case 'HQ': ob_start(); imagejpeg($img_hq); $response->setContent(ob_get_clean()); $response->headers->set('Content-Type', image_type_to_mime_type(IMAGETYPE_JPEG)); $response->setStatusCode = 200; break; case 'MQ': ob_start(); imagejpeg($img_mq); $response->setContent(ob_get_clean()); $response->setStatusCode = 200; $response->headers->set('Content-Type', image_type_to_mime_type(IMAGETYPE_JPEG)); break; default: return $this->errorAction(404); } imagedestroy($img_hq); imagedestroy($img_mq); return $response; }

Неактивен

#9 2015.11.08 15:34

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

Можно было бы и выдавать картинку после сохранения с помощью nginx передав заголовок X-Accel-Redirect но хз че так не сделал. Может посчитал лишним.


Ну и собственно выдача в nginx

Код:

1
2
3
4
5
6
7
8
9
10
11
12
location ~* "^/(.*)/(HQ|MQ).jpg$" {
set $imageType $2;
set_escape_uri $imageName $1;
set $slash '_';
set $path $imageName$slash$imageType.jpg;
root /tmp/previews/;
if (-f /tmp/previews/$path) {
expires 3d;
rewrite (.*) /$path break;
}
rewrite (.*) /$path last;
}

Неактивен

#10 2015.11.10 13:03

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Выдача картинок с mysql с помощью nginx

у тебя все файлы в 1 папке были? возможно проблема в этом

Неактивен

#11 2015.11.12 19:16

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

Gemorroj написал:

у тебя все файлы в 1 папке были? возможно проблема в этом

Ну да как раз в этом и была проблема. Плюс каждое видео хранилось в отдельном файле. Вопервых при поиске видео функция setCache вызывалась ~150 раз а это чтение +запись.
Короче пока что ввесь кеш на mysql + memcache а превюшки кешируются на винте все в одной папке. трогать пока что не буду. Результаты отклика устраивают. Посмотрю что через недельку другую будет.

Неактивен

#12 2015.11.12 20:04

Gemorroj
Administrator
Откуда: Белоруссия
Зарегистрирован: 2007.11.03
Сообщений: 6593
Карма: 107
Профиль Веб-сайт

Re: Выдача картинок с mysql с помощью nginx

ну вот раздели просто по папкам файлы.
например  год/месяц/число/файл (2015/11/12/file.txt)

Неактивен

#13 2015.11.13 06:21

TLENS
Moderator
Откуда: Украина
Зарегистрирован: 2009.04.05
Сообщений: 2402
Карма: 14
Профиль

Re: Выдача картинок с mysql с помощью nginx

Gemorroj написал:

ну вот раздели просто по папкам файлы.
например  год/месяц/число/файл (2015/11/12/file.txt)

Ну насчет файлового кеша я уже разобрался. Перенес всю задачу на базу. А вот с превьюшками можно так сделать.

Неактивен

  • Главная
  • » SQL
  • » Выдача картинок с mysql с помощью nginx

Дополнительно

forum.wapinet.ru

PunBB Mod v0.6.2
0.012 s