Перейти к содержанию
Официальный форум поддержки Simpla

Рекомендуемые сообщения

Можно ли как-то симплу заставить работать с memcached или возможно поддержка уже реализована в движке?

Изменено пользователем Julius123
Ссылка на сообщение
Поделиться на другие сайты

Можно ли как-то симплу заставить работать с memcached или возможно поддержка уже реализована в движке?

Я когда-то давно общался на эту тему с Пикусовым, краткое содержимое диалога:

Вы так и не ответили почему не хотите добавить кеширование в симплу.

Потому что пока нечего кешировать

Было это 4 года назад...
Ссылка на сообщение
Поделиться на другие сайты

А что кешировать то хотите ?
Где Вам кажется он нужен (просто к каждому проекту нужен индивидуальный подход в этом плане )

Ссылка на сообщение
Поделиться на другие сайты
  • 1 год спустя...
  • 3 недели спустя...

Если кому интересно, вот модуль (/api/Cache.php):

<?php
/**
 * SimplaCMS memcacheD
 *
 * Класс обертка memcached для удобного использования в SimplaCMS
 *
 * @copyright	Copyright (c) 2016 Grinderspro
 * @link		http://grinderspro.ru
 * @author		Grigoriy Miroschnichenko <grinderspro@gmail.com>
 */
require_once('Simpla.php');
class Cache extends Simpla
{
    /**
     * Конструктор класса
     */
    public function __construct()
    {
        $this->init();
    }
    /**
     * Будущий экземпляр memcache
     */
    public $mem;
    /**
     * Массив - конфигурация параметров
     *
     * @return array customized attribute labels
     */
    private $config = [
        'host' => '127.0.0.1',
        'port' => 11211,
        'extension' => 'memcached', // or memcache
        'lifeTimeCache' => 86400,
    ];
    /**
     * Флаг типа используемого расширение PHP
     *
     * True - memcache
     * False - memcached
     */
    private $isMemcached = false;
    /**
     * Инициализация
     */
    private function init()
    {
        $this->isMemcached = $this->isMemcachedUse();
        if (!extension_loaded($this->config['extension'])) {
            throw new Exception("Php extension {$this->config['extension']} not foun. Please install the memcache extension.");
        }
        $this->isMemcached ? $this->mem = new Memcached() : $this->mem = new Memcache();
        $this->mem->addServer($this->config['host'], $this->config['port']);
    }
    /**
     * Извлекает значение из кеша с указанным ключом.
     *
     * @param string $stringKey уникальный ключ
     */
    public function get($stringKey)
    {
        if($this->mem != null)
            $result = $this->mem->get($this->stingToHash($stringKey));
        if (!empty($result))
            return $result;
        else
            return false;
    }
    /**
     * Помещает знаение в кеш по ключу
     *
     * @param string $stringKey ключ
     * @param $value Резальтирующий набор (набор данных, которые необходимо положить в кеш)
     * @param $lifeCache время жизни кеша
     */
    public function set($stringKey, $value, $lifeCache = 86400)
    {
        if ($this->isMemcached) {
            $this->mem->set($this->stingToHash($stringKey), $value, $lifeCache);
        } else {
            $this->mem->set($this->stingToHash($stringKey), $value, 0, $lifeCache);
        }
    }
    /**
     * Удаляет значение из памяти по ключу
     *
     * @var string $stringKey attribute labels
     */
    public function del($stringKey)
    {
        $this->mem->delete($this->stingToHash($stringKey));
    }
    /**
     * Аннулирует все существующие записи в кеше
     *
     * @var integer $delay Период времени, по истечению которого произвести полную очистку кеша
     * @return true or false
     */
    public function clearall($delay = 0)
    {
        $this->mem->flush();
    }
    /**
     * Из обычной строки в md5 hash
     *
     * @var string $stringKey - Ключ
     */
    private function stingToHash($stringKey)
    {
        return md5('key'.$stringKey);
    }
    /**
     * Проверяет исходя из значений конфигурационного массива $this->config
     * используется ли PHP расширение memcached
     */
    private function isMemcachedUse()
    {
        if($this->config['extension'] == 'memcached')
            return true;
    }
}

