
Чиний устгах гэж байгаа өгөгдөл 12 өөр газар оршиж байхад чи устгана гэж яг юу яриад байгаа юм бэ ?

Г.Энгүүнбаяр
Багш


Г.Энгүүнбаяр
Багш
Чи Software Engineer-ээр нэгэн компанид оржээ . Дарга чинь чамд "Чи нэг 123 id-тай хэрэглэгчийн бүх мэдээллийг устгаадах " гэж тушаал буулгажээ . Чи тэгээд л энэхүү нийтлэлийг хайж олоод уншиж эхэлж байна гэж төсөөлөн уншицгаая .
Хэрэглэгчийн мэдээлэл PostgreSQL дээр хадгалагддаг гэж үзье. DELETE FROM users WHERE id = 123 ажилласны дараа primary database тухайн хэрэглэгчийг байхгүй гэж үзнэ. Гэхдээ энэ нь зөвхөн тухайн database-ийн одоогийн logical state өөрчлөгдсөн гэсэн үг. Өгөгдөл системийн бусад хэсэгт байсаар байж болно.
Production системд database-ийн өгөгдлийг хэд хэдэн replica дээр хуулдаг. Хэрэв asynchronous replication ашиглаж байгаа бол primary дээр deletion хийгдсэн ч replica-ууд тэр өөрчлөлтийг шууд хүлээж авахгүй байж болно. Тухайн мөчид primary дээр хэрэглэгч байхгүй боловч нэг replica дээр хэрэглэгч байсаар байх боломжтой. Тиймээс “хэрэглэгч устсан уу?” гэсэн асуултад аль database-ээс асууснаас хамаарч өөр хариу гарч болно.
Хэрэглэгчийн мэдээллийг хурдан уншихын тулд Redis зэрэг cache ашигладаг гэж бодъё. user:123 гэсэн key дотор Alice-ийн мэдээлэл хадгалагдсан байж болно. Database-ээс Alice-г устгасан ч cache invalidation хийгдээгүй бол Redis Alice-г буцаасаар байна. Ингэснээр database-ийн хувьд Alice байхгүй боловч application-ийн хувьд Alice одоо ч байгаа мэт харагдана. Энэ бол cache invalidation яагаад distributed system-ийн хамгийн хэцүү асуудлуудын нэг байдгийн нэг шалтгаан юм.
Хэрэглэгч profile зураг, PDF, video зэрэг файл upload хийсэн бол database-д зөвхөн metadata, харин бодит файл object storage дээр хадгалагддаг архитектур түгээмэл. Database-ийн user record-ийг устгалаа гээд users/123/avatar.png автоматаар устахгүй. Тиймээс database дээр хэрэглэгч байхгүй болсон ч түүний файлууд storage дээр оршсоор байж болно.
Backup бол “устгасан өгөгдөл хаашаа явдаг вэ?” гэсэн асуултын хамгийн сонирхолтой хэсгүүдийн нэг. Лхагва гарагт хэрэглэгчийг устгасан боловч Даваа гарагийн backup дотор тэр хэрэглэгч бүрэн бүтнээрээ байж болно. Энэ нь системийн алдаа биш. Backup-ийн үндсэн зорилго нь өмнөх state-ийг хадгалж, disaster recovery хийх боломжийг өгөх явдал. Тиймээс одоогийн database-ээс устсан гэдэг нь backup-аас мөн устсан гэсэн үг биш.
Database дотор өгөгдөл өөрчлөгдөхөөс өмнө тухайн өөрчлөлтийг WAL буюу Write-Ahead Log-д бичих механизм ашиглагддаг. Тэнд INSERT, UPDATE, DELETE зэрэг үйлдлийн талаарх мэдээлэл тодорхой хугацаанд хадгалагдаж болно. Иймээс current database state дээр Alice байхгүй байсан ч database-ийн recovery болон replication-д ашиглагдах historical information дотор Alice өмнө нь байсан тухай мэдээлэл үлдсэн байж болно.
Event-driven architecture ашигладаг системд хэрэглэгчийг устгасны дараа UserDeleted(123) гэх мэт event Kafka зэрэг message broker руу илгээгдэж болно. Search service, analytics service, recommendation service зэрэг олон consumer уг event-ийг өөр өөрийнхөөрөө боловсруулна. Гэхдээ бүх service event-ийг яг нэгэн зэрэг хүлээж авахгүй. Зарим нь миллисекундын дараа, зарим нь хэдэн секунд эсвэл системийн доголдлын үед бүр удаан хугацааны дараа боловсруулж болно. Тиймээс deletion нь нэг database operation биш, систем даяар тархдаг process болж хувирдаг.
Production database-ийн өгөгдлийг analytics хийхийн тулд BigQuery, Snowflake, Redshift, ClickHouse зэрэг data warehouse руу хуулдаг систем байж болно. Production database дээр хэрэглэгч устсан ч warehouse дээр түүний historical purchase, transaction эсвэл behavioral data байсаар байж болно. Учир нь operational database болон analytical system өөр өөр зорилготой бөгөөд тэдгээрийн retention policy мөн өөр байдаг.
Server талаас өгөгдлийг устгасан ч хэрэглэгчийн төхөөрөмж дээр аль хэдийн очсон өгөгдлийг сервер бүрэн хянаж чадахгүй. Browser-ийн IndexedDB, localStorage, service-worker cache, mobile application's offline database зэрэгт мэдээлэл хадгалагдсан байж болно. Тиймээс server дээр хэрэглэгчийг устгасан нь хэрэглэгчийн төхөөрөмж дээр өмнө нь хадгалагдсан бүх copy устсан гэсэн үг биш.
Одоо DELETE /users/123 гэсэн ганц хүсэлтийг авч үзье. Энэ хүсэлт primary database дээр deletion хийхээс гадна Redis cache-ийг invalid хийх, search index-ийг шинэчлэх, object storage дахь файлуудыг устгах, event stream рүү deletion event илгээх, бусад service-үүдийн database-ээс хэрэглэгчийг устгах зэрэг олон үйлдлийг trigger хийж болно. Нэг deletion command системийн олон хэсэгт өөр өөр deletion operation үүсгэдэг.
Distributed system-д network найдвартай биш учраас UserDeleted(123) event consumer-д хүрэхгүй байх боломжтой. Тиймээс retry хийх шаардлагатай болно. Гэвч retry хийвэл нэг deletion event хоёр удаа боловсруулагдаж болно. Иймээс deletion operation idempotent байх ёстой. Өөрөөр хэлбэл нэг хэрэглэгчийг нэг удаа эсвэл таван удаа устгах хүсэлт ирсэн ч эцсийн state ижил байх ёстой.
Бүр илүү хэцүү нөхцөл бол устгасан өгөгдөл дахин гарч ирэх явдал. Жишээ нь primary database дээр user үүсээд дараа нь устсан боловч replica deletion event-ийг авч амжаагүй байж болно. Replica network-оос салж, дараа нь хуучин state-тэйгээ буцаж ирвэл устгасан хэрэглэгч дахин харагдах эрсдэлтэй. Distributed database ийм resurrection буюу устгасан өгөгдөл дахин “амьдрах” асуудлыг version, sequence number, tombstone зэрэг механизмаар шийддэг.
Primary database-ээс устсан үед үү? Replica-ууд бүгд шинэчлэгдсэн үед үү? Redis cache цэвэрлэгдсэн үед үү? Search index шинэчлэгдсэн үед үү? Object storage-ийн файлууд устсан үед үү? Kafka-ийн event retention дууссан үед үү? Backup-ууд expiration болсон үед үү? Эдгээрийн аль нь зөв хариулт вэ гэдэг нь системийн шаардлагаас хамаарна. Зарим системд logical deletion хангалттай байдаг бол зарим системд өгөгдлийн бүх historical copy-г тодорхой хугацаанд устгах шаардлагатай байдаг.
DELETE бол үнэндээ нэг operation биш. Энэ нь database state өөрчлөх, replica-д propagation хийх, cache invalidation хийх, search index шинэчлэх, object storage цэвэрлэх, event боловсруулах, backup retention удирдах зэрэг олон subsystem-ийн нийлбэр процесс юм. Нэг өгөгдөл системийн 10 гаруй өөр representation-д оршиж байвал “устгах” гэдэг нь тухайн representation бүрийг тус тусад нь зөв төлөвт оруулах асуудал болж хувирна.
Тиймээс хамгийн сонирхолтой асуулт нь “Database-ээс энэ record-ийг яаж устгах вэ?” биш.
Харин:
“Бид энэ өгөгдлийн бүх хуулбар хаана байгааг мэдэхгүй байхад түүнийг үнэхээр устгасан гэж хэзээ хэлж болох вэ?”
Энэ асуулт DELETE гэсэн энгийн CRUD operation-ийг distributed systems, replication, consistency, caching, event-driven architecture, backup, storage lifecycle зэрэг системийн дизайны том асуудал болгон хувиргадаг .
Нийтлэлээ дуусгахаасаа өмнө ганц асуулт асууя . Энэ бүх дараалалсан багц үйлдэлээс нэг нь бүтэлгүйтвэл ЧИ ЯАХ ВЭ ?
Амжилт