• Главная
  • » 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
Сообщений: 6588
Карма: 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
Сообщений: 6588
Карма: 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
Сообщений: 6588
Карма: 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?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($fp8192);
        }
        rewind($fp);
        
        if (!$old_data) {
            $data['expire'] = $_SERVER['REQUEST_TIME'];
            fputs($fpserialize($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($fpserialize($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($fpserialize($old_data));
            }   
            
        }
        
        fclose($fp);
        
    }

А вот новая

Код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?php
 
public 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
 
public 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_cache0777);
        }
        $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($chCURLOPT_HTTPHEADER$headers);
        curl_setopt($chCURLOPT_HEADERfalse);
        curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
        curl_setopt($chCURLOPT_TIMEOUT10); 
        curl_setopt($chCURLOPT_ENCODING ,"");
        curl_setopt($chCURLOPT_FOLLOWLOCATIONtrue);
        $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_hq0000$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
Сообщений: 6588
Карма: 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
Сообщений: 6588
Карма: 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.015 s