Ця база даних у вогні…

Ця база даних у вогні…

Дозвольте мені розповісти про технічну історію.

Багато років тому я розробляв додаток із вбудованими у нього функціями спільної роботи. Це був зручний експериментальний стек, у якому використовувався повний потенціал раннього React та CouchDB. Він у реальному часі синхронізував дані щодо JSON OT. Його використовували у внутрішній роботі компанії, проте широка застосовність та потенціал в інших сферах були очевидними.

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

Ця база даних у вогні…
Насправді це стало проблемою. Наше демо працювало саме так, як імітували роботу своїх додатків усі інші. Якщо конкретно, інформація миттєво передавалася від А до Б, навіть якщо це великі медіафайли. Після входу у систему кожен користувач бачив нові записи. За допомогою програми різні користувачі могли спільно працювати чітко над одними й тими самими проектами, навіть у разі переривання Інтернет-підключення десь у селі. У неявній формі подібне мається на увазі в будь-якому нарізаному After Effects відео про продукт.

Незважаючи на те, що всі знали, для чого потрібна кнопка Refresh, ніхто зовсім не розумів, що веб-програми, які вони просять нас створювати, зазвичай схильні до своїх обмежень. І якщо вони більше не знадобляться, то досвід користувача буде зовсім іншим. В основному вони помічали, що можна «чатитися», залишаючи співрозмовникам нотатки, тому запитували, чим це відрізняється, наприклад від Slack. Уф-ф-ф!

Дизайн повсякденних синхронізацій

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

Класичним прикладом цього є користувач, який протягом двадцяти хвилин дивиться на spinner.gifгадаючи, коли ж нарешті завершиться робота. Розробник зрозумів би, що процес, ймовірно, завис, і що gif ніколи не пропаде з екрану. Ця анімація імітує виконання роботи, але з пов'язані з її станом. У подібних випадках деякі технарі люблять закочувати очі, дивуючись ступеня помилки користувачів. Однак зауважте, хто з них вказує на годинник, що обертається, і говорить, що він насправді стоять нерухомо?

Ця база даних у вогні…
У цьому полягає суть цінності реального часу. У наші дні бази даних реального часу, як і раніше, використовуються вкрай мало, і багато хто ставиться до них з підозрою. Більшість таких баз даних активно схиляється до стилю NoSQL, через що зазвичай використовують рішення на основі Mongo, про які краще забути. Однак для мене це означає комфорт роботи з CouchDB, а також вивчення проектування структур, які здатні заповнювати даними не тільки якийсь бюрократ. Думаю, що я витрачаю свій час оптимальніше.

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

Ця база даних у вогні…
У обох назвах є слово Fire. Одне я згадую з ніжністю. Друге для мене інший вид вогню. Я не поспішаю говорити їхні назви, тому що, як тільки я це зроблю, ми зіткнемося з першою великою проблемою — іменами.

Перший називається Firebase Real-Time Database, а другий - Firebase Cloud Firestore. Обидва вони є продуктами з Firebase suite Google. Їх API називаються, відповідно, firebase.database(…) и firebase.firestore(…).

Так сталося тому, що База даних реального часу - Це просто вихідний Firebase до його покупки Google у 2014 році. Потім у Google вирішили як паралельний продукт створити копію Firebase на основі big data компанії, і назвали її Firestore with a cloud. Сподіваюся, ви ще не заплутались. Якщо все-таки заплуталися, не хвилюйтеся, я сам переписував цю частину статті десять разів.

Тому що потрібно вказувати Firebase у питанні про Firebase, та Пожежний магазин у питанні Firebase, принаймні, щоб вас зрозуміли кілька років тому на Stack Overflow.

Якби існувала нагорода за найгірший неймінг програмних продуктів, цей випадок безумовно став би одним із претендентів. Відстань Хеммінга між цими назвами настільки мала, що заплутує навіть досвідчених інженерів, пальці яких друкують одну назву, хоча голова думає про інше. Це з тріском провалилися плани, вигадані з найкращими намірами; вони виконали пророцтво про те, що база даних буде у вогні. І я анітрохи не жартую. Людина, яка придумала таку схему найменувань, стала причиною крові, поту та сліз.

Ця база даних у вогні…

Піррова перемога

Можна було б подумати, що Firestore це заміна Firebase, його нащадок наступного покоління, але це було б помилкою. Firestore гарантовано не підходить для заміни Firebase. Схоже, хтось вирізав із нього все цікаве, а більшу частину того, хто залишився, заплутав у різний спосіб.

