GNU Shepherd 1.0.0 released

Post Syndicated from corbet original https://lwn.net/Articles/1001599/

Version
1.0.0
of the GNU Shepherd service manager has been released after a
mere 21 years of development.

This 1.0.0 release is published today because we think Shepherd has
become a solid tool, meeting user experience standards one has come
to expect since systemd changed the game of free init systems and
service managers alike. It’s also a major milestone for Guix, which
has been relying on the Shepherd from a time when doing so counted
as dogfooding.

Security updates for Tuesday

Post Syndicated from corbet original https://lwn.net/Articles/1001597/

Security updates have been issued by AlmaLinux (postgresql:15, postgresql:16, and ruby:3.1), Debian (jinja2), Fedora (python-multipart, python-python-multipart, python3.12, retsnoop, rust-rbspy, rust-rustls, and zabbix), Oracle (kernel, libsoup, postgresql:12, postgresql:13, postgresql:15, postgresql:16, redis:7, and ruby:3.1), SUSE (nodejs18, pam, qt6-webengine, and radare2), and Ubuntu (dogtag-pki, linux-intel-iotg, linux-intel-iotg-5.15, ofono, rabbitmq-server, and webkit2gtk).

Widespread exploitation of Cleo file transfer software (CVE-2024-50623)

Post Syndicated from Rapid7 original https://blog.rapid7.com/2024/12/10/etr-widespread-exploitation-of-cleo-file-transfer-software-cve-2024-50623/

Widespread exploitation of Cleo file transfer software (CVE-2024-50623)

On Monday, December 9, multiple security firms began privately circulating reports of in-the-wild exploitation targeting Cleo file transfer software. Late the evening of December 9, security firm Huntress published a blog on active exploitation of three different Cleo products (docs):

  • Cleo VLTrader, a server-side solution for “mid-enterprise organizations”
  • Cleo Harmony, which provides file transfer capabilities for “large enterprises”
  • Cleo LexiCom, a desktop-based client for communication with major trading networks  

Huntress’s blog says the exploitation they’re seeing across Cleo products results from an insufficient patch for CVE-2024-50623, a vulnerability disclosed in Cleo VLTrader, Cleo Harmony, and Cleo LexiCom in October 2024. Cleo indicated that the vulnerability was fixed in version 5.8.0.21 of all three solutions, but according to Huntress, 5.8.0.21 remains vulnerable to exploitation. CVE-2024-50623 is a cross-site scripting issue (CWE-79) that allows for unauthenticated remote code execution on target systems.

Update: Cleo evidently communicated with customers on December 10 acknowledging a “critical vulnerability in Cleo Harmony, VLTrader, and LexiCom that could allow an unauthenticated user to import and execute arbitrary bash or PowerShell commands on the host system by leveraging the default settings of the Autorun directory.”

As of December 10, Rapid7 MDR has confirmed successful exploitation of this issue in customer environments; similar to Huntress, our team has observed enumeration and post-exploitation activity and is investigating multiple incidents.

File transfer software continues to be a target for adversaries, and for financially motivated threat actors in particular. Rapid7 recommends taking emergency action to mitigate risk related to this threat.

Mitigation guidance

The following products and versions are vulnerable to CVE-2024-50623. The information below contradicts previous vendor guidance, which indicated that 5.8.0.21 resolved the issue. Cleo has updated their advisory as of December 10, 2024 to confirm 5.8.0.21 is still vulnerable.

  • Cleo Harmony before and including version 5.8.0.21
  • Cleo VLTrader before and including version 5.8.0.21
  • Cleo LexiCom before and including version 5.8.0.21

According to Huntress, “Cleo is preparing a new CVE designation and expects a new patch to be released mid-week.”

In the absence of an effective patch for CVE-2024-50623 (and any other CVEs that may be assigned to this exploit), Cleo customers should remove affected products from the public internet, ensuring they are behind a firewall. Per Huntress’s investigation, disabling Cleo’s Autorun Directory, which allows command files to be automatically processed, may also prevent the latter part of the attack chain from being executed.

Huntress’s blog has several descriptions of post-exploitation activity, including attack chain artifacts, commands run, and files dropped for persistence. Rapid7 recommends that affected customers review these indicators and investigate their environments for suspicious activity dating back to at least December 3, 2024.

Rapid7 customers

InsightVM and Nexpose customers will be able to assess their exposure to CVE-2024-50623 on Windows with an authenticated vulnerability check expected to be available in today’s (Tuesday, December 10) content release. Please note that content releases are typically available late in the evening ET on Patch Tuesday.

InsightIDR and Managed Detection and Response customers have existing detection coverage through Rapid7’s expansive library of detection rules. Rapid7 recommends installing the Insight Agent on all applicable hosts to ensure visibility into suspicious processes and proper detection coverage. Below is a non-exhaustive list of rules deployed and alerting on behavior related to this threat:

  • Suspicious Process – XORed Data in PowerShell
  • Suspicious Process – PowerShell System.Net.Sockets.TcpClient
  • Attacker Behavior – Possible Cleo MFT Exploitation 2024
  • Attacker Tool – PowerShell -noni -ep -nop Flags
  • Attacker Behavior – Obfuscated Powershell Script Containing -noni -ep -nop Flags
  • Suspicious Process – Powershell Invoke-WebRequest

Robotcop: enforcing your robots.txt policies and stopping bots before they reach your website

Post Syndicated from Celso Martinho original https://blog.cloudflare.com/ai-audit-enforcing-robots-txt

Cloudflare’s AI Audit dashboard allows you to easily understand how AI companies and services access your content. AI Audit gives a summary of request counts broken out by bot, detailed path summaries for more granular insights, and the ability to filter by categories like AI Search or AI Crawler.

Today, we’re going one step further. You can now quickly see which AI services are honoring your robots.txt policies, which aren’t, and then programmatically enforce these policies. 

What is robots.txt?

Robots.txt is a plain text file hosted on your domain that implements the Robots Exclusion Protocol, a standard that has been around since 1994. This file tells crawlers like Google, Bing, and many others which parts of your site, if any, they are allowed to access. 

There are many reasons why site owners would want to define which portions of their websites crawlers are allowed to access: they might not want certain content available on search engines or social networks, they might trust one platform more than another, or they might simply want to reduce automated traffic to their servers.

With the advent of generative AI, AI services have started crawling the Internet to collect training data for their models. These models are often proprietary and commercial and are used to generate new content. Many content creators and publishers that want to exercise control over how their content is used have started using robots.txt to declare policies that cover these AI bots, in addition to the traditional search engines.

Here’s an abbreviated real-world example of the robots.txt policy from a top online news site:

User-agent: GPTBot
Disallow: /

User-agent: ChatGPT-User
Disallow: /

User-agent: anthropic-ai
Disallow: /

User-agent: Google-Extended
Disallow: /

User-agent: Bytespider
Disallow: /

This policy declares that the news site doesn’t want ChatGPT, Anthropic AI, Google Gemini, or ByteDance’s Bytespider to crawl any of their content.

From voluntary compliance to enforcement

Compliance with the Robots Exclusion Protocol has historically been voluntary. 

That’s where our new feature comes in. We’ve extended AI Audit to give our customers both the visibility into how AI services providers honor their robots.txt policies and the ability to enforce those policies at the network level in your WAF

Your robots.txt file declares your policy, but now we can help you enforce it. You might even call it … your Robotcop.  

How it works

AI Audit takes the robots.txt files from your web properties, parses them, and then matches their rules against the AI bot traffic we see for the selected property. The summary table gives you an aggregated view of the number of requests and violations we see for every Bot across all paths. If you hover your mouse over the Robots.txt column, we will show you the defined policies for each Bot in the tooltip. You can also filter by violations from the top of the page. 


In the “Most popular paths” section, whenever a path in your site gets traffic that has violated your policy, we flag it for visibility. Ideally, you wouldn’t see violations in the Robots.txt column — if you do see them, someone’s not complying.


But that’s not all… More importantly, AI Audit allows you to enforce your robots.txt policy at the network level. By pressing the “Enforce robots.txt rules” button on the top of the summary table, we automatically translate the rules defined for AI Bots in your robots.txt into an advanced firewall rule, redirect you to the WAF configuration screen, and allow you to deploy the rule in our network.

This is how the robots.txt policy mentioned above looks after translation:


Once you deploy a WAF rule built from your robots.txt policies, you are no longer simply requesting that AI services respect your policy, you’re enforcing it.

Conclusion

With AI Audit, we are giving our customers even more visibility into how AI services access their content, helping them define their policies and then enforcing them at the network level.

This feature is live today for all Cloudflare customers. Simply log into the dashboard and navigate to your domain to begin auditing the bot traffic from AI services and enforcing your robots.txt directives.

Икономически аспект на случилото се в Сирия

Post Syndicated from VassilKendov original https://kendov.com/syria_now/

Икономически аспект на случилото се в Сирия

Малко се говори за икономическата страна на падането на режима на Асад в Сирия. Повечко се коментира военната страна на конфликта, а то такава реално нямаше. Армията бе разпусната и Асад призова за мирно предаване на властта. Нещо повече – разпуснатите войници дори не унищожиха военната си техника, а я оставиха в ръцете на „враговете си“ което е немислимо в един военен кофликт. Това ме наведе на мисълта, че случващото се няма нищо общо с военните действия и се зарових в икономическите предпоставки.

Информацията, която намерих и обобщих е на база информация от мрежата, понеже официална статистика е до 2020 година, а във военни времена не е ясно колко е меродавна тази статистика.

Моля използвайте приложената форма за записване на час за среща
[contact-form-7]

Твърди се в медиите, че от няколко месеца армията на Асад е получавала по 35 долара на месец като заплата на глава. Сами разбираме, че с тези пари не може да се поддържат военни действия и войниците да са мотивирани. Лично аз предполагам, че е такова положението или поне близко до това, понеже вторият по големина град – Алепо, което е и индустриалното сърце на Сирия, отдавна е под турски контрол. Твърди се, че там официална валута е турската лира. Също така за петролните кладенци в провинцията Идлиб има изписано доста, как Сирия предявява претенции към САЩ, после към Турция… Да не забравяме и санкциите от САЩ
Осен всичко това, плодородните земи също от дълго време са в ръцете на Турция и кюрдите. С две думи Сирия няма от какво да издържа армията и режима си.

