MapReduce на примере MongoDB

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 17:56, 31 мая 2018.
MapReduce на примере MongoDB
Mapreduce-mongodb.jpg
Разработчики: MongoDB Inc., Google
Состояние разработки: Активное
Веб-сайт mongodb.org, google.com

MapReduce на примере MongoDB - это взаимосвязь NoSQL MongoDB c MapReduce. Более подробно об этих инструментах Вы можете узнать, перейдя по соответствующим ссылкам. В данной статье рассматривается лишь их применение на практике, но для ввода читателя в суть статьи приведено краткое описание.

  • MongoDB - кроссплатформенная документо-ориентированная система управления базами данных. Классифицированная как база данных NoSQL. Чаще применяется для работы с JSON файлами;
  • MapReduce - это подход параллельной обработки больших объемов сырых данных, например, результаты парсинга сайтов, логов веб запросов и т.п.

Основные особенности и плюсы

Так как, пример основан на MongoDB[1] и MapReduce[2], соответственно он принимает в себя их возможности и особенности.

MongoDB:

  • Специальные запросы - поиск по области, запросы по диапазону, поиск регулярного выражения;
  • Документо-ориентированность - хранение и работа осуществляется через файлы, что важно отметить, скорость работы напрямую зависит от того, все действия осуществляются через файлы;
  • Индексация - любое поле в документе MongoDB могут быть проиндексированы;
  • Файл хранения - MongoDB может быть использован в качестве файловой системы, пользуясь балансировки нагрузки и репликации данных содержит более нескольких машин для хранения файлов;
  • Существует множество драйверов для различных языков программирования.

MapReduce:

  • Производительность - эффективная работа с большим объемом данных(от 100 Гб);
  • Надежность - не требует высокой квалификации разработчика, в том числе его знаний и опыта по написанию многопоточного кода.

Недостатки

От MongoDB

  • Отсутствует понятие "изоляция". Любые данные, которые считываются одним клиентом, могут параллельно изменяться другим;
  • Требовательна к ресурсам - память и место на диске;
  • Нет понятия "транзакция". Атомарность гарантируется только на уровне целого документа, т.е. частичное обновление документа произойти не может.

От MapReduce

  • Однопоточность(использование только одного экземпляра JavaScript-кода), но следует отметить, что может-быть использовано множество таких экземпляров одновременно.

Установка и работа

Для работы примера используется

  • Microsoft Windows 10 - Операционная система, на которой будет происходить демонстрация примера;
  • mongodb-win32-x86_64-2008plus-ssl-3.6.3-signed - клиент для работы с MongoDB, скачанный с официального сайта;
  • Python 3.6 - язык программирования, на котором осуществляется демонстрация примера, т.е. работа с MongoDB;
  • Pycharm - интегрированная среда разработки для языка программирования Python;
  • Pymongo - библиотека для работы в Python c MongoDB;
  • JSON_util - библиотека для работы с JSON файлами в Python.

Для начала установим MongoDB

Шаг 1:

Для оптимальной работы лучше подготовить отдельную директорию для БД на первом уровне файловой системы Вашего диска.

Шаг 2:

В созданной Вами директории добавляем 2 папки:

  • data - директория для наших БД. В ней создаем папку db;
  • log - директория для хранения логов программы, а также файл mongo.log.

Результат после Шагов 1 и 2:

После выполнения действий выше, должно получиться так:

Результат после Шагов 1 и 2

Шаг 3:

Скачаем загрузочный файл с официального источника:

Официальный сайт MongoDB

Шаг 4:

Установим MongoDB. Для этого кликнем по установленному файлу, т.к. мы настроили директорию для MongoDB, выбираем "Сustom", а далее директорию, которую создавали ранее, выбираем для того, куда установиться программа.

Установочное окно MongoDB

Шаг 5:

Далее в окне, снимаем галочку "Install MongoDB Compass". Это необходимо во избежании ошибок при установке. При необходимости, ее можно установить после установки MongoDB.

Установочное окно MongoDB

Результат после Шагов 3, 4, 5:

Результатов Шагов 3,4,5

Шаг 6:

Осуществим настройку флагов, соответственно нужно перейти в папку bin Вашей директории MongoDB:

mongod --directoryperdb --dbpath C:\mongodb\data\db --logpath C:\mongodb\log\mongo.log --logappend --install
  • mongod --directoryperdb --dbpath C:\mongodb\data\db (указываем куда складывать БД);
  • --logpath C:\mongodb\log\mongo.log(настройка логов, с адресом куда записывать);
  • --logappend --install (объединение логов и установка).

Результат после Шага 6:

Настройка MongoDB

Шаг 7:

Проверяем работу MongoDB. Для этого необходимо запустить cmd от имени администратора, т.к. для работы службы необходимы права администратора, в ином случае, система ответит:"Отказано в доступе".

net start MongoDB

Дополнительный шаг:

Если последний шаг не произвел запуск MongoDB, вышла "Системная ошибка 2", Вам могут помочь следующие действия:

  • Переходим в папку data;
  • Создаем файл mongod.cfg;
  • Открываем его и заполняем.
systemLog:
    destination: file
    path: C:\mongodb\log\mongo.log
storage:
    dbPath: C:\mongodb\data\db

Пути Вам следует прописать самостоятельно, то есть к папке db и к файлу mongo.log, соответственно тому, как Вы настраивали директория для MongoDB.

