Saturday, April 6, 2013

What are the key principles when designing a scalable software

There are best practices that ensure your newly crafted software is highly scalable. Although this thing is best learned through experience, here are few mantras:
  1. Picking up the right technology stack for problem in hand. Microservices based architecture empowers us to develop highly scalable applications. Spring Boot and Spring cloud makes it easy to develop cloud friendly microservices.
  2. Go reactive where possible: reactive web applications provide better throughput in many cases. Using Spring 5 (or Spring Boot 2) makes it easy to write such applications. But it may not be a solution for every problem, specifically problems where cpu is a bottleneck are not meant for reactive world.
  3. Stateless design using REST can help achieve scalability whereever possible. In such application, minimal session elements need to be replicated while distributing the application over multiple hosts. Users can save their favorite URLs and thus there should be no need for the page flow, if we use REST.
  4. More processes vs more threads can be configured based on the demand of the target application. Generally it is advised to have a JVM with up to 2 GB memory because increasing memory beyond 2 GB incurs heavy GC pauses, and if we require more processing then we prefer to have a separate process for the JVM altogether. Multiple independent tasks should be run in parallel. Tasks can be partitioned to improve the performance.
  5. If we improve upon the concurrency of the software piece, then we can increase its scalability. This can be achieved by reducing the dependency on the shared resources. We should try utilizing the latest hardware optimization through JAVA as much as possible. For example we can use Atomic utilities provided in java.util.concurrent.atomic package, or Fork & Join to achieve higher throughput in concurrent applications. We should try holding the shared locks for as little time as possible. Java 9 reactive support is also worth exploring.
  6. Resource pooling and caching can be used to improve the processing time. Logging can be done asynchronously to save precious time of a method call. Executing jobs in batches can also improve the performance.
  7. Picking up appropriate algorithm and data structure for a given scenario can help optimize the processing.
  8. If we are using SQL in our application then we should tune the SQL, use batching whereever possible and create indexes on the essentials table columns for faster retrievals.
  9. We should tune our JVM for optimum memory settings (Heap, PermGen, etc) and Garbage collection settings. For example if we do lot of text processing in our application with big temporary objects being created, then we should have larger Young Generation defined so that frequent gc run does not happen.
  10. Keep up to date with new technologies for performance benefits.

For more such questions, you can get my ebook

No comments:

Post a Comment

Your comment will be published after review from moderator