Уведомления

Группа в Telegram: @pythonsu

#1 Июль 25, 2012 08:55:19

andreiru
От:
Зарегистрирован: 2010-11-06
Сообщения: 154
Репутация: +  0  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

Здравствуйте!

С Redis работаю недавно, есть список файлов:
/dir/dir2/file.txt
/dir/file2.txt
и т.п

Думаю хранить это так:
Два списка, файлы и каталоги:

dirs = ['/:root', 'dir:0', 'dir2:1'] #('имя_каталога:ид_каталога_выше')
files = [[2, 'file.txt']] #(ид_каталога, имя файла)

Подскажите такой подход правилен ?
P.S конечно кол-во запросов увеличиться при построение пути, но зато памяти меньше нужно



Отредактировано andreiru (Июль 25, 2012 08:56:44)

Офлайн

#2 Июль 25, 2012 12:01:55

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

А какого рода запросы?
И сколько файлов, ну хотя бы порядок количества.



Офлайн

#3 Июль 25, 2012 12:18:13

andreiru
От:
Зарегистрирован: 2010-11-06
Сообщения: 154
Репутация: +  0  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

Файлов 1 - 1.5 млн.
Нужно искать по имени и расширению файла.



Офлайн

#4 Июль 25, 2012 15:31:17

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

Тогда я не вижу смысла разделения названий директорий и имен файлов.
Для каждого полного пути, если позволяют ресурсы, вам нужно добавить сущности: имя файла и его расширение, которые использовать для поиска.

Плюс, учитывая ваше замечание о памяти, обязательно настроить Редис:
http://redis.io/topics/memory-optimization

Если использовать дополнительно Set, где имя множеств - расширение файлов, а набор - пути (или ссылки на них - в зависимости от наличия памяти), то поиск по расширению делается одной командой.
Если храним ссылки, то их можно организовать как Хеши, в которых хранится путь к файлу.



Офлайн

#5 Июль 25, 2012 15:41:33

andreiru
От:
Зарегистрирован: 2010-11-06
Сообщения: 154
Репутация: +  0  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

Хочу попробовать разобраться с разбиением:

class Host:
    self.name = 'test.ru'
    def addPath(self, path):
        #разбиваю. путь на каталоги
        dirs = ['/'] + [v for v in path.split('/') if v != '']
        dir_up = 'root'
        # список в котором храняться каталоги хоста
        paths_id = 'host:%s:paths' % self.name
        for dir in dirs:
            dir_key = '%s:%s' % (dir, dir_up)
            if r.sismember(paths_id, dir_key):
                # как здесь узнать index элемента dir_key ?
            else:
                dir_up = r.llen(paths_id)
                r.sadd(paths_id, dir_key)



Офлайн

#6 Июль 25, 2012 18:20:00

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

andreiru
# как здесь узнать index элемента dir_key ?
А зачем?
У вас множество, оно по-умолчанию содержит только уникальные значения.
Если элемент уже есть во множестве, то sadd вернет 0.



Офлайн

#7 Июль 25, 2012 18:44:14

andreiru
От:
Зарегистрирован: 2010-11-06
Сообщения: 154
Репутация: +  0  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

class Host:
    self.name = 'test.ru'
    def addPath(self, path):
        #разбиваю. путь на каталоги
        dirs = ['/'] + [v for v in path.split('/') if v != '']
        dir_up = 'root'
        for dir in dirs:
            r.sadd('host:%s:paths' % self.name, dir_key)
            # здесь нужно положить в dir_up индекс dir_key
            # dir_up = 
            # Может есть метод: r.index('host:%s:paths' % self.name, dir_key) который возвращает индекс элемента ?
            # я в документации не нашёл
        return dir_up



Отредактировано andreiru (Июль 25, 2012 18:58:18)

Офлайн

#8 Июль 25, 2012 19:54:20

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

Еще раз, зачем?
У множества нет индекса.
Но, допустим, он бы был. Что вы с ним делать собирались?

И по использованию множеств вопрос.
Вы решили использовать множество не так как я посоветовал - ваше дело.
Но зачем его использовать именно так как вы используете я не понял.
Зачем в одном множестве хранить список всех файлов одного хоста?



Отредактировано Lexander (Июль 25, 2012 19:57:53)

Офлайн

#9 Июль 26, 2012 06:34:38

andreiru
От:
Зарегистрирован: 2010-11-06
Сообщения: 154
Репутация: +  0  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

Зачем в одном множестве хранить список всех файлов одного хоста?
Я это в целях экономии памяти

Для каждого полного пути, если позволяют ресурсы, вам нужно добавить сущности: имя файла и его расширение, которые использовать для поиска.
что такое сущности ?

т.e будет список файлов

/dir/dir2/file.txt
/dir/file2.txt

и ещё два списка по которым ищем ?



Отредактировано andreiru (Июль 26, 2012 06:39:39)

Офлайн

#10 Июль 26, 2012 11:57:05

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Хранение списка файлов в Redis

andreiru
и ещё два списка по которым ищем ?
Да.
Это будет очень эффективно.
Естественно, при условии, что у вас есть свободная память.
Исходя из приведенного вами количества элементов, память есть.

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

О способе хранения данных. Пример.
1. Список путей файлов - list, после добавления пути в список мы получаем его индекс (ссылку).
2. Список расширений - set. Имя множества - расширение файла, а элементы множества - индексы (ссылки) из п.1.

Теперь чтобы получить список всех путей для искомого расширения нам достаточно выбрать множество по его имени и для каждого элемента множества с помощью LINDEX получить путь к файлу.

Чтобы реализовать поиск по имени файла, мы можем выбрать 2 пути.
1. Используем строки, где ключ - имя файла (подчеркиваю, только часть пути - имя, без расширения), значение - путь к файлу или индекс из списка (ссылка).
Теперь поиск по имени файла работает не только по полному имени, но и с помощью KEYS, используя все его возможности. Получение списка путей - аналогично примеру выше.
Из недостатков: т.к. возможны коллизии ключей, то нужно к ключу прибавлять уникальный суффикс или префикс. Например, код компьютера, сервера, хоста.
2. Тупо хранить в качестве ключа строки полный путь к файлу и поиск осуществлять через KEYS. При этом не важно, что будет хранится в самой строке, для поиска нам нужен ключ. Поиск можно делать не только по имени файл, но и по любой другой части пути. Это самый функциональный вариант.
Однако расход памяти тут будет наибольший из-за длины ключей. Плюс будет низкая скорость поиска.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version