Using DNS to estimate the worldwide state of IPv6 adoption

Post Syndicated from Carlos Rodrigues http://blog.cloudflare.com/author/carlos-rodrigues/ original https://blog.cloudflare.com/ipv6-from-dns-pov


In order for one device to talk to other devices on the Internet using the aptly named Internet Protocol (IP), it must first be assigned a unique numerical address. What this address looks like depends on the version of IP being used: IPv4 or IPv6.

IPv4 was first deployed in 1983. It’s the IP version that gave birth to the modern Internet and still remains dominant today. IPv6 can be traced back to as early as 1998, but only in the last decade did it start to gain significant traction — rising from less than 1% to somewhere between 30 and 40%, depending on who’s reporting and what and how they’re measuring.

With the growth in connected devices far exceeding the number of IPv4 addresses available, and its costs rising, the much larger address space provided by IPv6 should have made it the dominant protocol by now. However, as we’ll see, this is not the case.

Cloudflare has been a strong advocate of IPv6 for many years and, through Cloudflare Radar, we’ve been closely following IPv6 adoption across the Internet. At three years old, Radar is still a relatively recent platform. To go further back in time, we can briefly turn to our friends at APNIC1 — one of the five Regional Internet Registries (RIRs). Through their data, going back to 2012, we can see that IPv6 experienced a period of seemingly exponential growth until mid-2017, after which it entered a period of linear growth that’s still ongoing:

IPv6 adoption is slowed down by the lack of compatibility between both protocols — devices must be assigned both an IPv4 and an IPv6 address — along with the fact that virtually all devices on the Internet still support IPv4. Nevertheless, IPv6 is critical for the future of the Internet, and continued effort is required to increase its deployment.

Cloudflare Radar, like APNIC and most other sources today, publishes numbers that primarily reflect the extent to which Internet Service Providers (ISPs) have deployed IPv6: the client side. It’s a very important angle, and one that directly impacts end users, but there’s also the other end of the equation: the server side.

With this in mind, we invite you to follow us on a quick experiment where we aim for a glimpse of server side IPv6 adoption, and how often clients are actually (or likely) able to talk to servers over IPv6. We’ll rely on DNS for this exploration and, as they say, the results may surprise you.

IPv6 Adoption on the Client Side (from HTTP)

By the end of October 2023, from Cloudflare’s perspective, IPv6 adoption across the Internet was at roughly 36% of all traffic, with slight variations depending on the time of day and day of week. When excluding bots the estimate goes up to just over 46%, while excluding humans pushes it down close to 24%. These numbers refer to the share of HTTP requests served over IPv6 across all IPv6-enabled content (the default setting).

For this exercise, what matters most is the number for both humans and bots. There are many reasons for the adoption gap between both kinds of traffic — from varying levels of IPv6 support in the plethora of client software used, to varying levels of IPv6 deployment inside the many networks where traffic comes from, to the varying size of such networks, etc. — but that’s a rabbit hole for another day. If you’re curious about the numbers for a particular country or network, you can find them on Cloudflare Radar and in our Year in Review report for 2023.

It Takes Two to Dance

You, the reader, might point out that measuring the client side of the client-server equation only tells half the story: for an IPv6-capable client to establish a connection with a server via IPv6, the server must also be IPv6-capable.

This raises two questions:

  1. What’s the extent of IPv6 adoption on the server side?
  2. How well does IPv6 adoption on the client side align with adoption on the server side?

There are several possible answers, depending on whether we’re talking about users, devices, bytes transferred, and so on. We’ll focus on connections (it will become clear why in a moment), and the combined question we’re asking is:

How often can an IPv6-capable client use IPv6 when connecting to servers on the Internet, under typical usage patterns?

Typical usage patterns include people going about their day visiting some websites more often than others or automated clients calling APIs. We’ll turn to DNS to get this perspective.

Enter DNS

Before a client can attempt to establish a connection with a server by name, using either the classic IPv4 protocol or the more modern IPv6, it must look up the server’s IP address in the phonebook of the Internet, the Domain Name System (DNS).

Looking up a hostname in DNS is a recursive process. To find the IP address of a server, the domain hierarchy (the dot-separated components of a server’s name) must be followed across several DNS authoritative servers until one of them returns the desired response2. Most clients, however, don’t do this directly and instead ask an intermediary server called a recursive resolver to do it for them. Cloudflare operates one such recursive resolver that anyone can use: 1.1.1.1.

