19 Ekim 2016 Çarşamba

Apache THRIFT

Apache Thrift nedir?

Farklı programlama diller arasında iletişim kurabileceğiniz, bunu ölçeklenebilir, verimli ve sorunsuz bir şekilde yapabileceğimiz bir yazılım çatısıdır (framework). Bu işlemleri yaparken RPC (remote procedure call) kullanır.

RPC, request–response protokolüne benzemektedir. Bu yapıda bir istek yapıldığında sonuç gelene kadar client (istemci) bloklanır. RPC ek olarak asenkron işlemlere müsade etmektedir. XHTTP (Ajax) gibi düşünebilirsiniz.

Binary protokolünü kullanmaktadır. Binary olması çok hızlı çalışmasını sağlamaktadır.

Siz bir arayüz tanımlıyorsunuz. Sonrasına buna göre istediğiniz dilde kod yapısını çıkarıyor. Size de boşlukları doldurmak kalıyor.

Kullanılabilir dillerden bazıları;
C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi ...

Biz PHP ile Python'u konuşturan örnek bir uygulama yapalım;


brew install thrift --with-python --with-php
git clone https://github.com/volkan/thrift-works
cd thrift-works
thrift -r --gen php:server tutorial.thrift
thrift -r --gen php:server shared.thrift
thrift -r --gen py tutorial.thrift
thrift -r --gen py shared.thrift
Python için;

pip install thrift

Veya

cd lib/py
python setup.py install

İki ayrı pencere;

python server/PythonServer.py

php client/PhpClient.php

Böylece farklı dillerde iletişimi sağlamış olduk. Örnekler arasında "zip()" olanın içine "sleep" ile bekleme yapmasını söyledim. Ancak kod akışından bir engelleme olmadan arka planda çalışmaya devam ediyor. (Asenkron) Server tarafında "zip()" yazısı 5 saniye sonra çıkıyor.





Dikkat çekmesi için bazı görseller paylaşacağım. Kaynakları da aşağıda veriyorum. İyi incelemeler :)



Kaynaklar:
https://www.youtube.com/watch?v=e8Df_8yMGRU
http://nordicapis.com/microservice-showdown-rest-vs-soap-vs-apache-thrift-and-why-it-matters/

2 Ekim 2016 Pazar

SolrCloud yeni bir başlangıç

Daha önce hızlıca SolrCloud hakkında konuşmuştuk. Şimdi hızlı bir şekilde temel komutları gözden geçirelim.

bin/solr start -e cloud
Default ayarlarla kurulumu tamamlıyoruz. Daha sonra tekrar çalıştırmak istediğimizde aşağıdaki şekilde çalıştırabiliriz.

bin/solr start -cloud -p 8983 -s "example/cloud/node1/solr" -m 2g
bin/solr start -cloud -p 7574 -s "example/cloud/node2/solr" -z localhost:9983 -m 2g
Sistem default ayarlarla ayağa kalktıktan sonra aşağıdaki şekilde kontrol ediyoruz.

➜  solr-6.0.0 bin/solr status

Found 2 Solr nodes:

Solr process 4600 running on port 7574
{
  "solr_home":"/Users/volkan/project/solr/solr-6.0.0/example/cloud/node2/solr",
  "version":"6.0.0 48c80f91b8e5cd9b3a9b48e6184bd53e7619e7e3 - nknize - 2016-04-01 14:41:49",
  "startTime":"2016-10-01T20:15:22.133Z",
  "uptime":"0 days, 0 hours, 3 minutes, 27 seconds",
  "memory":"91.5 MB (%18.6) of 490.7 MB",
  "cloud":{
    "ZooKeeper":"localhost:9983",
    "liveNodes":"2",
    "collections":"1"}}


Solr process 4497 running on port 8983
{
  "solr_home":"/Users/volkan/project/solr/solr-6.0.0/example/cloud/node1/solr",
  "version":"6.0.0 48c80f91b8e5cd9b3a9b48e6184bd53e7619e7e3 - nknize - 2016-04-01 14:41:49",
  "startTime":"2016-10-01T20:15:15.915Z",
  "uptime":"0 days, 0 hours, 3 minutes, 34 seconds",
  "memory":"74.3 MB (%15.1) of 490.7 MB",
  "cloud":{
    "ZooKeeper":"localhost:9983",
    "liveNodes":"2",
    "collections":"1"}}

Solr kendi içinde 3 farklı config yapısıyla geliyor. Biz bunlardan "data_driven_schema_configs" olanı seçip üzerinde çalışacağız.

Bu ayar yapısında tanımlamasını yapmadığımız "field" lar otomatikmen en uygun olana çevrilir. Klasik ElasticSearch kur çalıştır yapısı gibi düşünebilirsiniz. Ama gerçek anlamda işi olan biri default ayarlarla yetinemez ;)

 server/solr/configsets/data_driven_schema_configs/conf/ dizininde işimiz bittikten sonra yapılan değişiklikleri zookeeper'a göndermemiz gerekiyor. Solr içinde zookeeper yönetmek için güzel bir script mevcut. Bununla işlerimizi rahatlıkla hâlledebiliyoruz.

➜  solr-6.0.0 ./server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:9983
usage: ZkCLI
 -c,--collection    for linkconfig: name of the collection
 -cmd                    cmd to run: bootstrap, upconfig, downconfig,
                         linkconfig, makepath, put, putfile,get,getfile,
                         list, clear, updateacls
 -d,--confdir       for upconfig: a directory of configuration files
 -h,--help               bring up this help page
 -n,--confname      for upconfig, linkconfig: name of the config set
 -name              name of the cluster property to set
 -r,--runzk         run zk internally by passing the solr run port -
                         only for clusters on one machine (tests, dev)
 -s,--solrhome      for bootstrap, runzk: solrhome location
 -val               value of the cluster to set
 -z,--zkhost        ZooKeeper host address
Examples:
zkcli.sh -zkhost localhost:9983 -cmd bootstrap -solrhome /opt/solr
zkcli.sh -zkhost localhost:9983 -cmd upconfig -confdir /opt/solr/collection1/conf -confname myconf
zkcli.sh -zkhost localhost:9983 -cmd downconfig -confdir /opt/solr/collection1/conf -confname myconf
zkcli.sh -zkhost localhost:9983 -cmd linkconfig -collection collection1 -confname myconf
zkcli.sh -zkhost localhost:9983 -cmd makepath /apache/solr
zkcli.sh -zkhost localhost:9983 -cmd put /solr.conf 'conf data'
zkcli.sh -zkhost localhost:9983 -cmd putfile /solr.xml /User/myuser/solr/solr.xml
zkcli.sh -zkhost localhost:9983 -cmd get /solr.xml
zkcli.sh -zkhost localhost:9983 -cmd getfile /solr.xml solr.xml.file
zkcli.sh -zkhost localhost:9983 -cmd clear /solr
zkcli.sh -zkhost localhost:9983 -cmd list
zkcli.sh -zkhost localhost:9983 -cmd clusterprop -name urlScheme -val https
zkcli.sh -zkhost localhost:9983 -cmd updateacls /solr

Aşağıdaki şekilde yaptığımız değişiklikleri Zookeeper'a gönderiyoruz.

solr-6.0.0-> ./server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:9983 -cmd upconfig -confdir server/solr/configsets/data_driven_schema_configs/conf -confname gettingstarted
Yaptığımız değişikliklerin yansıması için;

curl http://localhost:8983/solr/admin/collections?name=gettingstarted&action=RELOAD&wt=json

Bundan sonra shar sayısı ve diğer bütün ayarlar için şuraya bir göz atmak gerekiyor; https://cwiki.apache.org/confluence/display/solr/Collections+API Temel bir şeyleri yazalım.

Backup; Sunucu da öncelikle örnek bir dizin açalım. Daha sonra bu dizine "solr" kullanıcısı için yazma yetkisi verelim

mkdir -p /home/backup/solr 
sudo chown solr:solr /home/backup/solr
curl http://localhost:8983/solr/admin/collections?action=BACKUP&name=gettingstarted&collection=gettingstarted&location=/home/backup/solr&async=1000

async komutu ile arka planda bu süreç çalışmaya devam edecek. Daha sonra ürecin durumunu öğrenmek için

curl http://localhost:8983/solr/admin/collections?action=REQUESTSTATUS&requestid=1000

Süreci farklı şekilde gözden geçirmek adına, hızlıca bir collection oluşturalım;

solr-6.0.0-> bin/solr create_collection -shards 2 -replicationFactor 2 -c test -d server/solr/configsets/data_driven_schema_configs

Bu collection için 2 shard oluşturduk. replicationFactor ise 3 dedik. Şu demek; Bütün datamız ikiye bölünecek. (shard sayısı) replicationFactor ise datanın kaç katı alan kullanacağımızı belirliyor.

Datanın toplam boyutu * replicationFactor kadar yerimiz olmalı. "replicationFactor" 2 olduğunda her sunucuda birebir kopya var demek. 3 olduğunda ek olarak birer "shard"'ın daha kopyası elimizde demek. 4 desek her "shard"'ın 2 yedeği olacak demek. "shard" sayısını daha sonra artırabilirsiniz. Mevcut "shard"ları bölebilirsiniz. API linkinde bu bilgiler mevcut. Aşağıdaki örnek data basımı yaptık.

solr-6.0.0-> bin/post -c test3 example/films

solr-6.0.0-> bin/post -h

Usage: post -c  [OPTIONS] 
    or post -help

   collection name defaults to DEFAULT_SOLR_COLLECTION if not specified

OPTIONS
=======
  Solr options:
    -url  (overrides collection, host, and port)
    -host  (default: localhost)
    -p or -port  (default: 8983)
    -commit yes|no (default: yes)

  Web crawl options:
    -recursive  (default: 1)
    -delay  (default: 10)

  Directory crawl options:
    -delay  (default: 0)

  stdin/args options:
    -type  (default: application/xml)

  Other options:
    -filetypes [,,...] (default: xml,json,jsonl,csv,pdf,doc,docx,ppt,pptx,xls,xlsx,odt,odp,ods,ott,otp,ots,rtf,htm,html,txt,log)
    -params "=[&=...]" (values must be URL-encoded; these pass through to Solr update request)
    -out yes|no (default: no; yes outputs Solr response to console)
    -format solr (sends application/json content as Solr commands to /update instead of /update/json/docs)


Examples:

* JSON file: bin/post -c wizbang events.json
* XML files: bin/post -c records article*.xml
* CSV file: bin/post -c signals LATEST-signals.csv
* Directory of files: bin/post -c myfiles ~/Documents
* Web crawl: bin/post -c gettingstarted http://lucene.apache.org/solr -recursive 1 -delay 1
* Standard input (stdin): echo '{commit: {}}' | bin/post -c my_collection -type application/json -out yes -d
* Data as string: bin/post -c signals -type text/csv -out yes -d $'id,value\n1,0.47'

➜  solr-6.0.0 du -hs example/cloud/node1/solr/test3_shard1_replica1
 76K example/cloud/node1/solr/test3_shard1_replica1
➜  solr-6.0.0 du -hs example/cloud/node1/solr/test3_shard2_replica2
 64K example/cloud/node1/solr/test3_shard2_replica2
➜  solr-6.0.0 du -hs example/cloud/node1/solr/test3_shard1_replica3
 76K example/cloud/node1/solr/test3_shard1_replica3
➜  solr-6.0.0 du -hs example/cloud/node2/solr/test3_shard2_replica1
 64K example/cloud/node2/solr/test3_shard2_replica1
➜  solr-6.0.0 du -hs example/cloud/node2/solr/test3_shard1_replica2/
 76K example/cloud/node2/solr/test3_shard1_replica2/
