Где хранить объекты общего кэша в Cloud Run?

Я создаю конвейер приема данных с помощью Cloud Run. My Cloud Run API вызывается каждый раз, когда файл помещается в корзину GCS через Pub Sub. Мне нужно загрузить некоторые метаданные, которые содержат текст для данных, которые я принимаю. Эти метаданные изменяются нечасто. Я, очевидно, не хочу перезагружать его в память при каждом выполнении. Каков мой лучший вариант? То, что я смог исследовать до сих пор, это:

Опция 1

Вы также можете кэшировать объекты в памяти, если их повторное создание при каждом запросе службы требует больших затрат. Перемещение этого из логики запроса в глобальную область действия приводит к повышению производительности. https://cloud.google.com/run/docs/tips#run_tips_global_scope-java

В примере, приведенном по этой ссылке, функция HeavyComputation вызывается только один раз при холодном запуске? Что делать, если мне нужно время от времени перезапускать эту функцию при обновлении метаданных. Я также нахожу следующую информацию тревожной, поскольку она, кажется, говорит о том, что нет никакой гарантии, что другие экземпляры будут повторно использовать объект или нет.

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

Вариант 2

Используйте что-то вроде Redis или Cloud Memory Store, которое обновляется облачной функцией каждый раз, когда происходят изменения. И все экземпляры облачного API извлекают метаданные из Redis. Будет ли это менее или более эффективным, чем вариант 1? Любые другие недостатки в этом?

Если есть другие лучшие способы сделать это, мне было бы очень интересно.

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


person AIK DO    schedule 23.12.2019    source источник


Ответы (2)


Относительно первого варианта (Вариант 1):

Функция heavyComputation() здесь будет вызываться только при холодном запуске, каждый раз создается новый экземпляр контейнера Cloud Run (когда максимально превышено количество запросов, которые можно отправить параллельно данному экземпляру контейнера, и поэтому создается новый экземпляр).

Чтобы решить второй вариант (Вариант 2):

На данный момент Cloud Run (полностью управляемый) не поддерживает бессерверный доступ к VPC, поэтому подключение к Cloud Memorystore невозможно. Отслеживайте следующий запрос функции, чтобы получать всю необходимую информацию и обновления от команды разработчиков Cloud Run, чтобы проверять, когда эта функция будет доступна.

Вы можете найти некоторые обходные пути в этом сообщении и в уже упомянутом запросе функции. В основном они состоят из:

  1. Использование кластера Google Kubernetes Engine с Cloud Run.
  2. Настройте экземпляр Redis на Compute Engine.
person Daniel Ocando    schedule 24.12.2019
comment
Разве MemoryStore не является еще одним сервисом, таким как BigQuery или GCS? Не могли бы вы объяснить, почему для Cloud Run требуется доступ к VPC без сервера для использования MemoryStore? - person AIK DO; 26.12.2019
comment
Кроме того, в этой теме куча людей говорит, что Cloud Run API общедоступен, но я не верю, что это правда. При развертывании API он спрашивает, хотим ли мы разрешить анонимный доступ или нет. Я что-то упускаю? - person AIK DO; 26.12.2019
comment
У Cloud Memorystore очень строгие требования к подключению, согласно которым экземпляры должны совместно использовать той же сети VPC, что и другие сервисы. Бессерверный доступ к VPC обеспечивает связь между бессерверными службами (например, Engine, Cloud Functions и вскоре Cloud Run) и сеть VPC в контексте Google Cloud Platform. - person Daniel Ocando; 26.12.2019
comment
Что касается Cloud Run API, вы можете выбрать между общедоступными службами или требовать аутентификации. Но это было связано с аутентификацией, то есть, кто может вызывать Cloud Запустить службу. То, на что они ссылаются, связано с подключением, а это означает, что, поскольку по умолчанию каждая служба имеет внешнюю конечную точку, они доступны для общедоступного Интернета через URL-адрес службы по умолчанию. Требуется, чтобы сервисы Cloud Run были доступны не в общедоступном Интернете, а по внутреннему IP-адресу в сети VPC. - person Daniel Ocando; 26.12.2019
comment
Являются ли атаки типа DoS единственной проблемой для общедоступных сервисов? Или есть другая забота? - person AIK DO; 27.12.2019
comment
Google Cloud Platform имеет множество встроенных функций безопасности (включая защиту от DDoS), и по умолчанию вы защищены от многих из этих атак. Проблема в большей степени ориентирована на бизнес, в средствах защиты частной информации вашей компании от доступа к общедоступному Интернету и защиты ваших серверных служб от общедоступных конечных точек. - person Daniel Ocando; 27.12.2019

