#python #database #nosql #mapreduce #riak
#python #База данных #nosql #mapreduce #riak
Вопрос:
Согласно документам Riak (с использованием привязок Python), get_keys() чрезвычайно дорогой и не подходит для производства. Мой вопрос в том, подходит ли очень простой запрос карты. Например, используя этап отображения только с функцией:
function(v) { return [v.key]; }
будет ли это работать лучше, чем get_keys()? почему Riak не поставляется с этой реализацией вместо текущей версии get_keys() ? Есть ли лучший способ перечислить ключи для корзины?
Комментарии:
1. Здравствуйте, вы можете сделать некоторые измерения производительности с
timeit
помощью module. Сравните два варианта и посмотрите, какой из них самый быстрый; тогда вы сможете узнать, сработали ли разработчики Riak лучше, чем ваше простое решение 🙂
Ответ №1:
get_keys()
Функция вызывается list_keys
в серверной части и считается дорогостоящей операцией, поскольку она выполняет полное сканирование пространства ключей. В зависимости от вашей серверной части Riak это также может включать полное сканирование данных, хранящихся на диске (на ум приходит InnoStore). Серверная часть хранилища по умолчанию (Bitcask) хранит все ваши ключи в памяти, поэтому производительность не должна быть такой большой проблемой.
Другая причина list_keys
, по которой считалось дорогостоящим, заключается в том, что раньше это была операция блокировки, поскольку она включала то, что разработчики Basho называют «сгибом» по всем ключам. list_keys
теперь используется снимок корзины (вместо чтения текущего пространства ключей), и это также упрощает операцию.
Это стало проще с обновлением до Riak 1.0. Если вы используете серверную часть LevelDB, вы можете включить вторичные индексы в корзине и использовать $key
индекс (автоматически предоставляемый Riak), чтобы получить список всех ключей в корзине.
Что касается того, почему Riak не поставляется с лучшей реализацией чего-то подобного: спросите, для чего предназначена функциональность. В СУБД получение всех первичных ключей таблицы требует полного сканирования таблицы. В Riak получение всех ключей из корзины требует сканирования всех данных в каждом узле, а затем отправки имен ключей обратно на исходный узел, объединения этих данных и последующей отправки их вызывающему клиенту. Из-за распределенного, неупорядоченного состояния Riak эта операция является дорогостоящей, независимо от того, как вы ее нарезаете. Как я изложил выше, есть способы сделать это лучше.
Ответ №2:
Если вы используете серверную часть eleveldb (которая реализована с помощью библиотеки LevelDB), ваши ключи хранятся в отсортированном порядке, поэтому вы можете сделать что-то вроде:
def get_bucket_keys(riak_client, bucket_name, start='0', stop='Z'):
for record_key in riak_client.index(bucket_name, '$key', start, stop).run():
yield record_key
for key in get_bucket_keys(riak.RiakClient(), 'mybucket'):
print key
С помощью eleveldb riak сканирует все узлы только для указанного диапазона. Итак, если вы заполняете свои корзины таким образом, чтобы вы могли управлять диапазонами клавиш, список ключей корзины может быть очень производительным.
Компромисс заключается в том, что вы не можете указать ОГРАНИЧЕНИЕ на количество ключей, обрабатываемых на каждом узле. Вот почему вам НУЖНО управлять ключами для наборов, в которых вам нужен список ключей.