Вставьте тысячи объектов в разумное время в BigTable - PullRequest
1 голос
/ 16 июня 2011

У меня возникают некоторые проблемы, когда я пытаюсь вставить 36k французских городов в BigTable. Я анализирую файл CSV и помещаю каждую строку в хранилище данных, используя следующий фрагмент кода:

import csv
from databaseModel import *
from google.appengine.ext.db import GqlQuery

def add_cities():
spamReader = csv.reader(open('datas/cities_utf8.txt', 'rb'), delimiter='\t', quotechar='|')
mylist = []
for i in spamReader:
    region = GqlQuery("SELECT __key__ FROM Region WHERE code=:1", i[2].decode("utf-8"))
    mylist.append(InseeCity(region=region.get(), name=i[11].decode("utf-8"), name_f=strip_accents(i[11].decode("utf-8")).lower()))
db.put(mylist)

Требуется около 5 минут (!!!), чтобы сделать это с локальным сервером разработки, и даже 10, когда они удаляются с помощью функции db.delete (). Когда я пробую онлайн, вызывая страницу test.py, содержащую add_cities (), истекает тайм-аут 30 секунд. Я из мира MySQL и считаю, что стыдно не добавлять 36 тыс. Сущностей менее чем за секунду. Я могу ошибаться в способе сделать это, поэтому я обращаюсь к вам:

  • Почему это так медленно?
  • Есть ли способ сделать это в разумные сроки?

Спасибо:)

Ответы [ 3 ]

2 голосов
/ 16 июня 2011

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

Основная причина, по которой это происходит так медленно, заключается в том, что вы делаете запрос (в виде 'Region') для каждой записи, которую выдобавлять.Это неизбежно существенно замедлит ход событий.Есть две вещи, которые вы можете сделать, чтобы ускорить процесс:

  • Используйте code из Region в качестве key_name, что позволяет вам быстрее получать данные из хранилища вместо запроса.Фактически, поскольку вам нужен только ключ региона для ссылочного свойства, в этом случае вам вообще не нужно извлекать регион.
  • Кэшируйте список регионов в памяти или вообще не сохраняйте его в хранилище данных.,По своей природе, я предполагаю, что регионы - это небольшой список и редко меняющийся, поэтому, возможно, нет необходимости сохранять его в хранилище данных.

Кроме того, вы должны использовать mapreduce framework при загрузке больших объемов данных, чтобы избежать тайм-аутов.Он также имеет встроенную поддержку для чтения CSV-файлов из BLOB-магазинов.

2 голосов
/ 16 июня 2011

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

0 голосов
/ 18 июня 2011

FWIW мы обрабатываем большие CSV в хранилище данных, используя mapreduce, с некоторой начальной обработкой / проверкой внутри задачи.Даже задачи имеют ограничение (10 минут) на данный момент, но это, вероятно, хорошо для вашего размера данных.

Убедитесь, что вы делаете вставки и т. Д.вы пакетируете как можно больше - не вставляете отдельные записи, и то же самое для поиска - get_by_keyname позволяет передавать массив ключей.(Я полагаю, что на данный момент db put имеет ограничение в 200 записей?)

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

Наконец, синхронизация всего, что есть в SDK, в значительной степени бессмысленна - думайте об этом как об отладчике больше, чем что-либо еще!

...