As a simplified example, when a client asks 1.1.1.1 for the IP address where “www.example.com” lives, 1.1.1.1 will go out and ask the DNS root servers3 about “.com”, then ask the .com DNS servers about “example.com”, and finally ask the example.com DNS servers about “www.example.com”, which has direct knowledge of it and answers with an IP address. To make things faster for the next client asking a similar question, 1.1.1.1 caches (remembers for a while) both the final answer and the steps in between.

This means 1.1.1.1 is in a very good position to count how often clients try to look up IPv4 addresses (A-type queries) vs. how often they try to look up IPv6 addresses (AAAA-type queries), covering most of the observable Internet.

But how does a client know when to ask for a server’s IPv4 address or its IPv6 address?

The short answer is that clients with IPv6 available to them just ask for both — doing separate A and AAAA lookups for every server they wish to connect to. These IPv6-capable clients will prioritize connecting over IPv6 when they get a non-empty AAAA answer, whether they also get a non-empty A answer (which they almost always get, as we’ll see). The algorithm driving this preference for modernity is called Happy Eyeballs, if you’re interested in the details.

We’re now ready to start looking at some actual data…

IPv6 Adoption on the Client Side (from DNS)

The first step is establishing a baseline by measuring client IPv6 deployment from 1.1.1.1’s perspective and comparing it with the numbers from HTTP requests that we started with.

It’s tempting to count how often clients connect to 1.1.1.1 using IPv6, but the results are misleading for a couple of reasons, the strongest one being hidden in plain sight: 1.1.1.1 is the most memorable address of the set of IPv4 and IPv6 addresses that clients can use to perform DNS lookups through the 1.1.1.1 service. Ideally, IPv6-capable clients using 1.1.1.1 as their recursive resolver should have all four of the following IP addresses configured, not just the first two:

  • 1.1.1.1 (IPv4)
  • 1.0.0.1 (IPv4)
  • 2606:4700:4700::1111 (IPv6)
  • 2606:4700:4700::1001 (IPv6)

But, when manual configuration is involved4, humans find IPv6 addresses less memorable than IPv4 addresses and are less likely to configure them, viewing the IPv4 addresses as enough.

A related, but less obvious, confounding factor is that many IPv6-capable clients will still perform DNS lookups over IPv4 even when they have 1.1.1.1’s IPv6 addresses configured, as spreading lookups over the available addresses is a popular default option.

A more sensible approach to assess IPv6 adoption from DNS client activity is calculating the percentage of AAAA-type queries over the total amount of A-type queries, assuming IPv6-clients always perform both5, as mentioned earlier.

Then, from 1.1.1.1’s perspective, IPv6 adoption on the client side is estimated at 30.5% by query volume. This is a bit under what we observed from HTTP traffic over the same time period (35.9%) but such a difference between two different perspectives is not unexpected.

A Note on TTLs

It’s not only recursive resolvers that cache DNS responses, most DNS clients have their own local caches as well. Your web browser, operating system, and even your home router, keep answers around hoping to speed up subsequent queries.

How long each answer remains in cache depends on the time-to-live (TTL) field sent back with DNS records. If you’re familiar with DNS, you might be wondering if A and AAAA records have similar TTLs. If they don’t, we may be getting fewer queries for just one of these two types (because it gets cached for longer at the client level), biasing the resulting adoption figures.

The pie charts here break down the minimum TTLs sent back by 1.1.1.1 in response to A and AAAA queries6. There is some difference between both types, but the difference is very small.

IPv6 Adoption on the Server Side

The following graph shows how often A and AAAA-type queries get non-empty responses, shedding light on server side IPv6 adoption and getting us closer to the answer we’re after:

IPv6 adoption by servers is estimated at 43.3% by query volume, noticeably higher than what was observed for clients.

How Often Both Sides Swipe Right

If 30.5% of IP address lookups handled by 1.1.1.1 could make use of an IPv6 address to connect to their intended destinations, but only 43.3% of those lookups get a non-empty response, that can give us a pretty good basis for how often IPv6 connections are made between client and server — roughly 13.2% of the time.

The Potential Impact of Popular Domains

