Використання Memcached: чи корисна практика оновлювати кеш при оновленні бази даних?


13

Це питання стосується кращих практик архітектури.

Наша сучасна архітектура

У мене клас PHP, який отримує доступ до MySQL для отримання інформації про користувачів. Давайте назвемо це User. Userдоступ до нього багато разів, тому ми реалізували шари кешування для зменшення навантаження.

Перший шар - це те, що ми називаємо кешем "на запит". Після отримання даних з MySQL ми зберігаємо їх у приватній власності User. Будь-які наступні запити для даних повертають властивість замість того, щоб повторно запитувати дані з MySQL.

Оскільки веб-запит живе і вмирає на основі запиту, цей кеш лише перешкоджає додатку отримувати доступ до MySQL більше одного разу в одному запиті.

Наш другий шар - Memcached. Коли приватна власність порожня, ми спочатку перевіряємо Memcached на дані. Якщо Memcached порожній, ми запитуємо дані MySQL, оновлюємо Memcached та оновлюємо приватну власність User.

Питання

Наш додаток - це гра, і іноді вкрай важливо, щоб деякі дані були якомога актуальнішими. Протягом приблизно п'яти хвилин запит на читання даних користувача може статися 10 або 11 разів; то може відбутися оновлення. Подальші запити на читання повинні бути оновлені, або механіки ігор не вдається.

Отже, що ми зробили, це реалізувати фрагмент коду, який виконується, коли відбувається оновлення бази даних. Цей код встановлює ключ у Memcached з оновленими даними, тому всі наступні запити до Memcached є актуальними.

Це оптимально? Чи є якісь занепокоєння щодо продуктивності чи інші "готчі", про які слід пам'ятати, намагаючись підтримувати такий "живий кеш", як це?


Що це стосується видалення та повторного додавання даних?
Майк Накіс

Уточнили заголовок питання.
Стівен

Чому б просто не закінчити термін кешування даних? Оновлення означає, що вам потрібно забезпечити збереження оновлення (так що, якщо нові дані потрібно буде оновити таким чином, вам доведеться продовжувати змінювати оновлення). Термін дії кешу означає, що все знову витягнуто з бази даних --- і будь-яке нове оновлення не потребує нових змін коду оновлення. Мінусом є те, що навантаження на базу даних може бути більшою.
Пітер К.

@ Peter Так, ми теж думали про це. Якщо ніяких інших проблем з нашим нинішнім підходом не виникне, ми будемо його дотримуватися. Інакше ми можемо піти з тим, що ви описали.
Стівен

1
@Stephen Підхід, який ви описуєте, називається "Записати через кеш", і є досить поширеним підходом.
Сріпаті Крішнан

Відповіді:


10

Моя рекомендація - переглянути профіль використання та свої вимоги до кешу.

Я не бачу жодної причини, чому б ви залишали несвіжі дані запам’ятовуються. Я думаю, ви обрали правильний підхід, тобто: оновіть БД.

У будь-якому випадку вам знадобиться обгортка для оновлення БД (що ви зробили). Ваш код для оновлення Користувача в БД і в оперативній пам'яті також повинен робити натиск на запам’ятоване, АБО закінчення терміну дії в пам’яті.

Наприклад, якщо ваші користувачі зазвичай оновлюють один раз на сеанс як частину виходу з системи, не має великого сенсу оновлення даних у кеш-пам'яті (наприклад, загальна оцінка високого балу) - вам слід вимкнути їх відразу.

Якщо вони збираються оновлювати дані (наприклад, поточний стан гри), а потім через 0,2 секунди у вас буде негайне звернення до сторінки PHP, яке запитає дані, ви хочете, щоб вони були свіжими в кеш-пам'яті.


3

Я б не пішов про це так, як ви окреслили. Що вам потрібно зробити, це вирішити, чи потрібні вам фактично повністю оновлені дані. Потім, якщо вам це потрібно, вирішіть, які частини даних потрібно постійно оновлювати, і відокремте їх від речей, які можна кешувати у вашій архітектурі.

Наприклад, ви, ймовірно, хочете оновити електронну адресу свого користувача, як тільки вони його змінять, тому ви не надсилатимете електронні листи на неправильну адресу, але навряд чи дата народження або прізвище користувача буде потрібно повністю сучасний, щоб забезпечити гідне користувацьке враження. (Примітка. Я не використовую приклад архітектури ігор, оскільки не знаю, в яку гру націлити її, і я думаю, що цю досить легко зрозуміти).

Таким чином у вас є два чіткі набори даних: коротко- та довгострокові кешовані дані. Ви, ймовірно, можете піти з тривалістю кешу на хвилину або близько того, що стосується короткострокових даних, просто щоб зняти навантаження на БД, але довгострокові дані можуть залишатися в кеші на тривалість ковзання на стільки, наскільки це б / в.

Тоді вам потрібно розібратися з оновленнями. Я спершу подивився на використання тригера БД, щоб просто видалити елементи з кешу, коли вони застаріли. Це змусить ваш бізнес-рівень запустити оновлення кешу при наступному запиті даних, звільнивши деякий простір у кеші, якщо дані не використовуються (наприклад, якщо користувач змінює свою адресу електронної пошти, то виходить негайно) . Якщо це спричинить проблеми з продуктивністю в інтерфейсі (тобто введете занадто велике відставання під час очікування оновлення кешу), ви можете подивитися на просто спровокування виклику кеша, як тільки вилучено елемент з кеша. Я також роздивився б оптимізацію часу зчитування БД для цього невеликого набору даних, щоб гарантувати, що будь-яке відставання, викликане оновленням кешу, буде мінімальним (це повинно бути простіше, оскільки вам потрібно лише завантажити дані, які вам справді потрібні).

Що я б не робив, ні за яких обставин, це додавати додатковий метод заповнення кешу, оскільки тоді вам потрібно буде підтримувати виклик (і гачки API тощо) у двох місцях.

Що стосується gotchas, головне, на що потрібно бути обережним, якщо ви пишете безпосередньо в кеш, - це синхронізація. Якщо багато потоків намагаються читати, коли ви робите мовчазне оновлення, у вас можуть виникнути серйозні проблеми з недійсними даними, що призведе до поваги, коли намагаються оновити дані в першу чергу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.