Изучение кэширования с помощью кода

Кэширование — это

техника, используемая для хранения результата вычислений, чтобы будущие запросы на результат могли быть обслужены путем возврата вычисленного результата вместо повторного завершения результата и возврата dededit


Adab работает в магазине электронной коммерции. Каждый раз, когда клиент запрашивает страницу продукта. Django-сервер Adab выполняет следующие шаги, чтобы вычислить HTML для отправки клиенту.

  1. Получает данные о продукте, данные о продавце продукта

данные о товаре, данные о продавце, отзывы о товаре из базы данных PostgreSQL.

  1. Получение данных о товарах, которые были куплены вместе с товаром, путем запроса к базе данных neo4j graph.
  2. Создать HTML, используя данные и шаблон продукта с помощью шаблонизатора Django.

В пик сезона магазин Адаба получает тысячи запросов в секунду.

Адаб заметил, что некоторые запросы задерживаются

и требуют больше времени на обработку, что вызвано вычислениями, необходимыми для создания HTML для продукта. Ответственность Адаба заключается в том, чтобы обслуживать своих клиентов как можно лучше, поскольку он получает от них оплату.

Адаб хочет уменьшить задержку, что он должен сделать?


Кэширование — это решение проблемы Адаба. Каждый раз, когда клиент запрашивает страницу продукта. Мы можем вычислить HTML для продукта, сохранить его в кэше и вернуть HTML.
При последующих запросах на продукт мы можем возвращать результаты из кэша.
кэша.

В случае изменения информации о товаре, отзывов о товаре, данных о продавце или о товаре, купленном вместе (это можно обнаружить, запустив задание cron с помощью celery в Python), данные о товаре изменяются, поэтому, чтобы предотвратить предоставление устаревших данных, мы можем просто удалить HTML товара из кэша. Это называется аннулированием кэша.

Кэширование — это эффективная техника для уменьшения задержки нашего бэкенда. При использовании кэширования вы должны избегать заблуждения, связанного с кэшированием большинства ответов вашего API.
Обычно веб-приложения следуют принципу Парето, то есть 20 процентов точек API запрашиваются 80 процентов времени.

Теперь adab может решить хранить страницу подробностей продавца и страницу заказа пользователя в кэше, потому что Adab считает, что это уменьшит задержку для этих конечных точек.

Конечно, это уменьшит задержку для этих конечных точек, но Адаб также должен знать, что ему нужно будет аннулировать кэш пользователя каждый раз, когда размещается новый заказ, кэш продавца нужно будет аннулировать каждый раз, когда происходит изменение в модели продавца или модели продукта. Ему придется написать код для синхронизации кэша и базы данных друг с другом.
Следует всегда стремиться к простоте как в жизни, так и в коде. Заказы пользователя и страница продавца могут создаваться по запросу клиента. Это упростит архитектуру Adab, так как ему не нужно будет писать код для синхронизации базы данных и кэша друг с другом.

Несколько примеров, когда кэширование является хорошим решением.

  • Страница товара на сайтах электронной коммерции.
  • Страница вопроса на сайте вопросов и ответов (например, StackOverflow).
  • Страница курса на сайте по продаже курсов.
  • Тема Reddit.

Как правило, большинство приложений рассчитаны на чтение, поэтому кэширование может использоваться в нескольких приложениях.

Давайте посмотрим, как можно реализовать кэширование на одном сервере.
На одном сервере кэш может быть реализован с помощью словаря python.

Кэш должен поддерживать операции get, set и delete.
Реализация на языке python

class Cache:
    data = {}

    def get(self, key):
        if key in self.data:
            return self.data[key]
        else:
            return None

    def set(self, key, value):
        self.data[key] = value

    def delete(self, key):
        if key in self.data:
            del self.data[key]
Вход в полноэкранный режим Выход из полноэкранного режима

Кэширование в многосерверной среде.
В многосерверной среде нам необходимо центральное место для хранения кэша, которое называется веб-сервером кэша.
Двумя веб-серверами кэша являются Redis и Memcache.

Redis также имеет встроенную персистентность, то есть он будет хранить кэш в памяти и на диске. Теперь в случае отключения электричества в центре обработки данных, когда Redis загрузит приложение снова, он заполнит кэш в памяти с диска.

