All streams
Search
Write a publication
Pull to refresh
151
0
Андрей Смирнов @smira

User

Send message
Я не понял последний абзац про людей.

Эти посты — о memcached, и действительно без него или подобного ему сделать описанный счетчик вряд ли удастся на нагруженном сайте. Когда цифры будут добираться, например, до 30000 человек поситетелей, нам нужно будет инкрементировать счетчик 100 раз в секунду (если считаем онлайнеров за 5 минут = 300 секунд). 100 запросов в секунду для БД является паразитной нагрузкой, т. к. она умеет многое, но ради фактически увеличение значения ключа выполняет очень много посторонней работы, лучше те же 100 запросов в секунду отдать под полезную для БД функциональность.
Memcached работает гораздо быстрее. Это не истина в последней инстанции, но кол-во запросов в секунду, которые способен выполнить MySQL на порядки ниже аналогичной цифры в memcached.
Я в следующем посте напишу простой и корректный способ на add/delete, больше ничего не нужно ;) Для реализации двоичного семафора
Попадает не фотка, как я понимаю, а информация о ней. Информация о фотографии — это 200 байт? 500? Килобайт? Не так ли страшно, что она закэшируется несколько раз? Тут всегда будет некоторый trade-off между бешеной оптимизированностью и чистотой кода.

Результаты поиска, скорее всего, кэшироваться вообще не должны (или только самые популярные запросы). А во всех остальных ситуациях поможет сброс кэша (о нём попозже).

То есть проблема есть, конечно, но с той или иной степенью достоверности её можно решить :)
Насколько я знаю, какой-то замечательной книги, где было бы всё описано, просто не существует. Но возьмем Ваш пример с хранимыми процедурами.

Пусть у меня есть класс StoredProcedure, и я вызываю хранимки, например, так:

$proc = new StoredProcecudure('get_photos');
$result = $proc->call($user->id);


Тогда я в StoredProcedure::call имею возможность всегда встроить кэширование впоследствие. Если буду делать что-то типа:

$con = ....
$result = $con->query("SELECT get_photos({$user->id})");


То вряд ли я встрою в такого рода код легко кэширование.

А кэшировать выборки — это не такое плохое решение. Кэшировать объекты тяжело в PHP, если мы про него говорим.

Кхм-кхм… Нескромно. Я попробовал «Андрей Смирнов»
Добавлю, что использование md5 и serialize — это не блажь, а невозможность для каждой выборки руками формировать ключ — выборок слишком много и слишком много разных у них параметров.
Для начала постройте логику без кэширования. Определите, как это работает. Кэширование — это оптимизация, ей — последняя очередь при разработке. Теперь посмотрите на логику. Спроектируйте её так, чтобы способы оптимизации — кэширование и т. п. — можно было воткнуть логику в тех точках, где это разумно (посмотрите, что можно в принципе кэшировать: контент, вывод и т. п.). Когда логика будет работать, разделять права доступа и т. п.: посмотрите, как часто дергается эта страница? какие запросы генерирует? чем отличается страница для разных пользователей? как и что лучше закэшировать? не меняя логику, добавьте кэширование в нужные точки. Проведите еще эксперименты, измените схему кэширования, и т. п.
Это очень спорный вопрос, что лучше кэшировать: выборку или вывод (HTML). С точки зрения глобальной эффективности — лучше всего HTML, отдавать его nginx с модулем memcached. Но это в идеале, если задача позволяет. Бывают проекты (например, соц. сети), где одна и та же страница может кардинально различаться в зависимости от того, кто её смотрит. Плюс еще может быть куча отличий в зависимости от ранга пользователя, чего-то еще. В такой ситуации оказывается выгоднее кэшировать выборки, а HTML формировать на лету.

Для новостного сайта, например, можно кэшировать HTML, вставляя на лету только нужные банеры.
Не спорю, просто хочу отметить:
1) На тему уникальности и прочего: habrahabr.ru/blogs/webdev/42972/#comment_1063460
2) Спорный момент, накладные расходны на обращение к memcached на несколько порядков больше вычисления md5 и serialize
3) Да, заглянув в memcached и взглянув на ключ 01234fdef345, я не скажу, что это за кэш. Согласен. Оно мне часто надо? Если очень надо, можно полное имя ключа записать в значение еще одним параметром.
4) С md5() работать не сложнее, просто клиент от имени вычислял бы md5 перед обращением. Какая разница?
5) Ключ становится длинным, потому что в тяжелом большом проекте выборка зависит от ооочень большого числа параметров. И там работает общий подход, каждый ключ строить руками — это можно сойти с ума.
Когда будет столько элементов в кэше, то я сразу же пойду сменю хэш ;)

Есть SHA-256, SHA-512 — там добавляется такое количество бит данных, что вероятность опять дико снизится.
Да, именно так, но вероятность этого 2-128. Это очень маленькое число :)

В теории есть, на практике больше вероятность получить изменения в ячейке памяти, вызванные космическими лучами ;) Или битый сектор на диске. То есть существует гораздо больше проблем, с которыми надо бороться ;)
Сорри, схожу с ума, то есть он запрещен, но ровно то и написано в исходном коменте.
Пробел (32) тоже запрещен :)
Вроде бы не забыл:
«На самом деле одному серверу ставится в соответствие 100-200 точек на оси (пропорционально его весу в пуле), что улучшает равномерность распределения ключей по серверам в случае изменения их конфигурации.»

Может, было незаметно
Обеспечить уникальность ключа (в строгом смысле) сложно. В предложенной схеме в теории возможны коллизии, когда md5() от двух разных параметров даст одинаковый ключ, хотя для практики это слишком маловероятно.

Однако уникальность обеспечить тяжело, длина ключа ограничена, не всегда в этих условиях мы можем построить уникальный ключ. Параметры выборки уникальны, md5 от них — не факт.

Здесь речь идёт об отображениях (функциях), которые сопоставляют выборки и их ключи кэширования. Одной выборке соответствует ровно один ключ, две разные выборки имеют два разных ключа (если забыть про вероятность коллизии в md5).
Совершенно согласен, добавлю, что сервер не знает ничего о кластере. Это сделано специально. Такой подход упрощает архитектуру сервера.
Будут лежать до истечения срока годности или будут вытеснены другими ключами, если памяти не будет хватать. Они накладных расходов в принципе не принесут, распределения размера ключей для slab-аллокатора изменить не должны.
Примечание: изменили расположение — изменили расположения с точки зрения клиента, то есть он за ним обратится на другой сервер, где такого ключа нет, сервера об этой перетасовке ничего не знают, поэтому для клиента переместившийся ключ == потеряный ключ.
Нет, тут есть один существенный момент. Ну пусть было 100 ключей, по 25 на каждом, пусть хэш каждого ключа соответствует его номеру. Функция распределения ключей: ключ % 4 + 1.

Тогда ключи 0, 4, 8,… лежат на 1-м сервере, 1, 5, 9,… — на 2-м, 2, 6, 10,… — на 3-м и 3, 7, 11,… — на 4-м.

Пусть 4-й сервер выходит из строя, теперь функция распределения ключей: ключ % 3 + 1.

И теперь ключи 3, 7, 11,… — их значения потеряны (т. к. лежали на упавшем сервере), это 25%.

Далее, берем ключ 6 — он лежал на 3-м сервере, теперь он лежит на 1-м, берем ключ 5 — раньше на 1-м, теперь на на 3-м сервере. Ну и т. д. Сколько ключей сохранили своё расположение?

Те, для которых k % 3 = k % 4. Сколько таких?

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity