Введення в графи та Neo4j

графи
введення

До графа треба звертатися «ваше сяйво»

Табличка – наше все

Програмісти автоматизують світ. Почавши з автоматизації підрахунку грошей, де табличні записи природні, програмісти почали заштовхувати в таблички все, чого їх допустили. І це працювало. В минулому столітті. І це добре т.к. з глибин вікової давності ми отримали SQL – мови запитів до табличці. SQL вистачає майже завжди - він простий, логічний і всі знають. А коли не вистачає, то його розширюють. І далі ми працюватимемо з розширеннями та діалектами SQL.

У реальному світі дещо складніше. У табличках представляти великі та складні залежності складно та не ефективно за ресурсами (дисковий простір, процесор, і головний ресурс – час). А які дані не є ідеальними для табличок? Може це зайві дані?

Важливий граф

У математиці є поняття граф - набір вершин (вузли) та зв'язків цих вершин (ребро).

Мінімальний граф – це дві вершини та одне ребро між ними. Наприклад, цим мінімальним графом ми можемо намалювати сімейну пару: М ---- Ж. Тобто граф – це природні зв'язки речей і ланцюжки цих зв'язків.

Наприклад, записати структуру папок на комп'ютері до таблички. Для рубістів штук 5 гемів є лише одне правильне рішення – ltree + індекси. Крім правильного, є ідеальне рішення: LDAP. А структуру організації у табличку? Теж можна, але погана витівка, LDAP і тут рятує. І те й те дерева – є корінь і гілки, найтовстіша гілка – стовбур :-)

Не бачив у житті жодного графа

Та навіть мій улюблений git це графік. Виконайте у будь-якому своєму репозиторії:

І ви побачите дерево змін.

Ще один граф – це родинні зв'язки у Зоряних Війнах (як випам'ятайте, там тільки Імператор був сиротою): https://nplus1.ru/news/2016/02/10/star-wars-graph.

А ще на графах інтернет тримається. Наприклад, алгоритм Дейкстри вирішує завдання якнайшвидший/найкоротший шлях знайти.

Коли ми простий граф ми можемо його намалювати в табличках.

Графи, до речі, бувають різні. Граф, в якому зв'язку спрямовані і не створюють петель називається . направлений ациклічний граф https://en.wikipedia.org/wiki/Directed_acyclic_graph. Цей тип графа важливий для розуміння логіки роботи Spark-додатків, також він допомагає формалізувати бізнес процеси і прискорювати їх.

Залежно в додатку теж граф, наприклад, ruby-erd може для рубі додатка намалювати.

Neo4j та прості запити

А якщо у нас тисячі вузлів? То теж можемо використати таблички, тільки втомимося. Ось тут на допомогу приходить спеціалізований інструмент – графові бази даних. Їх багато, але ми виберемо Neo4j - вона сама проста для початку і має прекрасний веб-інтерфейс з візуалізацією, а красива картинка іноді інформативніше тисячі слів.

Є графові "бази", що використовують табличне зберігання даних, але використовують графову абстракцію - ця порнографія працює тільки в специфічних умовах (у цих умовах платять добре, тому запам'ятовуємо cassandra + titan або Spark).

Потроху почнемо вивчати Neo4j з даними, доступними кожному.

Спочатку запустимо Neo4j, що дуже легко, як і все в Java світі:

  1. Качаєте архів neo4j-community-3.0.3 з офіційного сайту http://neo4j.com/
  2. Розпаковуєте tar-xzvf./neo4j-community-3.0.3-unix.tar.gz
  3. Запускаєте ./bin/neo4j start

А взагалі не треба. Зупиняйте: ./bin/neo4j stop . Зробимо сучасно та молодіжно.

А далі самеЦікаве, причина чому варто починати з Neo4j: відкрийте у браузері http://localhost:7474/. Все, ви - володар графової бази даних.

Інтерактивна консоль та візуалізація спростить старт. А ще ми відключили аутентифікацію --env=NEO4J_AUTH=none. Для наших експериментів вона не потрібна, а для бойових систем треба все закривати параноїдально. Хоча це і смішно - закривати і Docker:)

Також там є документація щодо можливостей системи та статистика щодо використовуваних ресурсів.

Створимо мінімальний граф.

У цій статті головний діалект мови SQL зветься "Кефір": https://neo4j.com/developer/cypher-query-language/

І подивимося на результат:

Граф у нас спрямований, навіть у наш божевільний вік чоловік спрямований до жінки. Цікаво, що напрямок при пошуку можна знехтувати:

A можна не зневажати:

Ще ми можемо вибрати найсильніші стосунки, чого розмінюватися на короткі інтрижки:

Нотатки по Кефіровським запитам для ігор на дозвіллі.

Створюємо ноди, якщо ні:

Створюємо відносини, якщо їх немає, і якщо їх немає:

Поновлюємо вагу відносин, якщо вони є:

Дивимося в Neo4j лише сотню найсильніших відносин:

Шукаємо вершини з більш ніж 2 зв'язками:

Ну і якщо захочемо видалити:

Все класно, все працює, просто. Але користі жодної.

Пишемо програми з Neo4j, Spark та даними Твіттера

Потрібно залити інші дані. І спливає питання про те, як програма взагалі може спілкуватися з Neo4j?