➜  solr-6.0.0 du -hs example/cloud/node2/solr/test3_shard2_replica3
 64K example/cloud/node2/solr/test3_shard2_replica3




Umarım faydası olur :)

1 Haziran 2016 Çarşamba

Ölü XML den Diri XML çıkarmak :)

VitrinGez'de yoğun bir şekilde XML işliyoruz. Ancak firmalardan çoğu zaman düzgün çalışan XML alamıyoruz. Koskoca firmaya XML'i düzeltir misin de diyemiyorsunuz!

Biz bazı firmalardan XML alamayınca siteyi crawl ediyoruz. Bunun içinde scrapy kullanıyoruz. Scrapy kullanırken bozuk XML lerde dahi çalıştığını farkettim. O zaman kaynak kodu inceledim.

https://github.com/scrapy/scrapy/blob/master/scrapy/utils/iterators.py#L18

def xmliter(obj, nodename):
    """Return a iterator of Selector's over all nodes of a XML document,
       given the name of the node to iterate. Useful for parsing XML feeds.
    obj can be:
    - a Response object
    - a unicode string
    - a string encoded as utf-8
    """
    nodename_patt = re.escape(nodename)

    HEADER_START_RE = re.compile(r'^(.*?)<\s*%s(?:\s|>)' % nodename_patt, re.S)
    HEADER_END_RE = re.compile(r'<\s*/%s\s*>' % nodename_patt, re.S)
    text = _body_or_str(obj)

    header_start = re.search(HEADER_START_RE, text)
    header_start = header_start.group(1).strip() if header_start else ''
    header_end = re_rsearch(HEADER_END_RE, text)
    header_end = text[header_end[1]:].strip() if header_end else ''

    r = re.compile(r'<%(np)s[\s>].*?</%(np)s>' % {'np': nodename_patt}, re.DOTALL)
    for match in r.finditer(text):
        nodetext = header_start + match.group() + header_end
        yield Selector(text=nodetext, type='xml').xpath('//' + nodename)[0]
Yukarıda gördüğünüz üzere yapılan iş aslında çok basit. Önce xml'i küçük parçalara ayıyor. Sonra her birini bağımsız birer xml elemanı gibi kontrol ediyor. Mesela aşağıdaki gibi bir XML yapımız olsun. Dikkat ederseniz ID 5 olan kısımda etiketi bozuk oluşturdum. Büyük bir XML dosyamız olsa küçücük bir kısım yüzünden bütün XML çöp oluyor. Kodları gist'e koydum. Buradan inceleyebilirsiniz. https://gist.github.com/volkan/0d3af41be13a628201b1cee82246d095

$xml = '

';

echo fixXML($xml, 'product');

function fixXML($xml, $nodeName) {

        $patternTag = sprintf('/<%s[\s>].*?<\/%s>/s', $nodeName, $nodeName);
        preg_match_all($patternTag, $xml, $matches);

        $start = '';
        $end = '';
        $list = [];
        $wrongItem = [];
        $doc = new \DOMDocument();
        foreach ($matches[0] as $key => $item) {
            try {
                $tmpXML = $start . $item . $end;
                $status = @$doc->loadXML($tmpXML);
                if ($status == false) {
                 throw new \Exception;
                }
                $list[] = $item;
            } catch (\Exception $e) {
                $wrongItem[] = $item;
            }
        }

        $xml = $start . implode("\n", $list) . $end;

        return $xml;
}

29 Mayıs 2016 Pazar

SolrCloud kurulumu (ve ZooKeeper)

Solr 4 ile birlikte master-slave mevzusu devam etmekle birlikte SolrCloud olarak birden fazla solr makinenin birleştirilerek hata durumunda en az kayıpla çalışma devam etmesi ve bunlar olurken isteklerin tek bir makineye yönlendirilip arkada geri kalan işleri Solr'un hâlletmesi planlanmış. (fault tolerance and high availability).