Однак побіжний погляд на два продукти може збити вас з пантелику: здається, що вони роблять одне і теж, через в основному однакові API і навіть в одній і тій же сесії баз даних. Відмінності малопомітні і виявляються лише за ретельному порівняльному вивченні розлогої документації. Або коли намагаєшся портувати код, що ідеально працює на Firebase, щоб він працював з Firestore. Вже тоді ти з'ясовуєш, що інтерфейс бази даних спалахує, як тільки намагаєшся виконати перетягування мишею в реальному часі. Повторюся, я не жартую.

Клієнт Firebase ввічливий у тому сенсі, що він буферизує зміни та виконує автоматичний повтор спроб оновлення, при яких пріоритет віддається останній операції запису. Однак, Firestore має обмеження в 1 операцію запису на документ на користувача в секунду, і це обмеження накладається сервером. При роботі з ним ви самі повинні знайти спосіб обійти його та реалізувати обмежувач частоти оновлень, навіть коли ви просто намагаєтеся створити свою програму. Тобто Firestore — база даних реального часу без клієнта реального часу, яка маскується під нього за допомогою API.

На цьому ми починаємо бачити перші ознаки існування Firestore. Можливо, я помиляюся, але підозрюю, що хтось високо в керівництві Google подивився після покупки на Firebase і просто сказав: Ні, боже мій, ні. Це не прийнятно. Тільки не під моїм керівництвом».

Ця база даних у вогні…
Він з'явився зі своїх покоїв і проголосив:

Один великий документ JSON? Ні. Ви розділите дані на окремі документи, кожен із яких буде розміром не більше 1 мегабайта».

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

При такому обмеженні ви будете змушені змиритися з тим фактом, що один документ у базі даних не буде схожий на жоден об'єкт, який користувач міг би назвати документом.

«Масиви масивів, які можуть рекурсивно утримувати інші елементи? Ні. Масиви будуть містити лише об'єкти чи числа фіксованої довжини, як задумано Господом».

Тому якщо ви сподівалися помістити у свій Firestore GeoJSON, то виявите, що це неможливо. Неприпустимо нічого неодномірного. Сподіваюся, ви любите Base64 та/або JSON всередині JSON.

«Імпорт та експорт JSON через HTTP, інструменти командного рядка або панель адміністратора? Ні. Ви зможете лише експортувати та імпортувати дані до Google Cloud Storage. Так, здається, воно зараз називається. І коли я говорю „ви“, то звертаюся тільки до тих, хто має повноваження Project Owner. Всі інші можуть піти та створити тікети.»

Як бачите, модель даних FireBase легко описати. Вона містить один величезний документ JSON, що зв'язує ключі JSON із шляхами URL. Якщо ви запишете за допомогою HTTP PUT в / FireBase наступне:

{
  "hello": "world"
}

те GET /hello поверне "world". В основному це працює саме так, як ви очікуєте. Колекція об'єктів FireBase /my-collection/:id еквівалентна словнику JSON {"my-collection": {...}} в корені, вміст якого доступний в /my-collection:

{
  "id1": {...object},
  "id2": {...object},
  "id3": {...object},
  // ...
}

Це працює добре, якщо кожна вставка має ID без колізій, для чого в системі є стандартне рішення.

Іншими словами, база даних на 100% сумісна з JSON (*) і добре працює з HTTP, наприклад, з CouchDB. Але в основному ви використовуєте її через API реального часу, який абстрагує websockets, авторизацію та підписки. Панель адміністратора має обидві можливості, дозволяючи та виконувати редагування в реальному часі, та імпорт/експорт JSON. Якщо у своєму коді ви дотримуватиметеся того ж, то здивуєтеся, який обсяг спеціалізованого коду пропаде, коли ви зрозумієте, що patch і diff JSON дозволяють вирішити 90% рутинних завдань з обробки постійного стану.

Модель даних Firestore схожа на JSON, але відрізняється від неї у деяких критично важливих аспектах. Я вже згадував відсутність масивів усередині масивів. Модель sub-collections полягає в тому, щоб вони були концепціями першого класу, окремими від документа, що містить їх JSON. Оскільки для цього немає готової серіалізації, для отримання та запису даних потрібен спеціалізований шлях виконання коду. Для обробки власних колекцій потрібно писати свої скрипти та інструменти. Панель адміністратора дозволяє вносити лише невеликі зміни по одному полю за раз, і не має можливостей імпорту/експорту.

Вони взяли базу даних NoSQL реального часу і перетворили її на повільну не SQL з автооб'єднанням і окремим стовпцем не JSON. Щось на кшталт GraftQL.

Ця база даних у вогні…

Гарячий Java