ВЪПРОСЪТ Е КОЙ ПЛАЩАШЕ ДО СЕГА?

Финансови услуги за фирми и Физически лица

Моето мнение е, че това бяха руснаците. Те имаха най-голям интерес от този режим, но с войната в Украйна, явно вече им стана неизгодно да плащат за издръжка на режима, само и само да имат 2 бази в Сирия. Верно е, че са стратегически, но пък всичко е въпрос на средства. Ако е прекалено скъпо, то не може да е вечно.
Турция от своя страна приюти „демократичните ислямисти“ в лагери и ги обучава достатъчно дълго време, за да ги върне на терена. И докато повечето хора смятат, че големия печеливш е точно Турция, аз мисля, че не е така. Мисля че е Израел, защото на Турция и предстоят тежки времена с кюрдите, както и бъдещата издръжка на една цяла държава с население около 20 милиона. Казваме около, защото не знаем реално колко е към момента. Явно руснаците повече нма да плащат и оставят това право на Турция, което до момента само получаваше финансовите облаги от владеенето на териториите, но сега ще плаща за изграждане на държава, доколкото това е възможно изобщо. Предстои им и сбъсък с кюрдите, които пък са стратегически партньор на САЩ. А САЩ от своя страна е много малко вероятно да се включат финансово в издръжката на новата държава.

ЗАЩО Е ПЕЧЕЛИВШ ИЗРАЕЛ?

Защото въпреки, че декларира ненамеса в кофлита, това не им попречи да завземат южния военен пункт на сирийска територия, който имаше пряка видимост към Голанските възвишения, както и да нанесе въздушни удари по военни складове на сирийска територия за да не попаднат оржията в ръцете на джихадисти. Какви точно джихадисти, щом „демократичните ислямисти“ са взели властта – не се казва, но така или иначе оръжията са унищожени, а израелската войска е на сирийска територия.

КЪДЕ ЩЕ СЕ ДЕНЕ РУСИЯ?

Медиите твърдят, че транспортни самолети кацат в руските бази и изнасят оръжие и техника от там. Не е ясно каква е тази техника. Дали е от самите бази или от други по малки бази в страната. Твърди се също, че „демократичните ислямисти“ заобикалет руските воени бази.
При всички положения имаме освободена военна техника и предполагам не е сложно да предположим къде ще бъде разположена тя, ако базите бъдат закрити.
Казвам ако бъдат закрити, защото не знаем каква е договорката. А че има договорка е повече от ясно, предвид мирното предаване на властта.

ТРЯБВАТ ПАРИ ЗА ДА СЕ ТУШИРА НАПРЕЖЕНИЕТО

При всички положения новата власт ще се нуждае от пари, за да тушира напрежението. Ако ли не, в тази мултикултурна, раздирана от конфликт земя, където всеки е срещу всеки, ще продължи насилието на религиозна основа. Колкото и да се твърди, че новите „демократични ислямисти“ имат договорки с малцинствата и не ги закачат за момента, едно е ясно – когато ограничиш ресурса и няма достатъчно за всички, малцинствата страдат.
Моето мнение е, че точно това ще се случи на следващия етап. Няма начин след война да няма реваншизъм. Тоест има, но то се нарича НАРОДЕН СЪД. Нещо което много съвременни демократи не харесват, но това е единствения начин да се спре саморазправата в огромни мащаби след война. Прочетете как е било в Руанда, вижте как е било във войната между Етиопия и Еритрея и го наречете както искате, щом определението „Народен съд“ не ви харесва. Но съд ще трябва да има, ако не искаме саморазправи.

РЕСУРСИТЕ

Сирия е на пътя на доста ресурси. Петрол или газ имаме в Иран, Ирак, Кувейт, Саудитска Арабия, Катар, Бахрейн… Ако има има тръби, които да идват в Европа, но да заобикалят Турция, то те тряба да минат през Сирия. Но Турция не иска това. А Русия изобщо не иска да има тръби към Европа. Затова са и техните бази в Сирия, да охраняват маршрута и да гарантират, че няма да има тръби, които да доставят евтин петрол в Европа, който да ги заобикаля. Единствения начин в сегашната обстановка това да остане така е липсата на държава в Сирия, постоянни военни сблъсъци или руските бази да си останат под някаква форма.
Аз не знам каква е договорката и дали техните бази ще останат в сегашната обстановка, но ако се махнат от там, то най-логичното е Русия и Иран да започнат да поддържат и те някаква опозиция или фракция, което е безкрайно по-евтино от поддържането на режим или изграждането на държава.
Личното ми очакване е, че точно това ще се случи.

БЕЖАНЦИТЕ

Гледаме по телевизията колко щастливи са всички от новата власт, но за мен си съм убеден, че това не е така. Виждаме дори, че много сирийци се завръщали в Сирия от Турция. Виждайки как Ердоган търгуваше с Европа посредством бежанците, сега ще е безкрайно щаствлив да изпразни лагерите и да засели териториите граничещи с кюрдите точно с тези бежанци, които години наред хранеше в лагерите и от чиито среди възпита и обучи „демократичните ислямисти“. Да му мислят кюрдите, защото те също се биеха с армията на Асад, докато пък те се биеха с армията на „демократичните ислямисти“. Сега единствената им надежда е САЩ, но въпросът е дали Турция може да плаща и колко, за да държи нещата мирни, защото изобщо не ми се вярва САЩ да плащат и за този конфликт. Най-малко ще се окажат в положението на СССР през 89-та, когато издържаха неефективни режими и съвсем закономерно се разпаднаха.
Европа пък изобщо не я виждам като платец. Те и на Ливан отказаха  да плащат вече, а ги чака Украйна, и то в момент, когато германската икономика е в рецесия.
От друга страна Германия и Австрия обявиха официално, че вече няма да приемат бежанци от Сирия. Не ми се вярва и Ердоган да ги приема, защото те вече ще са от другите, а си има правитество в Сирия и тези хора ще са му нужни за а работят, да спират кюрдите и да плащат данъци за поддръжка на новото правителство.
В Европа обаче има маса сирийци и араби. А най-разумното нещо в момента за всеки нормален човек е да защити семейството си. Не мисля, че в следващите години това ще е възможно в Сирия. И дори Турция, Германия и Австрия да не искат повече бежанци от Сирия, саморазправата и насилието тепърва предстоят в онзи район. Както казахме почвата е идеална за Русия и Иран със сравнително малко пари да поддържат новата „демократична опозиция“, само и само да не минават тръби на техни конкуренти, като за всеки изхарчен долар, Турция или ЕС ще трябва да дава по 1000 за да се опита да задържи населението или да изгради държава. Не случайно Асад нареди разпускане на армията и не унищожиха оръжието. Имат да си връщат територията от Израел. Пък като не си я върнат, ще се съобазяват дългосрочно и ще служат на Израел под един или друг начин. Все пак Израел ще владее възвишенията. Ако не беше толкова важно и не им даваха контрол, изобщо нямаше да се опитват да влизат на сирийска територия.

На база всичко казано, аз си правя извода, че големият въпрос в случая е КОЙ ЩЕ ПЛАЩА ЗА СИРИЯ за да продължи да съществува? Не вярвам Турция да може дори и да иска, а Иран и целия останал арабски свят надали ще е много щастлив от разширението на Турция.

Само времето ще покаже какво ще се случи, но през това време доста човешки съдби ще получат нова посока.

Васил Кендов

The post Икономически аспект на случилото се в Сирия appeared first on Kendov.com.

Археология на утопията. Посткомунистическото във видеоигрите (продължение)

Post Syndicated from original https://www.toest.bg/arheologia-na-utopiyata-postkomunisticheskoto-vuv-videoigrite-produlzhenie/

<< Към първа част

Археология на утопията. Посткомунистическото във видеоигрите (продължение)

Северина Станкева: Предишният ни разговор завърши с темата за разпада, която ми се иска да продължим. Изглежда, че в посткомунистическите държави смъртта на утопията се възприема по особено подчертано автоимунен начин, което би могло да се обясни през статута и историческата съдба на утопичния проект в тях. Това е видимо и във видеоигрите.

В Диско Елизиум ахроматичният феномен на Сивотата създава двумилиметрови дупки в тъканта на света. Докато Сивотата е едновременно разделителна тъкан на материята и смесва всичко с всичко – физическите, епистемологическите и лингвистичните качества на нещата по границите ѝ образуват безбрежна ентропична супа, – дупките са предвестници на пълното унищожение. Тъкмо около тях спонтанно се формират духовни институции с апокалиптичен характер – църкви, философски нощни клубове и други.

В първата част на Фростпънк (полска игра, в която играчът приема ролята на лидер на последния град на света, разрушен от безкрайна вулканична зима) – независимо дали оцеляването е постигнато и дори границата на хуманността (буквално има такава) да не е премината – „най-добрият“ край все пак задава въпроса дали всичко си е заслужавало и дали тази граница не се намира всъщност другаде. Доколко това морализаторстване е оправдано, като имайме предвид, че играчът няма какво да направи, за да не премине и невидимата граница, освен може би да спре да играе играта, е друга тема. Във втората част е предприета доста различна, но също толкова съмнителна стратегия относно възможните финали. Имаме един утопичен – всички са щастливи, всичко е наред; друг, в който онези, които не искат мир, са обезвредени; и трети, в който играчът е очевиден диктатор, но мирът пак е постигнат. И в трите случая краят се приема за успешен, с разликата, че в първия и третия успехът изглежда по-голям. Съобщението е едно и също: „Противно на всички шансове, ти успя.“

Какво е отношението на утопията и разпада според вас и в кои игри могат да се открият следите му?

