10 Kasım 2020 Salı

Geospatial Searches - En Yakın Komşu Arama (Nearest Neighbor Search)

Giriş
Belli bir alan içinde bir şey arama için kullanılır. Temel 3 tane yöntem var
1. Point and Radius
2. Bounding Box
3. Polygon

Bu 3 tane arama yönteminin hangi veriyapısı veya algoritma ile gerçekleştirildiği ayrı bir konu. En yakın komşu arama yazısında bazı fikirler var.

1. Point and Radius
Bu arama yönteminin diğer isimleri aynı zamanda "point and radius", "point and distance, "radius-based" gibi isimlerle de biliniyor.

Örnek
Şöyle bir örnek verilebilir.
Often we want to know what's nearby or within a specified distance of a specific point. In my use case, I'd like to know what cities and towns are near the GRSM national park...maybe within 50 miles as a starting point.
2. Bounding Box
Bu arama yönteminde yarıçap yerine bir kutunun sol üst ve sağ alt köşesi verilir.

3. Polygon
Bu arama yönteminde bir kapalı polygon'un köşeleri verilir. 

Apache Kafka Connect

Kafka Connect Nedir?
Açıklaması şöyle
Kafka Connect was added in the Kafka 0.9.0 release, and uses the Producer and Consumer API under the covers. The Connect Service is part of the Confluent platform and comes with the platform’s distribution along with Apache Kafka. 
Bir başka açıklama şöyle. Yani harici kaynakları Kafka'ya bağlamak için Kafka Connect kullanılır
Kafka Connect is an integration framework for connecting external sources/destinations to Kafka.
Bir başka açıklama şöyle. Yani Source ve Sink kavramları var
It can ingest databases to Kafka topics as a “source” connector or as a “sink” connector it can feed other data systems such as Elasticsearch.

Kafka Connect Cluster Başlatma
Kafka kurulumundaki
1. connect-standalone.sh veya
2. connect-distributed.sh
kullanılır.

Connector Olmadan Başlatmak İçin
Örnek
Şöyle yaparız
export KAFKA_INSTALL_DIR=<kafka installation directory e.g. /home/foo/kafka_2.12-2.5.0>

$KAFKA_INSTALL_DIR/bin/connect-distributed.sh connect-distributed.properties


Connector Çeşitleri
İki Çeşit Connector Var
1. Source Connector : Bir kaynağı sorgular ve oradaki veriyi Kafka'ya ithal eder
2. Sink Connector : Kafka'daki veriyi bir kaynağa ihraç eder.

Standalone ve Distributed Mode
Açıklaması şöyle
Apache Connect can be run in two modes: Standalone and Distributed. The first one is for testing and development.
Source Connector Örnekleri
1. 2. JDBCSourceConnector
JdbcSourceConnector yazısına taşıdım

Sink Connector Örnekleri

1. JDBCSinkConnector
JdbcSinkConnector yazısına taşıdım

6 Kasım 2020 Cuma

MongoDB Komutları - Veri tabanı

Veri tabanı Silme
Şöyle yaparız
db.dropDatabase()
Veri tabanı İstatistikleri
Şöyle yaparız
db.stats()
Kullanılan Veri tabanını Değiştirme/Veri tabanı Yaratma
use X komutu kullanılan veri tabanını değiştirir veya yaratır. 
Örnek
Şöyle yaparız.
> use temp
switched to db temp
Kullanılan Veri tabanını Görme
Şöyle yaparız
db     —> bulunduğun db yi gösterir
Veri tabanlarını Listeleme
Şöyle yaparız
show dbs
Collection'ları Listeleme
Şöyle yaparız
show collections 
    or
show tables

MongoDB Komutları

Giriş

mondod komutu
mongod komutu yazısına taşıdım

1. Veritabanı Komutları
Veritabanı Komutları yazısına taşıdım

2. Collection İşlemleri
Collection ilişkisel veri tabanındaki table gibi düşünülebilir.

aggregate metodu
aggreate metodu yazısına taşıdım

bulkWrite metodu
bulkWrite metodu yazısına taşıdım

