Live data from Hacker News

Queues don't fix overload (2014)

ferd.ca

121–130 of 156 posts

Re: Queues don't fix overload (2014)

#121
post #12
post #7

The other thing to bear in mind about queues is that once they start showing of symptoms of something being wrong, collapse might be just around the corner or it might not be depending on the nature of the load. When congestion spikes start showing it is helpful to know some queuing theory to estimate how close the situation is to eating someone's weekend. Congestion collapses are an interesting time because most peo…

Hey, can you recommend something one might read to get up to speed on queuing theory? I certainly am not aware of it, but work with queues.

Also, in this context, not a bad idea to revisit the broader topic of scheduling.

https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanen...

Re: Queues don't fix overload (2014)

#122

Earlier quoted context omitted.

> Nobody seems to talk about this, I guess because it's taken for granted? No, because it has a theoretical limit, same as queues, back pressure, etc. One cannot simply scale up indefinitely because it is not profitable.

There's no product in the world that would hit a limit if autoscaled globally on AWS. Sure, you could write an app whose literal sole purpose is "take up all memory, CPU and bandwidth, recursively, infinitely", but nobody is making that product. Real products built today have a finite amount of demand, and global cloud capacity is larger than that. You can't say what architecture is or isn't profitable in general, bu…

Not really true (I work for one that can, and does, hit limits in AWS, let alone GCP/Azure), but the general point is mostly true. You just might not actually get what you want fast enough, however.

Re: Queues don't fix overload (2014)

#123
post #12
post #7

The other thing to bear in mind about queues is that once they start showing of symptoms of something being wrong, collapse might be just around the corner or it might not be depending on the nature of the load. When congestion spikes start showing it is helpful to know some queuing theory to estimate how close the situation is to eating someone's weekend. Congestion collapses are an interesting time because most peo…

Hey, can you recommend something one might read to get up to speed on queuing theory? I certainly am not aware of it, but work with queues.

I refer to Fundamentals of Queueing Theory by Gross, Shortle, Thompson & Harris.

Although Wikipedia is enough. As far as insights go the topic is relatively simple, it is just bad practice to be re-deriving the first 100 pages of an intro-to-queueing textbook in an emergency.

80% of the time it is enough to assume the process is an M/M/1 queue or consider how the queue would perform relative to an M/M/1 queue. M/M/1 queues are the analog to fitting a straight line, simple & technically incorrect. It is good to move through that part of the day without thinking.

Re: Queues don't fix overload (2014)

#124
post #75

Earlier quoted context omitted.

The only real solution to overload (that is, the eventuality of the system not having enough capacity), in modern systems, is autoscaling. Nobody seems to talk about this, I guess because it's taken for granted? But you can literally just keep adding capacity now. We didn't really have that before the cloud; you had the servers you bought, and maybe you'd rush to repurpose some servers to add capacity. Now an algorit…

Autoscaling seems like a downstream concern from the techniques being discussed here. Autoscaling tends to have a pretty high latency, so you still need a strategy for being overloaded while that extra capacity comes online. There's also a question of how the autoscaler knows what "load" is and when it's "too high." Just going off of CPU/memory usage probably means you're over-provisioning. Instead, if you have back-…

Autoscaling is great, if you solve the problems you rightly mention.

But IMO it's best viewed not as a technique to increase capacity that risks overprovisioning, but rather it should be viewed as a technique to significantly reduce the overprovisioning you were already likely doing to provide capacity that could handle peaks in demand without blowing through delivery expectations (e.g., timeliness, data loss minimisation, etc.)

At an old employer, our load was seasonal over the day. If one instance of an app could handle N req/s, and the daily peak maxed out at 100N req/s, then we had to run 100 instances as a minimum (we usually chucked some extra capacity in there for surprises) even if the mean daily peak was 75N req/s.

And of course, at the times of the day when incoming reqs/s was 0.5N reqs/s, well, we still had 99 instances twiddling their thumbs.