Kendi kurulum scripti ile tomcat gibi bir web server kurmadan doğrudan kendi içinde gelen jetty isimli web server ile çalıştırabiliyorsunuz. Cloud yapısındaki datanın senkron olması için ZooKeeper isimli araç kullanılmakta. Localde test yapmak için ZooKeeper kurmanıza gerek yok. Kendi içinde gömülü geliyor. Ama prod ortam için kurmalısınız. Çünkü solr kapanırsa ZooKeeper da kapanıyor.

Düzenleme: Docker ile bütün işlemler burada: https://github.com/volkan/docker-solr-cloud

Basit olarak kurup çalıştırmak için şurada anlatılan işlemleri yapıyoruz. Özetlersek;




wget https://archive.apache.org/dist/lucene/solr/5.5.1/solr-5.5.1.tgz
tar zxvf solr-5.5.1.tgz
cd solr-5.5.1

bin/solr -e cloud
Buradan sonra gelen bütün seçenekleri enter'e basarak geçin. Sorunsuz bir şekilde kurulması gerekiyor. Aşağıdaki şekilde durumu kontrol edebilirsiniz.

bin/solr status

Bizim asıl amacımız Production ortamında bunu kurmak. Şimdi onun için başlıyoruz. Örnekler Centos 6 için anlatılacaktır.
Öncelikle varsa iptables stop edin yok yapamam diyorsanız şu kuralları kuracağınız bütün makinelere ekleyin;

vi /etc/sysconfig/iptables

-A OUTPUT -j ACCEPT
-A INPUT -p tcp --dport 2181 -j ACCEPT
-A INPUT -p tcp --dport 2182 -j ACCEPT
-A INPUT -p tcp --dport 2183 -j ACCEPT


yum install lsof -y
yum install java-1.7.0-openjdk java-1.7.0-openjdk-devel -y #java 1.7 yoksa
yum install -y system-config-services #docker için
useradd solr
cd /opt
wget https://archive.apache.org/dist/lucene/solr/5.5.1/solr-5.5.1.tgz
tar xzf solr-5.5.1.tgz && solr-5.5.1/bin/install_solr_service.sh --strip-components=2
bash solr-5.5.1/bin/install_solr_service.sh solr-5.5.1.tgz
service solr start
chown solr:solr /var/solr -R #Solr home directory /var/solr/data not found! Gibi bir sorun çıkarsa

Aşağıdaki çıktı ilk güzel haber :)

[root@9afe0af76150 opt]# service solr start
Waiting up to 30 seconds to see Solr running on port 8983 [-]
Started Solr server on port 8983 (pid=877). Happy searching!
Şimdi aynı makinede solr sayısını ikiye çıkaralım.

cd /opt
bash solr-5.5.1/bin/install_solr_service.sh solr-5.5.1.tgz -s solr2 -p 8984

Waiting up to 30 seconds to see Solr running on port 8984 [-]
Started Solr server on port 8984 (pid=1072). Happy searching!
Burada işimiz şimdilik bitti. ZooKeeper kurulumuna geçiyoruz örnek olması için tek makinede birden fazla makineye kuruyormuş gibi anlatıyorum;

cd /opt
wget http://mirror.vorboss.net/apache/zookeeper/current/zookeeper-3.4.8.tar.gz
tar xzf zookeeper-3.4.8.tar.gz
cp -R /opt/zookeeper-3.4.8/ /opt/zookeeper-3.4.8-2
cp -R /opt/zookeeper-3.4.8/ /opt/zookeeper-3.4.8-3
ln -s /opt/zookeeper-3.4.8/ /opt/zookeeper
ln -s /opt/zookeeper-3.4.8-2/ /opt/zookeeper2
ln -s /opt/zookeeper-3.4.8-3/ /opt/zookeeper3

vi /usr/local/sbin/zkrun

nano veya vi ile açtığınız dosyaya aşağıdaki kodu yerleştirin.

#!/bin/sh

# chkconfig: - 75 50
# description: Starts and stops Zookeeper

cd /opt/zookeeper
bin/zkServer.sh $1

cp /usr/local/sbin/zkrun /usr/local/sbin/zkrun2
cp /usr/local/sbin/zkrun /usr/local/sbin/zkrun3
chmod +x /usr/local/sbin/zkru*
zkrun2 ve zkrun3 için "cd /opt/zookeeper" kısmını "cd /opt/zookeeper2" ve "cd /opt/zookeeper3" olarak değiştirin.

ln -s /usr/local/sbin/zkrun /etc/init.d/zookeeper
ln -s /usr/local/sbin/zkrun2 /etc/init.d/zookeeper2
ln -s /usr/local/sbin/zkrun3 /etc/init.d/zookeeper3
chkconfig --add zookeeper
chkconfig --add zookeeper2
chkconfig --add zookeeper3
chkconfig zookeeper on
chkconfig zookeeper2 on
chkconfig zookeeper3 on

zoo.cfg leri ayarlamakta sıra; zoo.cfg dosyası oluşturup içine şunları koyuyoruz

vi /opt/zookeeper/conf/zoo.cfg

dataDir=/var/lib/zookeeperdata/1
clientPort=2181
initLimit=5
syncLimit=2
server.1=localhost:2888:3888
server.2=localhost:2889:3889
server.3=localhost:2890:3890

Burada server.1 çok önemli. Çünkü bu sayıya göre data içinde myid dosyası oluşturup değer vereceğiz. localhost yazan kısım hosts dosyasında yer alan diğer solr sunucularımız olabilirdi. Ben de bu kısım şöyle;

server.1=solr1:2888:3888
server.2=solr2:2889:3889
server.3=solr3:2890:3890
/opt/zookeeper/conf/zoo.cfg dosyasını diğer zookeeper lara kopyalıyoruz.

cp /opt/zookeeper/conf/zoo.cfg /opt/zookeeper2/conf/zoo.cfg 
cp /opt/zookeeper/conf/zoo.cfg /opt/zookeeper3/conf/zoo.cfg 
Şimdi /opt/zookeeper2/conf/zoo.cfg ve /opt/zookeeper3/conf/zoo.cfg dosyasında yer alan "dataDir" ve "clientPort" kısmında 1 yazan yerleri sırasıyla 2 ve üç yapıyoruz. portlarıda 2182,2183

mkdir -p /var/lib/zookeeperdata/1 mkdir -p /var/lib/zookeeperdata/2 mkdir -p /var/lib/zookeeperdata/3
echo 1 > /var/lib/zookeeperdata/1/myid
echo 2 > /var/lib/zookeeperdata/2/myid
echo 3 > /var/lib/zookeeperdata/3/myid

service zookeeper start && service zookeeper2 start && service zookeeper3 start
ZooKeeper da tamamlandı. Kontrol için aşağıdaki komutu yazıp ilgili çıktıyı görmeliyiz

[root@9afe0af76150 opt]# service zookeeper status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Mode: follower
[root@9afe0af76150 opt]# service zookeeper2 status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper2/bin/../conf/zoo.cfg
Mode: leader
Şimdi Solr'a bu ZooKeeper'ları tanımlama zamanı. /etc/default/solr.in.sh ve /etc/default/solr2.in.sh dosyalarını açıp ZK_HOST alanındaki yorum kısmını kaldırıyoruz. Buraya şunu yazıyoruz;

ZK_HOST="localhost:2181,localhost:2182,localhost:2183"
Sonra solrları restart ediyoruz.

service solr restart
service solr2 restart

Hemen ilk collectionumuzu oluşturuyoruz.

[root@9afe0af76150 opt]# bash /opt/solr/bin/solr create_collection -shards 2 -replicationFactor 2 -c product2 -d /opt/solr-5.5.1/server/solr/configsets/data_driven_schema_configs

Connecting to ZooKeeper at localhost:2181,localhost:2182,localhost:2183 ...
Uploading /opt/solr-5.5.1/server/solr/configsets/data_driven_schema_configs/conf for config product2 to ZooKeeper at localhost:2181,localhost:2182,localhost:2183