Є підтримка формату для хіпстерів HTTP API з JSON, у ньому є навіть завантаження даних пачками. Тож із цього боку все правильно, але дарма.

Наступний варіант: протокол Bolt. Bolt бінарний, шифрований та винайдений спеціально для Neo4j.

Кожен додаток має придумати свій протокол, бо протоколів не вистачає.

Є прогноз, що Spark Streaming через 5 років буде не актуальним, але зараз за нього платять. І він ще й не стрімінг жодного разу :)

Насамперед завантажуємо вихідники Spark на свою локальну машинку.

Якщо це ваше перше знайомство з твіттером з цього боку, то ключики і токени брати тут https://apps.twitter.com. Після модифікації прикладу може бути так:

Зверніть увагу – neo4j-spark-connector нам зараз не потрібний, замість нього ми візьмемо neo4j-java-driver, який відповідає тільки за зв'язок java-додатку та Neo4j без вивантажень і завантажень у природні формати RDD або GraphFrame. Але слідом. статті вони нам знадобляться для справжньої роботи носяча горда назва Big Data інженер.

Компілюємо та ставимо в локальний Maven репозиторій бібліотеку neo4j-java-driver:

Кладемо наш код у src/main/scala/org/apache/spark/examples/streaming/Twitter2neo4j.scala . Перебуваючи в папці examples, додаємо в ./pom.xml :

Далі компілюємо приклади разом із нашим: викликайте mvn -Phadoop-2.6 -Dhadoop.version=2.6.0 -DskipTests clean package .

До речі, на моєму курсі насамперед вчимося maven, gradle та sbt. Це є основою основ. Найважливіше тільки bash.

У нас виходить jar файлик з яким далі працюватимемо. Замість компіляції Spark знову ж таки використовуватимемо модний Docker.

Зверніть увагу на версію Spark – 1.6.1. Важливо щоб ваш пакет і Spark були однією версією, а то Spark так швидко розвивається, що іноді навіть занадто швидко.

Пам'ятаємо про безпеку. І ще один цікавий момент за Docker - образ для нас зібрав незрозуміло хто, а докер працює від рута (хіпстери писали, що з них взяти). Теоретично, це величезна дірка в безпеці. Ясміливо виконую дані дії - в останній Fedora з включеним selinux, що захищає дірявий докер. А користувачів убунтів не шкода. До речі, супер крута та модна версія докера називається chroot.

Запустимо контейнер (коробочку, цебро), експортуючи поточну папку в /shared c правом лише читання(ro) і перемаркуючи selinux контекст в svirt_sandbox_file_t.

Контекст SELinux для пісочниці залишиться після зупинки контейнера. Також експортуємо нами скомпільовану бібліотеку для neo4j-java-driver.

А ось був би у нас свій центральний репозиторій, наприклад, Nexus – було б простіше.

Для цього викликаємо docker ps grep -i neo4j awk '' і дивимося id контейнера.

Ось ми опинились у контейнері. У нас є хадуп та спарк. Але хадуп ми чіпати не будемо - він нам не заважає, а Spark запустимо так, щоб він виконувався локально(-master local[4]):

Чекаємо на хвилини хоча б 10 і дивимося результат. Але що більше даних зберемо, то цікавіше.

neo4j

Якщо хочете красивіше, динамічніше і може навіть у реальному часі, то на mkdev є курс Катерини Шпак. Там навчають d3.js та іншим хитрощам гарного фронтенду. Взагалі в Big Data половина справи - це презентувати ваші досягнення середньостатистичного менеджера, у якого хоч і класична освіта, але без картинки не зрозуміє.

У цьому прикладі є один важливий момент – не використовується суперсила Spark. Адже в Spark ми можемо побудувати одразу готовий граф, агрегувати всі повідомлення і лише потім заливати в Neo4j. Цим можна значно підвищити кількість інформації, що переробляється системою. Але кого це хвилює у навчальному прикладі. Та навіть насправді це мало кого хвилює :)

Висновки та прогнози на наступну частину

Так ось, використовуючи великий масив даних зрізних джерел можна користувача впізнавати і за непрямими доказами. Так що той факт, що у мене параною зовсім не скасовує стеження за кожним з нас. І приємніше бути ще й тим, хто стежить, аніж тим, за ким стежать. І графи тут дуже допомагають, про що поговоримо у наступній частині. До речі - заразом подивимося рішення, коли Neo4j не вистачає, адже за всіх своїх переваг Neo4j не масштабується. Автори Neo4j із цим не згодні, але хто їм вірить.

До речі особливість всіх nosql рішень - база будується виходячи з того що і як ви будете вимагати. Коли кричать, що щось schemaless - означає або брешуть, або неможливо працювати :)

Додаткове читання

Ми розповідаємо, як стати найкращим розробником, як підтримувати та ефективно застосовувати свої навички. Інформація про вакансії та акції ексклюзивна для більш ніж 8000 передплатників. Приєднуйся!

  • mkdev
  • Ментори
  • Спеціалізації
  • Статті
  • Про проект
  • Що таке менторство
  • Як проходить навчання
  • Ціни
  • FAQ
  • Impressum
  • Обліковий запис
  • Записатись
  • Соц мережі