Software Architecture etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Software Architecture etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

28 Eylül 2023 Perşembe

Yazılım Mimarisi - Event Driven Architecture (EDA) - Claim Check

Giriş
Açıklaması şöyle
This pattern could be used whenever a message cannot fit the supported message limit of the chosen message bus technology. 
Açıklaması şöyle
For example, a message may contain a set of data items that may be needed later in the message flow, but that are not necessary for all intermediate processing steps. We may not want to carry all this information through each processing step because it may cause performance degradation and makes debugging harder.

Sending such large messages to the message bus directly is not recommended, because they require more resources and bandwidth to be consumed. Also, most messaging platforms have limits on message size, so you may need to work around these limits for large messages.
Çözüm
Açıklaması şöyle. Yani veri tabanı gibi bir yere kaydedip ID değerini gönderiyoruz
Store the entire message payload into an external service, such as a database. Get the reference to the stored payload and send just that reference to the message bus. The reference acts like a claim check used to retrieve a piece of luggage, hence the name of the pattern. Clients interested in processing that specific message can use the obtained reference to retrieve the payload, if needed.
Mesaj işlendikten sonra veri tabanından silinebilir

22 Nisan 2023 Cumartesi

Yazılım Mimarisi - Strangler (Sarmaşık) Örüntüsü

Giriş
Not : Strangler için OpenAPI ya da eski adıyla Swagger kullanılabilir.

Açıklaması şöyle
The name refers to strangler vines that grow around trees, gradually building up a solid structure that eventually is able to completely replace the tree that they started growing around. The strangler pattern for microservices means to gradually and strategically build a "mesh" of microservices around an existing monolith, replacing certain functions as needed, and over time potentially replacing the monolithic application entirely.
Stranger örüntüsü API'yi değiştirirken testlerin bozulmasını da engelleyebilir. Açıklaması şöyle
build an anti-corruption layer, or a facade, or a proxy between your tests and the SUT, so you can change the API of the SUT without having to change too many parts of your tests. That will allow you to keep the tests as they are for now. Later, when you have some time for cleaning up, you may decide to migrate the tests to the new API one-by-one.

This approach is also known as strangler pattern and can often be used to gradually swap out legacy components by components with a new design, not only for tests.
Şeklen şöyle. Burada ilk hafta Strangler örüntüsü istekler halen eski sisteme yönlendiriyor. Daha sonraki haftalarda micro servislere yönlendiriyor






25 Aralık 2021 Cumartesi

Yazılım Mimarisi - Deduplication Patterns

Giriş
Dağıtık mimarilerde ve özellikle microservice mimarisinde aynı mesaj birden fazla kez gelebilir. Bu mesajların ayıklanmasına deduplication deniliyor. Kullanılabilecek bazı yöntemler şöyle

1. Idempotent Consumer Pattern
Idempotency (Denkgüçlülük) Nedir yazısına taşıdım. Ancak kısaca tüketen taraf 
- ya mesajları bir sayı ile takip eder ve tekrar gelen mesajları ayıklar
- ya da tüm işleri en baştan yapar

2. Transactional Outbox
Outbox Pattern yazısına taşıdım. Ancak kısaca üreten ve tüketen taraflar birbirlerini direkt çağırmazlar. Bunun yerine aracı olarak veri tabanını kullanırlar. Böylece 
- üreten taraf veri tabanına yazmayı başardığında mesajın gideceğini garanti eder.
- tüketen taraf mesajı başarıyla işleyip veri tabanından sildiğinde mesajın tüketildiğini garanti eder
- tüketen taraf için kod yazmak şart değil. CDC araçlarından birisi de kullanılabilir

3. Kafka Transaction API — for exactly-once delivery semantics
Bu çözüm tabii ki eğer Kafka kullanıyorsak geçerli. Apache Kafka Message Delivery Semantics yazısına taşıdım. Aslında Transactional Outbox ile aynı mantık. Farklı olarak veri tabanı yerine Kafka kullanılıyor. Böylece
- üreten taraf Kafka Transaction'ınını başarıyla commit'lerse mesajın gideceğini garanti eder.
- tüketen taraf mesajı başarıyla işleyip Kafka Transaction'ınını başarıyla commit'lerse mesajın tüketildiğini garanti eder

23 Kasım 2021 Salı

Yazılım Mimarisi - Event Driven Architecture (EDA) With Event-Carried State Transfer pattern

Event-Carried State Transfer Pattern Nedir?
Açıklaması şöyle
As the name suggests, the main characteristic for the event-carried state transfer pattern is that the events contain state, which is quite different from notification events that just contain an identifier to retrieve state from the producer.
Örnek
Şöyle yaparız
{
  "specversion" : "1.0",
  "type" : "com.example.orderPlaced",
  "order" : {
    "id" : "A001-1234-1234",
    "time" : "2020-12-15T00:00:00Z",
    "products" : [{
      "id" : "1234321",
      "name" : "eBook Seven Languages in Seven Weeks",
      "price" : 25.00,
      "quantity" : 1
    }]
  }
}
Açıklaması şöyle. Burada önemli olan event'in içinde işlenmesi için gerekli alanların da olması. Böylece işleyen kod gidip tekrar çağrı yapıp bu bilgileri toparlamak zorunda kalmıyor
Including state in events eliminates the need for the consumer to make a call back to the producer to retrieve state. Instead, consumers build a private replica of state by storing the state from events they consume.
Yani tüketen taraf şu şekilde veri tabanına erişmek zorunda kalmıyor. Eğer üreten taraf zaten bu bilgiye sahipse, veri tabanına yapılan çağrılar azaltılabilir.
User user = userRepository.findById(event.getUserId());
Fat Event vs Delta Event
Açıklaması şöyle
In many publications an event that contains any state is referred to as a fat event. That would make all events that leverage the event-carried state transfer pattern fat events. Some authors, including myself, make distinctions between delta events and fat events. Delta events contain just the properties that changed, so just enough detail, nothing more.
Ne Zaman Kullanılmamalı
Eğe tüketen taraf verinin en son haline ihtiyaç duyuyorsa yani  Consumers require real-time accuracy gibi bir durum varsa  Event-Carried State kullanılmaz

