Google Datastore очень медленный из PHP AppEngine

Я получаю доступ к Google Cloud Datastore из своего экземпляра PHP App Engine с помощью официального google-cloud-php.

Я постоянно вижу задержку более 0,35 секунды на запрос. Даже для простых запросов с менее чем 100 объектами в хранилище данных.

Мое веб-приложение должно выполнять около 4 последовательных запросов к хранилищу данных на запрос, что делает хранилище данных полностью непригодным для использования (постоянная задержка от 1,5 до 3 секунд на загрузку страницы)

Я что-то упускаю?


Вот как я подключаюсь к хранилищу данных:

        // Same issue even without 'authCache' (a memcached wrapper).
        $authCache = new DatastoreAuthCache();
        $datastore = new DatastoreClient([
            'projectId' => AppIdentityService::getApplicationId(),
            'authCache' => $authCache
        ]);
        Datastore::$ds = $datastore;

Вот два примера моих запросов:

    // Lookup by keys.
    $ds = Datastore::get();
    $queryResults = $ds->lookupBatch($keys);
    $rows = keyValue($queryResults, "found");

    // Query by fields.
    $query = $ds->query()
        ->kind(self::EntityName)
        ->filter('owner', '=', $a)
        ->filter('target', '=', $b)
        ->limit(1)
        ->keysOnly();

    $results = $ds->runQuery($query);
    foreach ($results as $entity) {
        return $entity;
    }

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

Вот что я уже пытался уменьшить задержку:

  • Добавлен обработчик authCache для кеширования токенов API хранилища данных (без влияния)

  • Подтвержденное хранилище данных и экземпляр движка приложения находятся в одном регионе.

  • Подтверждено, что index.yaml настроен правильно

  • Подтверждено, что задержка связана с вызовами хранилища данных, а не с бизнес-логикой

  • Другие серверные части базы данных работают нормально (сервер Cloud SQL возвращается через ‹0,1 секунды). Эмулятор локального хранилища данных также возвращается через ‹0,01 секунды.

Что я могу сделать, чтобы уменьшить задержку?


comment
На самом деле не могу ответить, следует ли ожидать задержку, но, возможно, одно из решений, чтобы сделать ее, по крайней мере, более быстрой, - это переместить код запроса на вызов AJAX. Таким образом, остальная часть вашей страницы может загружаться быстрее, и тогда вы просто будете ждать данных. Возможно, это просто решает проблему, но я подумал, что предлагаю это, если хотите.   -  person    schedule 17.03.2019
comment
У этого может быть много причин ... есть ли способ увидеть и проверить ваш проект вживую?   -  person Kerim Yagmurcu    schedule 17.03.2019
comment
Сервис - это серверная часть мобильного приложения, поэтому, к сожалению, я не думаю, что есть простой способ сделать это.   -  person N S    schedule 17.03.2019
comment
Я также попытался использовать параметр keyFilePath для загрузки учетных данных учетной записи службы вместо учетных данных приложения по умолчанию, и мои запросы по-прежнему занимают ~ 0,6 секунды каждый   -  person N S    schedule 17.03.2019


Ответы (2)


Я не уверен, что это можно считать ответом, но я постараюсь помочь вам отладить его с помощью драйвера стека.

Просмотрите свои журналы в облачной консоли - https://console.cloud.google.com/logs/viewer

Ищите медленного обработчика.

gae_log_message

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

Это будет выглядеть примерно так:

stack_driver_tracing

person afed    schedule 20.03.2019
comment
Спасибо, я не знал об этом! Я вижу около сотни записей /remote_socket.Connect .Receive и .Poll - это нормально? .Poll, по-видимому, является здесь проблемным методом, поскольку он вызывает большую часть задержки хранилища данных. Вот скриншот: prnt.sc/n1x19g - person N S; 23.03.2019
comment
Я недавно видел это в AppEngine при использовании cURL для вызовов REST API. какую среду выполнения PHP вы используете? Возможно, вам лучше перейти на Protobuf API - person Tom; 02.04.2019

Самым большим узким местом является установление соединения с хранилищем данных (это может занять до 200 мс, здесь помогает кеш аутентификации). К сожалению, это плохая новость для php, потому что мы не можем установить постоянное соединение. Клиенту хранилища данных необходимо повторно подключаться при каждом запросе.

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

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

Пакетные обновления, полученные службой cron, также могут помочь быстрее выпустить запрос. Уведомления могут быть отправлены в `веб-сокет или получены при последующих запросах.

Вы не упомянули об этом, поэтому неясно, используете ли вы gRPC, DatastoreClient будет использовать grpc по умолчанию, если модуль установлен, в противном случае он возвращается к REST, что значительно медленнее по сравнению.

Чтобы проверить, установлено ли у вас grpc:

php -m|grep grpc

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

person nickl-    schedule 23.03.2019