Но чтобы заставить его работать, нужно изменить все строки с запросами к БД. ВСЕ. Делать это долго и нудно.

https://github.com/grinderspro/memcached-cms-simplacms/blob/master/README.md

Изменено пользователем question
Ссылка на сообщение
Поделиться на другие сайты

Если кому интересно, вот модуль (/api/cache.php):

<?php
/**
 * SimplaCMS memcacheD
 *
 * Класс обертка memcached для удобного использования в SimplaCMS
 *
 * @copyright	Copyright (c) 2016 Grinderspro
 * @link		http://grinderspro.ru
 * @author		Grigoriy Miroschnichenko <grinderspro@gmail.com>
 */
require_once('Simpla.php');
class Cache extends Simpla
{
    /**
     * Конструктор класса
     */
    public function __construct()
    {
        $this->init();
    }
    /**
     * Будущий экземпляр memcache
     */
    public $mem;
    /**
     * Массив - конфигурация параметров
     *
     * @return array customized attribute labels
     */
    private $config = [
        'host' => '127.0.0.1',
        'port' => 11211,
        'extension' => 'memcached', // or memcache
        'lifeTimeCache' => 86400,
    ];
    /**
     * Флаг типа используемого расширение PHP
     *
     * True - memcache
     * False - memcached
     */
    private $isMemcached = false;
    /**
     * Инициализация
     */
    private function init()
    {
        $this->isMemcached = $this->isMemcachedUse();
        if (!extension_loaded($this->config['extension'])) {
            throw new Exception("Php extension {$this->config['extension']} not foun. Please install the memcache extension.");
        }
        $this->isMemcached ? $this->mem = new Memcached() : $this->mem = new Memcache();
        $this->mem->addServer($this->config['host'], $this->config['port']);
    }
    /**
     * Извлекает значение из кеша с указанным ключом.
     *
     * @param string $stringKey уникальный ключ
     */
    public function get($stringKey)
    {
        if($this->mem != null)
            $result = $this->mem->get($this->stingToHash($stringKey));
        if (!empty($result))
            return $result;
        else
            return false;
    }
    /**
     * Помещает знаение в кеш по ключу
     *
     * @param string $stringKey ключ
     * @param $value Резальтирующий набор (набор данных, которые необходимо положить в кеш)
     * @param $lifeCache время жизни кеша
     */
    public function set($stringKey, $value, $lifeCache = 86400)
    {
        if ($this->isMemcached) {
            $this->mem->set($this->stingToHash($stringKey), $value, $lifeCache);
        } else {
            $this->mem->set($this->stingToHash($stringKey), $value, 0, $lifeCache);
        }
    }
    /**
     * Удаляет значение из памяти по ключу
     *
     * @var string $stringKey attribute labels
     */
    public function del($stringKey)
    {
        $this->mem->delete($this->stingToHash($stringKey));
    }
    /**
     * Аннулирует все существующие записи в кеше
     *
     * @var integer $delay Период времени, по истечению которого произвести полную очистку кеша
     * @return true or false
     */
    public function clearall($delay = 0)
    {
        $this->mem->flush();
    }
    /**
     * Из обычной строки в md5 hash
     *
     * @var string $stringKey - Ключ
     */
    private function stingToHash($stringKey)
    {
        return md5('key'.$stringKey);
    }
    /**
     * Проверяет исходя из значений конфигурационного массива $this->config
     * используется ли PHP расширение memcached
     */
    private function isMemcachedUse()
    {
        if($this->config['extension'] == 'memcached')
            return true;
    }
}

Но как его заставить работать, мне непонятно.

 

https://github.com/grinderspro/memcached-cms-simplacms - исходник

Ссылка на сообщение
Поделиться на другие сайты

Читайте написанное мной выше: каждую конструкцию с запросом к MySQL надо переписывать. Это не сложно, но очень долго.

Ссылка на сообщение
Поделиться на другие сайты

Читайте написанное мной выше: каждую конструкцию с запросом к MySQL надо переписывать. Это не сложно, но очень долго.

 

