2012-06-19 18 views
8

Çok büyük bir CSV dosyasına (1 GB +) sahibim, 100.000 satıra sahip.Bir CSV dosyasını birden çok parçaya bölme ve bu kodları Java kodunda paralel olarak okuma

Gönderilecek bir HTTP isteği için bir gövde oluşturmak üzere CSV dosyasındaki her satırı ayrıştırmak için bir Java programı yazmalıyım. Başka bir deyişle, CSV dosyasındaki satırlara karşılık gelen 100.000 HTTP isteği göndermem gerekir. Bunları tek bir iş parçacığında yaparsam çok uzun olacak.

Yapmak için 1.000 iş parçacığı oluşturmak istiyorum i) CSV dosyasından bir satır okuyun, ii) gövdesi, okuma satırının içeriğini içeren bir HTTP isteği oluşturun ve iii) HTTP isteğini göndererek yanıt alın.

Bu şekilde, CSV dosyasını 1.000 parçaya bölmem gerekir ve bu parçaların birbiriyle çakışmamış satırları olmamalıdır.

Böyle bir ayrıştırma işleminin en iyi yolu nedir?

+1

* Çok büyük bir CSV dosyasına (1GB +) sahibim, günümüzde bilgisayarlar için 100.000 satırlık bir * var, bu hiç de büyük değil. CPU'lardan çok daha fazla iş parçacığına sahip olmak, tüm CPU'ları doyurabilmeniz bir hatadır. Sonunda IO departmanında bağlı olacak, bir sunucuya eşzamanlı eşzamanlı talepler göndermek, DoS'u kasten denemeden çok da mantıklı değil. – bestsss

cevap

7

Tek bir dosyayı birden fazla konumda eşzamanlı olarak okumak daha hızlı gitmenize izin vermez (ancak yavaşlayabilir) önemli ölçüde aşağı).

Dosyayı çoklu iş parçacıklarından okumak yerine, dosyayı tek bir iş parçacığından okuyun ve bu satırların işlemlerini paralel hale getirin. Tek bir iş parçacığı, CSV'nizi satır-line olarak okumalı ve her satırı bir sıraya koymalıdır. Birden çok iş parçacığı, sıradan sonraki satırı almalı, ayrıştırmalı, bir isteğe dönmeli ve isteği gerektiği gibi eşzamanlı olarak işlemelidir. İşin bölünmesi, daha sonra, eksik bir çizgi ya da çakışma olmadığından emin olmak için tek bir iş parçacığı tarafından yapılacaktı. Tek dizisindeki

+0

Dosyayı okumadan önce aynı boyutta birden çok parçaya bölmek için bölünmüş bir işlem yapmak mümkün mü? Eğer öyleyse, dosya bölünmüş olduktan sonra, paralel olarak yığınları okumak için birden fazla iş parçacığına bakmak, tüm dosyayı okuyan tek bir iş parçacığından daha hızlı olacaktır, değil mi? – JuliaLi

+0

@JuliaLi Hayır, gerçekten değil: büyük dosyalar genellikle bir disk üzerinde birbirine yakın bulunan birden çok bloğu işgal eder.Diskler ardışık bloklara erişmede çok daha hızlı olduğu için, manyetik başlığın yeniden konumlandırılmasına gerek yoktur, diskten büyük bir dosya okumak, ardışık olarak yapıldığında çok daha hızlıdır. – dasblinkenlight

4

CSV'nin satırlarını okuyan ve okunan satırların listesini oluşturan bir iş parçacığına sahip olabilirsiniz. Bu, bir sınıra ulaştığında, örn. Bir istek olarak göndermek için sabit boyutlu bir iş parçacığı havuzuna geçmek için 100 satır.

Sunucuda 1000 çekirdek bulunmadığı sürece, 10-100 eşzamanlı istekleri kullanmanın daha hızlı olduğunu görebiliyorum.

+0

Bir HTTP yanıtı almak için ne kadar süreceğine bağlıdır. İlgili sunucular yavaşsa, iş parçacıklarının çoğu G/Ç için bekler. – biziclop