Мы начнем с вашей первоначальной предпосылки: «Я, очевидно, не хочу перезагружать его в память при каждом выполнении». Для меня это не всегда верное утверждение. Если я внедряю технологию кэширования, то, как программист, я трачу время на то, чтобы сделать ее правильно, и ввожу возможности для ошибок и обслуживания. Если бы я сэкономил 100 мс на выполнение, сколько тысяч и тысяч выполнений потребуется, чтобы окупиться при этих затратах по сравнению с экономией за счет увеличения времени выполнения? Обычно я заранее использую самый простой подход и готов отслеживать операции в будущем и вносить улучшения только в случае необходимости.

Тем не менее, давайте предположим, что вы определили, что будете делать миллион новых запросов на создание файлов в секунду и хотите оптимизировать. Ключ к пониманию того, как лучше всего использовать Cloud Run, заключается в том, что он запускает целый контейнер, который может обрабатывать одновременные запросы. Я полагаю, что значение по умолчанию равно 80. Это означает, что если бы было создано 80 одновременных файлов, был бы создан только один экземпляр контейнера и было бы обработано 80 параллельных событий. Если вы программируете на Java, это будет означать 80 одновременных потоков внутри одной и той же JVM. Каждый поток будет иметь параллельную адресацию к общей глобальной переменной. Только если поступил 81-й запрос и ни один из предыдущих 80 еще не был выполнен, будет создан новый контейнер Cloud Run.

Это говорит мне о том, что моим первым «улучшением» будет заполнение данных кеша в моей JVM при первом использовании и сохранение их для последующего повторного использования. Когда вы заполняете данные кэша? Это будет ваш выбор дизайна. Вы можете заполнить все это заранее при первом запуске контейнера... это было бы разумно, если бы вы знали, что данные будут использоваться для каждого запроса. В качестве альтернативы, если у вас есть несколько кэшируемых значений, рассмотрите возможность создания карты, которая содержит ваши пары имя/значение, и имеет метод доступа, который возвращает кэшированное значение (если есть) или извлекает из медленного хранилища, кэширует и возвращает значение (если оно изначально не присутствовало). ).

person Kolban    schedule 23.12.2019
comment
Мои метаданные находятся в bigquery. Получать одну и ту же информацию (как я уже сказал, она нечасто менялась) при каждом вызове, чтобы выполнить возврат к BigQuery, будет довольно дорого. Представьте себе, что загружаются миллионы файлов, и в начале каждого вызова я обращаюсь к Bigquery, чтобы получить одну и ту же информацию без необходимости. Спасибо за ваше объяснение работы в облаке на уровне контейнера. Это помогло кое-что прояснить. Итак, вы говорите, что только когда при 81-м запросе этот второй контейнер раскручивается, он собирается повторно запустить эту глобальную переменную? - person AIK DO; 24.12.2019
comment
Есть ли способ заставить его перезапустить все экземпляры облачного запуска, если метаданные изменились в bigquery? - person AIK DO; 24.12.2019
comment
Ага... итак, у нас здесь две истории... одна - это стоимость запроса на использование метаданных, а вторая - стоимость извлечения при получении их один раз для каждого контейнера. Если мы предположим, что вам нужно выполнять запрос BigQuery каждый раз, когда происходит какое-либо изменение метаданных, то, если бы вы могли выполнить свой запрос и сохранить свои данные в виде объекта GCS, их можно было бы дешево и быстро получить в вашем контейнере. - person Kolban; 24.12.2019
comment
Re: Когда второй контейнер раскручивается. Второй контейнер запустится только в том случае, если будет обработано больше одновременных запросов, чем вы заявили. Если значение по умолчанию равно 80 одновременным запросам и ни разу их не было больше, то вы будете запускать один контейнер вечно. Однако, если у вас есть всплеск трафика и вы обнаружите, что самый новый запрос приведет к 81 одновременным запросам, тогда будет создан новый контейнер для выполнения ваших последних запросов. Контейнеры будут остановлены (до нуля) после настраиваемого периода простоя. - person Kolban; 24.12.2019
comment
Почему поиск gcs обязательно будет дешевле, чем bigquery, если мне приходится делать это неоднократно. одна вещь, которую я должен добавить, это то, что в моем коде я делаю именно то, что вы ранее предлагали, когда я загружаю метаданные, т. е. создаю объекты словаря, которые дают мне O (1) поиск при поиске информации. Это сделало мой код сверхбыстрым, и я сохраню его. но я хочу делать это как можно меньше. - person AIK DO; 24.12.2019
comment
Привет ... всегда есть несколько измерений головоломок, которые нужно решить ... мне было неясно, кэшируете ли вы решение для производительности или кэшируете для решения по стоимости (т.е. запрос BQ может стоить больше, чем хранилище GCS поиск). Поэтому нам нужно просить дешевле с точки зрения времени или стоимости, или того и другого. Когда вы сказали, что это будет дороже, я подумал о финансовых затратах. - person Kolban; 24.12.2019
comment
ААА понятно. Да, сейчас я говорю исключительно о производительности. Но хороший момент. - person AIK DO; 24.12.2019