Чрезмерно малые операции с хранилищем данных Google App engine

#google-app-engine #google-cloud-datastore

#google-app-engine #google-облачное хранилище данных

Вопрос:

У меня возникли некоторые проблемы с хранилищем данных Google App engine. С тех пор, как была введена новая модель ценообразования, стоимость запуска моего приложения значительно возросла.

Причиной, по-видимому, являются «небольшие операции с хранилищем данных», на которые приходится более 20 миллионов операций в день!

У кого-нибудь была эта проблема, я не думаю, что я выполняю чрезмерное количество ключевых запросов, и у меня всего 5000 пользователей, с примерно 10-20 запросами в минуту.

Заранее спасибо!

Редактировать

Хорошо, получил некоторую статистику, это примерно через 3 часа. Вот что я вижу на своей панели мониторинга в разделе выставления счетов: Панель управления Appengine - выставление счетов

И вот некоторые статистические данные:

Статистика

Очевидно, что существует довольно много вызовов datastore.get. Я начинаю думать, что проблема в моем дизайне. Эти данные соответствуют учетным записям. У каждого пользователя есть учетная запись, но учетная запись может быть одного из двух типов, для этого я использую композицию. Таким образом, каждый объект учетной записи имеет ссылку на свой объект субаккаунта. В результате, когда я выполняю поиск ближайших пользователей, это включает в себя выборку учетных записей с помощью запроса, а затем выполнение get для каждой учетной записи, чтобы получить ее вспомогательную учетную запись. Главный запрос на картинке статистики — это вызов, который получает 100 учетных записей, а затем должен выполнить get для каждой из них. Я бы подумал, что это очень легкий запрос, но, думаю, нет. И меня все еще смущает количество небольших операций с хранилищем данных, записываемых на моей панели мониторинга.

Комментарии:

1. Из любопытства, каким был ваш типичный ежемесячный счет до и после?

2. Моя ежедневная норма составляла 2 доллара, и я никогда не достигал этого. Сейчас это 5 долларов, и я превышаю его каждый день. Я думаю, мне пришлось бы увеличить до 9 долларов в день.

3. Извините, я тоже должен был спросить об этом, но используете ли вы memcache вообще?

4. Нет, я действительно не заглядывал в memcache. Я бы подумал, что хранилище данных может обрабатывать текущий объем данных по гораздо более разумной цене. Тем не менее, я запускаю не сайт, а серверную часть приложения, игры, поэтому она довольно сложна в обработке.

5. «Главный запрос на картинке статистики — это вызов, который получает 100 учетных записей, а затем должен выполнить get для каждой из них». Вы должны извлекать все 100 ключей одним пакетом, а не выполнять отдельные операции. Смотрите здесь для объяснения шаблона. Кроме того, вам определенно следует хранить объекты, к которым часто обращаются, в memcache, чтобы сократить время поиска в хранилище данных.

Ответ №1:

Обязательно используйте appstats, как предлагает Дрю; независимо от того, какую библиотеку вы используете, она расскажет вам, какие операции выполняют ваши обработчики. Наиболее вероятными виновниками являются запросы только для ключей и операции подсчета.

Комментарии:

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

Ответ №2:

Я бы посоветовал использовать AppStats (Python / Java) для профилирования вашего трафика и определения, какой обработчик генерирует больше всего операций с хранилищем данных. Если вы разместите код здесь, мы потенциально сможем предложить оптимизации.

Комментарии:

1. Я знаю, куда направляется большая часть моего трафика, и я использую ‘Siena’, библиотеку Java, которая работает с GAE. Я пройдусь по своему коду и попытаюсь выделить фрагменты, которые могут оказаться полезными.

2. AppStats настроен, обновит мой исходный пост, когда у меня будет больше информации. Спасибо.

Ответ №3:

Не сканируйте свое хранилище данных, используйте get (ключ) или get_by_id (идентификатор) или get_by_key_name (ключевое имя) как можно чаще.

Ответ №4:

Много ли у вас свойств ReferenceProperty в ваших моделях? Доступ к ним вызовет db.get для каждого свойства, если вы не выполните предварительную выборку. Это вызвало бы 101 запрос db.get.

 class Foo(db.Model):
   user = db.ReferenceProperty(User)

foos = Foo.all().fetch(100)
for f in foos:
  print f.user.name  # this triggers db.get(parent=f, key=f.user)
  

Комментарии:

1. С помощью Java API, который я использую, мне нужно вручную получить каждое свойство, на которое ссылается другой объект. Сейчас пытаюсь выполнять пакетную выборку, чтобы посмотреть, даст ли это мне необходимый импульс.

2. Проверьте эту запись в блоге, которую я написал, часть предварительной выборки: bravenewmethod.wordpress.com/2011/03/23 /…