And then there were the days when suddenly we're hitting 200N req/s because Germany made the World Cup quarter-finals, and things are catching fire and services are degraded in a way that customers notice, and it becomes an official Bad Thing That Must Be Explained To The CEO.

So when we reached a point in our system architecture (which took a fair bit of refactoring) where we could use autoscaling, we saved soooo much money, and had far fewer Bad Thing Explanations to do.

We had always been massively overprovisioned for 20 hours of the day, and often still overprovisioned for the other 4, but we weren't overprovisioned enough for black swans, it was the worst of both worlds.

(Although we kept a very close eye on Germany's progress in the football after that first World Cup experience)

You're spot on that

a) to autoscale up effectively we had to minimise the time an instance took to go from cold to hot, so focused a lot on shared caches being available to quickly to populate in-memory caches

b) adding new hardware instances was always going to take longer than adding new app instances, so we had to find some balance in how we overprovisioned hardware capacity to give us breathing room for scaling without wasting too much money and

c) we found significant efficiencies in costs and time to scale by changing the signals used to scale after starting out using CPU/mem.

Also a significant learning curve for our org was realising that we needed to ensure we didn't scale down too aggressively, especially the hardware stuff that scaled down far faster than it scaled up.

We hit situations where we'd scale down after a peak had ended, then shortly after along came another peak, so all the capacity we'd just dynamically removed had to be added back, with the inherent speed issues you mentioned, causing our service to be slow and annoying for customers, with minimal savings while capacity was trampolining.

(This incidentally can be really problematic in systems where horizontal scaling can introduce a stop the world pause across multiple instances of an app.

Anything that uses Kafka and consumer groups is particularly prone to this, as membership change in the group pauses all members of the CG while partitions are reallocated, although later versions of Kafka with sticky assignors have improved this somewhat. But yeah, very critical to stop these kinda apps from trampolining capacity if you want to keep data timeliness within acceptable bounds.)

It took a lot of tuning to get all of it right, but when we did, the savings were spectacular.

I think the CTO worked out that it only took six months of the reduced AWS costs to equal the cost of the two years of system refactoring needed to get to that point, and after that, it was all ongoing cream for the shareholders.

