З чого почати вивчати BigData

Привіт народ. Вирішив я з мавпи перетворитися на людину. Давно вирішив, насправді, але не розумів як мені вивчати алгоритми та структури даних, щоб було прям цікаво до жаху. Ну, не потрібні мені вони у повсякденному житті, виходить, от і якось забуваю ними займатися.

Мій background - Java, Android + трохи Clojure, зовсім трохи.

І ось рішення, від якого, можливо, ви захочете, як добрі люди, відмовити мене. Де-не-де, а BigData алгоритми і структури даних - центральна тема. Можу, звичайно, помилятися, але, як мені здається ймовірність мала. Але з чого розпочати? Гуглити, звичайно, рішення хороше, але можна вибрати не те, а хочеться те, в чому ви, прямо, впевнені точно.

Хочу зауважити, що тут не стоїть завдання стати світовим генієм у цій сфері, просто так, собі хочеться, мізки, так би мовити, повправляти. Але перспективу повного впровадження в цю сферу не виключаю, чому б і ні. Головне – правильно почати та вибрати потрібні матеріали.

Дуже сподіваюся на ваші поради, друзі, і резюмуючи:

Чи варто вивчати BigData взагалі? І з чого почати?

BigData не дуже пов'язана зі структурами даних - в основному це різноманітні просторові структури, швидше більше пов'язана з алгоритмами NLP, класифікації та машинного навчання.

Насамперед потрібно вибрати засіб обробки та зберігання. У випадку з Java це HBase Cassandra HBase - коли пишеться в базу дуже багато, і більшість індексів "саморобні". Cassandra - коли співвідношення читання / запису 4:3, так як у Cassandra вже є кошти колонкову індексацію.

У випадку з реальним високонавантаженням це ScyllaDB - має ті ж особливості що і HBase, але С++11 і Share-nothing approach і відтого в 6-7 разів швидше.

Для БД до 200Гб вистачить банального MySQL'я з R-tree індексом та Engine Archive. Ось PostgreSQL при правильному налаштуванні спокійно будує B-tree індекси для обсягів даних в 500-700Гб, що для MySQL'я непосильне завдання Ну і в PostgreSQL часто доводиться дописувати сишні функції агрегації і будувати за ними різноманітні індекси, іноді просторові (gin / gist).

Ось невеликий огляд різних типів індексів.

Від себе ще додам MVP-tree для пошуку схожих персептивних хешів і Fusion-tree як їстівніший варіант дерева Ван Емде Боаса.

З приводу хіпстер-культу навколо MongoDB - скажу що PostgreSQL з індексами на хеш-таблицях і невеликими множинами документів в 1.5-3 рази швидше, тому що "Building Index with Vodka". А нормальна реплікація і партикування безпосередньо залежить від принципів вирішення завдання Консенсусу в кожному конкретному додатку, і без розуміння роботи Raft/Paxos не варто сподіватися на дива тієї ж MongoDB або PostgreSQL, вони є не більше ніж інструментами для вирішення цього завдання.

MongoDB дуже навіть нічого для реактивних проектів на основі Meteor, а для решти вже GoldenHammer™.

Ну після того, як розібралися що і де і як зберігати, тепер можна думати з приводу обробки. Є давня книжка "Алгоритми інтелектуального Інтернету" та "Програмуємо колективний розум" Хоча назви перекладені українською досить дивно і звучать досить наївно - це гарне введення у прості засоби обробки та аналізу даних.

По машинному навчанню можна пройти курс Ендрю Ін на курсері.

Є Південний DataScience-централ, там є багато чого корисного. Його можна почитати. Є ще поверхові CheetSheet'и, бачив і краще, але не знайшов.

ЯкDeepLearning представник раджу розібратися з Theano, і способами описаними тут. У продакшенах ця штука до неподобства слоупочна і бачив товаришів, які більш-менш успішно злізли на Neon.

Якщо лізти в Java, то на прикладі Spotify найчастіше використовуються зв'язки Apache Kafka -> Apache HBase -> Apache Storm -> Apache Spark (mllib) -> Apache HBase -> Apache Phoenix -> Hibernate + будь-який MVC фреймворк тощо.

Звичайно про відносно високу продуктивність і хороше вертикальне масштабування не йдеться, якщо брати C++11 ScyllaDB -> Neon добре відпрофілювати і допиляти, можна отримати в 3-5 разів вище продуктивність і, відповідно, набагато менші затримки, але зазвичай всім влом. REST API під таке зазвичай намагаються писати на сях (без плюсів) у вигляді розширень під Nginx, що є досить породистим склепінням - у більшості випадків банального golang/netty буде достатньо.

У Hadoop стек зараз прийнято не лізти, тому що він дуже "заінтерпрайсян" і без гарної підтримки і допилки з боку вендорів у реальних проектах просто нею забелен, тому майже все на нього, в тій чи іншій мірі, забили. Наприклад, той же Spotify.

З приводу HA і Zookeeper можна побачити багато срача, особливо в Netflix'e, тому для менеджменту високої доступності краще використовувати саме їх рішення - eureka або для стійкості до відмови Hystrix. Хоча я не можу сказати що це досить зрілі проекти - у них теж вистачає вад, але вони набагато швидше від інших Apache виробів.

Не можна робити одночасно відмовостійкі та високодоступні програми - тому що CAP теорема має місце бути.

Ще є дуже тонкий момент з Java в цілому - потрібно мінімізувати час складання сміття і лізти в offheap, варто глянути якреалізовані буфери в netty - це arena аллокатор за типом того, що використовується jemalloc і різна misc.unsafe брехня. Можна ще пробувати Hazelcast / Terracotta, але важливо там теж саме, тільки платно і "розподілено".

Для REST API я найчастіше використовую Vert.x та ванільну Java. Overhead від Scala досить великий, а час компіляції просто вирвиглазное. Для мінімізації копі-пасти цілком безпечно використовувати Groovy c @ Immutable та @ CompileStatic. Але в Vert.x'e він весь "динамічний":

Я нічого не можу сказати з приводу продуктивності Clojure, він місцями занадтоinvokeDynamic. Природно, що ванільна Java буде швидше, але я без поняття на скільки.