2013-07-28 5 views
1

나는 사용자와 상호 작용하는 과정에서 여러 개의 큰 객체 모음을 만드는 PHP 응용 프로그램을 개발 중입니다. 객체는 사용자의 요청에 따라 유지되어야하며이를 성공적으로 구현하기 위해 PHP 세션을 사용했습니다. 객체는 사용자가 수행 한 작업에 만족하고 저장할 객체가 나타내는 정보를 요청할 때까지 지속됩니다.여러 대형 객체에 대한 PHP 객체 직렬화

응용 프로그램을 프로파일 링 할 때 세션 시작에 요청 총 시간의 절반 (요청에 대해 약 4 초)이 소요됨을 발견했습니다. 모든 저장 개체가 사용자의 각 요청에 사용되는 것은 아니기 때문에 요청에 필요한 개체를 선택적으로 복원하여 응용 프로그램의 응답 속도를 향상 시키려고했습니다. 이렇게하려면 개체를 개별 파일로 직렬화하고 필요한 것만 직렬화했습니다. serialize/unserialize가 막대한 양의 메모리 (그리고 실행 시간)를 소비했기 때문에이 변경은 실제로 애플리케이션을 폭발적으로 증가 시켰습니다. 세션 처리기가 하위 집합 만 수행하려는 시도보다 적은 시간과 적은 메모리 소비로 모든 개체를 직렬화하고 비 직렬화 할 수 있다는 사실에 놀랐습니다. 나는 이것이 모든 직렬화 된 객체 데이터를 메모리에 로딩했기 때문에 발생할 수 있다고 생각하지만 확실하지는 않습니다.

코드 파일에 직렬화 된 객체를 작성 :

private static function getRegistry($registryName) { 
    // First check to see if the registry is already active in this request 
    if (isset(self::$activeRegistries[$registryName])) { 
     $registry = self::$activeRegistries[$registryName]; 
    } else { 
     // The registry is not active, so see if it is stored for the session 
     if (isset($_SESSION["filemap"]) && isset($_SESSION["filemap"]) && isset($_SESSION["filemap"]["registries"][$registryName])) { 
      $filePath = $_SESSION["filemap"]["registries"][$registryName]; 
      if (file_exists($filePath)) { 
       $registry = unserialize(file_get_contents($filePath)); 
       self::$activeRegistries[$registryName] = $registry; 
      } else { 
       throw new repositoryException("Exception while getting serialized object for registry '$registryName'"); 
      } 
     } else { 
      // The registry is not saved in the session, so create a new one 
      $registry = self::createRegistry($registryName); 
      $filePath = "/tmp/" . session_id() . $registryName; 
      $_SESSION["filemap"]["registries"][$registryName] = $filePath; 
      self::$activeRegistries[$registryName] = $registry; 
     } 
    } 
    return $registry; 
} 
: 직렬화 된 객체를 검색 할 수

public static function writeClose() { 
    foreach (self::$activeRegistries as $registryName=>$registry) { 
     if (isset($_SESSION["filemap"]) && isset($_SESSION["filemap"]["registries"]) && isset($_SESSION["filemap"]["registries"][$registryName])) { 
      $path = $_SESSION["filemap"]["registries"][$registryName]; 
      if (file_put_contents($path, serialize($registry)) === false) { 
       throw new repositoryException("Exception while writing the '$registryName' registry to storage"); 
      } 
     } else { 
      throw new repositoryException("Could not find the file path for the '$registryName' registry"); 
     } 
    } 
} 

코드에 따라

직렬화 내가 사용한 객체 문자열을 비 일렬 화 할 수있는 코드

PHP 세션 핸들러를 사용하여 각 요청에 대한 모든 콜렉션을 검색하는 것보다 애플리케이션을 개선 할 수 있습니까?

+0

그래서 세션 대신 사용자의 데이터를 저장하는 데 파일을 사용 했습니까? 요청에 대한 사용자 데이터를 갖고 싶습니다. 그리고 임시 파일에 넣는 것이 좋은 해결책이 될 것이라고 생각하지만 그것을 uniq로 만들어야합니다. 더 많은 도움을 받으려면 코드에 대해 더 알아야하고 ** 아마 ** AJAX도 도움이 될 것입니다. – ncm

+0

나는 PHP 세션 핸들러와 사용자 생성 객체의 직렬화 표현을 포함하는 파일을 사용했다. 직렬화 및 직렬화 해제 프로세스는 엄청난 양의 메모리와 시간을 소모합니다. 세션은 올바르게 작동하고 메모리 및 시간면에서 훨씬 효율적이지만 사용자의 요청을 처리하는 데 필요한 절반 또는 전체 시간을 소모합니다. 성능을 향상시킬 방법을 찾고 있습니다. 직렬화 및 직렬화를 수행하는 데 사용한 코드는 원래 게시물에 나와 있습니다. 더 많은 코드를 보려면 mee를 참조하십시오. – Frank

+0

나는 코드를 볼 필요가 있다고 말하지 않았다. 나는 코드에 대해 더 많이 알 필요가 있다고 말했다. 그 과정에 대해서. 각 요청에 얼마나 많은 양의 데이터를 저장하거나 복원해야하는지 등의 정보를 알아야합니까? 해당 데이터 또는 일부 데이터가 필요하지 않은 요청이 있습니까? 아마도 각 요청에서 데이터의 작은 부분을 설정하거나 가져와야하는 경우 성능을 향상시킬 수있는 방법이있을 수 있습니다. 적어도 시뮬레이트 된 코드 시뮬레이션 데이터와 시뮬레이트 된 요청을 통해 더 많은 도움을받을 수 있습니다. – ncm

답변

0

세션이 저장된 위치를 변경하여 기존 세션 기반 구현의 속도를 향상시킬 수 있습니다. 기본적으로 세션 데이터는 서버의 파일에 기록 된 다음 브라우저 쿠키를 통해 상관됩니다. 세션에 많은 양의 데이터가 포함되어 있으면보고있는 시간이 실제 드라이브의 검색 시간과 읽기 시간 일 가능성이 큽니다.

그러나 PHP는 여러 가지 세션 저장 방법을 지원합니다. 나는 memcached를 옵션을 시도 제안 : http://php.net/manual/en/memcached.sessions.php

session.save_handler = memcached 
session.save_path = "localhost:11211" 

당신은 물론 memcached를 설치해야합니다.

관련 문제