Redis — интересная технология, поскольку она также поддерживает pub-sub, работает как брокер событий, инкремент счетчика, декремент счетчика. Я хочу, чтобы вы прочитали документацию по Redis и узнали о ней, так как это будет полезно для вас. Документация также содержит учебник, в котором Twitter построен с использованием только Redis.

Если вы читаете это в браузере, добавьте документацию по Redis в закладки.

Код для установки и запуска Redis в контейнере docker с помощью docker-compose выглядит следующим образом.

version: "3.8"
services:
  redis:
    image: redis:6.2.6-alpine
    ports:
      - 6379:6379
Вход в полноэкранный режим Выход из полноэкранного режима

Реализация на JavaScript

import { createClient } from "redis"

async function connect() {
  const client = createClient({
    url: "redis://localhost",
  })

  client.on("error", (err) => console.log("Redis Client Error", err))

  await client.connect()
  return client
}

async function main() {
  const client = await connect()

  await client.set("fruit", "guava")
  console.log(await client.get("fruit"))
  client.del("fruit")
}
Вход в полноэкранный режим Выход из полноэкранного режима

Всякий раз, когда вы подключаетесь к Redis, вы подключаетесь к нему по сети. Если предположить, что ваши серверы приложений и кэш-сервер находятся в одном центре обработки данных, что является обычным случаем, то задержка обычно составляет 0-9 мс.
Задержка запроса составляет от 200 до 400 мс из Дели в Мумбаи. 209 мс примерно равны 200 мс.

Центральное кэширование веб-сервера с помощью Redis — это решение, которое обычно используется инженерами. Избегайте заблуждений, связанных с оптимизацией для 9 мс с помощью самостоятельно разработанного сложного алгоритма ради простоты.

Теперь перейдем к окончательному решению проблемы Адаба:
Когда поступает запрос на страницу продукта.
Мы получим ее из кэша, если страница не существует в кэше, мы создадим ее и сохраним в кэше Redis, а затем вернем ответ.

Код Python

def get_product_page(product_id):
    key = f'product#{product_id}'
    result = cache.get(key)
    if result is None:
        page = create_page(product_id)
        cache.set(key, page)
        result = page
    return result
Вход в полноэкранный режим Выйти из полноэкранного режима

В приведенном выше коде мы расставили имена ID продукта, добавив к ним ‘product#’.
Эта техника разделения имен широко используется в базах данных NoSQL. С помощью этой техники в кэше можно хранить несколько моделей.
Например, если Адаб решит хранить ответ JSON для популярных товаров для каждой категории. Он может использовать namespacing для его хранения, ключ будет иметь формат

‘category#{category_name}#popular’.

Вопросы:
В) Напишите одно преимущество и один недостаток кэширования.
A) Преимущество:
Уменьшает задержку
Недостаток:
Дополнительный код для синхронизации базы данных и кэша друг с другом
друг с другом

В) Twitter, YouTube, StackOverflow, Reddit — это read-heavy или write-heavy?
О) Тяжелые для чтения

В) Назовите два веб-сервера кэширования?
A) Redis и Memcache

В) Большинство веб-приложений работают в режиме чтения или записи.
О) Тяжелые для чтения.

В) Какая техника используется в базе данных NoSQL для хранения нескольких моделей?
A) Расстановка имен

В) Напишите три случая использования кэширования.
A)

  • Страница товара в магазине электронной коммерции
  • Страница курса на сайте онлайн-образования
  • Страница вопроса на сайте вопросов и ответов.

В) Какие из следующих страниц являются плохими кандидатами для кэширования.
a. Заказы пользователей в формате JSON для магазина электронной коммерции.
b. Цена акции
c. Тема на Reddit
A) a, b

В) Напишите файл docker-compose для запуска Redis.
A)

version: "3.8"
services:
  redis:
    image: redis:6.2.6-alpine
    ports:
      - 6379:6379
Войти в полноэкранный режим Выйти из полноэкранного режима

В) Напишите код для подключения к Redis с помощью node JS.
Установите пару ключ-значение для ‘fruit’ и ‘guava’.
Теперь получите значение для ключа ‘fruit’.
A)

import { createClient } from "redis"

async function connect() {
  const client = createClient({
    url: "redis://localhost",
  })

  client.on("error", (err) => console.log("Redis Client Error", err))

  await client.connect()
  return client
}

async function main() {
  const client = await connect()

  await client.set("fruit", "guava")
  console.log(await client.get("fruit"))
}
Войти в полноэкранный режим Выход из полноэкранного режима

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *