Кеш, який живе в оперативній пам'яті
Майже п’ята частина зображень лічильника, які малює ця служба, вже нічого не змінює. Скрипт стеження за мишею з попереднього покоління перезавантажує картинку при кожному русі, і відколи ці запити перестали будь-що збільшувати, два поспіль дають ту саму картинку, байт у байт.
Очевидний кандидат на кеш. Цікавими були рішення, куди його покласти й на чому будувати ключ.
Не на диск
Це працює на Raspberry Pi, і диск тут — картка SD. Класти туди намальовані картинки означало б близько 70 МБ запису на день в обмін на виміряну ощадність у 1,6 хвилини процесорного часу на день.
Це поганий обмін. Картки SD помирають від запису, а купується похибка округлення на машині, яку процесор не обмежує. Тому кеш живе в /dev/shm, тобто в tmpfs, тобто в оперативній пам’яті. Виміряно там: 0,027 мс на читання, 0,036 мс на запис, 1,9 ГБ вільно.
Після перезавантаження все зникає. Для кеша це не втрата, а нормальний стан справ.
На тому самому Pi працює Redis. Його не взяли з причини, ніяк не пов’язаної з технікою: він належить іншому застосунку й захищений для нього паролем. Спільний примірник зв’язав би дві непов’язані служби так, що поганий день однієї ставав би поганим днем іншої.
Ключ містить числа
Звичайний ключ кеша — це тотожність плюс термін придатності, а термін придатності — це парі: за останні п’ять хвилин нічого важливого не змінилося. У лічильника те, що змінюється, і є саме тим, що показано.
Тому показані значення йдуть усередину ключа. Зміниться число — це інший ключ, і картинка малюється наново. Парі зникає замість того, щоб укладатися обережно. Кожне зараховане відвідування збільшує щонайменше загальний підсумок, отже жодне зараховане відвідування не може дістати застарілу картинку. Термін, що лишився, — лише верхня межа для значень, яких у ключі немає: тижневих, місячних і річних.
Що довелося перевірити заздалегідь
Кеш безпечний лише тоді, коли збережене є функцією його ключа. Це твердження про кожне оформлення, і його перевірили, а не взяли на віру:
- жодне оформлення не використовує
rand(),mt_rand(),shuffle()чиuniqid() - жодне оформлення не читає годинник точніше, ніж погодинно
- параметри стеження старого скрипта не читаються ніде в дереві
Останній пункт дав найгарніший провал усієї вправи. Поки ці параметри входили до ключа, кожен запит ніс трохи інші координати миші, отже кожен ключ був неповторним. Кеш пропрацював цілий день і записав 13 влучань. Він працював бездоганно і не робив нічого, а це найважче помітний різновид поломки.
А якщо тут щось відмовить — нечитний каталог, повний диск, зіпсований запис — картинка малюється звичайним чином. Кеш ніколи не має бути причиною того, що лічильник не з’явився.