Якщо Firestore повинен був стати більш надійним і масштабованим, то іронія в тому, що розробник отримає менш надійне рішення, ніж при виборі FireBase «з коробки». Те ПЗ, яке необхідне Бурхливому Адміністратору Бази Даних, вимагає такого рівня зусиль і калібру фахівців, що це просто нереалістичне для ніші, в якій, ймовірно, має бути хороший продукт. Це схоже на те, як HTML5 Canvas зовсім не є заміною Flash, якщо немає інструментів розробки та програвача. Більше того, Firestore загрузла у прагненні до чистоти даних та стерильної валідації, що просто не відповідає тому, як середній бізнес-користувач любить працювати: для нього все необов'язково, тому що до самого кінця все є чернеткою

Основний недолік FireBase в тому, що клієнт був створений на кілька років раніше свого терміну ще до того, як більшість веб-розробників дізналася про іммутабельність. Через це FireBase передбачає, що ви будете змінювати дані, а тому не використовує переваги іммутабельності, що забезпечується користувачем. Крім того, він не використовує дані повторно в снепшотах, що передаються користувачеві, через що виконувати diff набагато складніше. Для великих документів його механізм транзакцій на основі змінних diff просто неадекватний. Хлопці, адже у нас вже є WeakMap у JavaScript. Це зручно.

Якщо надати даним потрібну форму, і робити дерева занадто об'ємними, то цю проблему можна обійти. Але мені цікаво, став би FireBase набагато цікавіше, якби розробники випустили по-справжньому хороший клієнтський API, що використовує іммутабельність у поєднанні з серйозною практичною порадою структури баз даних. Натомість вони, схоже, спробували полагодити те, що не зламано, і від цього стало гірше.

Я не знаю всієї логіки, яка лежала в основі створення Firestore. Міркування про мотиви, що виникають усередині чорної скриньки — це також частина розваги. Таке протиставлення двох надзвичайно схожих, але незрівнянних баз даних трапляється досить рідко. Наче хтось подумав: "Firebase - це просто функція, яку ми можемо емулювати в Google Cloud", але при цьому ще не відкрив для себе концепцію визначення вимог реального світу або створення корисних рішень, що задовольняють всі ці вимоги. «Нехай про це думають розробники. Просто зробіть UI красивим ... А можна додати більше вогню?

Я розумію пару речей про структури даних. Я точно бачу, що концепція "все в одному великому дереві JSON" - це спроба абстрагувати з бази даних будь-яке відчуття великомасштабної структури. Очікувати, що програмне забезпечення просто впорається з будь-яким сумнівним фракталом структури даних — це просто безумство. Мені не потрібно навіть уявляти, наскільки погано все може бути, я проводив жорсткі аудити коду бачив таке, що вам, людям, і не снилося. Але я також знаю, як виглядають гарні структури, як їх використовувати и чому це потрібно робити. Я можу уявити світ, у якому Firestore здавалася б цілком логічною, а люди, які її створили, вважали б, що проробили хорошу роботу. Але ми живемо не на цьому світі.

Підтримка побудови запитів FireBase погана за будь-якими стандартами, її практично не існує. Вона безперечно вимагає поліпшення або хоча б перегляду. Але Firestore не набагато краще, оскільки вона обмежена тими ж одновимірними індексами, які є в простий SQL. Якщо вам потрібні запити, які люди виконують з хаотичними даними, то потрібен повнотекстовий пошук, фільтри на кілька діапазонів і довільний порядок, що задається користувачем. При уважному вивченні функції простого SQL власними силами занадто обмежені. Крім того, єдині SQL-запити, які люди можуть виконувати в продакшені, - це швидкі запити. Вам знадобиться спеціалізоване рішення для індексування з продуманими структурами даних. Для решти, принаймні, має бути інкрементне map-reduce або щось подібне.

Якщо ви пошукайте інформацію про це в документах Google, вам, сподіваюся, вкажуть у напрямку чогось типу BigTable і BigQuery. Однак усі ці рішення супроводжуються таким обсягом густого жаргону корпоративних продажів, що ви швидко повернетеся назад і почнете шукати щось інше.

Останнє, що вам потрібно у разі бази даних реального часу, — це щось створене людьми і для людей, які працюють за шкалою окладів для керівництва.

(*) Це жарт, немає такого поняття, як сумісність із JSON на 100%.

На правах реклами

Підшукуєте VDS для налагодження проектів, сервер для розробки та розміщення? Ви точно наш клієнт 🙂 Подобова тарифікація серверів різних конфігурацій, антиDDoS і ліцензії Windows вже включені у вартість.

Ця база даних у вогні…

Джерело: habr.com

Додати коментар або відгук