• +1
    1. А я думал, что такой способ не используют в крупных проектах. Часто вижу комментарии, где это называют костылем.

    С вопросом я немного не так выразился. Как я понял в данном случае базы синхронизируются на прямую, как бы они это делали и в условиях расположения на одной стойке.

    А как вообще синхронизируются данные (базы, файлы) между дата центрами? Ведь, например, знать о определенном юзере (его аватарке, настройках и.т.д) порой нужно в обоих центрах. Да и запись в них тоже по идее может быть из любого места. Что будет при одновременной записи в двух местах.
    Эволюция архитектуры: от «самописных» сервисов к HandlerSocket
  • 0
    заменив его хорошо зарекомендовавшей себя “master-master” репликацией между площадками

    Меня интересуют два вопроса:
    1. как вы делаете «master-master» репликацию между mysql базами?
    2. как синхронизируются дынные между территориально удаленными серверами?

    Можно об этом рассказать или хотя бы дать источники. Сколько я этим не интересовался. Везде говорили, что «master-master» в mysql дает кашу в данных. А на территориально удаленных серверах есть задержка.

    Эволюция архитектуры: от «самописных» сервисов к HandlerSocket
  • 0
    Было бы очень удобно добавить следующие функции:
    • Настройка репликации. Например, не реплицировать определенный папки в дереве. К примеру папку кэша. Или файлы по маске. К примеру, svn/git.
    • Синхранизация с сервером. Единовременное скачивание с сервера всего дерева файлов на клиент по запросу пользователя. Т.е. репликация в обратную сторону с сохранением фильтров репликации. К примеру, программист ведет разработку с разных компов. Дома и с работы. Поработав на работе, он приходит домой, нажимает кнопку синхранизации и получает у себя на компе свежее дерево файлов с которым можно работать
    RealSync — односторонняя синхронизация исходников в реальном времени для веб-разработчиков
  • 0
    Статья как раз во время! Хотел потеснить облачный хостинг.
    Ловите виртуальный плюс в карму.

    Бесплатный облачный PHP-MySQL хостинг для небольшого сайта на основе Amazon AWS
  • 0
    Да. Обычно Varnish учат игнорировать куки.
    Например так.

    sub vcl_recv {
      unset req.http.cookie;
    }
    


    Или делают это более хитрее. Для примера можно посмотреть посмотреть конфиги Varnish, когда его ставят перед Drupal или Wordpress. В любом случае без модификации самого приложения не обойтись.
    Symfony2. Подводные камни кэширования
  • 0
    1. Varnish по-умолчанию не кэширует страницы при наличии куки.

    2. Кука создается всегда при старте сессии. Не стартовать сессию для не авторизованных пользователей в Symfony нельзя, пользуясь стандартным механизмом Security Component.

    3. Научить Varnish игнорировать конкретную куку можно, но как по ней различить авторизованного пользователя(кэшировать нельзя) и не авторизованного(кэшировать можно) я пока не придумал и не нашел.

    4. уникальная кука — имелось ввиду значение.
    Symfony2. Подводные камни кэширования
  • +2
    Правильно. И на уровне Symfony это работает. Но Varnish видя куку не авторизованного пользователя это дело не кэширует. Как различить в Varnish авторизованного и не авторизованного пользователя я пока не нашел.
    Symfony2. Подводные камни кэширования
  • +1
    Вы правы, переименовал.
    Symfony2. Подводные камни кэширования
  • +5
    Symfony очень удобный и производительный фреймворк. Даже метафреймворк. На его базе можно создавать множество различных приложений. В том числе и фреймворков. Например, Silex.

    Есть просто некоторые вещи, которые неудобно делать. А именно, проекты где контент меняется в зависимости от авторизации пользователя. Причем когда этого контента много. Как в случае с хабром. И то это проблема больше реализации кэша, чем самого Symfony. Ничто не мешает написать свою оболочку.
    Symfony2. Подводные камни кэширования
  • 0
    Конечно, можно. В моем случае хоть и не идентичные, но очень схожие.
    Там и там последние публикации с одинаковым набором данных: заголовок, автор, блог.
    Естественно это сравнение приблизительно!
    Symfony2. Подводные камни кэширования
  • 0
    А можно подробнее? Я не понял, что вы имеете ввиду.
    Symfony2. Подводные камни кэширования
  • +1
    http://dvjournal.ru/
    Мое хобби. Первый проект на Symfony2. Дизайн и программирование — моё. Еще и пишу статьи.
    Я веб-разработчик, дизайнер, etc…
  • +2
    Очень интересная ситуация!

    Из access.log
    87.250.254.242 - - [30/Nov/2010:23:59:56 +0300] GET /slovo/poizi/671.htm HTTP/1.1 "200" 4240 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/ "-"

    * This source code was highlighted with Source Code Highlighter.


    Из моего кэтчера пауков:
    Nov 30 23:59:56 symfony [err] [Yandex] Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots) [If-Modified-Since: Tue, 23 Nov 2010 02:59:34 GMT][<хост>/slovo/poizi/671.htm]

    * This source code was highlighted with Source Code Highlighter.


    Код кэтчера такой:
    $pattern = '/(google)|(yandex)|(scooter)|(stack)|(aport)|(lycos)|(fast)|(rambler)/msi';

        if(isset($_SERVER['HTTP_USER_AGENT']) && preg_match($pattern, $_SERVER['HTTP_USER_AGENT'], $out))
        {
          $bot = self::$se[strtolower($out[0])];
          $agent = $_SERVER['HTTP_USER_AGENT'];

          $message = '['.$bot.'] '.$agent.' [If-Modified-Since: '.(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : 'no').']['.$request->getUri().']';
          sfContext::getInstance()->getLogger()->err($message); 
        }


    * This source code was highlighted with Source Code Highlighter.


    Получается робот все спрашивает как надо!

    Заголовок Last-Modified, Symfony и ускорение поисковой индексации
  • +8
    Автор молодец. Написать за 2 недели сервер и клиент, да еще с учетом масштабирования. Плюс дизайн сделать (хоть не супер, но все же хоть что-то).
    Я как разработчик проникся уважением.
    Многопоточные сервера писать это вам не плюшки в магазине покупать.

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

    Flash-игра «Мафия» в условиях «В контакте»
  • +3
    пошла реклама конкурентов ))))
    Flash-игра «Мафия» в условиях «В контакте»
  • +2
    > $cacheManager->remove('@sf_cache_partial?module=index&action=_listingBlock&sf_cache_key=*');

    Лучше не использовать звездочки (*) при чистке кэша при условии использования memcache. Так как при удалении со звездочкой используется метод removePattern, который проходит по всем ключам из кэша и удаляет нужные по маске. Так вот хранятся эти все ключи там же в memcache в отдельной записи [prefix]_metadata c expire равной 0. Может случится ситуация, когда объем записи превысит лимит. ( у меня случилось к слову ) А дальше у сами додумайте ).

    Отключить сохранение ключей в одну запись можно параметром:

    storeCacheInfo: true

    В версия symfony < 1.2.9 эти ключи добавлялись даже без удаления дубликатов:
    protected function setCacheInfo($key)
     {
      $keys = $this->memcache->get($this->getOption('prefix').'_metadata');
      if (!is_array($keys))
      {
       $keys = array();
      }
      $keys[] = $this->getOption('prefix').$key;
      $this->memcache->set($this->getOption('prefix').'_metadata', $keys, 0);
     }


    * This source code was highlighted with Source Code Highlighter.


    Сейчас ситуация лучше, ключи удаляются:
    protected function setCacheInfo($key, $delete = false)
     {
      $keys = $this->memcache->get($this->getOption('prefix').'_metadata');
      if (!is_array($keys))
      {
       $keys = array();
      }

      if ($delete)
      {
        if (($k = array_search($this->getOption('prefix').$key, $keys)) !== false)
        {
         unset($keys[$k]);
        }
      }
      else
      {
       if (!in_array($this->getOption('prefix').$key, $keys))
       {
        $keys[] = $this->getOption('prefix').$key;
       }
      }

      $this->memcache->set($this->getOption('prefix').'_metadata', $keys, 0);
     }


    * This source code was highlighted with Source Code Highlighter.
    Кеширование в Symfony. Идеология HTML-кеширования. Components & partials
  • 0
    В каждый партиал или компонент можно передавать с параметрами sf_cache_key. В этом случае ключ не генерируется, генерируете его вы сами.

    Или вы можете переопределить обработчик генерации ключей. В settings.yml сразу после .settings определить параметр cache_namespace_callable.

    Например
    cache_namespace_callable: [«CacheGenerator», «generateCacheKey»]
    Кеширование в Symfony. Идеология HTML-кеширования. Components & partials
  • 0
    Я понял принцип о котором вы говорите. Обдумаю как его применить в узких местах проекта. Я думаю он не противоречит, а даже дополняет то, к чему я пришел. Спасибо.

    p.s. Вот только не знаю в знак благодарности минусовать вас или плюсовать :)
    Плагин sfPropelMemcachePlugin
  • +1
    слабовато разбираетесь в кэшировании

    Знаете, эта фраза поставила меня в тупик. Объясню почему — цикл моих статей не о том, в чем я слабо разбираюсь или не разбираюсь. Они, если вы посмотрите еще раз повнимательнее — о том, как я разобрался с насущными задачами

    Цель была поставлена при решении рабочей задачи, а спортивного вопроса — разбираюсь или нет — не стояло вообще.

    Общие фразы вашего комментария отнюдь не свидетельствуют о том, что вы разбираетесь в этом больше…

    Странно. Если разбираетесь — напишите как и в чем в отдельном посте. Понимаю, что клеить ярлык проще…

    Предложите решение лучше — с удовольствием почитаю и приму на вооружение!
    Плагин sfPropelMemcachePlugin
  • 0
    Написал не туда. Ответ.
    Плагин sfPropelMemcachePlugin
  • +2
    Изначально было так и реализовано, только без наблюдателя. В самой модели писался метод cleanCache, который и отвечал за чистку кэша view.

    Постараюсь объяснить на примере.
    Возьмем к примеру пользователя. У нас есть модель его самого, модель аватарки, картинок, профайла и т.д. и 10 разных блоков с этими данными в разных комбинациях. Пользователь сменил пол и мне надо сбросить во всех 10 блоках кэш, сменил город — в 8, аватарку — 5 и т.д. Добавили еще блок, бежим по всем классам, меняем метод cleanCache. Дизайн поменялся, опять меняем методы чистки кэша. К тому же на сайте не только юзер ;)

    Да можно сделать наблюдателя, попытать упростить все это дело. Но зачем?

    Понимаете, мы изменили подход. В шаблон приходят данные уже из кэша. Мне не надо думать о связях. О валидации. Модель все сделает за меня.
    Плагин sfPropelMemcachePlugin
  • +3
    С трудом могу представить где может сильно выйграть мемкеш, за счёт уменьшения объёма данных в несколько раз

    а мы и не говорим о сильном выиграше. Просто приятно когда объем кэша уменьшается с 400 мб до 100Мб.

    как могут добавить проблем сложные шаблоны — вполне представляю

    Согласен. Но в Symfony пока нет шаблонизатора. Все пишется в php. Некоторые партиалы/компоненты конечно приходится кэшировать. Тем не менее сопровождать проект стало легче. Ведь основной причиной перехода на кэширование модели была простота валидации данных.
    Плагин sfPropelMemcachePlugin
  • 0
    Предыдущий коммент отправился не вовремя ). Опишу подробнее.

    $oUser->save(); Обновит кэш вызовом метода (addInstanceToPool($this)).
    $oUser->delete(); Удалит из кэша объект (removeInstanceFromPool()).
    UserPeer::retrieveByPk(); Положит объект в кэш, если его там нет (getInstanceFromPool, addInstanceToPool())
    UserPeer::doDelete(); очистит весь кэш модели, если в него передадут объект Criteria (clearInstancePool()) или конкретный объект (removeInstanceFromPool()), если передадут PK.

    Таким образом, если мы будем менять данные в базе только через модель, за актуальность отвечает Propel, иначе — мы сами.
    Как я подружил «memcache» и Propel в Symfony
  • 0
    Каждый раз когда вызывается метод save у propel объекта, обновляется и кэш (addInstanceToPool($this)).

    Как я подружил «memcache» и Propel в Symfony
  • 0
    Точно. Спасибо за информацию. Обязательно попробую. Единственное, что огорчает, что это решение не из коробки (
    ORM – зло или Как я пытался кэшировать Propel в Symfony
  • 0
    1. У меня иное немного мнение на этот счет. Дело в том, что если использовать join'ов в Propel'e продолжая пример указанный в статье на 20 объектов фоток создастся 20 экземпляров объекта юзера, а не один на всех.
    2. Согласен, но ведь это скорее рекомендация, а не необходимость )
    3. Согласен.
    ORM – зло или Как я пытался кэшировать Propel в Symfony
  • 0
    >что при обновлении/создании объекта модели надо обновлять пул (и кэш) или он обновляется автоматически
    Обновлять пул не надо, т.к. при вызове метода save обновленный объект кладется в пул автоматически. Необходимо только переопределить 4 указанных в статье метода.

    >А в сторону Doctrine не смотрели?
    Нет не смотрел. Но там кажется эта ситуация решена.
    ORM – зло или Как я пытался кэшировать Propel в Symfony
  • –1
    Propel устанавливается плагинов в Symfony и обновляется непосредственно его разработчиками. Если мне необходимо переопределить генератор кода, то надо изменять плагин. А это значит я меняю код фреймворка.
    В документации по Symfony способа обойти эту ситуацию я не нашел. Если знаете, поделитесь ссылкой.

    ORM – зло или Как я пытался кэшировать Propel в Symfony