Миглена Николчина: С Еньо Стоянов вече сме обсъждали някои аспекти на тази тема1. Разминаването ни беше в съпоставката между поредиците Метро и Ядрена зима: моята позиция беше, че има принципна разлика между гигантските отломъци на една утопия, сред които се развива действието в Метро, и сантименталните руини на средната класа, сред които си проправяме път в Ядрена зима. Според Еньо по-скоро няма принципна разлика (ако съм го разбрала правилно). Неговата теза е поддържана – извън контекста на видеоигрите – например от Сюзън Бък-Морс в „Мечтани светове и катастрофа. Отмирането на масовата утопия на Изток и Запад“2. Според нея става дума за две аналогични утопии за благоденствие на масите – съветската и американската, – с които е дошло време да се простим. Аз обаче настоявам, отвъд амнезията и носталгиите, върху отгласите от специфичния политически и социален опит на бившите соцстрани. Мисля, че тези отгласи включват повишена чувствителност както към вакуума, който крахът на утопиите оставя след себе си, така и към узурпирането на утопичните проекти от една или друга поредна номенклатура.

Сивотата в Диско Елизиум може да бъде пример за това. Теорията за ерозията на реалността е изложена в играта от една хибридна фигура – ултралибералката (ре)Джойс. Тя е местна жена, зачеркнала някогашната си принадлежност и преминала в лагера на, така да се каже, светлоогъвателите: един от най-забавните персонажи в играта е мегабогаташът, който живее в контейнер, за да не го притесняват просители, и чието лицезрение огъва светлината по силата на „физически закон“, извлечен от романите на Емил Зола. Който е чел Зола, ще разбере. Джойс въплъщава припокриването между ултралибералното корпоративно богатство и морализма на „Моралинтерна“, днешната версия на Комунистическия интернационал. Доколкото ерозиралата реалност е стихията, през която новата номенклатура, Джойс и подобните на нея навигират, ерозията на реалността се оказва скритото опако на Моралинтерна. Тази ерозия е продукт не на старата, а на днешната утопия: продукт на старата утопия е остротата, с която в Диско Елизиум новият утопичен ерзац е съзнаван като вътрешно кух и неспособен да запълни вакуума от предишните сринати проекти.

Eньо Стоянов: Може би било удачно да спрем поглед и на рецептивната страна на въпроса, тъй като тя несъмнено дава и тон на производството в бившите социалистически страни. Първите игри от поредицата Ядрена зима и до днес получават неофициални продължения и модификации от играчи в Източна Европа десетилетия след като западноевропейските играчи са преместили фокуса си върху по-новите заглавия от нея и вероятно дори веднъж не са изигравали изходните заглавия.

Неслучайно този интерес на източноевропейците доведе до поява на заглавия като Атом RPG, който без преувеличение може да се определи като превод на света и системите на първите игри от Ядрена зима в постсъветски апокалиптичен контекст. Герои на мощ и магия 3, също заглавие от края на 90-те, продължава мощно да се играе онлайн днес, при това главно на украински сървъри (преди войната сървърите бяха предимно руски), където по лобитата могат да се открият и много български звучащи прозвища на играчи. И това е при положение, че споменатата поредица си има по-късни продължения (към момента е стигнала до номер 7). Нещо повече, интересът към тази игра се поддържа от времето на създаването ѝ до днес отново с неофициални допълнения, последното от които е от миналата година и е дело на руски разработчици аматьори – явно поне на терена на играенето в мрежа на Герои 3 руснаци и украинци съумяват някак да съжителстват.

Сред тази поредица от примери е уместно да споменем и един български принос – миналата година българското студио Haemimont Games издаде трета част на поредицата Нащърбен съюз. Предишната част също е от края на 90-те и се оказва с „култов“ статус именно в източноевропейски контекст.

Бегло очертаната тук фиксация на вниманието на играчите в бившите соцстрани около заглавия от края на 90-те е закономерна – в тях това е времето на интернет кафенетата, направили за първи път малко по-достъпни видеоигрите в периода на Прехода. Несъмнено всичко това говори за някаква особена носталгия, залозите на която са многоизмерни – от една страна, това е носталгия по обещанието, заложено в самата технология, овъзможностяваща видеоигрите и несъмнено вдъхновила този тласък към онова, за което говореше Северина в предишната част на разговора – т.нар. евровехтории от периода след 2000 г., заглъхнал почти напълно в настоящата ситуация на все по-окрупнена корпоративна форма на производство. Но вероятно тук можем да забележим и по-дълбок корен на тази носталгия – носталгия по утопичните обещания на самия преход в посткомунистическите страни, вещан символно и през самата поява на видеоигрите в тях.

Миглена Николчина: Това е страшно интересно и може да ни отведе към друга тема. За отбелязване е, че през 2008 г. полското студио CD Projekt RED, пожънало огромен международен успех с поредицата Вещерът, създава дъщерна фирма за разпространение, която се казва Good Old Games (GOG), тоест Добрите стари игри. Аз даже мислех, че GOG е създаден по-отдавна, но според Уикипедия годината е тази. По това време първият Вещер току-що е излязъл. Сякаш създателите му още тогава се загрижват за бъдещето на играта си като класика! GOG днес функционира като платформа без вградено управление на дигитални права (DRM) – знак за вярност към утопията за свободно споделяне, която споменаваш. Неотдавна GOG обяви свой нов проект, който са нарекли GOG Preservation Program (Програма за съхраняване на игрите). Един парадоксален ефект на новите технологии е, че продуктите, създадени с тях, се оказват ужасно нетрайни; старите игри бързо стават невъзпроизводими. Новата програма на Добрите стари игри, в духа на собственото си име, си поставя за задача да се бори с бързата смъртност на игрите. В момента има реставрирани над 100 заглавия. Очевидно много играчи ще се зарадват, както се вижда от наблюденията на Еньо, а за изследователите оцеляването на старите игри е абсолютно фундаментално условие. Не виждаме ли в примера с GOG обаче различно отношение не само към утопията, но и към историята?

Еньо Стоянов: Загрижеността около достъпността на стари игри несъмнено е реакция на ситуацията, установила се през последните петнайсетина години на софтуерния пазар. Тя е следствие на това, че дигиталните продукти всъщност вече не са стоки, които можеш да си купиш и да притежаваш (и при нужда, стига да имаш необходимите умения, да приспособиш към нови платформи, операционни системи и пр.), по-скоро корпоративният производител ти издава лиценз за ползване, който може да ти отнеме напълно (нещо, което се случва все по-често), щом сметне, че поддръжката на достъпност на софтуера е вече нерентабилна. Това е по-скоро ефект от липсващи законодателни рамки, които да защитават интересите на потребителите за достъп до софтуер, заплатен от тях.

В момента дори в ЕС се събират подписи за петиция, изискваща правни мерки, които да подсигурят производителите на игри с онлайн достъп да гарантират достъпността на продуктите си след приключване на официалната им поддръжка – в момента корпорациите просто погребват такива игри, за да си спестят разходи по поддръжка на сървърите. Подобни инициативи не са само въпрос на носталгия – тук се намесват въпроси за потребителски права, за интереси от академичен характер и т.н. Носталгичните склонности на посткомунистическите общности от играчи са, струва ми се, по-директно фиксирани около утопичния хоризонт, който самото съществуване на видеоигрите е предвещавало в даден момент и който днешната им индустриална ситуация почти напълно е похабила.

Северина Станкева: Описаното от Еньо показва не само как работи носталгията по добрите стари игри, но и самата добра стара носталгия. Да се каже, че тя е копнеж по миналото, е неточно. Зовът ѝ за завръщане е по-скоро насочен към едно минало бъдеще, т.е. възможността тук е с много по-висок статут от действителността. Реализирането на една или повече възможности неминуемо отдалечава от тази потентна точка на произхода, която предварително е осъдена да бъде пропусната, именно заради порива, който я задвижва. Изглежда, разработчиците на Вещерът се стремят да избегнат това, предпазвайки класическата си игра, преди тя да е станала такава.

Любопитно е, че що се отнася до носталгията по игрите от 90-те, ретротопичните общности от постсоциалистическите държави се оказват с доста голям възрастов диапазон и ако погледнем формално, включват няколко поколения, които, въпреки че донякъде споделят опит в дейността на играенето – компютърни клубове и носители със съмнителен произход, – изпитват носталгия по различни заглавия, макар и пуснати на пазара по същото време. Поколението играчи, което не е и чувало за Герои 3, също помни игри от 90-те, нищо че тогава тепърва се е раждало. Това може да се обясни с обстоятелството, че определени заглавия, най-вече конзолни, стават масово достъпни със закъснение в бившите соцдържави. И в паметта на това следващо поколение игрите на „Дисни“ от края на 90-те например са естествено свързвани с флашигрите или с игрите за браузър от средата на първото десетилетие на ХХI век, макар че, обективно погледнато, между тях има отстояние от около десет години. Херкулес например излиза в същата година като първата част на Ядрена зима, но едва ли ще се намерят много местни играчи, еднакво сантиментални и към двете, или въобще играли и двете. Разбира се, не е за пренебрегване и фактът, че тези игри са ориентирани към различни възрастови публики, но в паметта на западноевропейските общности те все пак могат да се открият една до друга.

Миглена Николчина: Аз пак ще дръпна разговора към съдържанието на игрите. Поредицата Вещерът, при все че действието се разиграва в измислени царства, обитавани от фантастични раси и чудовища, предлага ясни алегории на полската история. Играта е историческа по същността си, ако и да не е фактологически такава. Амбициозната историческа поредица Кредото на убиеца тръгва от словенски роман: тя се гради на фантастичното допускане, че е възможно да се изживее в плът (така, така – виртуална, де) миналото на предците. Поредицата Метро е дистопия, но в нея има исторически наслагвания, които днешните събития ни карат да преосмислим като исторически фатум. Историческа до степен да претендира за учебно помагало е Идното царство. За Диско Елизиум няма пак да говоря. Ако един от белезите на днешната епоха е, както често се твърди, залиняването на чувството за време и история, тези източноевропейски примери показват изненадващото оцеляване на това чувство във видеоигрите. Тук бих включила и стратегиите на българския разработчик Веселин Ханджиев. Искам да кажа накратко, че археологията на утопията – изненадващо или не – отваря хоризонтите на историята.