29 Ağustos 2021 Pazar

Yazılım Mimarisi - Space-Based Architecture

Giriş
Bu mimariyi ilk olarak burada gördüm. Şeklen şöyle

Açıklaması şöyle
The main idea behind the space-based pattern is the distributed shared memory to mitigate issues that frequently occur at the database level. The assumption is that by processing most of operations using in-memory data we can avoid extra operations in the database, thus any future problems that may evolve from there (for example, if your user activity data entity has changed, you don’t need to change a bunch of code persisting to & retrieving that data from the DB).

The basic approach is to separate the application into processing units (that can automatically scale up and down based on demand), where the data will be replicated and processed between those units without any persistence to the central database (though there will be local storages for the occasion of system failures).
Bu mimaride scalability (ölçeklendirme) ön planda. Bu açıda  cloud mimarilere benziyor. 

Ayrıca kendi kendine yeterli Processing Units (PU) var. Bu açıdan da mikro service mimarisine benziyor.

Veri tabanı olarak ta Distributed Shared Memory veya Grid Computing kullanıyor. 

16 Haziran 2021 Çarşamba

Yazılım Mimarisi - Replica/Replication - Çoğaltma

Giriş
Replication kelimensin Türkçesi çoğaltma

Replication V.S. Cache - Çoğaltma ve Ön Bellek
Açıklaması şöyle. Cache latency problemi içindir. Yazılım Mimarisi - Cache ölçeklemek için kullanılan diğer yöntem olan cache konusunu ele alıyor
From the perspective of scalability in distributed system design, cache and replication are used for different goals. Cache is in memory and is used to improve the latency. Replication is still in disk and is used to scale out read throughput and enhance durability.
Replication ve Scaling - Çoğaltma ve Ölçeklendirme
Replication, ölçekleme için kullanılan yöntemlerden birisi. Açıklaması şöyle
Caching is one of the two ways(the other is replication) to scale read heavy applications. 
Açıklaması şöyle
There are many techniques to scale a relational database: master-slave replication, master-master replication, federation, sharding, denormalization, and SQL tuning.
- Replication usually refers to a technique that allows us to have multiple copies of the same data stored on different machines.
- Federation (or functional partitioning) splits up databases by function.
- Sharding is a database architecture pattern related to partitioning by putting different parts of the data onto different servers and the different user will access different parts of the dataset
- Denormalization attempts to improve read performance at the expense of some write performance by coping of the data are written in multiple tables to avoid expensive joins..
- SQL tuning.
Data Replication vs. Data Synchronization - Veri Çoğaltması ve Veri Eş Uyumluluğu
Açıklaması şöyle. Yani Data Replication aynı veri tabanı içinde olur, Data Synchronization ise faklı veri tabanlarının eş uyumlu hale gelmesidir.
Data Replication:
Data replication involves creating multiple copies of data and distributing them across different systems or nodes(usually called standbys).

Data Synchronization:
Data synchronization, on the other hand, focuses on maintaining consistency and accuracy between the source of truth and other data sources.
Naive Methods of Data Replication - Çoğaltmanın Bön Yöntemleri
1. Kaynak veri tabanının gönderilecek değişiklikleri bellekte tutması. Eğer hedef veri tabanı ile bağlantı kaybolursa, kaynak sistemin belleği yetmeyeceği için çoğaltma bozulur

1. Primary Replica - Master-slave replication
Şeklen şöyle
Açıklaması şöyle
Only the primary DB host handles DB updates. The update on primary is synced to replicas via bin log replay. Most mainstream databases like MySQL have built in support for this setup. Read request is load balanced(LB) to the replicas.
2. Primary Replica Zayıflıkları
2.1 Primary Failure
Açıklaması şöyle
Github has shared their solution (here and here). The idea is to have a separate system that constantly monitors the status of master and the lag on each replica. The monitor will detect the primary’s failure and adjust the network topology to promote one replica as the new primary. This requires being exposed to many low level network details. I find it intimidating to depend on unfamiliar open source projects doing tricky stuff on the network.

Many NoSQL databases have symmetric hosts thus have good support for node failures. I believe the main benefit today from a NoSQL database like Cassandra is the ease of operation.
2.2 Consistency
Açıklaması şöyle
The primary replica set up will result in update delay in replicas and is a classic eventual consistency model. Essentially we trade strong consistency for read scalability. Eventual consistency is enough for most applications, except for ones requiring ‘read your write’ consistency.