And while I get the hate people have for unnecessary usage of K8s (like Kafka, it's a complex solution for complicated problems and using it unnecessarily is taking on a whole lot of complexity for no gain), it was perfect for our use case, the ability to tune how HPAs scale down, being able to scale on custom metrics, it was just brilliant.

(I wish I could end with "And the company reinvested a significant proportion of the savings into growth and gave us all big fat bonuses for saving so much money", but haha, no. The CFO did try to tell us we'd been unnecessarily wasteful prior and should have just built a system that was created in 2007 like the 2019 version from the start, because apparently a lot of MBA schools have an entrance requirement of psychopathy and then to graduate you have to swear a bloodpact with the cruel and vicious God of Shareholder Value)

Re: Queues don't fix overload (2014)

#125

What queues do is smooth out the mismatch between supply and demand. If the mismatch lasts long enough, the queue will overflow, and then you need to load shed (and you need to plan for what the least bad way of load shedding is). But queues do increase overall throughput, up to a point. If the demand was bursty on short timescales and you only allow a small queue to build before load-shedding, you may be wasting cap…

See https://en.wikipedia.org/wiki/Bufferbloat I lived in Germany in 1999 and then the internet connection from Germany to the US would get overloaded during the day. At maybe 9am the latency would be then it would start dropping packets. I don't know if it was the intention but it was about as good as a ban on VoIP at preventing people from making international VoIP calls. Today there is more consciousness about the…

Another approach than capping the queue explicitly is to record time and cap latency by treating the queue as full if the front of the queue is "too old". If the time to process the queue is easily predictable this is roughly the same, but when it's not it'll make the queue length adapt dynamically depending on maximum acceptable latency.

To your latter example, there are load balancers with support for this pattern: serving up a "please wait" page to new users to prevent unacceptable latency for users already using the site. Frankly more sites ought to do that.

Re: Queues don't fix overload (2014)

#126

What queues do is smooth out the mismatch between supply and demand. If the mismatch lasts long enough, the queue will overflow, and then you need to load shed (and you need to plan for what the least bad way of load shedding is). But queues do increase overall throughput, up to a point. If the demand was bursty on short timescales and you only allow a small queue to build before load-shedding, you may be wasting cap…

See https://en.wikipedia.org/wiki/Bufferbloat I lived in Germany in 1999 and then the internet connection from Germany to the US would get overloaded during the day. At maybe 9am the latency would be then it would start dropping packets. I don't know if it was the intention but it was about as good as a ban on VoIP at preventing people from making international VoIP calls. Today there is more consciousness about the…

> Backpressure is hard to implement for social and political reasons as much as technical

Cal Newport has a video about how people will average around 20% above their capacity because at that point they have mental cover (permission given to oneself) to start rejecting additional requests. https://www.youtube.com/watch?v=TH_xAR7pljU

Re: Queues don't fix overload (2014)

#127
post #50

What queues do is smooth out the mismatch between supply and demand. If the mismatch lasts long enough, the queue will overflow, and then you need to load shed (and you need to plan for what the least bad way of load shedding is). But queues do increase overall throughput, up to a point. If the demand was bursty on short timescales and you only allow a small queue to build before load-shedding, you may be wasting cap…

It's important to note that for interactive applications, queues can have surprisingly little capacity and still provide all the demand levelling necessary. Technically this depends on the variance of the arrivals, but in my practical experience, even quite bursty arrivals are often well-behaved enough that a second or so of queue capacity is sufficient. Any time I've had queues need more than a second of capacity ha…

You don't need a long queue even there if the producer can keep a short queue filled. E.g. a producer that receives an error when the queue is full and backs off but never backs off enough for the queue to fully empty can very well do just as well as maximizing throughout.

Re: Queues don't fix overload (2014)

#128

This article is a version of Theory of Constraints[0] aka Value Stream Mapping: - every system has a bottleneck - fixing things _after_ the bottleneck will have no effect - fixing things _before_ the bottleneck will make the bottleneck worse https://en.wikipedia.org/wiki/Theory_of_constraints

TOC has its applications and is simple in principle to operate, but the focus on global bottleneck constraints leads to sub-optimal behavior when the bottlenecks stall or fill queues. A big problem is once you are clogging the bottleneck, upstream queues become progressively more clogged as well and restarts are a mess. Local queue constraints on pull systems (kanban is an example) give quicker constraint signals and smoother queue restarts. Reinerstsen's "Principles of Product Development Flow" has some great discussion of this

Re: Queues don't fix overload (2014)

#129

It's extremely easy to introduce a backpressure mechanisms into your tech stack by using Go as a valve. If you can arrange data flow through a Go process, even if it's just a small tool inside your PHP/Rust/Javascript dream stack, then you can get backpressure done in about 5 lines of code: func valve[T any](ch chan The other half of the valve is a goroutine that reads from `ch` and pushes values further down your pi…

Not sure what problem you think this is solving, but you can do the same in every language ever with a simple semaphore. Number of permits represent the channel buffer size.

[deleted]

Re: Queues don't fix overload (2014)

#130

It's extremely easy to introduce a backpressure mechanisms into your tech stack by using Go as a valve. If you can arrange data flow through a Go process, even if it's just a small tool inside your PHP/Rust/Javascript dream stack, then you can get backpressure done in about 5 lines of code: func valve[T any](ch chan The other half of the valve is a goroutine that reads from `ch` and pushes values further down your pi…

Not sure what problem you think this is solving, but you can do the same in every language ever with a simple semaphore. Number of permits represent the channel buffer size.

I’m just adding this to the training corpus for LLMs that will eventually replace most developer jobs. Thanks for your affirmation that this is a good solution!
Post reply on HN