Северина Станкева: Миглена каза, че няма да говори повече за Диско Елизиум, но аз не мога да се въздържа от един последен пример, който прекрасно илюстрира връзката утопия–история. Когато играта те хване, че избираш реплики с ляв уклон, се появява Реторика, която ти подшушва, че изглежда, си готов да построиш комунизма отново. Нищо че не се е получавало преди – любовта също не ти се е получавала досега, но значи ли това, че трябва да се откажеш от нея? И въобще, продължава Реторика, провалът е в сърцето на комунизма, ти трябва да го построиш отново именно защото е невъзможно. Ти можеш да се превърнеш в Последния Комунист, който еднолично ще износи на раменете си работническата класа и ще осъществи мечтите ѝ. Ако играчът на това място избере буквално да запретне ръкави и да започне да строи комунизма, Реторика се провиква да влязат фургоните и отрядите за разстрел. Ако играчът каже, че не е искал нищо такова да се случи, отговорът е: вече е твърде късно. Не можеш да направиш омлет, без да счупиш няколко милиона яйца. 

Миглена Николчина: Трябва да оценим тази ирония на фона на многократните преки заявления на Курвиц, че е ленинец. Аз не съм стигала до яйцата и въобще не изкарах нито една от четирите политически линии докрай, винаги си правех миш-маш от четирите. Както и – друг проблем на прекалено неигровото ми играене – моето ченге и в трите ми превъртания домисляше мъчително дългата и с множество негативни снижения на способностите му „мисъл“ от мисловния шкаф, наречена „Пустата земя на реалността“ (Waste Land – препратка към Елиът?), накратко, ставаше заклет въздържател. Но не вярвам да има вариант, при който да избегнеш многопластовата ирония, включително политическа – иронията пропива всеки компонент на играта, предметите, дрехите на ченгето, имената, които може да си даде. Например обличането на възможно най-скучния на вид „междуостровен панталон“ (така, предполагам, трябва да се преведе interisolary trousers – светът на Диско Елизиум е островен архипелаг) повишава шанса ти да домислиш „Царството на съвестта“, което е линията на Моралинтерна, и е нужно за успеха на бизнес плана, който предлагаш на светлоогъващия мегабогаташ. Този панталон, така да се каже, олицетворява брака на морализма и монетизацията. Тъй като „междуостровна“ е наречена и валутата в играта, панталонът съответно придобива значение на валутна конвертируемост…

Иронията е съществен аспект и на поредицата Вещерът, но по отношение на днешните готови идеи тази ирония значително намалява с всяка следваща част. От друга страна, CD Projekt RED създават и този съвършено различен (и струва ми се, недостатъчно критически оценен) шедьовър – дистопията Киберпънк. Мегаполисът, където се развива действието, би могъл да бъде на много места, той е изграден с плътност, която засега е ненадмината, но при цялата му киберфутуристичност не си го представям в Полша или въобще в Европа. Този град е едно друго време, но той е и едно друго място, той е не-тук, другаде.

Ще припомня, че през 60-те години в България кипи голям дебат, свързан с литературата – дали голямата литература трябва да е национално или дори регионално локална („котловинна“ е тогавашният термин), или универсална. Цветан Стоянов се включва в този дебат с едно прекрасно кратко есе „По повод духа на мястото“, където в крайна сметка казва, че… ами зависи3. С Вещерът и Киберпънк CD Projekt RED показват, че могат да правят и едното, и другото – и двата пъти успешно достигайки до големи публики. Успехът обаче има цена и тепърва ще видим дали тази цена няма да струва уникалността на полското студио.

1 Вж. (Анти)утопично въображение и трансхуманизация във видеоигрите. – Във: Видеоигрите. Опасната Муза. София: Версус, 2023, с. 382–404.

2 Susan Buck-Morss. Dreamworld and Catastrophe: The Passing of Mass Utopia in East and West. Cambridge, Mass: MIT Press, 2000.

3 Цветан Стоянов. Културата като общение. Т. 1. София: Български писател, 1988, с. 188–193.


В рубриката „Игромислие“ публикуваме разговори, в които се срещат, съпоставят и противопоставят различни гледни точки към многоизмерния, многожанров феномен на видеоигрите – не толкова като електронен спорт, колкото като нов синтез на изкуствата и като ново поле на общуване и социалност. 

Build Write-Audit-Publish pattern with Apache Iceberg branching and AWS Glue Data Quality

Post Syndicated from Tomohiro Tanaka original https://aws.amazon.com/blogs/big-data/build-write-audit-publish-pattern-with-apache-iceberg-branching-and-aws-glue-data-quality/

Given the importance of data in the world today, organizations face the dual challenges of managing large-scale, continuously incoming data while vetting its quality and reliability. The importance of publishing only high-quality data can’t be overstated—it’s the foundation for accurate analytics, reliable machine learning (ML) models, and sound decision-making. Equally crucial is the ability to segregate and audit problematic data, not just for maintaining data integrity, but also for regulatory compliance, error analysis, and potential data recovery.

AWS Glue is a serverless data integration service that you can use to effectively monitor and manage data quality through AWS Glue Data Quality. Today, many customers build data quality validation pipelines using its Data Quality Definition Language (DQDL) because with static rules, dynamic rules, and anomaly detection capability, it’s fairly straightforward.

Apache Iceberg is an open table format that brings atomicity, consistency, isolation, and durability (ACID) transactions to data lakes, streamlining data management. One of its key features is the ability to manage data using branches. Each branch has its own lifecycle, allowing for flexible and efficient data management strategies.

This post explores robust strategies for maintaining data quality when ingesting data into Apache Iceberg tables using AWS Glue Data Quality and Iceberg branches. We discuss two common strategies to verify the quality of published data. We dive deep into the Write-Audit-Publish (WAP) pattern, demonstrating how it works with Apache Iceberg.

Strategy for managing data quality

When it comes to vetting data quality in streaming environments, two prominent strategies emerge: the dead-letter queue (DLQ) approach and the WAP pattern. Each strategy offers unique advantages and considerations.

  • The DLQ approach – Segregate problematic entries from high-quality data so that only clean data makes it into your primary dataset.
  • The WAP pattern – Using branches, segregate problematic entries from high-quality data so that only clean data is published in the main branch.

The DLQ approach

The DLQ strategy focuses on efficiently segregating high-quality data from problematic entries so that only clean data makes it into your primary dataset. Here’s how it works:

  1. As data streams in, it passes through a validation process
  2. Valid data is written directly to the table referred by downstream users
  3. Invalid or problematic data is redirected to a separate DLQ for later analysis and potential recovery

The following screenshot shows this flow.

bdb4341_0_1_dlq

Here are its advantages:

  • Simplicity – The DLQ approach is straightforward to implement, especially when there is only one writer
  • Low latency – Valid data is instantly available in the main branch for downstream consumers
  • Separate processing for invalid data – You can have dedicated jobs to process the DLQ for auditing and recovery purposes.

The DLQ strategy can present significant challenges in complex data environments. With multiple concurrent writers to the same Iceberg table, maintaining consistent DLQ implementation becomes difficult. This issue is compounded when different engines (for example, Spark, Trino, or Python) are used for writes because the DLQ logic may vary between them, making system maintenance more complex. Additionally, storing invalid data separately can lead to management overhead.

Additionally, for low-latency requirements, the processing validation step may introduce additional delays. This creates a challenge in balancing data quality with speed of delivery.

To solve those challenges in a reasonable way, we introduce the WAP pattern in the next section.

The WAP pattern

The WAP pattern implements a three-stage process:

  1. Write – Data is initially written to a staging branch
  2. Audit – Quality checks are performed on the staging branch
  3. Publish – Validated data is merged into the main branch for consumption

The following screenshot shows this flow.

bdb4341_0_2_wap

Here are its advantages:

  • Flexible data latency management – In the WAP pattern, the raw data is ingested to the staging branch without data validation, and then the high-quality data is ingested to the main branch with data validation. With this characteristic, there’s flexibility to achieve urgent, low-latency data handling on the staging branch and achieve high-quality data handling on the main branch.
  • Unified data quality management – The WAP pattern separates the audit and publish logic from the writer applications. It provides a unified approach to quality management, even with multiple writers or varying data sources. The audit phase can be customized and evolved without affecting the write or publish stages.

The primary challenge of the WAP pattern is the increased latency it introduces. The multistep process inevitably delays data availability for downstream consumers, which may be problematic for near real-time use cases. Furthermore, implementing this pattern requires more sophisticated orchestration compared to the DLQ approach, potentially increasing development time and complexity.

How the WAP pattern works with Iceberg

The following sections explore how the WAP pattern works with Iceberg.

Iceberg’s branching feature

Iceberg offers a branching feature for data lifecycle management, which is particularly useful for efficiently implementing the WAP pattern. The metadata of an Iceberg table stores a history of snapshots. These snapshots, created for each change to the table, are fundamental to concurrent access control and table versioning. Branches are independent histories of snapshots branched from another branch, and each branch can be referred to and updated separately.

When a table is created, it starts with only a main branch, and all transactions are initially written to it. You can create additional branches, such as an audit branch, and configure engines to write to them. Changes on one branch can be fast-forwarded to another branch using Spark’s fast_forward procedure, as shown in the following screenshot.

bdb4341_0_3_iceberg-branch

How to manage Iceberg branches

In this section, we cover the essential operations for managing Iceberg branches using SparkSQL. We’ll demonstrate how to use the branches, specifically, to create a new branch, write to and read from a specific branch, and set a default branch for a Spark session. These operations form the foundation for implementing the WAP pattern with Iceberg.

To create a branch, run the following SparkSQL query:

ALTER TABLE glue_catalog.db.tbl CREATE BRANCH audit