‘Read your write’ consistency can be improved by forcing the read request to primary if it’s following a write. Or naively force the read to wait for several seconds so that all replicas have caught up. When there are replicas not in the same datacenter(DC), the read will also need to be restricted to the same DC.
2.3 High Watermark
Açıklaması şöyle. Burada yazma ve okuma işlemleri Master'a gidiyor, ancak Master isteği işledikten sonra daha Replica'ya gönderemeden çöküyor. Yeni Master seçilince de bu işlemden haberi olmuyor
Let's assume, the leader received a write operation. The leader wrote the transaction on the WAL. Let's also take that a consumer read the operation immediately after it was written, and before the operation could be propagated to all the followers, the leader crashed.

Post the leader crash, the cluster would undergo Leader Election, & one of the followers becomes the new leader for that partition. However, the latest changes from the previous leader were not replicated to the new leader, i.e new leader is behind the old leader.

Now let's assume, another consumer tries to read the latest record. Since the new leader doesn't have the latest write, this consumer doesn't know about that record. This leads to data inconsistency/data loss, which is exactly we didn't want!!

Note: We do have these transactions in the WAL on the old leader, but those log entries cannot be recovered until the old leader becomes alive again.
Açıklaması şöyle
To overcome the problem, we use the concept of High Watermark.

The leader keeps track of the indexes of the entries that have been successfully replicated on each follower. The high-water mark index is the highest index, which has been replicated on the quorum of the followers.