Если б Вы вместо написания инструкции задумались хоть немного, а нет ли способа попроще, без "каждую конструкцию с запросом к MySQL надо переписывать", то наверняка быстро нашли бы решение полегче...

А то, что сейчас в инструкции - для новичка сойдет, а вообще за такое специалистов убивать надо - чистое вредительство...

Ссылка на сообщение
Поделиться на другие сайты

Если б Вы вместо написания инструкции задумались хоть немного, а нет ли способа попроще, без "каждую конструкцию с запросом к MySQL надо переписывать", то наверняка быстро нашли бы решение полегче...

А то, что сейчас в инструкции - для новичка сойдет, а вообще за такое специалистов убивать надо - чистое вредительство...

 

вариантов кеширования много. что значит "решение полегче"?

Ссылка на сообщение
Поделиться на другие сайты

Ну, например, вместо проверки в разных классах перенести это все в класс Database

 

логично. но вопросы остаются, к примеру:

- если взять api/Products/get_products() то в этом случае все if-ы все равно будут отрабатывать даже если кеш существует?

- или к примеру кешируем все бренды и запрос к одному бренду в этом случае это разные кеши?

- аналогичный вопрос по категориям, допустим есть 1000 категорий, что делать с ними, на каком этапе кешировать, ведь десериализация займет больше времени чем запрос к базе, как быть?))

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

 

или просто факт того что все запросы бездумно кешируются залог "простоты решения"? )) ...

Изменено пользователем DaVinci
Ссылка на сообщение
Поделиться на другие сайты

логично. но вопросы остаются, к примеру:

1. если взять api/Products/get_products() то в этом случае все if-ы все равно будут отрабатывать даже если кеш существует?

2. или к примеру кешируем все бренды и запрос к одному бренду в этом случае это разные кеши?

3. аналогичный вопрос по категориям, допустим есть 1000 категорий, что делать с ними, на каком этапе кешировать, ведь десериализация займет больше времени чем запрос к базе, как быть?))

4 помимо запросов к безе кешировать больше нечего для того что бы избежать лишних запросов к базе?

 

или просто факт того что все запросы бездумно кешируются залог "простоты решения"? )) ...

 

Эти вопросы все решаемые.

 

 

1. Очевидно, что будут. Если такое не нравится, конечно, можно переделывать на свой вкус...

2. Ответ очевиден - в предложенном варианте сделано так, что каждый элемент кеша привязан к своему SQL-запросу. Поэтому по запросу на все бренда,на бренд с ID=7,на бренд с ID=77 - будут три разных самостоятельных кеша. Опять-таки, кому не нравится, может переделать...

4. Тоже вроде бы очевидно. Если хотите избежать именно запросы к базе, то их и надо кешировать, а что ж еще-то? Конечно, теоретически можно и целые страницы сайта кешировать, но это больше подходит для поисковиков. Если мыслите более глубоко, поделились бы...

 

А вообще вопрос сложный, вариантов реализации великое множество. Один из  них - вдобавок к функции function query() создать  function queryCached(), и вызывать часть запросов новой функцией, часть  старой. Или можно в тексте запроса писать спец  значок  типа '! select * from __brands', наличие которого будет сигнализировать для query() указание для обработки с кешированием.  Думаю, подобная избирательность обязательно нужна - например, при работе админки кеширование вообще ни к чему - экономия малая, а неудобства могут быть... 

 

3. Тут конкретный вопрос вообще интересный - текущая работа с категориями в Simpla вообще крайне нерациональна как минимум по двум причинам...

Ссылка на сообщение
Поделиться на другие сайты

Эти вопросы все решаемые.

 

 

1. Очевидно, что будут. Если такое не нравится, конечно, можно переделывать на свой вкус...

2. Ответ очевиден - в предложенном варианте сделано так, что каждый элемент кеша привязан к своему SQL-запросу. Поэтому по запросу на все бренда,на бренд с ID=7,на бренд с ID=77 - будут три разных самостоятельных кеша. Опять-таки, кому не нравится, может переделать...