createCollection
Şöyle yaparız.
db.createCollection(“myCollection”, { capped : true, autoIndexID : true, size : 6142800,
max : 10000 } )
deleteMany metodu
Birden fazla satırı siler
Örnek
Şöyle yaparız
db.student.deleteOne({_id:3}
//delete the document which contains id=3.

db.student.deleteMany({_id:{$lt:3}}
//delete the documents which contains id is less than 3.
deleteOne metodu
Bir satırı siler

find metodu
find metodu yazısına taşıdım

findAndModify metodu
Açıklaması şöyle
MongoDB read and write operations aren’t performed as part of an atomic transaction, solving this with the database’s atomic findAndModify operation becomes trivial, 
findOne metodu
Açıklaması şöyle
If multiple documents satisfy the query, this method returns the first document according to the natural order which reflects the order of documents on the disk.
Örnek
db.collection.findOne({ $or: [ {"apple": "blah"}, {"orange": "blah"}, {"grape": "blah"} ] })
getcollectionnames metodu
Veri tabanında bir sürü collection olsun. Bu collection'lardan "account" isimli bir alan sahip olanları şöyle buluruz.
db.getCollectionNames().forEach(function(collname) {
    var count = db[collname].find({"account": {$exists: true}}).count();
    if (count > 0) {
      print(collname);
    }
})
Bu Oracle veri tabanındaki şu sorguya denk gelir.
SELECT * FROM ALL_TAB_COLUMNS WHERE COLUMN_NAME LIKE 'account'; 
insertOne
Örnek ver

insertMany
Örnek ver

insert metodu
Veriyi yaratmaya çalışır. Veri mevcutsa hata verir. Şöyle bir verimiz olsun
codes = [
  {code:'abc'},
  {code:'123'}
]
Bu veri şöyle eklenir.
db.collection.insert(codes) 
Veri struct + array of struct olabilir. Şöyle yaparız.
> db.coll.insert({
  "settings": {
    "system": "windows",
    "date": "mm-dd-yyyy",
    "time": "HH-MM-SS"
  },

  "info": [
    { "_id" : "99921", "city" : "CRAIG", "loc" : [ -133.117081, 55.47317 ]},
    ...
  ],

  "Weather": [
    {"_id":"99921", "weather": "cloudy"},
    ...
  ]
})
limit metodu
Döndürülen kayıt sayısını sınırlar. Genelde sort ile beraber kullanılması mantıklı
lowest = db.coll.find().sort({_id:1}).limit(1).next()._id;
min metodu
Elimizde şöyle kayıtlar olsun.
[
  { product_name: "O",vendor_name: "test1", category: "F",  date: "2015-06-12"},
  { product_name: "O",vendor_name: "test1", category: "F",  date: "2015-02-24"}, 
  { product_name: "A",vendor_name: "test2", category: "F",  date: "2015-07-11"},
  { product_name: "A",vendor_name: "test2", category: "F",  date: "2015-06-19"} 
]
En eski tarihli kayıtları şöyle buluruz. Çıktı olarak 2 ve 4. kayıtı alırız.
db.wab.aggregate([{
    $match : {
      vendor_name : {
        $in : ["test1", "test2"]
      },
      category : 'F'
    }
  }, {
    $group : {
      _id : {
        vendor_name : "$vendor_name",
        product_name : "$product_name"
      },
      business_date : {
        $min : "$business_date"
      }
    }
  }
])
updateOne
$unset ile kullanılırsa, dokümandan bir alan siler

save metodu
db.collection.save veriyi ya günceller ya da yaratır.

3 Kasım 2020 Salı

Yazılımda Deadlock

Deadlock Oluşturan Sebepler
Deadlock şu sebeplerden oluşur
1. Mutual Exclusion
2. Incremental Acquisition
3. No preemption
4. Circular Waits
Deadlock 'tan Kaçınma Yöntemleri
Açıklaması şöyle
There are three techniques to prevent deadlocks: 
1) Lock Ordering, 
2) Lock Timeout, and 
3) Deadlock Detection. 
Circular Wait
Burada dikkat edilmesi gereken kural şöyle
Mutex lock ordering rule: Given a total ordering of all mutexes, a program is deadlock-free if each thread acquires its mutexes in order and releases them in reverse order.
Bir başka açıklama şöyle
7.4.4 Circular Wait

The fourth and final condition for deadlocks is the circular-wait condition. One way to ensure that this condition never holds is to impose a total ordering of all resource types and to require that each process requests resources in an increasing order of enumeration.
Yani birden fazla mutex varsa tüm thread'ler aynı sırada lock işlemini yapmalı. Ve tersi sırada unlock işlemi yapılmalı

Örnek - Lock Sırasına Dikkat Edilmemesi
Şu kod deadlock'a sebep olur.
(1)                 |        (2)
  Lock mutex A   (success) |    Lock mutex B   (success)
  Lock mutex B   (wait)    |    Lock mutex A   (wait) 
                           X
                OUCH! DEADLOCK OCCURED
Örnek - Unlock Sırasına Dikkat Edilmemesi
Şu kod deadlock'a sebep olur.
       (1)                 |        (2)
  Lock mutex A   (success) |   Lock mutex A   (wait)
  Lock mutex B   (success) |    
  ....                     |
  Unlock mutex A           |                  (success)
  Relock mutex A (wait)    |   Lock mutex B   (wait)
                           X
                OOPS! I DEADLOCK AGAIN
Örnek - Java
Şu kod deadlock'a sebep olur
void increment(){
  synchronized(lock1){
    synchronized(lock2){
      variable++;
    }
  }
}

void decrement(){
  synchronized(lock2){
    synchronized(lock1){
      variable--;
    }
  }
}

2 Kasım 2020 Pazartesi

Yazılım Mühendisliği Neden Zor Bir Meslek

Giriş
Şu cümle hoşuma gitti
Writing software is hard.

Writing good software is harder.

Writing good, simple software is the hardest.

Writing good, simple software as a team is the hardest… est.
Sürekli Değişen Teknoloji
Teknolojiyi bir türlü yakalamak mümkün olmuyor. Hem teknoloji sayısı fazla, hem de bir teknolojiyi yakaladığımızı düşünsek bile eğer bir müddet bırakırsak ya yok olduğunu ya da bambaşka bir hale geldiğini görüyoruz. Yani sürekli bir mücade gerektiriyor. Bu da çok yorucu

Tecrübenin Hızla Erimesi
Teknoloji değişse bile elde tecrübe kalıyor diye düşünebiliriz. Ancak tecrübe de hızlı bir şekilde erozyona uğruyor. Defalarca gördüğüm gibi tecrübeli mühendis, genç mühendise teknik çözümde yardımcı olamıyor. Çünkü kendisi de ya konuyu bilmiyor ya da hiç denememiş. Ancak en fazla tahminen yardım edebiliyor.

Yazılım Mimarisi - Idempotency (Denkgüçlülük) Nedir

Giriş
Idempotency kelimesinin Türkçe karşılığı da biraz tuhaf aslında :)


Idempotency şu anlama gelir. Bir metodun başarıyla çalıştıktan sonra tekrar çağrılması durumunda, yeni bir değişiklik yapmamasıdır. Sistemin Idempotency özelliği mikroservis (mikroservice) mimarisi ile daha çok konuşulur oldu.

En çok kullanılan örneklerden birisi şöyle
In more complex micro service processes, the code executing when a client clicks the "Purchase button", typically invokes several micro services. Imagine something as follows.

1. User clicks the purchase button
2. Money is deducted from the client's account
3. Money is transferred to the manufacturer's account
4. The order is handled internally, and shipping is started

If step 3 or step 4 fails in the above process, you cannot simply rerun the process, because this would result in deducting the client's bank account twice. If all of the above invocations are idempotent though, the process can easily be re-animated by simply running it in its entirety once more.
Idempotency Yöntemleri
Idempotency için iki tane yöntem var.

1. Her şeyin en baştan yapılması
Bu yöntemin kullanılabilmesi için her şeyin en baştan yapılmasının zararsız olması gerekir. Örneğin bir web sayfası, sayfadaki bir bileşen değiştikçe tekrar tekrar render edilebilir. Sayfa en baştan render edildiği için zararsızdır.