IPv6 server side adoption measured by query volume for the domains in Radar’s Top 100 list is 60.8%. If we exclude these domains from our overall calculations, the previous 13.2% figure drops to 8%. This is a significant difference, but not unexpected, as the Top 100 domains make up over 55% of all A and AAAA queries to 1.1.1.1.

If just a few more of these highly popular domains were to deploy IPv6 today, observed adoption would noticeably increase and, with it, the chance of IPv6-capable clients establishing connections using IPv6.

Closing Thoughts

Observing the extent of IPv6 adoption across the Internet can mean different things:

  • Counting users with IPv6-capable Internet access;
  • Counting IPv6-capable devices or software on those devices (clients and/or servers);
  • Calculating the amount of traffic flowing through IPv6 connections, measured in bytes;
  • Counting the fraction of connections (or individual requests) over IPv6.

In this exercise we chose to look at connections and requests. Keeping in mind that the underlying reality can only be truly understood by considering several different perspectives, we saw three different IPv6 adoption figures:

  • 35.9% (client side) when counting HTTP requests served from Cloudflare’s CDN;
  • 30.5% (client side) when counting A and AAAA-type DNS queries handled by 1.1.1.1;
  • 43.3% (server side) of positive responses to AAAA-type DNS queries, also from 1.1.1.1.

We combined the client side and server side figures from the DNS perspective to estimate how often connections to third-party servers are likely to be established over IPv6 rather than IPv4: just 13.2% of the time.

To improve on these numbers, ISPs, cloud and hosting providers, and corporations alike must increase the rate at which they make IPv6 available for devices in their networks. But large websites and content sources also have a critical role to play in enabling IPv6-capable clients to use IPv6 more often, as 39.2% of queries for domains in the Radar Top 100 (representing over half of all A and AAAA queries to 1.1.1.1) are still limited to IPv4-only responses.

On the road to full IPv6 adoption, the Internet isn’t quite there yet. But continued effort from all those involved can help it to continue to move forward, and perhaps even accelerate progress.

On the server side, Cloudflare has been helping with this worldwide effort for many years by providing free IPv6 support for all domains. On the client side, the 1.1.1.1 app automatically enables your device for IPv6 even if your ISP doesn’t provide any IPv6 support. And, if you happen to manage an IPv6-only network, 1.1.1.1’s DNS64 support also has you covered.

***
1Cloudflare’s public DNS resolver (1.1.1.1) is operated in partnership with APNIC. You can read more about it in the original announcement blog post and in 1.1.1.1’s privacy policy.
2There’s more information on how DNS works in the “What is DNS?” section of our website. If you’re a hands-on learner, we suggest you take a look at Julia Evans’ “mess with dns”.
3Any recursive resolver will already know the IP addresses of the 13 root servers beforehand. Cloudflare also participates at the topmost level of DNS by providing anycast service to the E and F-Root instances, which means 1.1.1.1 doesn’t need to go far for that first lookup step.
4When using the 1.1.1.1 app, all four IP addresses are configured automatically.
5For simplification, we assume the amount of IPv6-only clients is still negligibly small. It’s a reasonable assumption in general, and other datasets available to us confirm it.
61.1.1.1, like other recursive resolvers, returns adjusted TTLs: the record’s original TTL minus the number of seconds since the record was last cached. Empty A and AAAA answers get cached for the amount of time defined in the domain’s Start of Authority (SOA) record, as specified by RFC 2308.

Intel Xeon D-1800 and D-2800 Series Launch Ice Lake-D Refreshed

Post Syndicated from John Lee original https://www.servethehome.com/intel-xeon-d-1800-and-d-2800-series-launch-ice-lake-d-refreshed/

Today Intel is announcing two new edge processor series. The Intel Xeon D-1800 and D-2800 series update Ice Lake-D platform capabilities

The post Intel Xeon D-1800 and D-2800 Series Launch Ice Lake-D Refreshed appeared first on ServeTheHome.

Тайният Списък “Рашков” – Част 1 Съдии със сметки и имоти зад граница

Post Syndicated from Екип на Биволъ original https://bivol.bg/rashkov-list-1.html

четвъртък 14 декември 2023


Списък с имена на магистрати, които не са декларирали сметки и имоти в чужбина, дълго време привличаше общественото и медийно внимание, след като бившият МВР министър Бойко Рашков се закани…

Security updates for Thursday

Post Syndicated from jake original https://lwn.net/Articles/955130/

Security updates have been issued by Debian (chromium and rabbitmq-server), Fedora (chromium, kernel, perl-CryptX, and python-jupyter-server), Mageia (curl), Oracle (curl and postgresql), Red Hat (gstreamer1-plugins-bad-free, linux-firmware, postgresql, postgresql:10, and postgresql:15), Slackware (xorg), SUSE (catatonit, containerd, runc, container-suseconnect, gimp, kernel, openvswitch, poppler, python-cryptography, python-Twisted, python3-cryptography, qemu, squid, tiff, webkit2gtk3, xorg-x11-server, and xwayland), and Ubuntu (xorg-server and xorg-server, xwayland).

На второ четене: „Дневник на чумата“

Post Syndicated from Стефан Иванов original https://www.toest.bg/na-vtoro-chetene-dnevnik-na-chumata/

„Дневник на чумата“ от Гонсало М. Тавареш

На второ четене: „Дневник на чумата“

превод от португалски Даринка Кирчева, изд. „Ерго“, 2022

Четох откъси от Дневника само месец след като добре познатият на български португалски автор започва да отразява реалността на живо, (Марин Бодаков ми прати линк към него на 1 април преди три години). И тогава, и днес тези дневникови записки ми стоят като стихотворения в проза. Като къси съединения между мисли, наблюдения и асоциации. Целта им е да държат автора на повърхността и успявайки да направят това – спасяват от хаос и удавяне и читателя.

Защо е нужно това връщане назад, когато на дневен ред са други кризи, други войни?

Миналото е чужда страна, а точно в тази се напомня, че има и бомби, които убиват без шум. Вирусът, който всъщност е тук и днес… Спомням си как четях и дневника на Франко Берарди – Бифо от същия период. Спомням си как с Ясен Василев превеждахме статии, мнения и анализи. Как си пишехме с приятели в Америка, Франция и Англия. Как чаках баща ми да дойде с колата си и да ми остави от така дефицитните в началото маски и как нервно пазарувах в кварталния магазин. Как се чувах всеки ден с родителите си. Как всяка седмица качвахме по един запис на театрално представление от архива на „Сфумато“. Как гледахме брифингите, как се възмущавахме, как лакомо четях „Моби Дик“, „Гаргантюа и Пантагрюел“, „Дон Кихот“ и всички останали дебели класики, които така и не бях прочел изцяло.

За португалеца този дневник е насъщен навик. Той е

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

А следата е от ясна по-ясна. Такава е и заради превода на Даринка Кирчева, която след Песоа, Сарамагу, Лиспектор и десетки други ни дава и това доказателство за таланта си.

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

Припомня се това, което не бива да се забравя от този период, за да не се превърне в изтласкана и потисната неартикулирана травма –

домът беше самотен затвор за мнозина. Реалността – индивидуална и колективна – бързо се превърна в нереалност и някои всекидневни навици и представи бяха забранен и немислим нонсенс. Димитров е извлякъл есенцията от това време чрез поредици от ситуации и прозаични пъзели. Цялостната картина, която сборникът създава, има естетически и документален характер, свидетелство за времето е въпреки фикционалната си закваска. С лекота надскача предварителните очаквания и някак между другото поставя сериозни въпроси, които отекват след края.

Ето само някои от тях: как да не си призрак приживе, със или без извънредни положения и ситуации; как и може ли да има днес животът пълнота и смисъл; как да се говори за това, за което често единствено мълчат не само медии, интелектуалци, анализатори, а и самите писатели, които вече рядко навлизат в сложни и поляризиращи теми. Артикулацията на травмата при Димитров става по безболезнен начин, не предизвиква фрустрация или съпротива при прочит. Това е едно от достойнствата на книгата – тя говори с тон на конкретика, достойнство и жизнеутвърждаване. Далечните – единствено във времево отношение – роднини на това писане са Ищван Йоркен, Кафка и Хашек, а по-близките хронологично са Итало Калвино, Сесар Айра и Етгар Керет.

Но гласът на Димитров е разпознаваем и негов. Този глас, подплатен със своеобразния му хумор и методичното му трудолюбие, има смелост да говори за трагедията като за трагедия, без да я омаловажава, а като ѝ противодейства. Такова писане показва и осмисля бруталността на българското всекидневие, противоотрова е срещу амнезията и гледа в очите конкретния ни и настоящ общ живот, прави го по-близък и разбираем. Такова писане доставя смисъл по щедър и неподменящ фактите начин.

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

Направих това много дълго отклонение, защото най-важното, което може да се извлече от Дневника на Тавареш, е, че е наложително да се пише за тук и сега в България. За нашето настояще и минало. С честност и откритост. С въображение и реалистичност. Трябва да разказваме историята си или някой друг ще ни я разкаже – съкратена и спестявайки много. Или пък тя ще се повтори.

На второ четене: „Дневник на чумата“

Разказването е свобода, съпротива и смисъл.

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

Португалецът разрежда бруталността на дните с цитати от Неруда, Канети, Слотердайк, Емили Дикинсън, Одън, Бенямин, Никанор Пара, Енценсбергер, Киняр, Оруел и десетки други. Не е сам, има книгите и две кучета в тези непредвидими и паникьосани месеци на извънредното положение, когато времето сякаш беше спряло и животът сякаш беше свършил приживе за стотици милиони хора.

Животът наистина се беше скъсил и оголил. Тавареш е прав, когато пише за

десетте животни с най-кратък живот. Включени в списъка: еднодневките и мухите. Пчелите работнички, пеперудите монарх, мравките и водните кончета. Да се грижим по-добре за който скоро ще умре. Бъди мил с един умиращ: мухи, пчели, мравки, пеперуди монарх и еднодневки. Не знам какво са еднодневките, но името е съвсем ясно. Едно нещастно животно, което на гърба си вече носи името на своята трагедия, на своята краткотрайност. Човекът също е еднодневка, макар да живее малко по-дълго и рядко да лети.

Лесно е да се каже да сме по-добри помежду си… Но още по-лесно човешкият живот се върна към нормалната си траектория, която е по-скоро самоунищожителна и предвещава още подобни катастрофи. Катастрофата преди три години се яви като отсъствие на всички неща. Тя може отново да се случи. Затова е и нужно

да се извлекат поне някакви поуки от това покъртително минало, в което са погребани милиони.

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

Казваш ми, че по-безсмъртна от грижата и яростта е радостта,

пише Хьолдерлин. Радостта от това, че си жив.

Но какво стана после? След като се оказа, че ще сме живи? Какво променихме? Как продължихме? Кои сме след пандемията? Кои ще сме и след края на войната? Ще отговорим ли по различен начин на собствените си – постоянно неспазени – обещания?


Активните дарители на „Тоест“ получават постоянна отстъпка в размер на 20% от коричната цена на всички заглавия от каталога на издателство „Ерго“, както и на няколко други български издателства в рамките на партньорската програма Читателски клуб „Тоест“. За повече информация прочетете на toest.bg/club.

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

Sliding window rate limits in distributed systems

Post Syndicated from Grab Tech original https://engineering.grab.com/frequency-capping

Like many other companies, Grab uses marketing communications to notify users of promotions or other news. If a user receives these notifications from multiple companies, it would be a form of information overload and they might even start considering these communications as spam. Over time, this could lead to some users revoking their consent to receive marketing communications altogether. Hence, it is important to find a rate-limited solution that sends the right amount of communications to our users.

Background

In Grab, marketing emails and push notifications are part of carefully designed campaigns to ensure that users get the right notifications (i.e. based on past orders or usage patterns). Trident is Grab’s in-house tool to compose these campaigns so that they run efficiently at scale. An example of a campaign is scheduling a marketing email blast to 10 million users at 4 pm. Read more about Trident’s architecture here.

Trident relies on Hedwig, another in-house service, to deliver the messages to users. Hedwig does the heavy lifting of delivering large amounts of emails and push notifications to users while maintaining a high query per second (QPS) rate and minimal delay. The following high-level architectural illustration demonstrates the interaction between Trident and Hedwig.

Diagram of data interaction between Trident and Hedwig

The aim is to regulate the number of marketing comms sent to users daily and weekly, tailored based on their interaction patterns with the Grab superapp.

Solution

Based on their interaction patterns with our superapp, we have clustered users into a few segments.

For example:

New: Users recently signed up to the Grab app but haven’t taken any rides yet.
Active: Users who took rides in the past month.

With these metrics, we came up with optimal daily and weekly frequency limit values for each clustered user segment. The solution discussed in this article ensures that the comms sent to a user do not exceed the daily and weekly thresholds for the segment. This is also called frequency capping.

However, frequency capping can be split into two sub-problems:

Efficient storage of clustered user data

With a huge customer base of over 270 million users, storing the user segment membership information has to be cost-efficient and memory-sleek. Querying the segment to which a user belongs should also have minimal latency.

Persistent tracking of comms sent per user

To stay within the daily and weekly thresholds, we need to actively track the number of comms sent to each user, which can be referred to make rate limiting decisions. The rate limiting logic should also have minimal latency, be cost efficient, and not take up too much memory storage.

Optimising storage of user segment data

The problem here is figuring out which segment a particular user belongs to and ensuring that the user doesn’t appear in more than one segment. There are two options that suit our needs and we’ll explain more about each option, as well as what was the best option for us.

Bloom filter 

A Bloom filter is a space-efficient probabilistic data structure that addresses this problem well. Simply put, Bloom filters internally use arrays to track memberships of the elements.

For our scenario, each user segment would need its own bloom filter. We used this bloom filter calculator to estimate the memory required for each bloom filter. We found that we needed approximately 1 GB of memory and 23 hash functions to accurately represent the membership information of 270 million users in an array. Additionally, this method guarantees a false positive rate of  1.0E-7, which means 1 in 1 million elements may get wrong membership results because of hash collision.

With Grab’s existing segments, this approach needs 4GB of memory, which may increase as we increase the number of segments in the future. Moreover, the potential hash collision needs to be handled by increasing the memory size with even more hash functions. Another thing to note is that Bloom filters do not support deletion so every time a change needs to be done, you need to create a new version of the Bloom filter. Although Bloom filters have many advantages, these shortcomings led us to explore another approach.

Roaring bitmaps Roaring bitmaps are sets of unsigned integers consisting of containers of disjoint subsets, which can store large amounts of data in a compressed form. Essentially, roaring bitmaps could reduce memory storage significantly and overcome the hash collision problem. To understand the intuition behind this, first, we need to know how bitmaps work and the possible drawbacks behind it.

To represent a list of numbers as a bitmap, we first need to create an array with a size equivalent to the largest element in the list. For every element in the list, we then mark the bit value as 1 in the corresponding index in the array. While bitmaps work very well for storing integers in closer intervals, they occupy more space and become sparse when storing integer ranges with uneven distribution, as shown in the image below.

Diagram of bitmaps with uneven distribution

To reduce memory footprint and improve the performance of bitmaps, there are compression techniques such as Run-Length Encoding (RLE), and Word Aligned Hybrid (WAH). However, this would require additional effort to implement, whereas using roaring bitmaps would solve these issues.

Roaring bitmaps’ hybrid data storage approach offers the following advantages:

  • Faster set operations (union, intersection, differencing).
  • Better compression ratio when handling mixed datasets (both dense and sparse data distribution).
  • Ability to scale to large datasets without significant performance loss.

To summarise, roaring bitmaps can store positive integers from 0 to (2^32)-1. Each positive integer value is converted to a 32-bit binary, where the 16 Most Significant Bits (MSB) are used as the key and the remaining 16 Least Significant Bits (LSB) are represented as the value. The values are then stored in an array, a bitmap, or used to run containers with RLE encoding data structures.

If the number of integers mapped to the key is less than 4096, then all the integers are stored in an array in sorted order and converted into a bitmap container in the runtime as the size exceeds. Roaring bitmap analyses the distribution of set bits in the bitmap container i.e. if the continuous interval of set bits is more than a given threshold, the bitmap container can be more efficiently represented using the RLE container. Internally, the RLE container uses an array where the even indices store the beginning of the runs and the odd indices represent the length of the runs. This enables the roaring bitmap to dynamically switch between the containers to optimise storage and performance.

The following diagram shows how a set of elements with different distributions are stored in roaring bitmaps.

Diagram of how roaring bitmaps store elements with different distributions

In Grab, we developed a microservice that abstracts roaring bitmaps implementations and provides an API to check set membership and enumeration of elements in the sets. Check out this blog to learn more about it.

Distributed rate limiting

The second part of the problem involves rate limiting the number of communication messages sent to users on a daily or weekly basis and each segment has specific daily and weekly limits. By utilising roaring bitmaps, we can determine the segment to which a user belongs. After identifying the appropriate segment, we will apply the personalised limits to the user using a distributed rate limiter, which will be discussed in further detail in the following sections.

Choosing the right datastore

Based on our use case, Amazon ElasticCache for Redis and DynamoDB were two viable options for storing the sent communication messages count per user. However, we decided to choose Redis due to a number of factors:

  • Higher throughput at lower latency – Redis shards data across nodes in the cluster.
  • Cost-effective – Usage of Lua script reduces unnecessary data transfer overheads.
  • Better at handling spiky rate limiting workloads at scale.

Distributed rate limiter

To appropriately limit the comms our users receive, we needed a rate limiting algorithm, which could execute directly in the datastore cluster, then return the results in the application logic for further processing. The two rate limiting algorithms we considered were the sliding window rate limiter and sliding log rate limiter.

The sliding window rate limiter algorithm divides time into a fixed-size window (we defined this as 1 minute) and counts the number of requests within each window. On the other hand, the sliding log maintains a log of each request timestamp and counts the number of requests between two timestamp ranges, providing a more fine-grained method of rate limiting. Although sliding log consumes more memory to store the log of request timestamp, we opted for the sliding log approach as the accuracy of the rate limiting was more important than memory consumption.

The sliding log rate limiter utilises a Redis sorted set data structure to efficiently track and organise request logs. Each timestamp in milliseconds is stored as a unique member in the set. The score assigned to each member represents the corresponding timestamp, allowing for easy sorting in ascending order. This design choice optimises the speed of search operations when querying for the total request count within specific time ranges.

Sliding Log Rate limiter Algorithm:

Input:
  # user specific redis key where the request timestamp logs are stored as sorted set
  keys => user_redis_key

  # limit_value is the limit that needs to be applied for the user
  # start_time_in_millis is the starting point of the time window
  # end_time_in_millis is the ending point of the time window
  # current_time_in_millis is the current time the request is sent
  # eviction_time_in_millis, members in the set whose value is less than this will be evicted from the set

  args => limit_value, start_time_in_millis, end_time_in_millis, current_time_in_millis, eviction_time_in_millis

Output:
  # 0 means not_allowed and 1 means allowed
  response => 0 / 1

Logic:
  # zcount fetches the count of the request timestamp logs falling between the start and the end timestamp
  request_count = zcount user_redis_key start_time_in_millis end_time_in_millis

  response = 0
  # if the count of request logs is less than allowed limits then record the usage by adding current timestamp in sorted set

  if request_count < limit_value then
    zadd user_redis_key current_time_in_millis current_time_in_millis
    response = 1

  # zremrangebyscore removes the members in the sorted set whose score is less than eviction_time_in_millis

  zremrangebyscore user_redis_key -inf eviction_time_in_millis
  return response

This algorithm takes O(log n) time complexity, where n is the number of request logs stored in the sorted set. It is not possible to evict entries in the sorted set like how we have time-to-live (TTL) for Redis keys. To prevent the size of the sorted set from increasing over time, we have a fixed variable eviction_time_in_millis that is passed to the script. The zremrangebyscore command then deletes members from the sorted set whose score is less than eviction_time_in_millis in O(log n) time complexity.

Lua script optimisations

In Redis Cluster mode, all Redis keys accessed by a Lua script must be present on the same node, and they should be passed as part of the KEYS input array of the script. If the script attempts to access keys located on different nodes within the cluster, a CROSSSLOT error will be thrown. Redis keys, or userIDs, are distributed across multiple nodes in the cluster so it is not feasible to send a batch of userIDs within the same Lua script for rate limiting, as this might result in a CROSSSLOT error.

Invoking a separate Lua script call for each user is a possible approach, but it incurs a significant number of network calls, which can be optimised further with the following approach:

  1. Upload the Lua script into the Redis server during the server startup with the SCRIPT LOAD command and we get the SHA1 hash of the script if the upload is successful.
  2. The SHA1 hash can then be used to invoke the Lua script with the EVALSHA command passing the keys and arguments as script input.
  3. Redis pipelining takes in multiple EVALSHA commands that call the Lua script and each invocation corresponds to a userID for getting the rate limiting result.
  4. Redis pipelining groups the EVALSHA Redis commands with Redis keys located on the same nodes internally. It then sends the grouped commands in a single network call to the relevant nodes within the Redis cluster and provides the rate limiting outcome to the client.

Since Redis operates on a single thread, any long-running Lua script can cause other Redis commands to be blocked until the script completes execution. Thus, it’s optimal for the Lua script to execute in under 5 milliseconds. Additionally, the current time is passed as an argument to the script to account for potential variations in time when the script is executed on a node’s replica, which could be caused by clock drift.

By bringing together roaring bitmaps and the distributed rate limiter, this is what our final solution looks like:

Our final solution using roaring bitmaps and distributed rate limiter

The roaring bitmaps structure is serialised and stored in an AWS S3 bucket, which is then downloaded in the instance during server startup. After which, triggering a user segment membership check can simply be done with a local method call. The configuration service manages the mapping information between the segment and allowed rate limiting values.

Whenever a marketing message needs to be sent to a user, we first find the segment to which the user belongs, retrieve the defined rate limiting values from the configuration service, then execute the Lua script to get the rate limiting decision. If there is enough quota available for the user, we send the comms.

The architecture of the messaging service looks something like this:

Architecture of the messaging service

Impact

In addition to decreasing the unsubscription rate, there was a significant enhancement in the latency of sending communications. Eliminating redundant communications also alleviated the system load, resulting in a reduction of the delay between the scheduled time and the actual send time of comms.

Conclusion

Applying rate limiters to safeguard our services is not only a standard practice but also a necessary process. Many times, this can be achieved by configuring the rate limiters at the instance level. The need for rate limiters for business logic may not be as common, but when you need it, the solution must be lightning-fast, and capable of seamlessly operating within a distributed environment.

Join us

Grab is the leading superapp platform in Southeast Asia, providing everyday services that matter to consumers. More than just a ride-hailing and food delivery app, Grab offers a wide range of on-demand services in the region, including mobility, food, package and grocery delivery services, mobile payments, and financial services across 428 cities in eight countries.

Powered by technology and driven by heart, our mission is to drive Southeast Asia forward by creating economic empowerment for everyone. If this mission speaks to you, join our team today!

[$] Logo and trademark issues for openSUSE

Post Syndicated from jake original https://lwn.net/Articles/954760/

A contest for new logos
for the openSUSE project and for
four separate distributions of it,
Tumbleweed, Leap, Slowroll, and
Kalpa, has turned into a
bit of an uproar in that community. A vote
has been held on the candidates
and winners have been announced, but
some are questioning why there is a need to change the existing logo (the
“Geeko”
chameleon) at all. In addition, there are questions about whether the
new logo will be trademarked (as previous ones have been)—and how many
years that will take.

GitHub Availability Report: November 2023

Post Syndicated from Jakub Oleksy original https://github.blog/2023-12-13-github-availability-report-november-2023/

In November, we experienced one incident that resulted in degraded performance across GitHub services.

November 3 18:42 UTC (lasting 38 minutes)

Between 18:42 and 19:20 UTC on November 3, the GitHub authorization service experienced excessive application memory use, leading to failed authorization requests and users getting 404 or error responses on most page and API requests.

A performance and resilience optimization to the authorization microservice contained a memory leak that was exposed under high traffic. Testing did not expose the service to sufficient traffic to discover the leak, allowing it to graduate to production at 18:37 UTC. The memory leak under high load caused pods to crash repeatedly starting at 18:42 UTC, failing authorization checks in their default closed state. These failures started triggering alerts at 18:44 UTC. Rolling back the authorization service change was delayed as parts of the deployment infrastructure relied on the authorization service and required manual intervention to complete. Rollback completed at 19:08 UTC and all impacted GitHub features recovered after pods came back online.

To reduce the risk of future deployments, we implemented changes to our rollout strategy by including additional monitoring and checks, which automatically block a deployment from proceeding if key metrics are not satisfactory. To reduce our time to recover in the future, we have removed dependencies between the authorization service and the tools needed to roll back changes.


Please follow our status page for real-time updates on status changes and post-incident recaps. To learn more about what we’re working on, check out the GitHub Engineering Blog.

The post GitHub Availability Report: November 2023 appeared first on The GitHub Blog.

The collective thoughts of the interwebz