+0

Ağ veya sunucu yavaşsa, daha büyük toplu iş boyutları veya daha küçük bir istek kullanmak, yükleme süresini artırabilir. Bunu test etmeden iyimser olduğunu söylemek imkansız. Benim amacım; Daha fazla iş parçacığı daha iyi düşünmeyin. –

+1

Ben de öyle demek istedim. Uygulamanızın G/Ç sınırı olması daha olası olduğundan, çekirdek sayısı temel alınarak sabit bir formül işe yaramayacaktır, en iyi olanı denemeniz gerekir. (Ya da muhtemelen aşırı derecede karmaşık bir uyarlama sistemi yazınız.) – biziclop

1

Dosya satırını bir satır okuyup okuduğunuz her satır için, her biri için HTTP isteğini gerçekleştirmek üzere bir görevi ExecutorService'a gönderin.

n th satırını okuyabilmeniz için önce birden çok iş parçacığındaki dosyanın okunması işe yaramayacaktır, çünkü önce diğerlerini de okumalısınız. (Dosyanız sabit genişlikli kayıtlar içeriyorsa, ancak CSV sabit bir genişlik biçimi içermiyorsa çalışabilir.)

+0

, sütunların ne zaman olduğunu bildiğiniz zaman satırın sonunu anlayabilirsiniz, ancak bu mümkün değildir. Yani birden fazla disk dizisi ve eşlenen dosya varsa birden çok iş parçacığı çalışırsa (okuma parçası için) – bestsss

+0

Dosya okunmadan önce aynı boyutta birden çok parçaya bölmek için bölünmüş bir işlem yapmak mümkün mü? Eğer öyleyse, dosya bölüntükten sonra, paralel olarak yığınları okumak için birden fazla iş parçacığına bakıyordu. – JuliaLi

2

Oku CSV dosyası, Runnable Task nesne oluşturarak hat Temsilciye havuzunda mevcut Thread birine bu hat almak ve uyumsuz infaz edileceği, Executors'ssubmit() onu geçtikten sonra. İşte

public static void main(String[] args) throws IOException { 

     String fName = "C:\\Amit\\abc.csv"; 
     String thisLine; 
     FileInputStream fis = new FileInputStream(fName); 
     DataInputStream myInput = new DataInputStream(fis); 
     ExecutorService pool=Executors.newFixedThreadPool(1000); 
     int count = 0; // Concurrent request to Server barrier 

     while ((thisLine = myInput.readLine()) != null) { 
      if (count > 150) { 
       try { 
        Thread.sleep(100); 
        count = 0; 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 

      pool.submit(new MyTask(thisLine)); 
      count++; 
     } 

    } 
} 

sizin Görev:

class MyTask implements Runnable { 
     private String lLine; 
     public MyTask(String line) { 
      this.lLine=line; 

     } 

     public void run() { 
      // 1) Create Request lLine 
      // 2) send the HTTP request out and receive response 
     } 
} 
0

Java 8, bu ay piyasaya sürülmesi bekleniyor, paralel akımlar ve lambdas aracılığıyla bu destek geliştirilmiş olacak. Oracle'ın paralelindeki tutorial akışları iyi bir başlangıç ​​noktası olabilir.

Buradaki bir tuzağın çok fazla paralellik olduğunu unutmayın.URL'leri alma örneği için, düşük sayıda paralel çağrının olması iyi bir fikir olabilir. Çok fazla paralellik sadece bant genişliğini ve bağlandığınız web sitesini etkilemez, aynı zamanda java'nın çalıştığı ortamların çoğunda sınırlı bir kaynak olan dosya tanımlayıcılarının da çalışmaması riskini de beraberinde getirir.

Netflix 'RxJava ve Akka yardımcı olabilecek bazı çerçeveler. Bu çerçevelerin önemsiz olmadığını ve öğrenmek için biraz çaba sarf edeceklerini unutmayın.

İlgili konular