Posts

Showing posts with the label architecture

The Power of Simplicity: How a random iterator saved the day

Image
 …and my database. How many times has something so simple saved the day? Sometimes, the simplest solutions can have a significant impact on a problematic situation. In this blog post, we'll explore one such scenario where a small algorithm change led to substantial performance improvements in an existing system. The problem  The issue at hand involved a component in a system using a database table as a makeshift queue for processing updated rows. Multiple processor instances read from the same table, with Redis locking in place to prevent concurrent processing of the same row. However, the processors working in the same order led to numerous collisions and timeouts, causing the system to slow down.  As illustrated in the image, the processors were interfering with one another; while they ultimately completed the work, excessive time was consumed in fruitless attempts to lock records, which consequently increased the strain on the database. The solution: A Random Iterator ...

Building an Active/Standby HA Architecture with Queue-Based Microservices using Azure Functions

Image
In recent years, the microservices architecture has gained traction owing to its remarkable scalability and adaptability. Azure Functions, a serverless compute service, facilitates the development of dynamic, scalable microservices. When designing microservices for enterprise systems, achieving high availability (HA) is crucial. This blog post delves into a strategy for constructing a HA architecture that incorporates queue-based microservices through the use of Azure Functions. Challenges with Queue-Based Microservices Creating HA queue-based microservices using Azure Functions comes with some design challenges. One of them is deciding between an Active/Active or Active/Standby architecture. While having an Active/Active architecture is trivial, it carries a cost from inter-region traffic and compute resources. Additionally, there may be scenarios where multiple consumers for the same queue are not necessary or desired, making Active/Standby a better option.  But there is a proble...

Saving costs in the cloud with smarter caching - Part 1

Image
A cache is a component where data is stored so that future requests can be served faster. So for example, in the context of a web application responding to multiple requests,  instead of hitting your backend database or microservice every time, the application can remember the last value for a given computation or call. One particular flavor is a centralized cache system, provided by tools like Redis, Memcached, etc. A central place where we store data temporarily and all instances of our app (and even other apps) can use it. There are many uses, from storing session data in a multi-server web application to providing a performance advantage by keeping a value that is costly to calculate or obtain.  A centralized cache is a lifesaver. But it tends to be overused and there are some scenarios where we could reduce its usage or completely skip it, and in doing so, save costs and improve performance.  Reducing the usage of the centralized cache. Let's have an example of a web...

The distributed monolith antipattern

Image
The words distributed and monolith are usually adversaries in software architecture, contrary to the monolith model,  a distributed approach will allow you to have isolated services as building blocks of functionality for your system. Let's assume you reached that architecture already, either from scratch or by decomposing an existing monolith. At this point you have a set of services.  Some people go and just say - "it's microservices!". Well..., that's not enough yet, but now you have all the pieces into individual services and the whole system working together.  This is a step into the right direction for scalability, but we can do more in other areas.  So, let's check: how do you deploy them ? If you deploy all services at once , you still have a lot to improve, for now you have a "distributed monolith" (Open to a better name for this), which I consider to be an antipattern, and this is more of a common practice than expected,...