Результат после Шагов 7, Дополнительный шаг:

Если в результате выполненных действий, у Вас все равно не запустился MongoDB, Вам может помочь:

  • Внимательно просмотрите пути к файлу mongo.log и папке db, исправьте, если они не соответствуют действительности;
  • Если Вы установили программу по умолчанию, Вам следует перенести папку с программой на более верхний уровень файловой системы диска и поменять пути к файлам, папкам.
Результат Шагов 7, Дополнительный шаг

Работа с MongoDB через драйвер pymongo

Запуск среды разработки

В примере используется среда Pycharm

Чтение "сырых данных"

MongoDB работает с файлами в JSON (JavaScript Object Notation). Есть файл формата json. Это "сырые" данные, которые содержат данные парсинга сайта с кулинарными рецептами. Его формат:

{"Курник": ["Мука пшеничная", "Мука", "Вода", "Грудка куриная", "Окорочок куриный", "Картофель", "Лук репчатый", "Соль", "Перец черный", "Желток яичный"], 
"Печенье с \"Орео\" и маршмеллоу": ["Печенье", "Сахар коричневый", "Масло сливочное", "Яйцо куриное", "Ванилин", "Пудинг", "Какао-порошок", "Разрыхлитель теста", "Соль", "Мука пшеничная", "Мука", "Маршмеллоу"],
"Сырные пампушки из кантона Юра": ["Мука пшеничная", "Мука", "Яйцо куриное", "Сыр твердый", "Вода", "Масло сливочное", "Перец красный жгучий", "Орех мускатный", "Соль"],
 "Макаронная запеканка": ["Ракушки", "Сыр голландский", "Сливки", "Сухари панировочные", "Панировка", "Орех мускатный", "Соль", "Масло растительное"], ...

Собственно, что мы хотим получить от нашего примера. В файле хранятся рецепты и ингредиенты. Мы хотим на выходе получить, сколько раз тот или иной ингредиент встречается в рецепте. У нас есть файл Soup.json с данными выше. Для начала считаем данные:

# Прочитаем файл json
    data = file_read()
# Функция для считывания json
def file_read():
    file = open('Soup.json', 'r')
    data = json_util.loads(file.read())
    file.close()
    return data

Подключение к MongoDB

    # Подключаемся к MongoDB
    connect = pymongo.MongoClient('localhost', 27017)
    # Т.к. бд еще нет, при обращение к ней создается автомат
    db = connect.book_of_receipt

Запишем данные в MongoDB

#Запушим данные на сервер
    result = db.receipts.insert_many([{'Food': receip, 'Ingredients': data[receip]} for receip in data])

Осуществим MapReduce

# Получаем ключ значения, с помощью emit, map
    map = Code('''function() {
                    this.Ingredients.forEach(function(z) {
                        emit(z,1);
                    });
                }                
                ''')

    # Подсчитываем количество встреч во всех рецептах
    reduce = Code('''function (key,values) {
                        var total = 0;
                        for(var i = 0; i < values.length; i++) {
                            total += values[i];
                        }
                        return total;
                    }
                    ''')

Запишем данные на сервер

    # Для записи данных также на сервер
    result = db.receipts.map_reduce(map, reduce, "results")

На выходе получаем:

    {'_id': 'Абрикос', 'value': 17.0}
    {'_id': 'Авокадо', 'value': 46.0}
    {'_id': 'Агар-агар', 'value': 15.0}
    {'_id': 'Аджика', 'value': 38.0}
    {'_id': 'Айва', 'value': 8.0}
    {'_id': 'Алкоголь', 'value': 5.0}
    {'_id': 'Алыча', 'value': 2.0}
    {'_id': 'Аммоний пищевой', 'value': 1.0}
    {'_id': 'Ананас', 'value': 50.0}
    ...

Видео пример

Вывод

В результате проделанной работы мы получили практические навыки в:

  • Установке, настройке MongoBD;
  • Работе c MongoDB через драйвер pymongo;
  • Осуществление MapReduce на "сырых" данных.

На примере, мы убедились, что отсутствие понятия "транзакция" в MongoDB мешает в тестирование, но в защиту этого недостатка можно сказать, что зачастую подсчет и выполнение первичного анализа данных выполняется единожды, поэтому применение MapReduce в рамках MongoDB является хорошим решением в определенном круге задач.

Источники

  1. "MongoDB". MongoDB for GIANT Ideas
  2. "MapReduce". MapReduce Tutorial'

Ссылки

  1. MongoDB [Электронный ресурс]: MongoDB Community Server / Дата обращения: 13.04.2018. — Режим доступа: https://www.mongodb.com/download-center?jmp=nav#community
  2. MongoDB [Электронный ресурс]: MongoDB Resources/ Дата обращения: 13.04.2018. — Режим доступа: https://www.mongodb.com/resource-center
  3. Habrahabr [Электронный ресурс]: Map-Reduce на примере MongoDB / Дата обращения: 12.04.2018. — Режим доступа: https://habrahabr.ru/post/184130/
  4. Python3 [Электронный ресурс]: Python3 Download / Дата обращения: 13.04.2018. — Режим доступа: https://www.python.org/downloads/
  5. PyMongo [Электронный ресурс]: PyMongo 3.6.1 Documentation / Дата обращения: 13.04.2018. — Режим доступа: https://api.mongodb.com/python/current/