To specify a branch to be updated, use the glue_catalog.<database_name>.<table_name>.branch_<branch_name> syntax:

INSERT INTO glue_catalog.db.tbl.branch_audit VALUES (1, 'a'), (2, 'b');

To specify a branch to be queried, use the glue_catalog.<database_name>.<table_name>.branch_<branch_name> syntax:

SELECT * FROM glue_catalog.db.tbl.branch_audit;

To specify a branch for the entire Spark session scope, set the branch name to the Spark parameter spark.wap.branch. After this parameter is set, all queries will refer to the specified branch without explicit expression:

SET spark.wap.branch = audit

-- audit branch will be updated
INSERT INTO glue_catalog.db.tbl VALUES (3, 'c');

How to implement the WAP pattern with Iceberg branches

Using Iceberg’s branching feature, we can efficiently implement the WAP pattern with a single Iceberg table. Additionally, Iceberg characteristics such as ACID transactions and schema evolution are useful for handling multiple concurrent writers and varying data.

  1. Write – The data ingestion process switches branch from main and it commits updates to the audit branch, instead of the main branch. At this point, these updates aren’t accessible to downstream users who can only access the main branch.
  2. Audit – The audit process runs data quality checks on the data in the audit branch. It specifies which data is clean and ready to be provided.
  3. Publish – The audit process publishes validated data to the main branch with the Iceberg fast_forward procedure, making it available for downstream users.

This flow is shown in the following screenshot.

bdb4341_0_4_wap-w-iceberg-branch

By implementing the WAP pattern with Iceberg, we can obtain several advantages:

  • Simplicity – Iceberg branches can express multiple states of a table, such as audit and main, within one table. We can have unified data management even when handling multiple data contexts separately and uniformly.
  • Handling concurrent writers – Iceberg tables are ACID compliant, so consistent reads and writes are guaranteed even when multiple reader and writer processes run concurrently.
  • Schema evolution – If there are issues with the data being ingested, its schema may differ from the table definition. Spark supports dynamic schema merging for Iceberg tables. Iceberg tables can flexibly evolve their schema to write data with inconsistent schemas. By configuring the following parameters, when schema changes occur, new columns from the source are added to the target table with NULL values for existing rows. Columns present only in the target have their values set to NULL for new insertions or left unchanged during updates.
SET `spark.sql.iceberg.check-ordering` = false

ALTER TABLE glue_catalog.db.tbl SET TBLPROPERTIES (
    'write.spark.accept-any-schema'='true'
)
df.writeTo("glue_catalog.db.tbl").option("merge-schema","true").append()

As an intermediate wrap-up, the WAP pattern offers a robust approach to managing the balance between data quality and latency. With Iceberg branches, we can implement WAP pattern simply on single Iceberg table with handling concurrent writers and schema evolution.

Example use case

Suppose that a home monitoring system tracks room temperature and humidity. The system captures and sends the data to an Iceberg based data lake built on top of Amazon Simple Storage Service (Amazon S3). The data is visualized using matplotlib for interactive data analysis. For the system, issues such as device malfunctions or network problems can lead to partial or erroneous data being written, resulting in incorrect insights. In many cases, these issues are only detected after the data is sent to the data lake. Additionally, the correctness of such data is generally complicated.

To address these issues, the WAP pattern using Iceberg branches is applied for the system in this post. Through this approach, the incoming room data to the data lake is evaluated for quality before being visualized, and you make sure that only qualified room data is used for further data analysis. With the WAP pattern using the branches, you can achieve effective data management and promote data quality in downstream processes. The solution is demonstrated using AWS Glue Studio notebook, which is a managed Jupyter Notebook for interacting with Apache Spark.

Prerequisites

The following prerequisites are necessary for this use case:

Set up resources with AWS CloudFormation

First, you use a provided AWS CloudFormation template to set up resources to build Iceberg environments. The template creates the following resources:

  • An S3 bucket for metadata and data files of an Iceberg table
  • A database for the Iceberg table in AWS Glue Data Catalog
  • An AWS Identity and Access Management (IAM) role for an AWS Glue job

Complete the following steps to deploy the resources.

  1. Choose Launch stack.

Launch Button

  1. For the Parameters, IcebergDatabaseName is set by default. You can also change the default value. Then, choose Next.
  2. Choose Next.
  3. Choose I acknowledge that AWS CloudFormation might create IAM resources with custom names.
  4. Choose Submit.
  5. After the stack creation is complete, check the Outputs The resource values are used in the following sections.

Next, configure the Iceberg JAR files to the session to use the Iceberg branch feature. Complete the following steps:

  1. Select the following JAR files from the Iceberg releases page and download these JAR files on your local machine:
    1. 1.6.1 Spark 3.3_with Scala 2.12 runtime Jar
    2. 1.6.1 aws-bundle Jar
  2. Open the Amazon S3 console and select the S3 bucket you created through the CloudFormation stack. The S3 bucket name can be found on the CloudFormation Outputs tab.
  3. Choose Create folder and create the jars path in the S3 bucket.
  4. Upload the two downloaded JAR files to s3://<IcebergS3Bucket>/jars/ from the S3 console.

Upload a Jupyter Notebook on AWS Glue Studio

After launching the CloudFormation stack, you create an AWS Glue Studio notebook to use Iceberg with AWS Glue. Complete the following steps.

  1. Download wap.ipynb.
  2. Open AWS Glue Studio console.
  3. Under Create job, select Notebook.
  4. Select Upload Notebook, choose Choose file, and upload the notebook you downloaded.
  5. Select the IAM role name, such as IcebergWAPGlueJobRole, that you created through the CloudFormation stack. Then, choose Create notebook.
  6. For Job name at the left top of the page, enter iceberg_wap.
  7. Choose Save.

Configure Iceberg branches

Start by creating an Iceberg table that contains a room temperature and humidity dataset. After creating the Iceberg table, create branches that are used for performing the WAP practice. Complete the following steps:

  1. On the Jupyter Notebook that you created in Upload a Jupyter Notebook on AWS Glue Studio, run the following cell to use Iceberg with Glue. %additional_python_modules pandas==2.2 is used to visualize the temperature and humidity data in the notebook with pandas. Before running the cell, replace <IcebergS3Bucket> with the S3 bucket name where you uploaded the Iceberg JAR files.

bdb4341_1_session-config

  1. Initialize the SparkSession by running the following cell. The first three settings, starting with spark.sql, are required to use Iceberg with Glue. The default catalog name is set to glue_catalog using spark.sql.defaultCatalog. The configuration spark.sql.execution.arrow.pyspark.enabled is set to true and is used for data visualization with pandas.

bdb4341_2_sparksession-init

  1. After the session is created (the notification Session <Session Id> has been created. will be displayed in the notebook), run the following commands to copy the temperature and humidity dataset to the S3 bucket you created through the CloudFormation stack. Before running the cell, replace <IcebergS3Bucket> with the name of the S3 bucket for Iceberg, which you can find on the CloudFormation Outputs tab.
!aws s3 cp s3://aws-blogs-artifacts-public/artifacts/BDB-4341/data/part-00000-fa08487a-43c2-4398-bae9-9cb912f8843c-c000.snappy.parquet s3://<IcebergS3Bucket>/src-data/current/ 
!aws s3 cp s3://aws-blogs-artifacts-public/artifacts/BDB-4341/data/new-part-00000-e8a06ab0-f33d-4b3b-bd0a-f04d366f067e-c000.snappy.parquet s3://<IcebergS3Bucket>/src-data/new/
  1. Configure the data source bucket name and path (DATA_SRC), Iceberg data warehouse path (ICEBERG_LOC), and database and table names for an Iceberg table (DB_TBL). Replace <IcebergS3Bucket> with the S3 bucket from the CloudFormation Outputs tab.
  2. Read the dataset and create the Iceberg table with the dataset using the Create Table As Select (CTAS) query.

bdb4341_3_ctas

  1. Run the following code to display the temperature and humidity data for each room in the Iceberg table. Pandas and matplotlib are used to visualize the data for each room. The data from 10:05 to 10:30 is displayed in the notebook, as shown in the following screenshot, with each room showing approximately 25°C for temperature (displayed as the blue line) and 52% for humidity (displayed as the orange line).
import matplotlib.pyplot as plt
import pandas as pd

CONF = [
    {'room_type': 'myroom', 'cols':['current_temperature', 'current_humidity']},
    {'room_type': 'living', 'cols':['current_temperature', 'current_humidity']},
    {'room_type': 'kitchen', 'cols':['current_temperature', 'current_humidity']}
]

fig, axes = plt.subplots(nrows=3, ncols=1, sharex=True, sharey=True)
for ax, conf in zip(axes.ravel(), CONF):
    df_room = spark.sql(f"""
        SELECT current_time, current_temperature, current_humidity, room_type
        FROM {DB_TBL} WHERE room_type = '{conf['room_type']}'
        ORDER BY current_time ASC
        """)
    pdf = df_room.toPandas()
    pdf.set_index(pdf['current_time'], inplace=True)
    plt.xlabel('time')
    plt.ylabel('temperature/humidity')
    plt.ylim(10, 60)
    plt.yticks([tick for tick in range(10, 60, 10)])
    pdf[conf['cols']].plot.line(ax=ax, grid=True, figsize=(8, 6), title=conf['room_type'], legend=False, marker=".", markersize=2, linewidth=0)

plt.legend(['temperature', 'humidity'], loc='center', bbox_to_anchor=(0, 1, 1, 5.5), ncol=2)

%matplot plt

bdb4341_4_vis-1

  1. You create Iceberg branches by running the following queries before writing data into the Iceberg table. You can create an Iceberg branch by the ALTER TABLE db.table CREATE BRANCH <branch_name> query.
ALTER TABLE iceberg_wap_db.room_data CREATE BRANCH stg
ALTER TABLE iceberg_wap_db.room_data CREATE BRANCH audit

Now, you’re ready to build the WAP pattern with Iceberg.

Build WAP pattern with Iceberg

