Как сделать резервную копию SimpleDB? - PullRequest
4 голосов
/ 01 июня 2011

Я разрабатываю приложение Facebook, которое использует SimpleDB для хранения своих данных, но я понял, что Amazon не предоставляет способ резервного копирования этих данных (по крайней мере, я знаю)

И SimpleDB работает медленно. Вы можете получить около 4 списков в секунду, каждый список из 100 записей. Не хороший способ сделать резервную копию тонны записей.

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

Так что я думаю об использовании потоков. Проблема в том, что если вы делаете выбор для всех ключей в домене, вам нужно дождаться значения next_token первой страницы, чтобы обработать вторую страницу и так далее.

Решением, о котором я думал, было создание нового атрибута, основанного на последних 2 цифрах идентификатора Facebook. Поэтому я бы начал поток с выбором для «00», другим для «01» и т. Д., Потенциально имея возможность запустить 100 потоков и делать резервные копии намного быстрее (по крайней мере, в теории). Соответствующим решением было бы разделить этот домен на 100 доменов (чтобы я мог создавать резервные копии каждого из них по отдельности), но это сломало бы некоторые варианты выбора, которые мне нужно сделать. Другое решение, возможно, более дружественное к PHP, - использовать задание cron для резервного копирования, скажем, 10000 записей и сохранить «next_token», затем следующее задание начинается с next_token и т. Д.

У кого-нибудь есть лучшее решение для этого? Если бы это было решение PHP, это было бы замечательно, но если оно включает в себя что-то другое, то его приветствуется в любом случае.

PS: до того как вы упомянули об этом, насколько я знаю, PHP все еще не безопасен для потоков. И я знаю, что если я не остановлю записи во время резервного копирования, будут проблемы с согласованностью, но я не слишком беспокоюсь об этом в данном конкретном случае.

Ответы [ 2 ]

1 голос
/ 27 июля 2011

Подход к созданию атрибута прокси-сегмента, безусловно, работает, исходя из моего опыта.

В качестве альтернативы, то, что мы сделали в прошлом, - это разбиение резервной копии на 2 этапа, чтобыполучить как можно больший потенциал для мультиобработки (хотя это в java и для записи в файл резервной копии, мы можем положиться на синхронизацию для обеспечения безопасности записи - не уверен, что сделка на стороне php).

По сути, у нас есть один поток, который выполняет выборку данных в домене, но вместо «SELECT * FROM ...», это просто «SELECT itemName FROM ...», чтобы получить ключи к записям, нуждающимся в поддержке.вверх.Затем они помещаются в очередь ключей элементов, которые пул потоков читает с помощью API getItem и записывает потокобезопасным способом в файл резервной копии.

Это дало нам лучшую пропускную способность в одном домене, чем вращение водин поток.

В конечном счете, с многочисленными доменами в нашей ночной резервной копии мы вернулись к выполнению резервного копирования каждого домена в одном потоке и модели типа «SELECT * FROM domain», главным образом потому, что у нас уже былпроисходит перегрузка потоков, и перегрузка потоков стала проблемой для процессора резервного копирования, но также из-за того, что программа резервного копирования стала опасно сложной.

0 голосов
/ 19 октября 2012

Я исследовал эту проблему по состоянию на октябрь 2012 года. Три основных вопроса, по-видимому, определяют выбор:

  1. Не существует «родного» способа обеспечить согласованный экспорт илиимпортировать с SimpleDB.Вы несете ответственность за понимание и управление последствиями этого для кода вашего приложения.
  2. Решение Amazon для резервного копирования не доступно, но множество сторонних компаний предлагают что-то в этом пространстве (обычно с «резервным копированием»).на S3 "в качестве опции).
  3. При некотором объеме данных вам необходимо рассмотреть многопоточный подход, который, опять же, имеет важные последствия в отношении: согласованности.

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

#simpledb2json.py

import boto
import simplejson as json

AWS_KEY = "YOUR_KEY"
AWS_SECRET = "YOUR_SECRET"

DOMAIN = "YOUR_DOMAIN"


def fetch_items(boto_dom, dom_name, offset=None, limit=300):
    offset_predicate = ""

    if offset:
        offset_predicate = " and itemName() > '" + offset + "'"

    query = "select * from " \
        + "`" + dom_name + "`" \
        + " where itemName() is not null" \
        + offset_predicate \
        + " order by itemName() asc limit " + str(limit)

    rs = boto_dom.select(query)

    # by default, boto does not include the simpledb 'key' or 'name' in the
    # dict, it is a separate property. so we add it:
    result = []
    for r in rs:
        r['_itemName'] = r.name
        result.append(r)

    return result


def _main():
    con = boto.connect_sdb(aws_access_key_id=AWS_KEY, aws_secret_access_key=AWS_SECRET)

    dom = con.get_domain(DOMAIN)

    all_items = []
    offset = None

    while True:
        items = fetch_items(dom, DOMAIN, offset=offset)

        if not items:
            break

        all_items += items

        offset = all_items[-1].name

    print json.dumps(all_items, sort_keys=True, indent=4)

if __name__ == "__main__":
    _main()
...