Как я могу хранить и запрашивать 50 миллионов простых сообщений Python? - PullRequest
2 голосов
/ 18 января 2011

Вопрос

Каждый dict имеет уникальное числовое поле id, но остальные переменные (хотя все текстовые или числовые значения). Было бы неплохо использовать некоторые простые функции запросов, например get where name contains 'abc' или where a < 123.

Какие у меня варианты?

Настройка

  • Python 2.6
  • 32-битный Ubuntu-сервер 256MB
  • одна машина
  • без свопа

пример dict:

{'id': 3823942, 'name': u'example', 'unknown_variable_key': u'foo'}

Примечания

не может использовать MongoDB: 32-битные процессы MongoDB ограничены до 2,5 ГБ данных
не могу использовать Redis, потому что ему нужен весь набор данных в ОЗУ

Ответы [ 5 ]

2 голосов
/ 18 января 2011

Вы можете попробовать использовать CouchDB.Это документно-ориентированная база данных.Есть примеры (например, здесь ) хранения миллионов и более документов.

Существует хорошее руководство для CouchDB.

Ваше поле числового идентификатораможет использоваться в качестве идентификатора документа.

Вы можете попробовать написать скрипт на python, который заполняет базу данных, используя массовые API (чтобы ускорить вставку этого количества объектов)

Представления могут использоваться для выполнения различных запросов.

[править]

Мне было интересно узнать об использовании памяти CouchDB и провел простой эксперимент.

Я вставил документы 5kk порциями по 50 тысяч документов в пустую базу данных.Это заняло около 15-20 минут на моем MacBook Code Duo.Во время вставки максимальное потребление памяти процессом CouchDB составляло 120 МБ при вставке 50 КБ документов в чанк и около 60 МБ при вставке 25 КБ.

Окончательный размер базы данных составляет около 1,2 ГБ.Потребление памяти в режиме простоя CounchDB составляет 40 МБ.Извлечение отдельных документов происходит мгновенно (с помощью веб-интерфейса Futon).

Я вставлял документы следующего формата (JSON, созданный с помощью Python):

'{"_id" : "%09d", "name" : "example", "field%d" : "hello"}' % 
    (num, random.randint(0, 100))

или

{"_id" : "005049980", "name" : "example", "field77" : "hello"}

_id используется в качестве ключа, и документы сортируются по этому ключу.

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

1 голос
/ 18 января 2011

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

маленькая таблица еще не получила большого внимания или использования, поэтому я был бы очень любопытенуслышать ваши отзывы / опыт работы с ним.

1 голос
/ 18 января 2011

Поскольку набор данных слишком велик для всей памяти, вы, скорее всего, ограничены решениями, использующими диск.Самый простой способ сохранить это сериализовать dict и сохранить как файлы, и есть несколько простых оптимизаций, которые вы можете сделать для индексации, чтобы вам не пришлось искать по всему набору данных в запросе.Если у вас есть доступ к сторонней базе данных (mysql или даже sqlite3), вы можете сохранить словари в таблице с столбцами id, key, value (чтобы каждый dict соответствовал нескольким строкам таблицы) и создать индекс по id и ключу.для запросов.

1 голос
/ 18 января 2011

Pytables может быть для вас вариант

0 голосов
/ 20 января 2011

Вы пробовали OrientDB ? Это быстрый NoSQL-движок для документов, поддерживающий SQL и транзакции. В 32-разрядных системах нет ограничений по пространству, даже если в 64-разрядных системах скорость выше.

Я только что попытался вставить 1 миллион проиндексированных документов JSON в новую базу данных OrientDB. Записи очень просты:

{'id': 0, 'name': 'Gipsy', 'type': 'Cat', 'race': 'European', 'country': 'Italy', 'price': 300.00}

Но с id и ценой, которые увеличиваются на 1 в каждом цикле. Это заняло 21 секунду на моем 3-летнем ноутбуке. Настройки динамической памяти 256 МБ.

Запрос:

ВЫБРАТЬ из ТЕСТА, где id = 30000

Заняло 0,01 секунды!

Код, использованный для вставки, взят из этого примера: http://code.google.com/p/orient/source/browse/trunk/tests/src/test/java/com/orientechnologies/orient/test/database/speed/DictionaryPutSpeedTest.java

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...