4. Тоже вроде бы очевидно. Если хотите избежать именно запросы к базе, то их и надо кешировать, а что ж еще-то? Конечно, теоретически можно и целые страницы сайта кешировать, но это больше подходит для поисковиков. Если мыслите более глубоко, поделились бы...

 

А вообще вопрос сложный, вариантов реализации великое множество. Один из  них - вдобавок к функции function query() создать  function queryCached(), и вызывать часть запросов новой функцией, часть  старой. Или можно в тексте запроса писать спец  значок  типа '! select * from __brands', наличие которого будет сигнализировать для query() указание для обработки с кешированием.  Думаю, подобная избирательность обязательно нужна - например, при работе админки кеширование вообще ни к чему - экономия малая, а неудобства могут быть... 

 

3. Тут конкретный вопрос вообще интересный - текущая работа с категориями в Simpla вообще крайне нерациональна как минимум по двум причинам...

 

все верно, вариантов кеширования много, в каждом конкретном случае необходим свой подход. потому кеширование относится к сервисам по работе с моделями и к репозиториям а не к сервису (api) Database, где кеширование просто результатов запросов приведет только к тому что все данные будут прилетать с диска через десериализацию, в случае если на борту стоит не ссд то результат будет спорным. еще не забываем про то что кеш в определенных случаях надо чистить и вешать зависимости, что в случае с кешированием результатов запросов которые формируются в Database может стать затруднительным занятием. если и внедрять кеширование то в итоге выйдет "каждую конструкцию с запросом к MySQL надо переписывать", не буквально конечно... потому ваша критика на данный счет немного избыточна))

Изменено пользователем DaVinci
Ссылка на сообщение
Поделиться на другие сайты

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

Ссылка на сообщение
Поделиться на другие сайты

Оффтопик.

Меня тут вообще мысль посетила во фронт-энде (index.php) брать каждый url с параметрами, делать его md5.

Кажется, это должно выглядеть так

$cacheurl = md5($_SERVER['REQUEST_URI']);

и сохранять на диск.

Нет, сначала проверять, есть ли такой файл на диске. Если есть, выдавать с диска. Очистка кеша - очистка папки. Всяко побыстрее тяжёлых запросов работать будет.

Надо только учесть:

корзину

отзыв

Только вопрос - как d index.php получить в переменную весь код страницы?

Изменено пользователем question
Ссылка на сообщение
Поделиться на другие сайты

Оффтопик.

Меня тут вообще мысль посетила во фронт-энде (index.php) брать каждый url с параметрами, делать его md5.

Кажется, это должно выглядеть так

$cacheurl == md5($_SERVER['REQUEST_URI']);

и сохранять на диск.

Нет, сначала проверять, есть ли такой файл на диске. Если есть, выдавать с диска. Очистка кеша - очистка папки. Всяко побыстрее тяжёлых запросов работать будет.

Надо только учесть:

корзину

отзыв

Только вопрос - как d index.php получить в переменную весь код страницы?

 

для чего, какого результата вы хотите достичь? если страница формируется за 0.1 или 0.6 или 0.3 разницы вы не почувствуете.

 

Надо смотреть индивидуально места которые нуждаются в кеширвании. к примеру каждый раз запрашивать количество товаров в категории - кешируйте на здоровье по хешу фильтра. какие либо рандомные запросы которые жрут много создайте таблицу с результатом и пусть крон наполняет переодически. отправьте в кеш результат дерева категорий, все бренды с ключами по url и id, напишите под них репозитории... и так далее... нет смысла кешировать ВСЕ - будет куча не состыковок которые возможно разрешить только зависимостями и событиями которые помимо всего прочего написать не так уж и легко но они в свою очередь тоже требуют запросы к базе.

 

опять же не стоит упускать json запросы которые могут существенно разгрузить

Изменено пользователем DaVinci
Ссылка на сообщение
Поделиться на другие сайты

Оффтопик.

Меня тут вообще мысль посетила во фронт-энде (index.php) брать каждый url с параметрами, делать его md5.

Кажется, это должно выглядеть так

$cacheurl = md5($_SERVER['REQUEST_URI']);

и сохранять на диск.

