Канал
У Льоні сьогодні
Нотатки архітектора систем та майстра на всі руки. Що я зробив, що з того вийшло, і що це все значить.
-
Навіщо потрібний S3?
Натрапив сьогодні на питання: навіщо s3? та в чому його плюси? та чи можна написати свій?. Люблю такі питання, бо хоч воно здається наївним, але я не сумніваюся, що дехто карго-культить (що таке карго-культ?) S3 та дарма не замислюється. Отже.
AWS Simple Storage Service - це глобальне сховище для всього, що нагадує файли. “Simple” воно у тому сенсі, що ми отримуємо безрозмірне масштабування — як в кількості “файлів”, так і в їхньому розмірі, та високу доступність — в тому числі й по HTTP з браузера. А ще — автоматичне шифрування, контроль доступу, автоматичне видалення за правилами та багато такого, про що я навіть не знаю.
“Простішою” альтернативою S3 буде робити власне файлове сховище. До певного масштабу, зберігати файли не так вже й важко, але ви швидко упретесь у розміри диска чи в пропускну здатність каналу чи в обмеження файлової системи… і так далі.
Тому вже давно ми беремо S3, коли потрібно зберігати завантаження користувачів, або взагалі щось схоже на файли. (Треба розуміти, що “файли” в S3 це суто умовність, насправді це база “ключ-значення”, в ній немає ніякої структури каталогів.)
Звісно, особливо S3 стає корисним, якщо наші сервіси мають лише ефемерний диск, бо їм треба кудись зберігати дані. А ще S3 широко використовується в самому AWS для всіляких сервісів. Я був здивований дізнатися, що мережевий диск EFS реалізований через S3, хоча ззовні виглядає як “простіша” файлова система.
S3 став стандартом де-факто для збереження “файлів”. Настільки, що багато (якщо не більшість) сховищ пропонують сумісний з S3 API: Cloudflare, Backblaze, Hetzner і так далі. Тобто я хочу сказати, що якщо вам не подобається Amazon, можна знайти альтернативу та зберегти зрозумілий режим доступу.
Або навіть захостити власний: MinIO, Localstack.
-
Як шукати причину збільшення CPU
Є у вас сервіс чи база, та в нього раптом виросло споживання процесора. Куди та як дивитися?
По-перше, тобі потрібні метрики. Та не тільки на цей момент, а історичні. Без метрик ти біжиш в темряві: це весело рівно до першої ями.
До речі: достаток метрик — недооцінена особливість AWS та й інших хмарних платформ. Метрики не даються безплатно, їх треба зібрати та зберегти. Та оскільки для нормальної роботи сервісу метрики не потрібні, цілком ймовірно ми до них так і не доберемось. Зате AWS відразу надає купи метрик для кожної бази та сервісу. Нам залишається тільки про них згадати.
Зростання бувають двох типів. Або планомірні, завдяки збільшенню попиту. Або — коли відбулося несподіване. Скоріше за все, ми дивимося на несподіване зростання — планомірне просто не так часто трапляється. Та з можливих причин я б ставив на нову фічу з необачним споживанням. Щоб це підтвердити, шукаємо smoking gun, тобто прямий доказ.
Для того відкриваємо достатню історію, щоб на нашому проблемному графіку було помітно зростання. Обираємо зручний інтервал агрегації, щоб уникнути дрібних коливань. Та дивимось, які ще метрики мають схожий графік? Які входи та виходи в нашого сервісу? Що на нього впливає? Звідки береться навантаження?
Потім можна перейти в інструмент APM - New Relic, Sentry тощо — та перевірити, яка саме активність корелює. Тут-то ми напевно і побачимо нашу проблемну фічу.
До речі, раз ми вже шукаємо зміни в коді, то можна було й з іншої сторони зайти. Наприклад, подивитися, що деплоїли в дату, коли витрати почали збільшуватись. Я не кажу, що це завжди працює, але часто — та знайти зміни в коді легше.
-
Смачні страви польської кухні
В мене сьогодні день народження, та я несподівано приготував аж дві страви польської кухні. На честь такого неймовірного збігу — трохи страв, які я люблю. Ніколи не чув позитивних відгуків про польську кухню, тож, може, мені вдасться трохи посунути статус кво.
-
Біґос — тушкована квашена капуста із мʼясом, ковбасою, грибами, обовʼязково духмяним перцем та кмином. Мені особливо подобається, що береться саме квашена. Звичайна тушкована капуста для мене надто прісна. Ну й набір спецій та додатків дуже відрізняється від тієї тушкованої капусти, яку можна знайти в Україні.
-
Журек — суп з житньої закваски. На вигляд білий такий. На смак — кислий. В нього традиційно кладуть картоплю, домашню ковбасу, та варене яйце. Гадаю, в селі таке було легко приготувати, бо закваска на хліб завжди стояла в домі. Сьогодні в Польщі можна купити її в магазині. А поза Польщею — просто пекти хліб та тримати вдома закваску.
-
Осципек — то є такий копчений сир. На смак він віддалено нагадує копчений сулугуні, але не складається з ниток. Зазвичай осципек продають маленькими закопченими коржиками. Найкраще це розігріти такий коржик на вогні, тоді сир всередині плавиться — це популярний смаколик на різдвяних ярмарках.
-
Карпатка - “торт-еклер”. Складається з двох шарів заварного тіста, між якими заварний (або інший) крем. Зверху карпатка посипається пудрою та певною мірою нагадує гори Карпати — заварне тісто сходить горбами. Я в принципі люблю еклери, та щасливий обійти відразу і формування тістечок, і начинення.
А ще є пирОги, запіканки, пачки, крижана зубрівка…. Та макарон з трускавкою. 🍓
-
-
Бази даних відрізняються не тільки швидкістю
Потрапив мені на очі пост Kafka is fast - I’ll use Postgres. Теза в ньому така, що PostgreSQL теж може бути буфером подій, та ще й з непоганою швидкістю, тож нащо та Kafka потрібна?
По-перше, нічого не маю проти того, що PostgreSQL - потужна універсальна база, та багатьом проєктам дійсно Kafka буде зайвою. Особливо якщо врахувати, що Kafka доцільно використовувати якнайменше з трьома вузлами. Але також зауважу, що головний сенс використання Kafka - не у її швидкості, а у надійності. Kafka - це барʼєр від стресу.
Наприклад. Є у вас критичний шматок інфраструктури, який генерує події. Класичний випадок — телеметрія. Якісь віддалені датчики надсилають показники — та вони точно не пристосовані, щоб зберігати пакети на своєму боці чи пробувати надсилати повторно. Додамо до того ще й те, що оновлювати ПЗ датчика — настільки складно, що, може, ми ніколи цього не будемо робити.
Отже. Куди ці події записувати? Нам потрібний такий сервіс, щоб він ніколи не простоював. Kafka і є таким сервісом. Збереження в Kafka відбувається найпростішим та найшвидшим способом, та навіть не накладає вимог за схемою даних. А вже звідти ми можемо забирати дані в зручному для нас режимі.
Або ось ще практичний приклад. Протягом останнього вильоту в AWS не запускалися функції Lambda. Якщо ваші дані приходили прямо у Lambda - вітаю, їх ніхто не обробив та тепер вони втрачені. А якщо перед Lambda стояла Kafka - то єдине, що загрожувало, це затримка обробки.
Так, PostgreSQL теж надійний, якщо говорити про нормальну роботу. Але знаєте, коли я останній час апгрейдив постгрес? У 2022, три роки тому. Бо це ж ціла історія — обовʼязково зупиняти продакшн або в кращому випадку робити тільки на читання. Потім вартувати над тією базою, щоб нічого не сталося.
А Кафку — та от минулого місяця оновив. Натиснув кнопку в панелі керування та порядок. Ніхто навіть цього не помічає, бо там кластер та оновлюється він поступово, без зупинки.
Така надійність та безвідмовність значить більше, ніж чисті показники швидкості.
-
Наскільки важливо розуміти спеціалізацію бази даних
Трохи допомагав хлопцям із проблемним навантаженням на ElasticSearch. Виявилося, проблема з запитами, де фігурував пошук зі скриптом. Скрипт виконував операцію на кшталт
foo - bar > THRESHOLD.Як побачив, то відразу все стало зрозуміло. OpenSearch будує з документів словники — де кожному значенню поля відповідає множина документів. OpenSearch швидкий, поки ти робиш пошук за словниками. Такий пошук виконується як операції над множинами, та тому є дійсно надзвичайно швидким, навіть коли в запиті згадується багато полів. Це — головна сила OpenSearch.
Але як тільки для пошуку доводиться читати самі документи — швидкість провалюється на порядок. Бо з операцій над множинами ми скочуємося до операцій над документами.
Тобто можливість пошуку за скриптом існує, щоб закрити рідку потребу, зробити щось неможливе можливим. Але вона ніяк не годиться для базового функціоналу. Це може приголомшити, якщо ти приходиш з бази загального призначення — як Postgres - де пошук по
foo - barне сильно відрізняється за пошуком поfooчиbar.В цьому сенсі я завжди любив документацію з Redis - в ній для кожної команди виписана обчислювана складність. Колись я робив складний рушій на основі Redis, та це було критично важливо для планування.
А у випадку з OpenSearch відповідь така: хочеш шукати за різницею полів — зберігай цю різницю в ще одно поле -
fooMinusBar. Та левову частку інтеграції OpenSearch складає саме планування наперед потрібних операцій та полів, які їх уможливлюють. -
Несподівано складна задача конвертації PDF в інший формат
Проблема: “Синево” тепер дають результат аналізів тільки у вигляді PDF. Для перегляду чи друку це нормально, зате для машинної обробки… Скажімо так, в мене була світла ідея передати результат у ШІ та спитати поради.
…ШІ той PDF прочитав “за діагоналлю”. Наплутав всі показники. Я чогось такого й очікував, тож планував конвертувати PDF в текстовий формат. Виявилося, це нелегко.
Звісно, річ не у тім, що PDF є двійковим форматом. Справжній його недолік в тому, що PDF є більше векторним зображенням, ніж текстом. Там немає аж ніякої структури документа.
В PDF відсутня викладка тексту як така. Кожний безперервний рядок стає окремим елементом файлу. Та й таблиці теж відсутні. Те, що ми бачимо, як таблицю — насправді є супом з текстових рядків. “Глюкоза” з координатами
123,456, “40” з координатами145, 567, “г/моль” з координатами156, 634.З цього супу і параграфи не так легко скласти! А як таблицю — то взагалі задача непіднімна. (Як виявляється.)
Найкраще в мене впорався застосунок Tabula - він принаймні вірно визначив таблицю, тільки підписи з перенесеннями перетворював на окремі рядки таблиці. Технічно, далі можна вручну виправити цю таблицю — позливати рядки разом — але в мене на це часу немає. Залишуся без ШІ-терапевта. 😄 (Бо в такому вигляді він теж читає неправильно.)
PDF - формат абсолютно несемантичний. Це нагадує, як важлива семантичність, наприклад, в HTML. Конвертори PDF у HTML існують, звісно, але залишають зміст у вигляді абсолютно позиційованих елементів
<div>.Звісно, в PDF є й потужна перевага — він ідеально відтворюється як на екрані, так і на аркуші. Я вас тільки прошу пропонувати й альтернативні формати.
-
ExifTool та робота над домашньою фотобібліотекою
Стала задача закинути кілька (… десятків гігабайтів) старих фотографій в Apple Photos. Здебільшого то скани. Та, хоч технічно можна прямо взяти та імпортувати як є, але тоді я втрачу останні крихти метаінформації.
А саме: в Apple Photos немає дерева каталогів, а фотографії насамперед впорядковані за датою. Плюс, звісно, альбоми, ключові слова, геолокація, але це все вторинне. І всього цього в мене взагалі немає. Є вбудована можливість створити з тек на диску альбоми, втім це мені теж мало допоможе — та й не хочу я купу зайвих альбомів.
Отже, виходить, треба підготувати фотографії так, щоб в Apple Photos в них можна зорієнтуватися. Та допоміг мені в цьому ExifTool - програма, яку обовʼязково треба знати для роботи з метаданими фотографій або навіть відео.
Почнемо з того, що вона сама вміє знаходити фотографії в дереві, робити резервні копії, а також навіть виконувати деяку логіку (наприклад, “записати метатег, тільки якщо його ще немає”.)
Потім, ExifTool здатний записати в титул фотографії її шлях. Це збереже той порядок, який був у фотографіях раніше, та принаймні допоможе їх впізнавати.
Далі, мені пощастило, що фотографії були розкладені в теки за роком. Щоб Apple Photos про це теж знав, можна взяти рік зі шляху, та записати у метатег
DateTimeOriginal. Тепер хоч приблизно все в порядку!Вийшло щось таке — вся робота однією командою:
exiftool -r \ '-Title<${directory}' \ -if 'not $DateTimeOriginal' '-DateTimeOriginal<${directory; $_=(split m!/!, $_)[1] . ":01:01 12:00:00"}' \ . -
Long Poll та проблеми зі звʼязком
Памʼятаєш, я казав, що дивним чином під час останнього збою AWS в нас застряг SQS - нічого не отримував, але й не відвалювався? Знайшов причину.
Отримання повідомлень з SQS працює за моделлю Long Poll: клієнт робить запит до сервера, а сервер відповідає тоді, коли в черзі зʼявляться повідомлення. Однак якщо черга порожня, то сервер через зазначений інтервал дасть порожню відповідь. В деяких реалізаціях Long Poll працює інакше — це клієнт обриває підключення. Але в AWS SQS все залежить саме від сервера.
Отже, що відбувається під час обриву звʼязку? Тут є важливий момент: обривів звʼязку не існує. Підключення TCP - це лише домовленість між клієнтом та сервером про майбутній обмін пакетами. Але відрізнити відсутність пакетів від “обриву” просто неможливо. Немає ніякого другого каналу, через який ми можемо “побачити” сервер та дізнатися, чи він досі підключений. Ти знаєш про це тільки з того, що він надіслав тобі пакет.
А отже виходить, якщо клієнт чекає відповідь через Long Poll від відключеного сервера — він ніколи не отримає пакетів, але також не отримає й помилки. І буде чекати звістки… нескінченно.
Вихід з цього зрозумілий: впровадити тайм-аут з боку клієнта. Що взагалі гарна ідея в будь-яких ситуаціях, як бачимо! Обриви звʼязку — абсолютно нормальна ситуація в інтернеті.
В деяких AWS SDK цей тайм-аут вже зробили — наприклад, aws-sdk-js та aws-sdk-php. А в
aws-sdk-go- поки ні. Зате його можна додати вручну з тим же ж результатом. Тайм-аут цей повинен трохи перебільшувати інтервал очікування, і тоді ми будемо надійно захищені від обривів. -
Що такого особливого в AWS us-east-1?
Якщо ти трохи спостерігаєш за подіями в інфраструктурі, може в тебе є два питання. Ну те, що
us-east-1- це регіон, тобто ізольована частина AWS, розташована умовно на сході США — сподіваюся, і так зрозуміло. Та, хоч в AWS є понад 30 регіонів, чому здається, що всі користуються AWSus-east-1? Та чому як проблеми з AWS - то обовʼязково самеus-east-1? Вони що дурні?us-east-1є найстарішим регіоном в AWS. Звісно, тут набереться найбільше клієнтів, особливо тих, що вже великі та успішні. Але також, цей регіон обріс найбільшим шаром технічного боргу. Попри це…us-east-1є першим регіоном для всього нового. Будь-який сервіс спочатку запускається вus-east-1, та інші регіони інколи суттєво відстають. А значить, є суттєво стабільнішими. :) Мабуть, в ідеальному світі самий “заборгований” регіон не був би ще й передовим по фічах, але маємо те що маємо.us-east-1є найдешевшим регіоном. Та це безперечно приваблює бізнеси. Я гадаю, роль “гама-тестерів” врахована в ціні, щоб клієнти не розбігалися, а навпаки — прибігали. Хоча я раджу обирати будь-який інший регіон (наприклад,eu-west-1.)us-east-1містить контрольну площину. Такі фундаментальні сервіси, як IAM чи Route 53 - існують саме в цьому регіоні. Тож, деякі проблеми вus-east-1будуть розповсюджуватися й на всі інші регіони. Наприклад, проблеми з DNS чи моделлю авторизації.Отже, якщо підсумувати,
us-east-1є “столицею” AWS. Проблеми в ньому й більш ймовірні, й більш помітні, ніж в будь-якому іншому регіоні. Тож немає нічого дивного в тому, що він завжди на слуху. -
Всі способи, якими я хостив PHP
-
Перші спроби були на Windows. Про Linux та тим паче macOS я нічого не знав. Здається що під Windows була готова збірка Apache+PHP+MySQL (може то був WAMP?), але можливо я ставив їх окремо. Запамʼятався графічний інтерфейс вебсервера Apache з рожевим пером. Все було супер просто, бо файли з диска ставали сторінками сайту. Та попри цю простоту, я навіть — як це зараз модно казати — селф-хостив форум — так, це було на Windows.
-
На шаред-хостінгу. Це коли хостинг дає тобі теку на FTP, ти туди заливаєш ті ж файли та вони стають сайтом. Власне, розроблялося все теж на Windows, а що там було на сервері — мені було мало цікаво.
-
На першій роботі через nginx. Перший раз довелося дізнатися, що взагалі-то на світі існує не тільки Apache. Та зʼявилися речі, які локально не працюють — хоча не пригадаю, які саме. (Ой, на тім роботі ще була купа Macromedia Flex, але то ціла інша історія.)
-
На виділеному хостингу… поки через Apache. Бо Apache був набагато простіше в налаштуванні, ніж nginx - та й PHP там був вбудований. Встановив сервер, дописав трохи конфігурації — і можеш так само копіювати файли, як і раніше.
-
Там же ж, але вже із nginx та PHP-FPM. Це фактично сервер застосунків для PHP - запускається окремим процесом, кешує скомпільований код, та служить бекендом для nginx. Спонукало перейти те, що я тримав також кілька застосунків на Rails, та вже nginx став більш зрозумілим рішенням — зворотнім проксі — ніж Apache, який пропонував підхід “все в одному”.
Цікаво, що починався PHP з парадигмою “я вказую шлях до файлу зі скриптом на сервері та викликаю його”, а прийшов до “застосунок є сервісом, який обробляє запити”. І тепер скриптові мови не так вже й відрізняються від компільованих.
-