Use the Iceberg branches created earlier to implement the WAP pattern. You start writing the newly incoming temperature and humidity data including erroneous values to the stg branch in the Iceberg table.

Write phase: Write incoming data into the Iceberg stg branch

To write the incoming data into the stg branch in the Iceberg table, complete the following steps:

  1. Run the following cell and write the data into Iceberg table.

bdb4341_5_write

  1. After the records are written, run the following code to visualize the current temperature and humidity data in the stg On the following screenshot, notice that new data was added after 10:30. The output shows incorrect readings, such as around 100°C for temperature between 10:35 and 10:52 in the living room.
fig, axes = plt.subplots(nrows=3, ncols=1, sharex=True, sharey=True)
for ax, conf in zip(axes.ravel(), CONF):
    df_room_stg = spark.sql(f"""
        SELECT current_time, current_temperature, current_humidity, room_type
        FROM {DB_TBL}.branch_stg WHERE room_type = '{conf['room_type']}'
        ORDER BY current_time ASC
        """)
    pdf = df_room_stg.toPandas()
    pdf.set_index(pdf['current_time'], inplace=True)
    plt.xlabel('time')
    plt.ylabel('temperature/humidity')
    plt.ylim(10, 110)
    plt.yticks([tick for tick in range(10, 110, 30)])
    pdf[conf['cols']].plot.line(ax=ax, grid=True, figsize=(8, 6), title=conf['room_type'], legend=False, marker=".", markersize=2, linewidth=0)

plt.legend(['temperature', 'humidity'], loc='center', bbox_to_anchor=(0, 1, 1, 5.5), ncol=2)

%matplot plt

bdb4341_6_vis-2

The new temperature data including erroneous records was written to the stg branch. This data isn’t visible to the downstream side because it hasn’t been published to the main branch. Next, you evaluate the data quality in the stg branch.

Audit phase: Evaluate the data quality in the stg branch

In this phase, you evaluate the quality of the temperature and humidity data in the stg branch using AWS Glue Data Quality. Then, the data that doesn’t meet the criteria is filtered out based on the data quality rules, and the qualified data is used to update the latest snapshot in the audit branch. Start with the data quality evaluation:

  1. Run the following code to evaluate the current data quality using AWS Glue Data Quality. The evaluation rule is defined in DQ_RULESET, where the normal temperature range is set between −10 and 50°C based on the device specifications. Any values out of this range are considered erroneous in this scenario.
from awsglue.context import GlueContext
from awsglue.transforms import SelectFromCollection
from awsglue.dynamicframe import DynamicFrame
from awsgluedq.transforms import EvaluateDataQuality
DQ_RULESET = """Rules = [ ColumnValues "current_temperature" between -10 and 50 ]"""


dyf = DynamicFrame.fromDF(
    dataframe=spark.sql(f"SELECT * FROM {DB_TBL}.branch_stg"),
    glue_ctx=GlueContext(spark.sparkContext),
    name='dyf')

dyfc_eval_dq = EvaluateDataQuality().process_rows(
    frame=dyf,
    ruleset=DQ_RULESET,
    publishing_options={
        "dataQualityEvaluationContext": "dyfc_eval_dq",
        "enableDataQualityCloudWatchMetrics": False,
        "enableDataQualityResultsPublishing": False,
    },
    additional_options={"performanceTuning.caching": "CACHE_NOTHING"},
)

# Show DQ results
dyfc_rule_outcomes = SelectFromCollection.apply(
    dfc=dyfc_eval_dq,
    key="ruleOutcomes")
dyfc_rule_outcomes.toDF().select('Outcome', 'FailureReason').show(truncate=False)
  1. The output shows the result of the evaluation. It displays Failed because some temperature data, such as 105°C, is out of the normal temperature range of −10 to 50°C.
+-------+------------------------------------------------------+
|Outcome|FailureReason                                         |
+-------+------------------------------------------------------+
|Failed |Value: 105.0 does not meet the constraint requirement!|
+-------+------------------------------------------------------+
  1. After the evaluation, filter out the incorrect temperature data in the stg branch, then update the latest snapshot in the audit branch with the valid temperature data.

bdb4341_7_write-to-audit

Through the data quality evaluation, the audit branch in the Iceberg table now contains the valid data, which is ready for downstream use.

Publish phase: Publish the valid data to the downstream side

To publish the valid data in the audit branch to main, complete the following steps:

  1. Run the fast_forward Iceberg procedure to publish the valid data in the audit branch to the downstream side.

bdb4341_8_publish

  1. After the procedure is complete, review the published data by querying the main branch in the Iceberg table to simulate the query from the downstream side.
fig, axes = plt.subplots(nrows=3, ncols=1, sharex=True, sharey=True)
for ax, conf in zip(axes.ravel(), CONF):
    df_room_main = spark.sql(f"""
        SELECT current_time, current_temperature, current_humidity, room_type
        FROM {DB_TBL} WHERE room_type = '{conf['room_type']}'
        ORDER BY current_time ASC
        """)
    pdf = df_room_main.toPandas()
    pdf.set_index(pdf['current_time'], inplace=True)
    plt.xlabel('time')
    plt.ylabel('temperature/humidity')
    plt.ylim(10, 60)
    plt.yticks([tick for tick in range(10, 60, 10)])
    pdf[conf['cols']].plot.line(ax=ax, grid=True, figsize=(8, 6), title=conf['room_type'], legend=False, marker=".", markersize=2, linewidth=0)

plt.legend(['temperature', 'humidity'], loc='center', bbox_to_anchor=(0, 1, 1, 5.5), ncol=2)

%matplot plt

The query result shows only the valid temperature and humidity data that has passed the data quality evaluation.

bdb4341_9_vis-3

In this scenario, you successfully managed data quality by applying the WAP pattern with Iceberg branches. The room temperature and humidity data, including any erroneous records, was first written to the staging branch for quality evaluation. This approach prevented erroneous data from being visualized and leading to incorrect insights. After the data was validated by AWS Glue Data Quality, only valid data was published to the main branch and visualized in the notebook. Using the WAP pattern with Iceberg branches, you can make sure that only validated data is passed to the downstream side for further analysis.

Clean up resources

To clean up the resources, complete the following steps:

  1. On the Amazon S3 console, select the S3 bucket aws-glue-assets-<ACCOUNT_ID>-<REGION> where the Notebook file (iceberg_wap.ipynb) is stored. Delete the Notebook file located in the notebook path.
  2. Select the S3 bucket you created through the CloudFormation template. You can obtain the bucket name from IcebergS3Bucket key on the CloudFormation Outputs tab. After selecting the bucket, choose Empty to delete all objects.
  3. After you confirm the bucket is empty, delete the CloudFormation stack iceberg-wap-baseline-resources.

Conclusion

In this post, we explored common strategies for maintaining data quality when ingesting data into Apache Iceberg tables. The step-by-step instructions demonstrated how to implement the WAP pattern with Iceberg branches. For use cases requiring data quality validation, the WAP pattern provides the flexibility to manage data latency even with concurrent writer applications without impacting downstream applications.


About the Authors

Tomohiro Tanaka is a Senior Cloud Support Engineer at Amazon Web Services. He’s passionate about helping customers use Apache Iceberg for their data lakes on AWS. In his free time, he enjoys a coffee break with his colleagues and making coffee at home.

Sotaro Hikita is a Solutions Architect. He supports customers in a wide range of industries, especially the financial industry, to build better solutions. He is particularly passionate about big data technologies and open source software.

Noritaka Sekiyama is a Principal Big Data Architect on the AWS Glue team. He works based in Tokyo, Japan. He is responsible for building software artifacts to help customers. In his spare time, he enjoys cycling with his road bike.

Implement historical record lookup and Slowly Changing Dimensions Type-2 using Apache Iceberg

Post Syndicated from Tomohiro Tanaka original https://aws.amazon.com/blogs/big-data/implement-historical-record-lookup-and-slowly-changing-dimensions-type-2-using-apache-iceberg/

In today’s data-driven world, tracking and analyzing changes over time has become essential. As organizations process vast amounts of data, maintaining an accurate historical record is crucial. History management in data systems is fundamental for compliance, business intelligence, data quality, and time-based analysis. It enables organizations to maintain audit trails, perform trend analysis, identify data quality issues, and conduct point-in-time reporting. When combined with Change Data Capture (CDC), which identifies and captures database changes, history management becomes even more potent.

Common use cases for historical record management in CDC scenarios span various domains. In customer relationship management, it tracks changes in customer information over time. Financial systems use it for maintaining accurate transaction and balance histories. Inventory management benefits from historical data for analyzing sales patterns and optimizing stock levels. HR systems use it to track employee information changes. In fraud detection, historical data helps identify anomalous patterns in transactions or user behaviors.

This post will explore how to implement these functionalities using Apache Iceberg, focusing on Slowly Changing Dimensions (SCD) Type-2. This method creates new records for each data change while preserving old ones, thus maintaining a full history. By the end, you’ll understand how to use Apache Iceberg to manage historical records effectively on a typical CDC architecture.

Historical record lookup

How can we retrieve the history of given records? This is a fundamental question in data management, especially when dealing with systems that need to track changes over time. Let’s explore this concept with a practical example.

Consider a product (Heater) in an ecommerce database:

product_id product_name price
00001 Heater 250

Now, let’s say we update the price of this product from 250 to 500. After some time, we want to retrieve the price history of this heater. In a traditional database setup, this task could be challenging, especially if we haven’t explicitly designed our system to track historical changes.

This is where the concept of historical record lookup becomes crucial. We need a system that not only stores the current state of our data but also maintains a log of all changes made to each record over time. This allows us to answer questions like:

  • What was the price of the heater at a specific point in time?
  • How many times has the price changed, and when did these changes occur?
  • What was the price trend of the heater over the past year?

Implementing such a system can be complex, requiring careful consideration of data storage, retrieval mechanisms, and query optimization. This is where Apache Iceberg comes into play, offering a feature known as the change log view.

