За последние 24 часа нас посетили 20645 программистов и 1098 роботов. Сейчас ищут 414 программистов ...

Название ключа для кеша

Тема в разделе "PHP для профи", создана пользователем Awilum, 14 окт 2019.

  1. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    324
    Симпатии:
    25
    Адрес:
    Earth
    Доброе времени суток!

    Проводя оптимизацию кода по рекомендациям blackfire.io дошел до пункта "YAML parsing should be cached in production" и вот я решил значит в своей обвёртке над YAML::decode добавить кеширование для всего что обрабатывается Yaml парсером, а в качестве названия ключа использую хеш контента.

    Код (Text):
    1.  
    2. public function decode(string $input)
    3. {
    4.     $key = md5($input);
    5.  
    6.     if ($this->flextype['cache']->contains($key)) {
    7.         return $this->flextype['cache']->fetch($key);
    8.     } else {
    9.         $res = YamlParser::decode($input);
    10.         $this->flextype['cache']->save($key, $res);
    11.         return $res;
    12.     }
    13. }
    Тестирую уже который день подряд и не вижу проблем с текущими данными и с новыми тоже, вроде бы все работает отлично. Одинаковый контент хранится под одним ключом, а если разный или новый, то хранится он под новым ключем.

    Я не совсем уверен в том что можно ли использовать хеш контента в качестве названия ключа и не вылезет ли это проблемой в будущем ? или все же стоит использовать более осмысленное именование ключей - передавая их название отдельным параметром в метод public function decode ?
     
  2. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    @Awilum, честно говоря хеш для обеспечения уникальности кеша используется достаточно часто. Если боишься коллизий, то выбери один два параметра которые меняются чаще всех (имеют большое количество вариантов) и просто сделай их конкатенацию с общим хешем.
     
  3. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Раз биткоину хватает SHA-2, то и вам хватит. На самом деле, даже md5 будет достаточно.
     
  4. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    324
    Симпатии:
    25
    Адрес:
    Earth
    Наверное не совсем меня поняли. Я не про md5 хеширование. Я про то что правильно ли получать название это ключа на основе контента который сохраняем в кеш. Да коллизии будут но такие ли они опасны ? все равно же редактируем потом реальный контент а не из хеша, хмм... например будет так - две разные страницы сайта с одинаковым контентом будут храниться под одним названием ключа, так как контент у них одинаковый
     
  5. Valick

    Valick Активный пользователь

    С нами с:
    12 авг 2018
    Сообщения:
    1.911
    Симпатии:
    328
    Речь о том, что два разных контента могут храниться под одним ключом - в этом и есть коллизия. Но возможность такого случая крайне мала.
    я же написал, что так делают очень (очень, очень) часто.

    Другой момент, что много хорошего тоже плохо. И когда кеша очень много, то это плохо. Поэтому кешируют не всё подряд, а что-то "тяжёлое" и редко изменяемое. А так же необходимо унифицировать кеш (например добавить в него несколько больше информации, чем требуется в конкретном случае) и который легко можно модифицировать для частного случая, отбросив лишнюю инфу или изменив некоторые параметры.
     
  6. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    324
    Симпатии:
    25
    Адрес:
    Earth
  7. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Ну вообще это звучит странно. Как ты будешь извлекать кеш? Придётся сначала извлечь контент, чтобы получить хэш, чтобы извлечь кэш?
     
  8. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    324
    Симпатии:
    25
    Адрес:
    Earth
    Вот так я делал раньше:
    1. Загружаю контент YAML файла (название то мне известно его) в строковую переменную file_get_contents
    2. Передаю переменную с YAML контентом в decode() который переводит YAML в массив
    3. Отображаю контент массив который мне вернул decode()

    Сейчас так:
    1. Загружаю контент YAML файла (название то мне известно его) в строковую переменную file_get_contents
    2. Передаю переменную с YAML контентом в decode()
    2.1. Получаю ключ на основе контента, который был передан вот так $key = md5($input);
    2.2. Если ключ есть в Кеше, тогда берем уже сохранённый массив в Кеше иначе парнем YAML контент, сохраняем его с ключом $key = md5($input); и возвращаем массив.
    3. Отображаю контент массив который мне вернул decode()

    PHP:
    1. public function decode(string $input) {
    2.     $key = md5($input);
    3.  
    4.     if ($this->flextype['cache']->contains($key)) {
    5.         return $this->flextype['cache']->fetch($key);
    6.     } else {
    7.         $res = YamlParser::decode($input);
    8.         $this->flextype['cache']->save($key, $res);
    9.         return $res;
    10.     }
    11. }
    если не кешировать по ключу, который основан на контенте, тогда надо передавать осмысленное название ключа и собственно к Кешу тогда наверное обращаться на более высшем уровне по всему коду, там где вызывается decode()

    но вроде как операций с файловой системой во втором варианте больше выходит... но backfire показывает что благодаря тому что не приходится каждый раз прогонять данные через YAML парсер, то производительность выростает в разы
     
    #8 Awilum, 15 окт 2019
    Последнее редактирование: 15 окт 2019
  9. Awilum

    Awilum Активный пользователь

    С нами с:
    15 ноя 2009
    Сообщения:
    324
    Симпатии:
    25
    Адрес:
    Earth
  10. Poznakomlus

    Poznakomlus Активный пользователь

    С нами с:
    12 сен 2014
    Сообщения:
    96
    Симпатии:
    19
    Адрес:
    Киев
    Не стоит кидать такие заявления.
    Смотрим документацию
    2 ** 32 = 4294967296
    это очень маленькое число для перебора
    достаточно легко сгенерировать все варианты $input
     
  11. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.553
    Симпатии:
    631
    Вы перепутали шестнадцатиричные символы с битами. md5 - это 128 бит.
    Но вы правы в том, что алгоритм очень лёгкий для современных компьютеров. Это даже плюс, если речь идёт не о пароле.