The leader can push the high-water mark index to all followers as part of a heartbeat message(in case it's a push based model)/leader can respond to the pull request from the followers with the high watermark index.
Açıklaması şöyle.  Yani master quorum sayısı kadar replica nın asgari watermark değerini hesaplar. Bu değer değişince replica'lara duyurur
The leader gets pull requests from the followers, with the latest offset they are in sync with. Hence the leader can easily make a call on when to update the high watermark. Once the high watermark is updated on the leader, with the next fetch, the leader will propagate the updated high watermark to the followers.
...
This guarantees that even if the leader fails and another leader is elected, the client will not see any data inconsistencies, as any client would not have read anything beyond the high watermark. This is how we can prevent inconsistent reads while ensuring high availability and resiliency........
2.4 Hazelcast EntryProcessor
Burada bir soru var

EntryProcessor ile direkt member üzerinde veriyi değiştirebilmek mümkün. Ancak burada karşımıza iki tane farklı çözüm çıkıyor
1. Güncelleme sadece Primary üzerinde yapılır ve veri asenkron olarak Replica'ya gönderir

2. Primary ve Replica aynı kodu çalıştırarak güncellemeyi birbirlerinden bağımsız olarak yaparlar.  Bu verinin her yerde daha hızlı güncellenmesini sağlar. 
Eğer Replica üzerinde hata olursa Primary belli aralıklarla Replica ile senkronize olduğu için en son veri de biraz gecikmeyle de olsa Replica'ya ulaşır.

3. Master-master replication
Açıklaması şöyle
Each database server can act as the master at the same time as other servers are being treated as masters. At some point in time, all of the masters sync up to make sure that they all have correct and up-to-date data.

Here are some advantages of master-master replication.
- If one master fails, the other database servers can operate normally and pick up the slack. When the database server is back online, it will catch up using replication.
- Masters can be located in several physical sites and can be distributed across the network.
- Limited by the ability of the master to process updates.
3.1 Conflict Resolution
Bazı yöntemler şöyle
3.1. Conflict avoidance
Açıklaması şöyle
It is the simplest strategy to avoid conflicts. We just need to ensure that all writes for a particular record goes to the same leader, or more aptly to the same data center. It might look simple, but edge cases, when the entire data center is down or such may hamper the entire application.
3.2. Convergent Conflict Resolution
Açıklaması şöyle
In multi-leader replication, there is no defined ordering of writes, thus making it unclear what the final value should be. This inconsistency questions the durability of the data and every replication must ensure that the data is the same at all places. This method of handling conflicts can be done in various ways :
- LWW(Last Write Win) — Each write is given a unique ID and the write with the highest write is chosen as the winner.
- Give each replica a unique Id and let writes originated at higher-numbered replicas take precedence over the lower counterparts.
- Merge the values.
- Record the conflict in an explicit data structure that preserves all the information , and write application code that resolves conflict later by notifying the user.
3.3. Custom conflict resolution logic
Açıklaması şöyle
Most multi-leader replication tools provide the option to custom define your conflict resolution in the application code. On write, as soon as a conflict is detected, the conflict handler is called, and it runs in the background to resolve it. On read, if a conflict is detected, all conflicting writes are stored and the next time data is read, these multiple versions of the data are returned to the application, which in turn prompts the user or automatically resolve the conflict, and write back to the database.
3.4. Automatic conflict resolution
Açıklaması şöyle
There has been a lot of research on building automatic conflict resolutions which would be intelligent enough to resolve the conflicts caused by concurrent data modifications.

- Conflict-free replicated data types( CRDTs) are a family of data structures for sets, maps, ordered lists, counters, etc that can be concurrently edited by multiple users. It uses two-way merges.
- Mergeable data structure tracks history explicitly, just like it, and uses a three-way merge function
- Operational transformation is the algorithm behind collaborative editing applications such as Google docs. It’s a whole big topic which is very interesting to study.

4. Replication ve Consistency
Hem replica yapıp hem de consistency için kullanılan bazı çözümler şöyle
1. Read-Impose Write-Consult-Majority

2. Leader-based Replication 
Tüm yazma işlemleri Leader'a yönlendirilir. Leader yazar ve veriyi diğerlerine dağıtır

3. Leased-Leader-based Replication




29 Nisan 2021 Perşembe

Yazılım Mimarisi - Cache

Giriş

Cache işlemi okumayı hızlandırır. Açıklaması şöyle
Caching is one of the two ways(the other is replication) to scale read heavy applications. 
Ancak kendi içinde de bazı problemler getirir. 

Yazılım Mimarisi - Replica ölçeklemek için kullanılan diğer yöntem olan replication konusunu ele alıyor

1. Race condition between delete and set
Önce veri tabanında değişiklik yapıp, daha sonra cache sistemde silme yaparsak bu problem olabiliyor. Açıklaması şöyle.
1. B got a cache miss and queried DB to get V0
2. A updated DB value from V0 to V1
3. A sent delete to cache, which was an no-op
4. B filled cache with V0

10 Mart 2021 Çarşamba

Yazılım Mimarisi - Microservice Mimarisinin Zorlukları

Giriş
Microservice mimarisi Hype Cycle'da "Trough of Disillusionment" kısmına yavaş yavaş geliyor. Açıklaması şöyle
Developers around the world are on a move to break down their monoliths into microservices. And they base this move on false assumptions. We already have many companies moving out of microservices back to monoliths. Microservices are now at the “Trough of Disillusionment”, in the Gartner Hype cycle.
Peki nerede Hype Cycle'da nerede olduğumuza bakmaksızın, bu mimarinin zorlukları nedir?

1. Microservice Mimarisinin Zorlukları
1.1 Yazılım Daha Karmaşık Hale Geliyor
Microservice mimari yazılımı daha karmaşık hale getiriyor. Açıklaması şöyle.
Microservices are generally undesirable because they turn your software into a distributed system – and distributed systems make everything a lot more difficult. But a service-oriented architecture has some important benefits:

- different services can be developed and deployed independently by different teams
- different services can be scaled independently
Bir başka açıklama şöyle.
...microservices introduce substantial complexity of their own, in addition to the base complexity of your system. You have to pay this “premium” in terms of reduced productivity. This means that for simple projects, microservices make you less productive. This changes for more complex projects: whereas a monolithic solution might become increasingly difficult to work with, a microservice architecture scales much better and requires roughly constant effort. You have to know whether the extra initial effort of microservices is worth it given your software system. Since you are asking this question, the answer is probably “no”.
Açıklaması şöyle.
Microservice architectures are certainly not without their own challenges, especially if you consider the explosion in independently moving parts it will give you. What you need to look out for, however, is focusing on the technicalities of it. Remember, just as SOA was about organizational structure rather than tools and standard protocols, microservices are about business agility rather than – again – tools and standard protocols.
1.2 Toplam Reliability Azalır
Uygulamanın toplam Reliability seviyesi yani Güvenilirlik seviyesi azalır. Açıklaması şöyle.
In the monolithic bare-metal application, if the server has an issue, be it network, hard drive, memory, or otherwise, the whole application goes down. So, if your provider gave you a 99.5% uptime guarantee, then you are confident of being up 99.5% of the time, however, with the microservice architecture, each component has its own uptime guarantee. So, if your application uses 10 services, each with 99.5% guarantee, then you now have 99.5% to the power of 10 = 95.0%.
2. Bazı Yanılsamalar
Microservice mimarisi ölçeklenebilir, kolay idame ettirilebilir, küçük ve dirençli yazılımlardır varsayımı aslında yanılsamalarla dolu.  Bazı yanılsamalar şöyle
Only microservices are scalable: FALSE. There are no metrics or methods that can be used to classify a code base as microservice or monolith. Even a 2 pizza team can be responsible by a monolith or by a microservice. It’s possible to scale both of them.

Only microservices code are easy to maintain: FALSE. If you have 5 developers responsible for a microservice, it’s already hard to reason about. It’s large, huge. If you call it a microservice or a monolith, it doesn’t matter. The number of lines of code are the same. You can organize your monolith into small modules so they can be easy to understand.

Microservices are small: FALSE. The word “micro” is misleading. Of course you can have a small microservice, but the recommendation is that microservices should not be so small that one developer can handle it alone. You’re only adding complexity and cost doing that. And again, you can have small and independent modules in your monolith.

Microservices are resilient: FALSE. Resilience is a matter of how you organize your modules or microservices and how they can still work on the presence of errors. You can have truly independent modules in a monolith that will work flawless or have 2 microservice bound by an HTTP call where it will only work when both are online only. Microservices are a distributed system, with a lot of moving parts. It’s much harder for it to be resilient than of a monolith.
3. Ne Zaman Microservice Kullanmalı
Tek parça (Monolith) yazılımın idamesi çok zor hale gelince düşünülebilir. Yani temel kural şöyle
Only add complexity when it solves problems you actually have
Açıklaması şöyle.
So my primary guideline would be don't even consider microservices unless you have a system that's too complex to manage as a monolith. The majority of software systems should be built as a single monolithic application. Do pay attention to good modularity within that monolith, but don't try to separate it into separate services.
Netflix örneği şöyle. Eğer 100 kişi aynı anda tek bir ürün üzerinde çalışamıyorsa, microservice mimarisi kullanılabilir.
Take for example the company that started all that: Netflix. They have one big product. One. How could be possible for 100 developers to work on the same git repository or code base? It’s fiscally impossible. That’s why they did it. And that is the only reason to use microservices.
4. Microservice İçin Gerekli Koşullar Sağlanmıyorsa
Açıklaması şöyle
For all the rest of us enterprise software developers, we should be writing monoliths. But not any monolith, a modular monolith. We want all the benefits microservices claims to provide within our monoliths.
Bu monolith içinde
1. Asenkron haberleşme için bir Message Broker olabilir
2. Şifreleri saklayan bir Security Vault olabilir
3. Yalıtılmış Containerlar olabilir.

5. Peki Ölçeklenedirme Ne Olacak?
Açıklaması şöyle. Yani önce vertical scalability seçeneği sonuna kadar kullanılmalı. Eğer direkt horizontal scalability seçeneği ile başlarsa, zaten bize gereken tüm kaynakları sadece Kubernetes gibi bir altyapıya harcıyoruz.
Enterprise software doesn’t require huge amounts of hardware. If your application will have 10000 concurrent users, one server is enough. Actually, it’s very affordable (in enterprise standards) at Amazon an EC2 machine with 40 cores and 128GB of RAM. So, you can vertically scale your applications a lot. That’s probably the total hardware of a complete kubernetes cluster that you would use to scale your application horizontally, but wasting memory on each replica server runtime. Which makes no sense, since application servers runs on top of the JVM. 

4 Mart 2021 Perşembe

Yazılım Mimarisi - Kappa Architecture - Stream Processing İçindir

Giriş
Açıklaması şöyle
In 2014 Jay Kreps started a discussion where he pointed out some discrepancies of Lambda architecture that further led the big data world to another alternate architecture that used less code resource and was capable of performing well in certain enterprise scenarios where using multi layered Lambda architecture seemed like extravagance.

Kappa Architecture cannot be taken as a substitute of Lambda architecture on the contrary it should be seen as an alternative to be used in those circumstances where active performance of batch layer is not necessary for meeting the standard quality of service. This architecture finds its applications in real-time processing of distinct events.
Açıklaması şöyle
In 2014, Martin Kleppman, author of the book Designing Data-Intensive Applications gave a seminal talk entitled Turning the database inside out. He outlined a new architectural pattern for processing data in real-time. The key insight is to externalize the write-ahead-log (WAL), which up to this point had been an internal (yet fundamental) component of every operational database. A streaming framework could then be used to process the log in near real-time, thereby providing an always-up-to-date equivalent to a materialized view.
...
In recent years, Kleppman’s inside-out database concept has gained popularity, and even acquired a name: Kappa architecture.
Bu mimari şeklen şöyle Hadoop tabanlı Batch Processing kısmı çıkarılıyor ve her şey Stream Processing ile hallediliyor.

Bu mimaride veri Hadoop gibi bir yerde devamlı saklanmadığı için hata yapılması durumunda geri dönüş daha zor.


10 Şubat 2021 Çarşamba

Yazılım Mimarisi - Lambda Architecture - Big Data İçindir

Giriş
Not Kappa Mimarisi yazısına bakabilirsiniz

2011 yılında Nathan Marz tarafından teklif edilen bir yaklaşım. Açıklaması şöyle
In 2011, Nathan Marz proposed an important approach to tackling the limitations of the CAP theorem in his blog, it called the Lambda architecture.
CAP teoremine göre Consistency seçersem, DB offline ise veri kaybederim. Availability seçersem de her zaman en son veriyi okuyamam. Lambda mimari ise CAP teoremindeki problemin tanımı şöyle söylüyor
 ... the use of mutable state in databases and the use of incremental algorithms to update that state. It is the interaction between these problems and the CAP theorem that causes complexity.

Bu mimari şeklen şöyle.


Bu mimaride 3 kısım var
1. Batch Processing yani Hadoop. Hadoop kendi sistemindeki verileri işler ve DB'deki tablolara yazar
2. Stream Processing. Apache Storm veya benzeri bir şey, son batch'ten itibaren gelen verileri işler ve DB'deki farklı tablolara yazar.
3. Interactive Queries . Bu kısım şekilde yok ancak DB'deki iki farklı tabloyu birleştirerek dışarıya sunar.

1. Batch Layer
Batch Layer'daki veri salt okunur ve eklenir. Açıklaması şöyle
Data in the master dataset must hold three properties as follows.
- Data is raw
- Data is immutable
- Data is eternally true

The master dataset is the source of truth. Even if you were to lose all your serving layer datasets and speed layer datasets, you could re-construct your application from the master dataset.
Bu katmanda "batch views" sonuçlar hesaplanıyor. Açıklaması şöyle
The first layer (the batch layer) stores the entire data set and computes batch views. The stored data set is immutable and append-only. New data is continually streamed in and appended to the data set, but old data will always remain unchanged. The batch layer also computes batch views, which are queries or functions on the entire data set. These views can subsequently be queried for low-latency answers to questions of the entire data set. The drawback, however, is that it takes a lot of time to compute these batch views.
Batch Processing sürekli eklenen veriyi iki şekilde işleyebilir. Açıklaması şöyle
Because our master dataset is continually growing, we must have a strategy for managing our batch views when new data becomes available.
- Re-computation algorithms: throwing away the old batch views and re-computing functions over the entire master dataset.
- Incremental algorithms: updating the views directly when new data arrives.
2. Stream Processing veya Speed Layer
Açıklaması şöyle. Burada önemli olan şey "batch views" hesaplaması yeniden yapıldıktan sonra, stream processing layer'daki veriyi temizlemek. Böylece hesaplamaya sıfırdan başlayacaktır. Neticede elimizde "stream views" tabloları olacaktır
The data that streams into the batch layer also streams into the speed layer. The difference is that while the batch layer keeps all of the data since the beginning of its time, the speed layer only cares about the data that has arrived since the last set of batch views completed. The speed layer makes up for the high latency in computing batch views by processing queries on the most recent data that the batch views have yet to take into account.
3. Serving Layer
Açıklaması şöyle. Aslında bu katmak Batch Layer içindeymiş gibi de düşünülebilir. Amacı "batch views" tablolarını dış dünyaya açmak.
The serving layer loads in the batch views and, much like a traditional database, allows for read-only querying on those batch views, providing low-latency responses. As soon as the batch layer has a new set of batch views ready, the serving layer swaps out the now-obsolete set of batch views for the current set.
4. Interactive Queries Layer
Hem "bath views" hem de "stream views" tablolarını birleştirerek dış dünyaya açar.

Lambda Mimarisi Nerede Kullanılır
Big Data kullanan IoT, Machine Learning projelerinde kullanılabilir.

Lambda Mimarinin Dezavantajları
1. İki Farklı Kod Olması
Açıklaması şöyle. Tabii bu durum doğal olarak maliyete yansıyacaktır.
... the challenge of maintaining two separate sets of code to compute views for the batch layer and the speed layer. Both layers operate on the same set — or, in the case of the speed layer, subset — of data, and the questions asked of both layers are similar. However, because the two layers are built on completely different systems (for example, Hadoop or Snowflake for the batch layer, but Storm or Spark for the speed layer), code maintenance for two separate systems can be complicated.

1 Şubat 2021 Pazartesi

Yazılım Mimarisi - Microservices Architecture - Database Per Service yani No Shared Database

Giriş
Açıklaması şöyle
Each microservice should have its own databases and Data MUST not be shared via a database. This rule removes a common cause that leads to tight coupling between services. For example, if two services share the same database, the second service will break if the first service has changed the database schema. Then teams will have to talk to each other before changing databases, leading to delays, taking us backward.

I think this rule is a good one and should not be broken.

However, there is a problem. We often share the database when two services share the same data (e.g. bank account data, shopping cart) and need to update the data transactionally, using database transactions to enforce consistency.
Servis Başına Veri Tabanı Farklı Bir Şekilde de Düşünülebilir
Açıklaması şöyle. Yani her servis bir bir veri tabanı teknolojisi de kullanabilir.
A different way to think about the database per service pattern
The database per service pattern is a bit of a misnomer because the database itself is actually less important than the data model when it comes to microservices. Thinking of the database per service pattern as a “data model per service” instead recognizes the importance of selecting the right data model ..
Şeklen şöyle


Güncellemeyi Tek Servise İndirgemek
Eğer aynı veriyi iki microservice güncellemek istiyorsa, sıkıntı çıkabiliyor. Güncellemeyi tek service yaptırmak için bazı çözümler şöyle

1.  İki servis arasına message queue yerleştirmek
Böylece sadece bir microservice güncelleme yapar ve veriyi diğerine gönderir.

2. İki servisi birleştirmek 
Bu yapılabiliyorsa güzel olabilir.

Eğer Güncellemeyi Tek Servise İndiremiyorsak
1. Transaction kullanmak
Eğer iki servis birleşemiyorsa transaction kullanmak gerekir. Eğer transaction kullanmak istemiyorsak bazı çözümler şöyle

2. Use Compensation and other lesser Guarantees
Burada bir başarısızlık varsa, bir microservice bunu düzeltici işi de yerine getiriyor.

Distributed Transaction
Sanırım buradaki sıkıntı şöyle
...it’s quite impossible to have a distributed transaction spanning all the services.

15 Ocak 2021 Cuma

Yazılım Mimarisi Microservices Architecture - Error Propagation

Giriş
Microservices Best Practices listesi şöyle
1. Have A Domain-Driven Design
2. Do Not Hard-Code values
3. Maintain Logging
4. Versioning
5. Authentication and Authorization
6. Dependency
7. Make Executable Contracts
8. Fault Tolerance
9. Documentation - Swagger veya OpenApi
Loglama
Elimizde şöyle bir çağrı zinciri olsun
Client -> A->B->C
Eğer C servisinde hata olursa ve tüm servisler aynı hata kodunu loglarsa, 3 tane kopya oluşur. Bu yüzden en doğrusu hatayı A servisinde loglamak. Açıklaması şöyle
If something fails, return immediately and don’t log everywhere. Only Log the error, where you initiated the process. So for the above scenario, you should log the error only in service “A”.
Hata Kodunun Değiştirilmesi
Birbirini zincirleme çağıran servislerde, hata kodu döndüren servis varsa, çağrıyı başlatan servis te aynı hata kodunu döndürmelidir. Eğer farklı bir hata kodu döndürülürse sebebi farklı yorumlanabilir.

Servisler hata kodları olarak HTTP Durum Kodları - 5XX SERVER ERROR Kodları kullanabilirler

Fan-Out/Fan-In API Integration Pattern yazısına da bakabilirsiniz.

Örnek - sıralı çağrılar
Elimizde şöyle bir çağrı zinciri olsun. Eğer C DB bakımda olduğu için isteği işleyemezse ve Http kodu 503 - Service Unavailable dönerse ancak B bunu 4XX haline getirirse ve A da 4XX dönerse, bu sefer Client kendi çağrısında bir parametre hatası olduğunu düşünecektir.
Client -> A->B->C->DB
Örnek - fan out çağrılar
Bir servis bir sürü servisi daha çağırıyorsa ve bunların sonuçlarını ayrı ayrı dönebilir. 
Örnek
Çıktı şuna benzer
//response payload from Expedia flights service to Expedia
{
  "httpCode": 200,
    "vendorAndFlights": [
      {
        "vendorName": "United Airline",
        "statusCode": 500,
        "flights": null
      },
      {
        "vendorName": "Cathay Pacific Airways",
        "statusCode": 404,
        "flights": null
      },
      {
        "vendorName": "Emirates",
        "statusCode": 200,
        "flights": 
         [
           {
             "from": ...
             "to": ...
           }
         ]
      }
}

4 Aralık 2020 Cuma

Yazılım Mimarisi - Microservices Architecture Choreography-Based Saga Örüntüsü - Kullanmayın

Giriş
Açıklaması şöyle.
In this approach, there is no central orchestrator. Each service participating in the Saga performs their transaction and publish events. The other services act upon those events and perform their transactions. Also, they may or not publish other events based on the situation.
Yani her servis akıştan haberdar. Açıklaması şöyle. Choreography-Based Saga Örüntüsü basit işler için kullanılabilir ve karmaşık transaction'larda pek iyi sonuç vermiyor.
In this approach, the services themselves are aware of the flow of the operations. After an initial message is sent to a service operation, it generates the next message to be sent to the following service operation. The service needs to have explicit knowledge of the flow of the transaction leading to more coupling between services.
Choreography-Based Saga Bağlamında Event Driven Architecture (EDA)
Şeklen şöyle
Compensation Operations
Açıklaması şöyle
Here, we can see that the flow starts from the client that sends the initial message to the first service through its input message queue. In its business logic, it can carry out its data-related operations in a local transaction defined within the service. After the operations are done, the overall workflow adds a message to the request queue of the next service in the choreography. In this manner, the overall transaction context will be propagated through these messages to each of the services until completion. 

In the case of failure in a service in the workflow, we need to rollback the overall transaction. For this, starting from the service which incurred the failure, it will clean up its resources, and send a message through a compensation queue to the service that was executed right before. This moves the execution of the previous step, does any compensation actions to rollback the changes done by its local transaction, and repeats the operation of contacting its previous service for compensation operations. In this, the error handling chain will reach the first service that will then ultimately send a message to the response queue. This is connected to the client to notify that an error has occurred and the total transaction has been rolled back successfully using compensation actions. 

As seen in the synchronous service invocation approach, when executing the local transactions in their respective services, we should maintain a transaction history table to ensure we don’t repeat the local operations in case the service receives duplicate messages. Also, in order to not lose the continuity of the workflow, a service should acknowledge the message from its request queue only after the database transaction is done and the next message is added to the request queue of the following service. This flow makes sure we don’t lose any messages and the overall transaction will finish executing either by succeeding or rolling back all the operations.
Compensating Action'ları çalıştırmak gerekir. Şeklen öyle




Yazılım Mimarisi - Microservices Architecture Orchestration-Based Saga Örüntüsü - Bunu Kullanın

Giriş
Bu Saga yöntemin bir tane Orchestrator (Saga Manager)  kullanılır. Açıklaması şöyle.
In this approach, there is a Saga orchestrator that manages all the transactions and directs the participant services to execute local transactions based on events. This orchestrator can also be thought of as a Saga Manager.
Saga Orchestrator veya Saga Manager haberleşme için Message Broker kullanabilir. Her şey REST olmak zorunda değil.

Örnek
Otel, taksi ve uçak rezervasyonu bir seferde yapan bir akış şöyle
1. Traveler sends a “Book Trip” request from the browser, which will hit the Trip microservice.

2. The Trip microservice is responsible for starting Saga. It calls on what is called as a Saga coordinator endpoint, starting a Saga. The coordinator announces a Saga identifier in response. The Trip microservice enlists itself with the created Saga by calling the Saga coordinator providing the Saga identifier and handing over addresses of REST endpoints for compensation (optionally confirmation) callbacks. Those are endpoint the coordinator can call back in response to the outcome of the execute action on any participating microservices.

3. The Trip microservice takes the Saga ID and adds it as an HTTP header to the REST call to the 3 other fulfilling microservices, Cab Microservice, Hotel Microservice and Flight Microservice. 

4. The called microservices distinguishes the Saga and they can enlist themselves (by announcing REST endpoints for compensation/confirmation callbacks) to Saga coordinator.

5. The participant microservices,  viz. Cab Microservice, Hotel Microservice and Flight Microservice executes the business process

6. Any of the participant microservices could fail the Saga by calling “Execution Failure” on the Saga coordinator.

7. Saga coordinator sends commands either to confirm or to compensate, to all participants

8. On way back, the initiator microservice is responsible for finishing the Saga by calling complete (with a success or failure flag) on the Saga coordinator with the saga identifier.
Compensation Operations
Örnek
Elimizde şöyle bir saga olsun

Compensation Operation için şu şartlar gerekli
1. Event Log
Açıklaması şöyle. Orchestrator bir event log tutmalı 
One way of handling this issue would be to keep a log of operations done by the admin service. This could be similar to the following:

TX1: CHECK INVENTORY
TX1: CREATE ORDER
TX1: UPDATE INVENTORY
TX1: PROCESS PAYMENT - FAILED
TX1: MARK ORDER AS CANCELLED
TX1: UPDATE INVENTORY - INCREMENT STOCK COUNTS
2. Servisler Idempotent Olmalı
Açıklaması şöyle. Idempotency Nedir yazısına bakabilirsiniz.
So the admin service can track the operations that have already been executed, and what hasn’t. But again, we have to be thoughtful of possible edge cases that can happen even when processing an event log like this. The admin service and its log is separate from the other remote service operations, thus those interactions themselves do not work transactionally. There are changes like the following:

- Admin service executes inventory service to revert inventory counts (by incrementing)
- Admin service updates its log with “TX1: UPDATE INVENTORY - INCREMENT STOCK COUNTS”

What if the first operation above executes, then the service crashes before the second operation? When the admin service continues its operations again, it will think that it didn’t do the inventory revert operation and will execute the first operation again. This will leave the inventory data with invalid values because it has done stock number increments twice, which isn’t good! This is a situation of having at-least-once delivery as we would often see in a distributed system. A common approach to handle this would be to model our operations to be idempotent. That is, even if the same operation is done multiple times, it will not cause any harm, and the target system’s state would be the same.
Orchestrator Compensation İşlemi Esnasında Çökerse
Bu yöntemin zayıflığının açıklaması şöyle. Eğer bir transaction ortasında Orchestrator çökerse, diğer katılımcılar tutarsız (inconsistent) bir durumda kalabilirler
An Orchestration based Saga is based on a central coordinator who is responsible for instructing individual services to continue or rollback. ... this central coordinator service is responsible for centralising the Saga’s decision making and sequencing the constituent transactions. ... 

The inherent weakness of an Orchestration based Saga is its central coordinator, which is it’s single point of failure. The Saga manager can be a separate service or a part of one of the coordinating microservices. If the Saga Manager goes down in the middle of a Saga, the entire participating microservices might remain inconsistent till the Saga Manager comes back to operational state.
Orchestration-Based Saga Örüntüsü İçin Event Driven Architecture (EDA)
EDA sadece Orchestration-Based Saga Örüntüsü için kullanılmaz. Genel bir kavramdır ancak bu bağlama çok iyi uyuyor. EDA için açıklama şöyle
Using this pattern, we can make sure if we emit a message successfully to a message broker that is meant to target some service, it will at some point be successfully sent to the intended recipient. This guarantee makes our other processes much easier to model. Also, the message broker’s asynchronous communication model, where it allows simultaneous reading and writing, provides much better performance due to lower overheads and wait times for roundtrip calls. Error handling is also simpler because even if the target service is down, the message broker will hold the messages and deliver them when the target endpoint is available. Additionally, it can do other operations such as failure retries and load balancing requests with multiple service instances. This pattern also encourages loose coupling between services. The communication happens via queue/topics, and producers and consumers do not need to know about each other explicitly.
Açıklaması şöyle
The communication between the coordinator services and other services will be done via request and response queues. 
Şeklen şöyle
Bu asenkron yapı sayesinde orchestrator bir Finite State Machine şeklinde tasarlanabiliyor. Açıklaması şöyle
The asynchronous communication between the coordinator service and the other services allows it to model the transactional process as a state machine, wherein each of the steps completed with the services can update the state machine. The state machine should be persisted in a database to recover from any failures of the coordination service. 
Örnek - State Machine Kullanan Orchestration-Based Saga
Açıklaması şöyle
Modeling a saga orchestrator as a state machine is an effective way to not only manage distributed transactions but also support long-running business transactions. A state machine consists of a set of states and a set of transitions between states that are triggered by events. Each transition can have an action, which for a saga is the invocation of a saga participant. 

The transitions between states are triggered by the completion of a local transaction performed by a saga participant. The current state and the specific outcome of the local transaction determine the state transition and what action, if any, to perform. As a result, using a state machine model makes designing, implementing, and testing sagas easier.
Şeklen şöyle

State'lerin açıklaması şöyle
Order Open  : The initial state. Saga set this state at the start of the workflow.
Blocking Seat  : When in this state, the saga is waiting for the SeatBlockingService to block the seat for booking.
Authorizing Payment  : The saga is waiting for a reply to the payment authorization command from PaymentService.
Allocating Seat : Waiting for SeatAllocationService to allocate the seat after payment success.
Reverse Payment :  If Seat allocation fails, the saga would send a request for a payment refund.
Unblock Seat  :  If payment authorization fails, the saga would send a fail event to unblock the seat.
Order Completed  :  A final state indicating that the saga was completed successfully.
Order Rejected  : A final state indicating that the Order was rejected by one of the participants.
Aynı anda birden fazla Saga çalışıyor olabilir. Şeklen şöyle