Понимание кэширования веб-ресурсов: на стороне сервера

Понимание кэширования веб-ресурсов: на стороне сервера

8 декабря 2022 г.

Тема кэширования веб-ресурсов так же стара, как и сама Всемирная паутина. Тем не менее, я хотел бы предложить как можно более исчерпывающий каталог того, как можно повысить производительность с помощью кэширования. Кэширование веб-ресурсов может происходить в двух разных местах: на стороне клиента — в браузере и на стороне сервера. В моем предыдущем сообщении я объяснил первое; этот пост посвящен последнему.

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

За прошедшие годы появилось несколько специализированных решений для кэширования ресурсов на стороне сервера: Memcached, Varnish, Squid и т. д. Другие решения менее ориентированы на кэширование веб-ресурсов и более универсальны, например,, Redis или Hazelcast .

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

Чтобы продолжить пример с прошлой недели, я буду использовать Apache APISIX для демонстрации кэширования на стороне сервера. APISIX использует подключаемый модуль proxy-cache для кэширования. К сожалению, на данный момент APISIX не интегрируется ни с одним сторонним решением для кэширования. Он предлагает два варианта: на основе памяти и на диске.

В общем, первое быстрее, но память дорогая, а второе медленнее, но дисковое хранилище дешево. Однако в OpenResty вариант с диском может быть быстрее из-за того, как LuaJIT обрабатывает память. Вероятно, вам следует начать с диска, и если он недостаточно быстр, смонтируйте /dev/shm.

Вот мои новые маршруты:

routes:
  - uri: /cache
    upstream_id: 1
    plugins:
      proxy-rewrite:
        regex_uri: ["/cache(.*)", "/$1"]
      proxy-cache: ~

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

В конфигурации proxy-cache по умолчанию используется дисковая конфигурация:

  proxy_cache:                      # Proxy Caching configuration
    cache_ttl: 10s                  # The default caching time in disk if the upstream does not specify the cache time
    zones:                          # The parameters of a cache
      - name: disk_cache_one        # The name of the cache, administrator can specify
                                    # which cache to use by name in the admin api (disk|memory)
        memory_size: 50m            # The size of shared memory, it's used to store the cache index for
                                    # disk strategy, store cache content for memory strategy (disk|memory)
        disk_size: 1G               # The size of disk, it's used to store the cache data (disk)
        disk_path: /tmp/disk_cache_one  # The path to store the cache data (disk)
        cache_levels: 1:2           # The hierarchy levels of a cache (disk)
      - name: memory_cache
        memory_size: 50m

Мы можем протестировать настройку с помощью curl:

curl -v localhost:9080/cache

Ответ интересный:

< HTTP/1.1 200 OK
< Content-Type: text/html; charset=utf-8
< Content-Length: 147
< Connection: keep-alive
< Date: Tue, 29 Nov 2022 13:17:00 GMT
< Last-Modified: Wed, 23 Nov 2022 13:58:55 GMT
< ETag: "637e271f-93"
< Server: APISIX/3.0.0
< Apisix-Cache-Status: MISS                      #1
< Accept-Ranges: bytes
  1. Поскольку кеш пуст, в APISIX произошла ошибка кеша. Следовательно, ответ исходит от восходящего потока.

Если мы снова curl до истечения срока действия кеша по умолчанию (300 секунд), ответ будет из кеша:

< HTTP/1.1 200 OK
...
< Apisix-Cache-Status: HIT

По истечении срока действия ответ исходит от восходящего потока, но заголовок является явным:

< HTTP/1.1 200 OK
...
< Apisix-Cache-Status: EXPIRED

Обратите внимание, что мы можем явно очистить весь кеш, используя собственный HTTP-метод PURGE:

curl localhost:9080/cache -X PURGE

После очистки кеша описанный выше цикл начинается заново.

Обратите внимание, что также можно обойти кеш, например,, в целях тестирования. Мы можем соответствующим образом настроить плагин:

routes:
  - uri: /cache*
    upstream_id: 1
      proxy-cache:
        cache_bypass: ["$arg_bypass"]       #1
  1. Обойти кеш, если вы отправляете параметр запроса bypass со значением, отличным от 0

curl -v localhost:9080/cache?bypass=please

Он обслуживает ресурс из восходящего потока независимо от состояния кеша:

< HTTP/1.1 200 OK
...
< Apisix-Cache-Status: BYPASS

Дополнительные сведения обо всех доступных параметрах конфигурации см. в подключаемом модуле proxy-cache.

Заключение

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

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

Исходный код доступен на GitHub.

Дальше:


Первоначально опубликовано на сайте A Java Geek 4 декабряго. , 2022 г.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE