Скачать CV
Назад к бизнес-кейсам

Расписание

Планировщик, который запускал один job четыре раза

withoutOverlapping жил в Memcached. Вытеснение HTML снимало mutex. Четыре пересборки писали один ключ листинга.

Контейнер schedule каждую минуту делает php artisan schedule:run. catalog:rebuild стоял на everyMinute() с withoutOverlapping(). Job занимал четыре минуты на грязном множестве из нескольких тысяч id. Четыре процесса писали одни ключи Memcached. Redis catalog:dirty не пустел, потому что каждый запуск добавлял id, которые предыдущий ещё не дописал.

withoutOverlapping() кладёт lock в кэш по умолчанию. CACHE_STORE был Memcached. Slab листинга и mutex делили slab-класс. Когда каталог забивал кэш, ключ lock уходил. Следующая минута не видела mutex и стартовала снова.

Проблема была в mutex внутри хранилища, которое HTML выбрасывает нарочно. Четыре пересборки дрались за один ключ листинга. Грязное множество не сходило. Lock нужен рядом с Horizon, в Redis, с TTL длиннее самой медленной пересборки.

Четыре старта, один ключ листинга, грязное множество Redis, которое не сходит.
Четыре старта, один ключ листинга, грязное множество Redis, которое не сходит.

Где живёт lock

Lock планировщика переехал в Redis. SET schedule:rebuild NX EX 600. Horizon уже там. Вытеснение HTML в Memcached этот ключ не снимет. Job по-прежнему читает грязные id из множества Redis, собирает slab и пишет Memcached. Строитель один.

Mutex рядом с HTML-slab это не mutex. Mutex рядом с Horizon это mutex.
Mutex рядом с HTML-slab это не mutex. Mutex рядом с Horizon это mutex.
  • onOneServer() ходит в тот же Redis, поэтому две реплики schedule не стартуют вместе.
  • Timeout lock длиннее самой медленной пересборки, которую мерили.
  • Пропущенная минута нормальна. Двойная пересборка нет.

Грязное множество теперь сходит. Memcached видит одного писателя. CPU контейнера schedule между тиками снова простой. Баг был не в cron. Баг был в lock внутри хранилища, которое страницы выбрасывает нарочно.

Какой опыт из этого

withoutOverlapping() ровно настолько хорош, насколько хранилище за CACHE_STORE. Memcached это не сервис lock.

TTL mutex короче job это второй старт. EX 600 скучный и верный.

Минуту пропущу раньше, чем запущу две пересборки. Перекрытие дороже задержки.

Назад к бизнес-кейсам