Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Уменьшение кол-ва подключений к mysql из php

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: Очень примитивный вопрос новичка.
clawham
Отправлено: 22 Января, 2019 - 19:10:06
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Янв. 2019  


Помог: 0 раз(а)




Здравствуйте!
Делаю примитивную систему - со скрипта пользователь загружает файл картинки, скрипт его пихает в blob базы данных и потом несколько десятков пользователей из другого скрипта смотрят эту картинку из базы данных. в базе данных остается только последняя картинка - предыдущие удаляются.

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

код получения картинки
PHP:
скопировать код в буфер обмена
  1.  
  2. <html>
  3. <head>
  4. <meta http-equiv="content-type" content="text/html">
  5. <title>Сохранение бинарных данных в базе данных MySQL</title>
  6. </head>
  7. <body>
  8. <?PHP
  9.  
  10. if($_POST['passwd'] == "1004")
  11. {
  12.  
  13.     // подключение к базе данных
  14.     // (возможно, вам придется настроить имя хоста, имя пользователя и пароль)
  15.     $dbh = new mysqli("localhost", "111", "111", "bd1");
  16.  
  17.     {
  18.         exit("Ошибка подключения к базе данных MySQL: Сервер база данных не доступен!<br>
  19.        Проверте параметры подключения к базе данных.");
  20.     }
  21.  
  22.     $data = addslashes(fread(fopen($_FILES['file']['tmp_name'], "r"),
  23.     filesize($_FILES['file']['tmp_name'])));
  24.  
  25.     $_POST['form_description'] = trim($_POST['form_description']);
  26.     $size = filesize ($_FILES['file']['tmp_name']);
  27.  
  28.     $result=$dbh->prepare("INSERT INTO binary_data (description,bin_data,filename,filesize,filetype,scr_id, ipaddr)
  29.  "."VALUES ('".$_POST['form_description']."',
  30.  '".$data."',
  31.  '".$_FILES["file"]["name"]."',
  32.  '".$size."',
  33.  '".$_FILES["file"]["type"]."',
  34.  '".$_POST['scrid']."',
  35.  '".$_SERVER['REMOTE_ADDR']."')");
  36.  
  37.         if(!$result) exit("Ошибка выполнения SQL запроса!");
  38.  
  39.         $result->execute();
  40.  
  41.         $id = $dbh->prepare();
  42.  
  43.         echo "<p>Этот файл имеет следующий идентификатор (ID) в базе данных: <b>|".$result->insert_id."|</b><br>";
  44.  
  45.  
  46.         $query = "SELECT t FROM binary_data WHERE scr_id=".$_POST['scrid']." ORDER BY t DESC LIMIT 1";
  47.                
  48.         $result = $dbh->query($query);
  49.          
  50.         if(!$result) exit("Ошибка выполнения SQL запроса 1!");
  51.          
  52.         $row = $result->fetch_array();
  53.        
  54.         $query = "DELETE FROM binary_data WHERE scr_id=".$_POST['scrid']." AND t<'".$row[0]."'";
  55.        
  56.         $result = $dbh->prepare($query);
  57.        
  58.         $result ->execute();
  59.        
  60.         if(!$result) exit("Ошибка выполнения SQL запроса 2!");
  61.          
  62.         echo "<br> Deleted ".$result->affected_rows." rows";
  63.  
  64.  
  65. }
  66. else
  67. {
  68. echo "<br><br><Muhahahaha<br><br>";
  69. }
  70. ?>
  71.  
  72. </body>
  73. </html>
  74.  


ну а получение картинки с сервера такое
PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3.  
  4. if(!preg_match("|^[\d]*$|",$_GET['id'])) exit();
  5.  
  6. // подключение к базе данных
  7. // (возможно, вам придется настроить имя хоста, имя пользователя и пароль)
  8. $dbh = new mysqli("localhost", "111", "111", "bd1");
  9.  
  10.  
  11. {
  12.   exit("Ошибка подключения к базе данных MySQL: Сервер база данных не доступен!<br>
  13.  Проверте параметры подключения к базе данных.");
  14. }
  15.  
  16. $query = "SELECT bin_data,filetype FROM `binary_data` WHERE scr_id = ".$_GET['id']." ORDER BY t DESC LIMIT 1";
  17. $result = $dbh->query($query);
  18.  
  19. if(!$result) exit("Ошибка выполнения SQL запроса!");
  20.  
  21. $row = $result->fetch_array();
  22.  
  23. Header( "Content-type: ".$row['filetype']."");
  24. echo $row['bin_data'];
  25.  
  26. ?>
  27.  


У каждого пользователя эта картинка на автообновлении стоит раз в секунду две три. пользователей дофига - в идеале чтоб хоть тысяча их была.
Аналогично - штук 10 выгружателей будет - раз в секунду или в две - не важно.

Во всех хостингах даже платных кол-во подключений к базе данных ограничено.
Как я понимаю проблем в строке - $dbh = new mysqli("localhost", "111", "111", "bd1"); - я каждый раз открываю новое подключение.
А как его сохранять-передавать? ведь это просто картинка выдается. у человека в браузере написано http://mysite[dot]myhost[dot]com[dot]ua/img.php и поставлено автообновление страницы каждую секунду. вот он и генерирует 3600 подключений в час... а ну да - эта фигня должна работать по три месяца непрерывно.
Как это правильно делается? есть какие-то глобальные переменные которые от запуска к запуску скрипта сохраняют свое значение?
 
 Top
Мелкий Супермодератор
Отправлено: 22 Января, 2019 - 20:21:59
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Начните с самого начала:
clawham пишет:
скрипт его пихает в blob базы данных

Вот отсюда - зачем?
Пишите в файл и раздавайте файлом.

В остальном:
По коду - вы поразительным образом умудрились совместить prepared statements и sql инъекции. Не надо так делать. Посмотрите примеры даже в документации, как передавать параметры для запроса.

clawham пишет:
я каждый раз открываю новое подключение.

Верно

clawham пишет:
есть какие-то глобальные переменные которые от запуска к запуску скрипта сохраняют свое значение?

Переменных нет. PHP намеренно сделан shared nothing
Но некоторые вещи бывают разделяемые, в частности mysqli можно попросить держать persistent connect: http://php.net/manual/en/mysqli.persistconns.php

clawham пишет:
Во всех хостингах даже платных кол-во подключений к базе данных ограничено.

Очень странно выделили "даже платных".
Не во всех, конечно. Возьмите банально VPS и подключайтесь к mysql так часто насколько у вас хватит ресурсов CPU.


-----
PostgreSQL DBA
 
 Top
clawham
Отправлено: 22 Января, 2019 - 20:38:22
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Янв. 2019  


Помог: 0 раз(а)




Вы так написали как вроде я чтото понимаю а я ничего не понимаю вообще...я этого франкенштейна собрал именно из кусков примеров в документации.

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

По поводу persistent sqli я ничего не понял - просто вместо localhost надо написать p:localhost?

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

На файлы переходить не буду просто потому что дальше будет аналогичная лабуда только не с картинками а с данными - штук 400 датчиков раз в 3 секунды должны будут делать запрос как на передачу картинки только там будут числовые данные и вот эти данные надо складировать в базу данных а потом опять же выдавать в графики и прочее и там уже рабочей лошадкой будет загрузка данных на сервер. и тоже надо как-то красиво это делать чтоб не насиловать sql

почему отдельно выделил платные? да потому что даже если взять самый дорогой план на https://thehost[dot]ua - то там всего 36000 соединений максимум... это ж всего 10 клиентов с обновлением раз в секунду наклоцать могут! Как не на нем порталы целые предлагается хостить с 10-ком сайтов? Немного чтот я недоганяю....
 
 Top
Мелкий Супермодератор
Отправлено: 23 Января, 2019 - 10:37:12
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




clawham пишет:
Ну и конечно же самый главный вопрос - а как можно более правильно написать код получения картинки? он является какбы рабочей лошадкой.

Повторюсь: зачем вам вовсе писать картинку в базу если заведомо известно что читать будут только последнюю?
Зачем вам вообще какой-то код для получения картинки?
Раздавать картинку напрямую файлом на порядок-другой дешевле чем из базы и ещё на пару порядков дешевле если не дёргать PHP. А та задача что вы пока что описали именно что не требует ни чтения базы ни даже вызова PHP для показа картинки.

clawham пишет:
По поводу persistent sqli я ничего не понял - просто вместо localhost надо написать p:localhost?

Согласно документации да. Редко mysqli вижу. В сравнении с PDO неудобный API для prepared statements.

clawham пишет:
а с данными - штук 400 датчиков раз в 3 секунды должны будут делать запрос как на передачу картинки только там будут числовые данные и вот эти данные надо складировать в базу данных а потом опять же выдавать в графики и прочее и там уже рабочей лошадкой будет загрузка данных на сервер. и тоже надо как-то красиво это делать чтоб не насиловать sql

Начать с того, что реляционная база вообще не очень подходящий выбор для откровенно time-series данных, для которых есть специальные time series database.
400 датчиков по 3 секунды, 4млрд событий в год. Ну такое. Пробовали сгенерировать фиктивных данных за пару месяцев? Для начинающего 350млн строк в месяц и попытка представить выборку из них на графике могут оказаться сюрпризом. Сильно зависит от того как именно строить графики, впрочем.

clawham пишет:
почему отдельно выделил платные? да потому что даже если взять самый дорогой план на https://thehost[dot]ua - то там всего 36000 соединений максимум... это ж всего 10 клиентов с обновлением раз в секунду наклоцать могут! Как не на нем порталы целые предлагается хостить с 10-ком сайтов?

А что, вот это - единственный вариант?
Ну хрень какая-то. Дешёвая. 7 долларов в месяц всего. Да даже топовый сервер всего на 32гб ram и с 4 ядрами предлагают. Что за ужас там ставят вместо SSD боюсь представлять. В общем компания явно специализируется на низкобюджетных клиентах с визитками и другой мелочёвкой. Что с другой стороны тоже неплохо, лучше чем пытаться угодить всем и не угодить никому в итоге.
Кому надо что-то приличнее - пойдут к другим. Лично мне привычна картина из нескольких серверов на 100-200ГБ RAM и нескольких десятков ядер CPU только под нужды базы обслуживающей всего один сайт.


-----
PostgreSQL DBA
 
 Top
clawham
Отправлено: 23 Января, 2019 - 20:06:02
Post Id


Новичок


Покинул форум
Сообщений всего: 3
Дата рег-ции: Янв. 2019  


Помог: 0 раз(а)




а можете привести пример если не сложно как решить эту же задачу через pdo и где что поменять чтоб сравнить persistent и не persistent варианты? мы уже раскошелились на виртуалку 1 ядро 512 рам 28 гиг винт 100 мегабит канал. протестировал на картинках - 20 юзеров с безлимитным обновлением и 4 юзера с 250 мсек выгрузкой картинки 1 мегабайт - у некоторых в 300 мсек приходит у некоторых в 0.5 - нам в общем-то достаточно - подниму задержку до 2 секунд и сервак будет пустым.

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

Конечно с моими познаниями в php это будет сложно но что делать. Я вообще програмист под Windows с# и sql для меня не новость. РНР новость и сервера сторонние новость...никогда дел не имел но ....всем уже подавай онлайн и кросплатформенность.

Я тут вот переписал по-другому примеру чтение базы

PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3.  
  4. if(!preg_match("|^[\d]*$|",$_GET['id'])) exit();
  5.  
  6. // подключение к базе данных
  7. // (возможно, вам придется настроить имя хоста, имя пользователя и пароль)
  8. mysql_pconnect('localhost', '111', '111') or die('Не удалось соединиться: ' . mysql_error());
  9.  
  10. mysql_select_db('bd1') or die('Не удалось выбрать базу данных');
  11.  
  12.  
  13. $query = "SELECT bin_data,filetype FROM `binary_data` WHERE scr_id = ".$_GET['id']." ORDER BY t DESC LIMIT 1";
  14. $result = mysql_query($query) or die('Запрос не удался: ' . mysql_error());
  15.  
  16. $row = mysql_fetch_array($result, MYSQL_ASSOC);
  17.  
  18. Header( "Content-type: ".$row['filetype']."");
  19. echo $row['bin_data'];
  20.  
  21. ?>
  22.  


так почему-то дольше картинку отдает и нагрузка на сервер больше(7% против 4% у старого метода) но в любом случае оно не критично на самом деле и лимитов больше и нет какбы.

Заранее большое спасибо за потраченное на меня время.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Обсуждение статей »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB