📜 ⬆️ ⬇️

Scaling is simple

From B2C-portals are expected primarily scaling. Unfortunately, scaling is too often declared a Technology issue - it’s enough to choose a fashionable technology and all problems are solved. The fact that this is not the case can appear, later on, in production mode (on the production system).
Instead of waving a mace of technology, I’ll tell you how to design a highly available, scalable portal with a well-thought-out architecture and a conscious rejection of the data model. The first part will describe common concepts, and possible scenarios and their solutions will follow.


Part one. Theory.

Long ago, in the dark times of the beginning of the Internet, that is, somewhere at the end of the past - the beginning of this millennium, the question of choosing the right architecture was often reduced to choosing the right database. When the director of a startup developer set a task for developers to build a new portal, the team mostly discussed whether it was necessary to buy Oracle Enterprise Edition , or you could get by with a standard license. Advanced companions experimented with Roet , Versant, or other object-oriented databases. After that, data models were created, which in most cases were database models, and all this before asking the question: what, exactly, should the system do, and how?

Today, 10 years and a lot of interesting developments in the field of software later, everything is very similar, except that instead of choosing Oracle or Informix, they argue about whether to take Mongo , Hadoop or ElasticSearch . Without a doubt, this is a good and very useful technology. However, the choice of technology should not precede the choice of architecture! In other words: technology, no matter how advanced it is, should serve the architecture, performing certain tasks within its framework. These tasks should be determined by the architecture and system requirements.
')
The Technology First approach, which can often be found in software development trenches, is very attractive for managers who are technically savvy: “If startup X uses Mongo, Bootstrap, ElasticSearch and / or Ruby, then this cocktail will help me, and if not, then I I always discourage investors: they say they used all the most modern technologies and that means they are not to blame ! ”Unfortunately (for the fate of a startup and fortunately for everyone else), this approach rarely leads to the correct solution of a specific problem .
But I advocate the opposite approach: Architecture First . This means that the problem is solved primarily by architecture, and technology is only a way to implement the architecture. Accordingly, technology is only part of the solution and only when it brings concrete benefits in the context of this solution.

Here is an example.

For many years, people tried to solve all the problems of portal building with the help of relational DBMS, and for many years all attempts to scale these portals were crowned with dust, as soon as Schema (Database Scheme) became rather complicated. As a result of this trouble, a generation of RDBMS heirs appeared - NoSQL DBMS (whether NoSQL bases are something fundamentally new or just reanimation of old ideas, in this context it is not important). Another thing is interesting: the success of NoSQL DBMS is based on the fact that they recognized the main problem of SQL DBMS, namely Joins , and simply do not support them. But if you build the architecture in such a way as to do without the Joins, that is, to deliberately abandon them , then the good old SQL databases scale without any special problems.

Architecture - what is it?

Before we talk about how to find the right architecture, which will support such standard requirements as flexibility (scalability), scalability (scalability) and manageability (manageability), you need to decide: what is actually architecture? Here opinions differ. Some consider the architecture as a very abstract type of descriptions of system requirements, a kind of requirement analysis; others are like the distribution of classes into packages. A wide variety of definitions of the concept of software architecture can be found on this page .
I consider the following to be the most successful:
Architecture (software) is the structure of the system, consisting of the components, the visible properties of these components and the relations between them.


In other words, the architecture deals with the components of the system and the communication between them. This definition is based on the concept of a component , but what is a component?
Components are components of our architectural ideas, which we define on various grounds: in particular, I am on responsibility for any business process or data.
A separate component is a collection of entities (for example, classes / objects) that perform a common task. For example, MessagingService is a component that is responsible for sending messages and consists of several classes (including the MessagingService interface itself).
The size of the component should be as small as possible, but sufficient to solve the problem (for Messaging, sending and receiving messages).

Returning to the B2C portals, we note their common, in terms of architecture, properties:


General architectural principles

One of the most popular architectures for building such portals is service-oriented (SOA). In the recent past, its reputation has suffered from the popularity of WebServices , architecture, with SOA having little in common, but which is often confused with it. SOA, being much older and more mature than WebServices, when used properly, offers a solution to many scaling problems.

