#JSON
3 нотаток
- ActiveRecord
- AmazonRedshift
- API
- AppleScript
- AWS
- AWSLambda
- Cadencia
- CGO
- Chezmoi
- CI
- Clojure
- Cloudflare
- CloudflarePages
- CloudWatch
- CssParser
- CтохастичнийТаймтрекер
- DNS
- Docker
- Dotfiles
- Fly.io
- GCP
- Git
- GitHub
- GitHubActions
- Go
- Golang
- GTD
- HomeAssistant
- Hugo
- I18next
- JavaScript
- Jira
- JSON
- Kafka
- MacMiniВДорозі
- MacOS
- Markdown
- Mastodon
- Obsidian
- ObsidianCanvas
- OmniWOPE
- OpenSearch
- Oura
- PagerDuty
- Ping
- Plausible
- PostgreSQL
- ReactNative
- Redis
- RSS
- Ruby
- RubyOnRails
- Sentry
- Sintra
- Slack
- SMTP
- SQL
- SQLite
- Svelte
- Swift
- SwiftData
- SwiftUI
- Telegram
- Terraform
- TLS
- TypeScript
- Vercel
- VPN
- WeightPlot
- WordPress
- XCode
- Адвент2024
- Бази Даних
- БДС
- Безпека
- Блокнот
- Вебтехнології
- ВолюІнформації
- Гаджети
- ДизайнМовПрограмування
- Ігри
- Інструменти
- ІнтеграційніТести
- Кава
- КеруваннняЗадачами
- Кодогенерація
- Криптографія
- Локалізація
- Маркетинг
- МетаПост
- МоїПроєкти
- Навігація
- Оптимізація
- ОсновиІнтернетБезпеки
- Помічник ШІ
- ПомічникШІ
- ПостПроПохід
- Програмування
- Продуктивність
- Проєкти
- Проза
- РДУГ
- Рівночасність
- РобочийКомп
- Розробка
- РозумнийБудинок
- СинПопросивПриготувати
- Сон
- СтохастичнийТаймтрекер
- Танці
- ХмарніТехнології
-
Формат JSONLines
JSON всім чудовий формат даних - текстовий, легко читається та пишеться людьми, швидко читається та пишеться машинами завдяки багатьом оптимізаціям. Але є в нього одне проблемне місце: щоб щось зробити з документом JSON, його доведеться повністю завантажити в памʼять. Коли даних стає сотні мегабайт, то завантаження їх в памʼять стає серйозним випробуванням: бо внутрішнє представлення може зайняти ще більше місця.
Перед тим, як обирати з форматів для Big Data, краще подивитися на JSON Lines. Це формат масиву даних, де в кожному рядку міститься повний документ JSON. (Звісно, при цьому розриви рядка в середині документа заборонені.)
Перевага JSONLines: кожен рядок можна читати та обробляти окремо (та вивільняти памʼять). Також можна, навіть без розбору змісту JSON, орієнтуватися в масиві — достатньо стежити за закінченнями рядка, щоб визначити місце, полічити записи, розділити масив (чи склеїти два!) тощо.
Недолік JSONLines: він все ж не такий загально прийнятний, як JSON. Також людям його читати важче. Ну й те, що JSONLines - обовʼязково масив. Тому сфера застосування — скоріше, машинні документи, чи запити до API. Я бачив JSONLines в пакетних запитах ElasticSearch, експортах AWS Redshift, AWS Kinesis Firehose… вебхуках Mailtrap. :) Раджу мати на озброєнні.
Ще дотепний факт: насправді є цілих два стандарти для JSON Lines - другий називається NDJson та функціонально ідентичний, за винятком медіатипу.
-
Потокова обробка JSON
Поки писав вчора про JSONLines, встиг дізнатися про альтернативу. Звичайний JSON теж можна обробляти потоком. Я маю на увазі, зчитувати частину, обробляти та вивільняти — звісно, коли йдеться про якийсь масив незалежних даних.
Адже ще одна перевага JSON - це його контекстно-незалежна рекурсивність (сам тільки що придумав). Вкладені обʼєкти синтаксично еквівалентні цілому документу. Нам не потрібно знати нічого про відступи, області імен, якісь посилання тощо. Якщо ми зчитуємо з потоку JSON та встановили вказівник в позицію початку вкладеного значення, то парсер буде готовий взяти та зчитати це значення, наче окрім нього нічого не існує. Залишиться тільки просувати вказівник до наступного значення, тобто повз кому.
Я все це не вигадав, а прочитав у прикладі до методу json.Decoder.Decode() з Go. Бо в Go декодер JSON відкриває достатньо інтерфейсу для поміркованого читання; можна читати цілий документ, а можна значення за значенням. В цілому, так можна зробити з будь-яким парсером, що читає потік — але ж пропускати коми та пробіли доведеться вручну.
Цікаво, що в JavaScript взагалі не бачу рідного модуля для читання JSON з потоку, а тільки з рядка. Знайшов ось stream-json, яка щось таке вміє. (А от JSONLines можна легко читати з потоку через модуль readline та обробляти рядок за рядком.)
Як бачимо, з одного боку, витончений читач може реалізувати потокову обробку й без обтяження споживача незвичним форматом даних. Але з іншого боку, JSONLines гарний тим, що там один документ на рядок, та працювати з ним можна звичайними текстовими засобами (наприклад,
wc -l, щоб підрахувати кількість документів.) -
Потоковий запис JSON
Я в попередньому пості писав про читання JSON поступово з вивільненням памʼяті, але ж хтось той JSON повинен був записати? Ситуація з записом значно простіша, та не потребує ніяких особливих інструментів.
Почнемо з того, що генерація JSON можлива в один прохід та може здійснюватись у вихідний потік. Можна навіть поєднати її зі стисканням в
gzipта пересилати через мережу з мінімальним буфером для виходу.(До речі: gzip стискає зміст через заміну повторюваних послідовностей. Таким чином, назви атрибутів та інші повторювані рядки в JSON - ідеальні вхідні дані для gzip.)
Але — інколи в нас немає всіх даних відразу — наприклад, вони не влазять в памʼять, або ми отримуємо їх пакетами з Kafka чи ще звідкілясь. Навіть в такому випадку нескладно утворити на виході єдиний JSON без залучення великого буфера.
Наприклад. Пишемо у вихід
[- початок масиву. Далі пишемо по черзі стільки даних, скільки потрібно — читаючи з бази або з генератора або де там ще в нас дані беруться. Наприкінці закриваємо масив:]. От і все!Інколи все, що потрібно — це трохи текстових операцій. Я колись так робив, щоб зливати з Kafka зміст для резервного копіювання.