2017-11-23 17 views
0

그래서이 CI 프로젝트를 데이터베이스에서 CSV로 변환했습니다.프로세스가 오래 걸려서 "이 페이지가 작동하지 않습니다. <ssh-server-ip-address>는 데이터를 보내지 않았습니다 .ERR_EMPTY_RESPONSE"

SSH 서버에 배포되었습니다.

모든 데이터를로드하려고합니다 (2,000,000 이상이 넘습니다). 그런 다음 CSV로 변환하려고합니다. 난 단지 이메일을 가진 행으로 필터링

내 첫 번째 시도는

그것은 성공적으로 (약간의 시간이 걸렸다) CSV로 데이터를 내보낼 (그래서 나 66,000+ 데이터입니다. 제공). 나는 마침내 내가 "CSV로 변환"를 클릭 한 후 모든 데이터를 내보낼 때

그러나, 그것은 너무 많은 시간 로딩을하고 브라우저 오류 제공 :

This page isn’t working 

<server-ip-address> didn’t send any data. 
ERR_EMPTY_RESPONSE 

이 상관 할 일이 있습니까를 서버와 함께?

나는 이러한 설정으로 /etc/php.ini에서 설정을 변경 시도 :

max_execution_time = 259200 
max_input_time = 259200 
memory_limit = 300M 
session.gc_maxlifetime = 1440 

을하지만 여전히 날 같은 오류를 제공합니다.

어떻게 해결할 수 있습니까? 제발 도와주세요.

UPDATE : 나는 여기있다, csv로 다운로드 내 코드를 포함 :

public function convcsv(){ 

     ini_set('memory_limit', '-1'); 
     set_time_limit(0); 

     $prefKey = $this->session->flashdata('prefKey'); 
     $searchKey = $this->session->flashdata('searchKey'); 
     $withEmail = $this->session->flashdata('withEmail'); 
     log_message('debug', 'CONVCSV prefKey = ' . $prefKey); 
     log_message('debug', 'CONVCSV searchKey = ' . $searchKey); 
     $list = $this->user_model->get_users($prefKey, $searchKey, $withEmail, "", ""); 
     log_message('debug', 'Fetched data'); 
     $headerArray = array("id", "prefecture_id", "industry_id", "offset", "name", "email"); 

     // Header 
     $header = str_replace(",", "", $headerArray); 
     $datas = implode(',', $header) . "\r\n"; 

     // Body 
     foreach($list as $body) 
     { 
      // 配列の内容を「,」区切りで連結する 
      $orig_email = $body['email']; 

      $mstring = preg_replace("/^([^a-zA-Z0-9])*/",',',$orig_email); 

      preg_match_all("/[\._a-zA-Z0-9-][email protected][\._a-zA-Z0-9-]+/i", $mstring, $matches); 
      $email = implode($matches[0]); 
      //$email = $matches[0]; 

      $datas .= $body["id"].",".$body["prefecture_id"].",".$body["industry_id"].",".$body["offset"].",".preg_replace('/[,]/',' ',$body["name"]).",".$email."\r\n"; 
     } 

     // 文字コード返還 
     $datas = mb_convert_encoding($datas, "SJIS-win", "UTF-8"); 

     // ダウンロード開始 
     $csvFileName = "phpList_" . date('Ymd_His') . ".csv"; 
     header('Content-Type: application/octet-stream'); 
     header('Content-Disposition: attachment; filename=' . $csvFileName); 
     header('Content-Transfer-Encoding: binary'); 
     while (ob_get_level() > 0) 
     { 
      ob_end_clean(); 
     } 

     ob_start(); 
     print trim($datas); 
     ob_flush(); 
     ob_end_clean(); 
     exit; 
    } 
+0

브라우저를 통해 다운로드해야합니까? ftp가 더 효율적입니다. – nogad

+0

@nogad 옵션이 없습니다. 그것은 데이터를 CSV로 변환하는 codeigniter 프로젝트에서 가져온 것입니다. –

+0

파일을 제공 하시겠습니까? 또는 데이터 스트림? 파일을 압축하는 것을 고려 했습니까? – nogad

답변

1

좋아, 내가 최선을 내가 할 수있는 당신이 준 것을 작은 데이터로 이것을 설명하려고합니다. 데이터베이스에서 데이터를 가져올 수 있다고 가정합니다. 회원님이 PDO에 unbuffered 쿼리를 사용할 수있는 경우이있다, 나는 버퍼링 쿼리를 사용하여 MySQL의에서 1 억 1000 만 개 행을 뽑아 한 측면 참고로

http://php.net/manual/en/mysqlinfo.concepts.buffering.php

을 (난 단지 지난 4-5년에 대한 PDO를 사용) 램의 56GB (Azure standard_A8, 꽤 l33t)의 서버에서.

데이터를 출력하는 데 일반적으로 브라우저가 페이지를로드 할 때 모든 서버 측을 "빌드"한 다음 브라우저에서이를 덤프 (일반적으로 말하면)합니다. 귀하의 경우 이것은 너무 많은 데이터입니다. 그래서,

(Psudo 틱 코드)

set_time_limit(-1); //set time limit. 

header('Content-Type: text/csv; charset=utf-8'); 
header('Content-Disposition: attachment; filename=data.csv'); 

$f = fopen('php:\\output', 'w'); 
while(false !== ($row = $stmt->fetch(PDO:FETCH_ASSOC))){ 
    fputcsv($f, $row); 
    flush(); 
} 

단점은 손 전 다운로드 파일의 크기를 알 수있는 실제 방법이 없다는 것입니다. 우리는 기본적으로 다운로드 헤더를 보낸 다음 출력 스트림에 각 행을 덤프하고 한 번에 한 줄씩 브라우저로 플러시합니다.

전반적으로 이것은 네트워크 트래픽이 더 많지만 메모리를 더 잘 관리하기 때문에 느린 속도입니다. 때로는 그것이 그대로입니다.

당신은 (출력 스트리밍) 페이지에

http://php.net/manual/en/function.flush.php

을 몇 가지 예를 볼 수 있습니다 그리고 당신은 그것이 작동하지 않는 경우 (첫째)과 같은 몇 가지 물건을 사용해야 할 수도 있습니다

,

@apache_setenv('no-gzip', 1); 
ini_set('zlib.output_compression', 0); 
ini_set('implicit_flush', 1); 

다운로드가 거의 즉시 시작되지만, 전체 파일이 부분적으로 오류로 출력되어 스크립트를 중간에 종료 할 수 있다고 보장 할 수 없습니다.

당신은 내가 버릇이야 기본으로 2GB을 가지고 6GB까지 런타임에 ini_set('memory_limit', '300M'); //set at runtime

마지막으로, 나는 세계적으로 시간 제한을 설정하지 말 가고픈 충동이 들게하지만,이 역시 memory_limit = 300M에 문제가있을 수 있습니다 대신 실행시이 방법으로 set_time_limit(-1);을 수행하십시오. 그렇게하면이 스크립트에만 영향을 주며 서버는 전체적으로 영향을 미치지 않습니다. 그러나 아파치 자체에서 시간 초과 문제가 발생할 수 있습니다. 서버와 브라우저 사이에는 많은 움직이는 부분이 있기 때문에 매우 까다로운 작업입니다. 대부분 서버, 서버 OS, 브라우저 등 (환경)에 따라 달라질 수 있습니다.

이상적으로 FTP 다운로드가 가능하지만 이상적인 솔루션 일 것입니다. 쉽게 소화 할 수있는 덩어리를 보내는 문제.