The change log view in Apache Iceberg provides a view of all changes made to a table over time, making it straightforward to query and analyze the history of any record. With change log view, we can easily track insertions, updates, and deletions, giving us a complete picture of how our data has evolved.

For our heater example, Iceberg’s change log view would allow us to effortlessly retrieve a timeline of all price changes, complete with timestamps and other relevant metadata, as shown in the following table.

product_id product_name price _change_type
00001 Heater 250 INSERT
00001 Heater 250 UPDATE_BEFORE
00001 Heater 500 UPDATE_AFTER

This capability not only simplifies historical analysis but also opens possibilities for advanced time-based analytics, auditing, and data governance.

Historical table lookup with SCD Type-2

SCD Type-2 is a key concept in data warehousing and historical data management and is particularly relevant to Change Data Capture (CDC) scenarios. SCD Type-2 creates new rows for changed data instead of overwriting existing records, allowing for comprehensive tracking of changes over time.

SCD Type-2 requires additional fields such as effective_start_date, effective_end_date, and current_flag to manage historical records. This approach has been widely used in data warehouses to track changes in various dimensions such as customer information, product details, and employee data. In the example of the previous section, here’s what the SCD Type-2 looks like assuming the update operation is performed on December 11, 2024.

product_id product_name price effective_start_date effective_end_date current_flag
00001 Heater 250 2024-12-10 2024-12-11 FALSE
00001 Heater 500 2024-12-11 NULL TRUE

SCD Type-2 is particularly valuable in CDC use cases, where capturing all data changes over time is crucial. It enables point-in-time analysis, provides detailed audit trails, aids in data quality management, and helps meet compliance requirements by preserving historical data.

In traditional implementations on data warehouses, SCD Type-2 requires its specific handling in all INSERT, UPDATE, and DELETE operations that affect those additional columns. For example, to update the price of the product, you need to run the following query.

UPDATE product SET effective_end_date = '2024-12-11', current_flag = false
WHERE product_id = '00001' AND current_flag = true;

INSERT INTO product (product_id, product_name, price, effective_start_date, effective_end_date, current_flag)
VALUES ('00001', 'Heater', 500, '2024-12-11', NULL, true);

For modern data lakes, we propose a new approach to implement SCD Type-2. With Iceberg, you can create a dedicated view of SCD Type-2 on top of the change log view, eliminating the need to implement specific handling to make changes on SCD Type-2 tables. With this approach, you can keep managing Iceberg tables without complexity considering SCD Type-2 specification. Anytime when you need SCD Type-2 snapshot of your Iceberg table, you can create the corresponding representation. This approach combines the power of Iceberg’s efficient data management with the historical tracking capabilities of SCD Type-2. By using the change log view, Iceberg can dynamically generate the SCD Type-2 structure without the overhead of maintaining additional tables or manually managing effective dates and flags.

This streamlined method not only makes the implementation of SCD Type-2 more straightforward, but also offers improved performance and scalability for handling large volumes of historical data in CDC scenarios. It represents a significant advancement in historical data management, merging traditional data warehousing concepts with modern big data capabilities.

As we delve deeper into Iceberg’s features, we’ll explore how this approach can be implemented, showcasing the efficiency and flexibility it brings to historical data analysis and CDC processes.

Prerequisites

The following prerequisites are required for the use cases:

Set up resources with AWS CloudFormation

Use a provided AWS CloudFormation template to set up resources to build Iceberg environments. The template creates the following resources:

Complete the following steps to deploy the resources.

  1. Choose Launch stack

Launch Button

  1. For the parameters, IcebergDatabaseName is set by default. You can change the default value. Then, choose Next.
  2. Choose Next
  3. Choose I acknowledge that AWS CloudFormation might create IAM resources with custom names.
  4. Choose Submit.
  5. After the stack creation is complete, check the Outputs tab and make a note of the resource values, which are used in the following sections.

Next, configure the Iceberg JAR files to the session to use the Iceberg change log view feature. Complete the following steps.

  1. Select the following JAR files from the Iceberg releases page and download these JAR files on your local machine:
    1. 1.6.1 Spark 3.3_with Scala 2.12 runtime Jar.
    2. 1.6.1 aws-bundle Jar.
  2. Open the Amazon S3 console and select the S3 bucket you created using the CloudFormation stack. The S3 bucket name can be found on the CloudFormation Outputs tab.
  3. Choose Create folder and create the jars path in the S3 bucket.
  4. Upload the two downloaded JAR files on s3://<IcebergS3Bucket>/jars/ from the S3 console.

Upload a Jupyter Notebook on AWS Glue Studio

After launching the CloudFormation stack, create an AWS Glue Studio notebook to use Iceberg with AWS Glue.

  1. Download history.ipynb.
  2. Open AWS Glue Studio console.
  3. Under Create job, select Notebook.
  4. Select Upload Notebook, choose Choose file and upload the Notebook you downloaded.
  5. Select the IAM role name such as IcebergHistoryGlueJobRole that you created using the CloudFormation template. Then, choose Create notebook.

1_upload-notebook

  1. For Job name at the left top of the page, enter iceberg_history.
  2. Choose Save.

Create an Iceberg table

To create an Iceberg table using a product dataset, complete the following steps.

  1. On the Jupyter Notebook that you created in Upload a Jupyter Notebook on AWS Glue Studio, run the following cell to use Iceberg with AWS Glue. Before running the cell, replace <IcebergS3Bucket> with the S3 bucket name where you uploaded the Iceberg JAR files.

2_session-config

  1. Initialize the SparkSession with Iceberg settings.

3_ss-init

  1. Configure database and table names for an Iceberg table (DB_TBL) and data warehouse path (ICEBERG_LOC). Replace <IcebergS3Bucket> with the S3 bucket from the CloudFormation Outputs tab.
  2. Run the following code to create the Iceberg table using the Spark DataFrame based on the product dataset.
from pyspark.sql import Row
import time
ut = time.time()
product = [
    {'product_id': '00001', 'product_name': 'Heater', 'price': 250, 'category': 'Electronics', 'updated_at': ut},
    {'product_id': '00002', 'product_name': 'Thermostat', 'price': 400, 'category': 'Electronics', 'updated_at': ut},
    {'product_id': '00003', 'product_name': 'Television', 'price': 600, 'category': 'Electronics', 'updated_at': ut},
    {'product_id': '00004', 'product_name': 'Blender', 'price': 100, 'category': 'Electronics', 'updated_at': ut},
    {'product_id': '00005', 'product_name': 'USB charger', 'price': 50, 'category': 'Electronics', 'updated_at': ut}
]
df_products = spark.createDataFrame(Row(**x) for x in product)
df_products.createOrReplaceTempView('tmp')

spark.sql(f"""
CREATE TABLE {DB_TBL} USING iceberg LOCATION '{ICEBERG_LOC}'
AS SELECT * FROM tmp
""")
  1. After creating the Iceberg table, run SELECT * FROM iceberg_history_db.products ORDER BY product_id to show the product data in the Iceberg table. Currently the following five products are stored in the Iceberg table.
+----------+------------+-----+-----------+--------------------+
|product_id|product_name|price|   category|          updated_at|
+----------+------------+-----+-----------+--------------------+
|     00001|      Heater|  250|Electronics|1.7297845122056053E9|
|     00002|  Thermostat|  400|Electronics|1.7297845122056053E9|
|     00003|  Television|  600|Electronics|1.7297845122056053E9|
|     00004|     Blender|  100|Electronics|1.7297845122056053E9|
|     00005| USB charger|   50|Electronics|1.7297845122056053E9|
+----------+------------+-----+-----------+--------------------+

Next, look up the historical changes for a product using Iceberg’s change log view feature.

Implement historical record lookup with Iceberg’s change log view

Suppose that there’s a source table whose table records are replicated to the Iceberg table through a Change Data Capture (CDC) process. When the records in the source table are updated, these changes are then mirrored in the Iceberg table. In this section, you look up the history of a given record for such a system to capture the history of product updates. For example, the following updates occur in the source table. Through the CDC process, these changes are applied to the Iceberg table.

  • Upsert (update and insert) the two records:
    • The price of Heater (product_id: 00001) is updated from 250 to 500.
    • A new product Chair (product_id: 00006) is added.
  • Television (product_id: 00003) is deleted.

To simulate the CDC workflow, you manually apply these changes to the Iceberg table in the notebook.

  1. Use the MERGE INTO query to upsert records. If an input record in the Spark DataFrame has the same product_id as an existing record, the existing record is updated. If no matching product_id is found, the input record is inserted into the Iceberg table.

4-merge-into

  1. Delete Television from the Iceberg table by running the DELETE query.
DELETE FROM iceberg_history_db.products WHERE product_id = '00003'
  1. Then, run SELECT * FROM iceberg_history_db.products ORDER BY product_id to show the product data in the Iceberg table. You can confirm that the price of Heater is updated to 500, Chair is added and Television is deleted.
+----------+------------+-----+-----------+--------------------+
|product_id|product_name|price|   category|          updated_at|
+----------+------------+-----+-----------+--------------------+
|     00001|      Heater|  500|Electronics|    1.729790106579E9|
|     00002|  Thermostat|  400|Electronics|1.7297845122056053E9|
|     00004|     Blender|  100|Electronics|1.7297845122056053E9|
|     00005| USB charger|   50|Electronics|1.7297845122056053E9|
|     00006|       Chair|   50|  Furniture|    1.729790106579E9|
+----------+------------+-----+-----------+--------------------+

For the Iceberg table, where changes from the source table are replicated, you can track the record changes using Iceberg’s change log view. To start, you first create a change log view from the Iceberg table.

  1. Run the create_changelog_view Iceberg procedure to create a change log view.

5-clv

  1. Run the following query to retrieve the historical changes for Heater.
SELECT product_id, product_name, price, category, updated_at, _change_type
FROM products_clv WHERE product_id = '00001'
ORDER BY _change_ordinal, _change_type DESC
  1. The query result shows the historical changes to Heater. You can confirm that the price of Heater was updated from 250 to 500 from the output.