Creating new collection 'product2' using command:
http://localhost:8984/solr/admin/collections?action=CREATE&name=product2&numShards=2&replicationFactor=2&maxShardsPerNode=2&collection.configName=product2

{
  "responseHeader":{
    "status":0,
    "QTime":31629},
  "success":{
    "172.17.0.2:8984_solr":{
      "responseHeader":{
        "status":0,
        "QTime":21578},
      "core":"product2_shard1_replica2"},
    "172.17.0.2:8983_solr":{
      "responseHeader":{
        "status":0,
        "QTime":21819},
      "core":"product2_shard2_replica1"}}}

Bu arada configde değişiklik yapmak için /opt/solr/server/scripts/cloud-scripts/zkcli.sh dosyasını kullanabilirsiniz. Örnek şemamız dinamik field yapısını desteklediği için direk kullanmaya başlayabilirsiniz.
PHP tarafında solarium isimli kütüphaneyi önerebilirim.

Aşağıdaki çıktıyı şu linke tıkladığınızda görürsünüz inşaallah :)
Not: Uygun vakitte Docker olarak kurulumu hazırlayıp buradan paylaşacağım.


18 Mart 2016 Cuma

Verileri Cloud Ortamlarda Aktarma

Şimdiye kadar disklerde çok veri kaybeden biri olarak uzun zamandır sanal disklerde verilerimi tutuyorum. Bu işe ilk DropBox ile başladım. Daha sonra Amazon'un 3 ay bedava sonra yıllığı $59.99 olan paketini aldım. Bütün verilerimi buraya yükledim. Biraz uzun sürdü ama sonuçta işler bitmişti. O sıralarda Android işletim sistemine sahip bir telefon kullanıyordum. Bunun Amazon Photos ve Amazon Cloud Drive uygulamaları işimi görüyordu.

Bir süre önce iphone bir telefona geçtim. Bu telefonla çektiğim 2 dakikalık videoların bile Amazon'a saatlerce gönderilemediğini farkettim. Biraz araştırınca son zamanlarda upload konularında amazonla ilgili ciddi sıkıntılar olduğunu gördüm. (Türkiye'ye özgü de olabilir.)

Amazon destek ekibiyle görüşüp çözümler aradık. Bir de üzerine Amazon Cloud Drive uygulamasının iphone da ses dosyalarını cloud'a gönderememesi beni iyice rahatsız etti.
Bu sırada alternatif olarak görebildiğim Google Drive'a aynı dosyaları upload ederek test ettim. Sonuç çok iyiydi. 100 GB limitli aylık $1.99 olan bir paket satın aldım. Aslında DropBox üzerinde 100GB seçeneği olsaydı onu tercih ederdim. Ancak bu seçenek mevcut değil.

Sonuç olarak Amazon Cloud hesabımı iptal etme kararı aldım. Amazon'a durumu yazdım. 3 ay bedava kullanım sonrasında 3 ay da ödeme ile kullandığım hâlde hiç kesinti yapmadan paranın tamamını iade edeceklerini söylediler. Müşteri memnuniyetinde çağ atlayan bir firma olan Amazon'a teşekkürlerimi sunuyorum.

Ben bütün datalarımı taşımak için DigitalOcean firmasında $10 dolarlık bir makine oluşturup rclone uygulaması ile ekstra yere ihtiyaç duymaksızın bütün datayı taşımaya başladım. Belki $5 lık bir makine de iş görecekti. Sonuç olarak şimdiye kadar ara ara hata mesajları alsamda transfer iyi gidiyor. Zaten sorun çıksada rclon sync komutu ile olmayan dosyaları senkron edebileceğimi biliyorum.

Umarım bu bilgiler işinize yarar :)

Düzenleme: DigitalOceans da açtığım makine bir gece çalıştı. Bu nedenle saat ücretlendirilmesi oldu. Çok düşük bir miktar. Ayrıca dublicate dosyaları silmek için şu kodu kullandım https://github.com/ncw/rclone/issues/329#issuecomment-196046151