From an architectural point of view, components in an SOA are services and clients, with each component being both at the same time. Externally visible properties of a component are the interfaces that it publishes. As for the relationship between the components, there are two types:



Direct communication is similar to a phone call to a taxi or pizza order service, indirectly comparable to a running line on a stock exchange board, which appears regardless of whether someone reads it or not. The polled methods, as well as the data being listened to, are interfaces in terms of architecture, that is, means of communication with the component.

Insulation to the bone marrow (to the database)

One of the main and most useful principles of SOA: the isolation of components from each other. Among other things, this means that each component is the absolute master of its data. No one has the right to change them, without notifying, at a minimum, the owner, and it is better to ask him to make a modification himself.
Service-oriented architecture can do many guitars, but its main advantage is in the absence of a global data model . The interfaces of each specific component is all that is known about it "outside". The inner life of his remains a purely personal matter, not known to anyone. This principle has not only supporters - after all, it is so convenient to carry out a complex investigation using one (three-story) SQL query! Yes, it is true, the connection between the data of different services at the DBMS level could be of some use in the investigation, statistical analysis and data mining ( data mining , in-depth, or data mining ). But where does it say that these connections must exist in a working environment? If someone needs data for analysis, no one bothers to regularly transfer them from the working system to the analytical one, and at the same time create as many connections as you like, and also turn the data sideways, upside down, or how else you like it. But the working system itself should not be contaminated by these “by-products” - the ballast that makes the brisk, fast “Ferrari” heavy and clumsy “Passat”.

Voluntary abandonment of the global data model in terms of system architecture means the following:


In order to fully enjoy the benefits of SOA, services must be properly "cut". Large, monstrous services often turn into “application in application”, and they themselves are subject to the problems that we were going to overcome. Too low-cut services lead to an overhead of communication, which kills all scaling at the root. How to find the right size of service?

The easiest way to do this is by adhering to the following two software development paradigms: Design by Responsibility and Layer Isolation . With the help of the latter, it is possible to determine the fundamental limits of the responsibility of services - what is a service (as a business logic) and what is not (for example, presentation logic). Design by Responsibility helps to cut services vertically, breaking them down by subject or functional specialization (messaging, search, etc.).

Proper cutting services
Scheme 1: Proper slicing services

After correctly identifying the services, you need to think about how they should “communicate” with each other.

Permitted (green) and forbidden (red) ways of communication
Scheme 2: Permitted (green) and prohibited (red) ways of communication

How to avoid a global data model?

The conventional layer model is vertical. Above is the presentation layer, at the bottom - persistent. Therefore, developers usually start with persistence and create a global data model. In fact, in SOA, you need to start from the middle :

Dependencies between layers
Scheme 3: Dependencies between layers

Thus, we can create a real service model in which each specific persistence meets the needs of its service, and only that. This leads to the strict isolation required for scaling:

Insulation of Persistence
Scheme 4: Insulation of Persistence

Another paradigm that is absolutely necessary to follow is KISS (Keep it Simple, Stupid). Regarding software architecture, KISS means that only absolutely necessary components must be part of our architecture. Anything that does not bring immediate benefits, and this may include modern technology, should be excluded. In other words, only those technologies that justify the cost of their support deserve the right to enter the final decision.

There are many small screws in good architecture.

But now, finally, the time has come when the services are designed and written, and it's time to rush to the embrasure - that is, under the real load of real users. Prior to launch, we often do not know what load a particular component will withstand. Of course, it’s good to have a realistic stress test. The problem is that in order to write a good test, we need to know the real behavior of the users, but in order to find out the real behavior of the users, we need ... to start.

Nevertheless, it is not at all scary to do tuning after the launch in working mode, because we all remember well what premature optimization is. It is important to monitor (Hi MoSKito !) Each component in order to recognize the bottlenecks in time and react before the component is completely overloaded. Knowing this “bottleneck”, we have different response capabilities. About two of them, Caches and Routing, we'll talk in the following sections .

Source: https://habr.com/ru/post/209202/


All Articles