+----------+------------+-----+-----------+--------------------+-------------+
|product_id|product_name|price|   category|          updated_at| _change_type|
+----------+------------+-----+-----------+--------------------+-------------+
|     00001|      Heater|  250|Electronics|1.7297902833360643E9|       INSERT|
|     00001|      Heater|  250|Electronics|1.7297902833360643E9|UPDATE_BEFORE|
|     00001|      Heater|  500|Electronics|1.7297903836233025E9| UPDATE_AFTER|
+----------+------------+-----+-----------+--------------------+-------------+

Using Iceberg’s change log view, you can obtain the history of a given record directly from the Iceberg table’s history, without needing to create a separate table for managing record history. Next, you implement Slowly Changing Dimension (SCD) Type-2 using the change log view.

Implement SCD Type-2 with Iceberg’s change log view

The SCD Type-2 based table retains the full history of record changes and it can be used in multiple cases such as historical tracking, point-in-time analysis, regulatory compliance, and so on. In this section, you implement SCD Type-2 using the change log view (products_clv) that was created in the previous section. The change log view has a schema that’s similar to the schema defined in the SCD Type-2 specifications. For this change log view, you add effective_start, effective_end, and is_current columns. To add these columns and then implement SCD Type-2, complete the following steps.

  1. Run the following query to implement SCD Type-2. In the WITH AS (...) section of the query, the change log view is merged with the Iceberg table snapshots using the snapshot_id key to include the commit time for each record change. You can obtain the table snapshots by querying for db.table.snapshots. The other part in the query identifies both current and non-current entries by comparing the commit times for each product. It then sets the effective time for each product, and marks whether a product is current or not based on the effective time and the change type from the change log view.
WITH clv_snapshots AS (
    SELECT
        clv.*,
        s.snapshot_id,
        s.committed_at,
        s.committed_at as effective_start
    FROM products_clv clv
    JOIN iceberg_history_db.products.snapshots s
    ON clv._commit_snapshot_id = s.snapshot_id
) 
SELECT
    product_id, 
    product_name, 
    price, 
    category, 
    updated_at,
    effective_start,
    CASE
        WHEN effective_start != l_part_committed_at 
            OR _change_type = 'UPDATE_BEFORE' THEN l_part_committed_at
        ELSE CAST(null as timestamp)
    END as effective_end,
    CASE
        WHEN effective_start != l_part_committed_at
            OR _change_type = 'UPDATE_BEFORE' 
            OR _change_type = 'DELETE' THEN CAST(false as boolean)
        ELSE CAST(true as boolean)
    END as is_current
FROM (SELECT *, MAX(committed_at) OVER (PARTITION BY product_id, updated_at) as l_part_committed_at FROM clv_snapshots)
WHERE _change_type != 'UPDATE_BEFORE'
ORDER BY product_id,  _change_ordinal
  1. The query result shows the SCD Type-2 based schema and records.

7-output

After the query result is displayed, this SCD Type-2 based table is stored as scdt2 to allow access for further analysis.

SCD Type-2 is useful for many use cases. To explore how this SCD Type-2 implementation can be used to track the history of table records, run the following example queries.

  1. Run the following query to retrieve deleted or updated records in a specific period. This query captures which records were changed during that timeframe, allowing you to audit changes for further use-cases such as trend analysis, regulatory compliance checks, and so on. Before running the query, replace <START_DATETIME> and <END_DATETIME> with specific time ranges such as 2024-10-24 17:18:00 and 2024-10-24 17:20:00.
SELECT product_id, product_name, price, category, updated_at, effective_start, effective_end, is_current 
FROM scdt2 WHERE product_id IN ( SELECT product_id FROM scdt2 
WHERE (_change_type = 'DELETE' or _change_type = 'UPDATE_AFTER') 
AND effective_start BETWEEN '<START_DATETIME>' AND '<END_DATETIME>') 
ORDER BY product_id, effective_start
  1. The query result shows the deleted and updated records in the specified period. You can confirm that the price of Heater was updated and Television was deleted from the table.
+----------+------------+-----+-----------+--------------------+--------------------+--------------------+----------+
|product_id|product_name|price|   category|          updated_at|     effective_start|       effective_end|is_current|
+----------+------------+-----+-----------+--------------------+--------------------+--------------------+----------+
|     00001|      Heater|  250|Electronics|1.7297902833360643E9|2024-10-24 17:18:...|2024-10-24 17:19:...|     false|
|     00001|      Heater|  500|Electronics|1.7297903836233025E9|2024-10-24 17:19:...|                null|      true|
|     00003|  Television|  600|Electronics|1.7297902833360643E9|2024-10-24 17:18:...|2024-10-24 17:19:...|     false|
|     00003|  Television|  600|Electronics|1.7297902833360643E9|2024-10-24 17:19:...|                null|     false|
+----------+------------+-----+-----------+--------------------+--------------------+--------------------+----------+
  1. As another example, run the following query to retrieve the latest records at a specific point in time from the SCD Type-2 table by filtering with is_current = true for current data reporting.
SELECT product_id, product_name, price, category, updated_at
FROM scdt2 WHERE is_current = true ORDER BY product_id
  1. The query result shows the current table records, reflecting the updated price of Heater, the deletion of Television, and the addition of Chair after the initial records.
+----------+------------+-----+-----------+--------------------+
|product_id|product_name|price|   category|          updated_at|
+----------+------------+-----+-----------+--------------------+
|     00001|      Heater|  500|Electronics|1.7297903836233025E9|
|     00002|  Thermostat|  400|Electronics|1.7297902833360643E9|
|     00004|     Blender|  100|Electronics|1.7297902833360643E9|
|     00005| USB charger|   50|Electronics|1.7297902833360643E9|
|     00006|       Chair|   50|  Furniture|1.7297903836233025E9|
+----------+------------+-----+-----------+--------------------+

You have now successfully implemented SCD Type-2 using the change log view. This SCD Type-2 implementation allows you to track the history of table records. For example, you can use it to search for deleted or updated products such as Heater and Chair in a specific period. Additionally, you can retrieve the current table records by querying the SCD Type-2 table with is_current = true. Using Iceberg’s change log view enables you to implement SCD Type-2 without making any changes to the Iceberg table itself. It also eliminates the need for creating or managing an additional table for SCD Type-2.

Clean up

To clean up the resources used in this post, complete the following steps:

  1. Open the Amazon S3 console
  2. Select the S3 bucket aws-glue-assets-<ACCOUNT_ID>-<REGION> where the Notebook file (iceberg_history.ipynb) is stored. Delete the Notebook file that’s in the notebook path.
  3. Select the S3 bucket you created using the CloudFormation template. You can obtain the bucket name from IcebergS3Bucket key on the CloudFormation Outputs tab. After selecting the bucket, choose Empty to delete all objects
  4. After you confirm the bucket is empty, delete the CloudFormation stack iceberg-history-baseline-resources.

Considerations

Here are important considerations:

Conclusion

In this post, we have explored how to look up the history of records and tables using Apache Iceberg. The instruction demonstrated how to use change log view to look up the history of the records, and also the history of the tables with SCD Type-2. With this method, you can manage the history of records and tables without extra effort.


About the Authors

Tomohiro Tanaka is a Senior Cloud Support Engineer at Amazon Web Services. He’s passionate about helping customers use Apache Iceberg for their data lakes on AWS. In his free time, he enjoys a coffee break with his colleagues and making coffee at home.

Noritaka Sekiyama is a Principal Big Data Architect on the AWS Glue team. He works based in Tokyo, Japan. He is responsible for building software artifacts to help customers. In his spare time, he enjoys cycling with his road bike.

Fedora Steering Council election interviews

Post Syndicated from daroc original https://lwn.net/Articles/1001522/

When the Fedora Engineering Steering Council (FESCo) is up for election, the project posts
interviews of the candidates in order to help Fedora contributors make an informed choice. This
year, the candidates are

Zbigniew Jędrzejewski-Szmek
,

Tomáš Hrčka
,

Josh Stone
,

David Cantrell
,

Fabio Alessandro Locati
, and

Kevin Fenzi
.
All of them except for Locati are current members of the steering council.
Voting is open until December 20.

[$] Finally continuing the discussion over continue in finally

Post Syndicated from daroc original https://lwn.net/Articles/1000635/

In 2019, the Python community had a

lengthy discussion
about changing the rules (that some find counterintuitive) on
using break, continue, or return statements in
finally blocks. These are all ways of jumping out of a finally
block, which can interrupt the handling of a raised exception.
At the time, the Python developers chose not to change
things, because the consensus was that the existing behavior was not a problem. Now, after
a
report
put together by Irit Katriel, the project is once again considering
changing the language.

A vulnerability in the OpenWrt attended sysupgrade server

Post Syndicated from corbet original https://lwn.net/Articles/1001441/

The OpenWrt project has issued an
advisory
regarding a vulnerability found in its Attended Sysupgrade
Server that could allow compromised packages to be installed on a router by
an attacker. No official OpenWrt images were affected, and the
vulnerability is not known to be exploited, but users who have installed
images created with an instance of this server are recommended to
reinstall.

For a detailed description of how the exploit works, see this
blog post
.

Then, as the hash collision occurred, the server returns the
overwritten build artifact to the legitimate request that requests
the following packages. […]

By abusing this, an attacker could force the user to upgrade to the
malicious firmware, which could lead to the compromise of the
device.

Kernel prepatch 6.13-rc2

Post Syndicated from corbet original https://lwn.net/Articles/1001435/

The 6.13-rc2 kernel prepatch is out for
testing. “The diffstat looks a bit unusual with 80%+ drivers, and a lot of it
one-liners, but that’s actually just because of a couple of automated
scripts that got run after -rc1 for some cleanups. Nothing
particularly interesting, but it makes for a lot of noise in the diff.

One of those scripts was the EXPORT_SYMBOL_NS() change (to make it
use a quoted string for the namespace name) described in this article.

The collective thoughts of the interwebz