Нет, сначала проверять, есть ли такой файл на диске. Если есть, выдавать с диска. Очистка кеша - очистка папки. Всяко побыстрее тяжёлых запросов работать будет.

Надо только учесть:

корзину

отзыв

Только вопрос - как d index.php получить в переменную весь код страницы?

 

Иногда, глядя с крыльца на двор и на пруд, говорил он о том, как бы хорошо было, если бы вдруг от дома провести подземный ход или чрез пруд выстроить каменный мост, на котором бы были по обеим сторонам лавки, и чтобы в них сидели купцы и продавали разные мелкие товары, нужные для крестьян. При этом глаза его делались чрезвычайно сладкими и лицо принимало самое довольное выражение; впрочем, все эти прожекты так и оканчивались только одними словами.

 

Гоголь Н.В., "Мертвые души"

Изменено пользователем phukortsin
Ссылка на сообщение
Поделиться на другие сайты

Иногда, глядя с крыльца на двор и на пруд, говорил он о том, как бы хорошо было, если бы вдруг от дома провести подземный ход или чрез пруд выстроить каменный мост, на котором бы были по обеим сторонам лавки, и чтобы в них сидели купцы и продавали разные мелкие товары, нужные для крестьян. При этом глаза его делались чрезвычайно сладкими и лицо принимало самое довольное выражение; впрочем, все эти прожекты так и оканчивались только одними словами.

 

Гоголь Н.В., "Мертвые души"

Шикарно. Главное - в тему.

Отвлекусь немного. Всё индивидуально, но если страница статична (например, каталог товаров или товар), то в самом index.php в начале, прям второй строкой пишем

 

ob_start();

 

И в конце 

 

$cacheurl = md5($_SERVER['REQUEST_URI']);
$htmlcode = ob_get_contents();
$cachefile = fopen('cache0/'.$cacheurl, 'w') or die("-");
fwrite($cachefile,$htmlcode);
fclose($cachefile);

Ура! В папке cache0 через время будет копия всех страниц сайта. Остаётся лишь при запросе страницы найти её в созданной папке и вывести, а если нет - выполнить всё то, что должна выполнять simpla.

Загвоздка осталась лишь с комментариями. Надо при написании коммента удалять из кэша копию страницы.

Ссылка на сообщение
Поделиться на другие сайты

Это все здорово, конечно))

А что делать, если товар закончился?

Или был удален из админки?

С такими решениями - головняка в десятки раз больше, чем пользы от них...

Ссылка на сообщение
Поделиться на другие сайты

Удалять кеш.



Протестировал свой сайт. Загрузка генерируемого html-кода - около 60-80 мсек, загрузка из кеша - 30-35 мсек.

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



для чего, какого результата вы хотите достичь? если страница формируется за 0.1 или 0.6 или 0.3 разницы вы не почувствуете.

А поисковики (возможно) почувствуют.

Ссылка на сообщение
Поделиться на другие сайты

Удалять кеш.

 

Протестировал свой сайт. Загрузка генерируемого html-кода - около 60-80 мсек, загрузка из кеша - 30-35 мсек.

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

 

А поисковики (возможно) почувствуют.

 

нет, не почувствует 

Ссылка на сообщение
Поделиться на другие сайты

Всё индивидуально, но если страница статична (например, каталог товаров или товар)...

В том-то и дело, что на сайте интернет-магазина таких страниц ПРАКТИЧЕСКИ НЕТ!

 

Возможно, Вам будет интересно прочесть обсуждения подобного вопроса в теме

http://forum.simplacms.ru/topic/8113-last-modified/?p=61250

Ссылка на сообщение
Поделиться на другие сайты

Поскольку мой случай индивидуален и к memcached не имеет отношения, создал отдельную тему с половиной решения

http://forum.simplacms.ru/topic/13683-кеширование-половина-решения/

Ссылка на сообщение
Поделиться на другие сайты

Поскольку мой случай индивидуален и к memcached не имеет отношения, создал отдельную тему с половиной решения

http://forum.simplacms.ru/topic/13683-кеширование-половина-решения/

Как определили процент решения?
Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...