2. Sadece başarısız adımların baştan yapılması - Tekil Numara İle Takip Edilir
Örneğin banka hesabından para çekilip, e-posta gönderilmesi işlemi olsun. Hesaptan para çekme işlemi başarılı, ancak e-posta gönderme işlemi başarısız ise, metod tekrar çağrıldığında sadece e-posta gönderme işlemi yapılmalıdır. Bu yöntemi gerçekleştirmek için kullanılacak yöntemlerden birisi de işlem başına bir tekil numara kullanılması. Açıklaması şöyle
Idempotency is actually very easy to implement. Just create a new Guid or Uuid, and associate with every invocation to your micro service invocations, and if the micro service endpoint encounters an identifier it has previously executed, it returns early, and doesn't apply any state changes to its internal states. This of course requires persisting the identifier for the execution somehow, but that's fairly simple in practice. If the client calling the endpoint requires access to the returned value, you can also persist the return value of some micro service process, and return the previous result, looking it up using the invocation identification as a criteria.
Örnek
Açıklaması şöylee
... we can maintain an INBOX table inside the consumer service’s database. It simply keeps track of what events were processed by recording their UUIDs.
After processing an event for the first time, the consumer marks the event as processed in the INBOX table. That should be transactional — making it possible to trap any rollbacks at the consumer level so that it can retry receiving the event.
Şeklen şöyle

Örnek
Kod olarak şuna benzer
function decrementInventoryStockCount(txid, pid, offset) {
  transaction {
    tx_executed = check transaction table record where id=txid
      if not tx_executed {
        prod_count = select count from inventory where product=pid
        prod_count += offset
        set count=prod_count in inventory where product=pid
        insert to transaction table with id=txid
      }
  }
}
Burada dikkat edilmesi gerek şeyler şöyle
1. Metod bir txid  yan işlem numarasını parametre olarak alıyor
2. Metod bir transaction içinde çalışıyor

txid kullanılmasının açıklaması şöyle
Sometimes it’s not feasible to make data operations idempotent due to transaction isolation issues we get in a microservices communication. This means we can’t blindly retry operations in a transaction if we are not sure whether an operation was executed in a remote microservice. This can be solved by having a unique identifier such as a transaction ID for the operation of the microservice call, so the target microservice will create a history of transactions executed against it. In this manner, for each microservice operation call, it can do a local transaction to check the history and see if this transaction has already been executed. If not, it will execute the database operation, and still in the local transaction, update the transaction history table as well.
HTTP ve Idempotency
Açıklaması şöyle. HTTP için dikkat edilmesi gereken şey POST istekleri.
RFC 2616 says that methods GET, PUT and DELETE should be idempotent. That means aside from error or expiration issues, the side-effects for multiple requests are the same as for a single request. So if I issue 1 GET request or 2 or 3 of them with the same request headers and body, the net result is going to be the exactly the same. The same idea applies to PUT and DELETE requests.
..
But if you read RFC 2616 you’ll notice that they left out the POST method. This method is intended to have side-effects since the intention was to use it to create new objects.

Idempotency'nin Önem Kazandığı Bazı Örnekler

1. Observer Tasarım Örüntüsü ve Idempotency
Observer tetiklenince idempotent olarak tabir edilen ve her şeyi baştan yapan bir metod çağırır. Açıklaması şöyle
Let's say you have an HTML page that is fairly complicated-- if you pick something in one dropdown, another control might appear, or the values in a third control might change. There's two ways you could approach this:

  1. Write a separate handler, for each and every control, that respond to events on that control, and updates other controls as needed.
  2. Write a single handler that looks at the state of all the controls on the page and just fixes everything.
The second call is "idempotent" because you can call it over and over again and the controls will always be arranged properly. Whereas the first call(s) may have issues if a call is lost or repeated, e.g. if one of the handlers performs a toggle.

The logic for the second call would be a bit more obscure, but you only have to write one handler.

And you can always use both solutions, calling the "fix everything" function as needed "just to be on the safe side."
2. Retry ve Idempotency
Bir işlem başarısız olduğunda tekrar denemek (retry) isteyebilir. Tekrar deneme yönteminde karşı tarafın Idempotent Receiver olması gerekir. Açıklaması şöyle.
One thing that you need to be mindful when retrying is message idempotency. What happens if we get an HTTP timeout when calling the Fan Courier HTTP API, but our shipment request was actually processed successfully, we just didn't get the response back? When we retry, we don't want to send a new shipment. This is why the Fan Courier Gateway needs to be an Idempotent Receiver. This means that it doesn't matter if it processes the same message only once or 5 times, the result will always be the same: a single shipment request.