• 21-01-2022, 23:27:44
    #1
    Değerli arkadaşlar merhaba, siz değerli arkadaşlarımızın da bir konuda fikirlerini almak isterim.

    Basit bir script’imiz bulunmaktadır. Bu script 160 tane sayfadan aynı mantıkla veri çekerek veritabanına kaydetmektedir. Veri API üzerinden çekilmekte ve API’nın veri sunma hızında herhangi bir problem bulunmamaktadır. Bir adet index.php sayfası bu 160 sayfayı javascript ile sürekli arkaplanda saniyede bir GET etmektedir. Asıl problemimiz şurda başlıyor.

    Her sayfa yenilendiğinde ortalama bir sayfa için 500 veri gelmekte ve bu 500 veri eğer ki VERİTABANINDA YOKSA veri tabanına eklenmektedir. Yani bir kontrol süreci ve ekleme süreci vardır.
    Yani sistem saniyede 160 tane sayfada, her bir sayfadan 500 veri almaktadır. Toplam 80.000 data saniyelik olarak sisteme eklenmekte ve kontrol edilmektedir.

    Sistem localhost’ta XAMPP’ta çalışmaktadır.
    Sistem sadece bu iş için tahsis edilmiştir. Ve işlemi yapan cihazın 128 GB RAM’ı ve i9 işlemcisi bulunmaktadır. Arka planda başka hiçbir şey çalışmamaktadır.
    Aynı özelliklere sahip bir server kiraladığımızda da aslında çok fazla bir hız olarak artış yaşamadık. Hatta 12 GB ram’li bir sunucuda bile daha fazla performans aldık.

    Sorumuzun aslı, ben bu sistemi jet hızında çalıştırmak için acaba ne yapabilirim ? Veri tabanını değiştirmek, veritabanı motorunu değiştirmek v.b tüm fikirlere açığım.
    Verileri tek tek TXT olarak bile kaydedip aradaki farkı milisaniye olarak hesapladım. Fakat performanslı olmadı. Mysql, Apache, Nginx üçlüsünün hepsi denendi. Sistemin ortalama verileri işlemesi 1 saniye sürüyor, tabii o 1 saniye içinde sayfa tekrar reload olduğu için ve bu işlemde 160 sayfada eş zamanlı yapıldığı için sistem ister istemez yavaşlamaya başlamakta. Tüm değerli arkadaşlarımın fikrini almak isterim 😊
  • 21-01-2022, 23:37:42
    #2
    Agentic Engineer
    No Sql denediniz mi hocam , Key value ile çalışıyor belki sizin için daha performanslı olabilir
  • 22-01-2022, 00:01:00
    #3
    Muhtemelen asıl sorununuz yazılımdaki "eğer ki VERİTABANINDA YOKSA veri tabanına eklenmektedir " bu bahsettiğiniz kısım.
    Ücretli Destek için PM gönderiniz.
    Faturalı ve Kurumsal olarak çalışmaktayız.
    Özel projeleriniz için Gizlilik Sözleşmesi yapılabilir.
  • 22-01-2022, 00:02:05
    #4
    Kod ve sql yapısını bilmiyoruz ama Veriler teker teker insert ediliyorsa yavaşlayacaktır. Olmayan kayıtları bir array de toplayıp tek seferde toplu insert yapabilirsin.
    telefondan yazıyorum kod paylaşamam ama Googleda örnekleri var


    "multiple insert into sql" şeklinde arayabilirsin.
  • 22-01-2022, 00:20:39
    #5
    Cevaplarınız için çok teşekkür ederim. Kod yapımız çok çok basit. Zaten ortalama 10 satır kod ya mevcut ya da değil, data’nın çekildiği yer ise API olduğu için oraya bir yaptırımımız zaten söz konusu değil.

    Verileri neden bir array’a alıp kontrol etmiyoruz ? Verilerin geldiği listede aynısının olma ihtimali yok. Fakat daha önceden yani bir önceki listeden veritabanına eklenmiş olma ihtimali var. Dolayısıyla tüm tabloyu çekip array’a aktarıp kontrol etmem minimum 10 saniye zaman kaybı olacaktır. Bunun yerine veritabanında unique değer tanımladık. Veriler’de INSERT IGNORE INTO sorgu kelimesiyle ekleniyor. Ve bu bu zamana kadar bulduğumuz en mükemmel yol oldu. Fakat benim bunu bile daha hızlı bir hale getirmem lazım 😊 Hatta kod yapısını da ileteyim nasıl basit bir SQL sorgusu olduğunu sizlerde yorumlayabilirsiniz.

    foreach ($datas as $key => $value)
    {
    $sorgu = $conn->prepare("INSERT IGNORE INTO $str(unixtime, orijinalsaat) VALUES(?, ?)");
    $sorgu->bindParam(1, $value['timestamp'], PDO::PARAM_STR);
    $sorgu->bindParam(2, $Orijinalsaat, PDO::PARAM_STR);
    $sorgu->execute();
    }
  • 22-01-2022, 01:06:07
    #6
    Merhaba, o kadar ram'e ihtiyaç olduğunu düşünmüyorum. Ben sizin yerinizde olsam gelen verileri redis gibi ram tabanlı bir veritabanı-cache sistemine yazardım, belirli aralıklarla da bulk insert ile veritabanına yazardım.

    + olarak getirecekleri; veritabanına az sayıda bağlantı açılacak, işlemler daha kısa sürelerde halledilecek ve veritabanı yorulmayacak.
    - olarak götürecekleri: sql veritabanlarında direkt destek olarak multi-insert yok, no-sql'e yönlenebilirsiniz, tercihinize, yaptığınız işe kalmış.

    edit: o kadar büyük verilerle çalışıp hız istiyorsanız derlenebilen dillere yönelmenizi öneririm.
  • 22-01-2022, 01:12:25
    #7
    Veritabanını postgresql yaparsanız daha hızlı sonuç alacağınızı düşünüyorum.
  • 22-01-2022, 03:07:40
    #8
    Yinede her işlem için ayrı ayrı insert yapıyorsunuz. Saniyede 160x500 => 80000 insert yapıyorsun. Ayrıca IGNORE komutu her insert işleminde yeniden indexlenir ekstra yük yapacaktır.
    Aşağıdaki gibi tek seferde insert etmelisin.
    Basitçe bir örnek kod oluşturdum. İhtiyacına göre düzenlersin.
    NOT. Tek seferde toplu insert işleminin de bir sınırı var, bunu kendin denersin. array_slice ile Array'i bölümlendirebilirsin. Veya bu mantığa göre kendin başka bir yapı oluşturabilirsin.

    Senin sorunun her saniyede 160x500 => 80000 insert işlemi yapman. bu önerdiğim yöntem ile saniyede 160 inserte düşürebilirsin.

            $arrSqlString = [];
            foreach ($datas as $key => $value)
            {
                array_push($arrSqlString, "('".$value['timestamp']."', '".$Orijinalsaat."')");
            }
            $sqlString = implode(",", $arrSqlString);
            unset($arrSqlString);
            $sorgu = $conn->prepare("INSERT IGNORE INTO $str(unixtime, orijinalsaat) VALUES $sqlString");
            $sorgu->execute();