김보안의 블로깅
  • 🏠 Home
  • 📚 Project
    • Blockchain
      • 🎦 PickMe
      • 🎦 IoTC
      • 🎦 Blackchain
      • 📃 Gemology
      • 🎦 PickMe
      • 🎦 PickMe
    • AI
      • 👋 A.I. Dream Reader
      • 🎦 A.I. Dream Reader
    • Security
      • 🎦 SNAC
    • Education
      • 🎦 Smart Lecture
  • 🤸‍♂ Hobby
    • Music
      • Violin
      • Guitar
      • Piano
      • Drum
    • Flower
      • Flower Certificate
    • Sport
      • Ski
      • Skateboard
      • Golf
      • Boxing

2013년 8월 9일 금요일

[PHP] Session 파일로 관리하지 마세요.

 SecureKim     오후 4:16     file, nginx php 느림, PHP, php 느림, php redis, php redis session, session     No comments   




Windows7+Apache에서 CentOS+Nginx로 갈아탔는데도 불구하고

PHP를 사용할 때 갑자기 매우 느려지는 현상이 있었습니다.

PHP-FPM 도 사용해보고 , Nginx가 Dynamic한 파일 처리에 적합하지 않다고 하여

Reverse Proxy로 Apahce를 연결해 보았지만 여전히 느린 현상이 없어지지 않았습니다.

그래서 지인과 이야기를 하던 도중 중대한 사실을 하나 알게되었습니다.

세션을 파일로 관리했던 것!

그러고보니 아무리 찾아봐도 느릴 이유가 없는데..

시스템 IO는 아직도 대부분의 시스템에서 가장 중요한 작업이고, 

강력한 Priority를 갖기 때문일 것이라 생각 했습니다.

그래서 그때부터 Redis와 PHP를 연결한 후 Redis-server 에서 세션을 다루어 보았습니다.

PHP에서 Redis를 사용하기 위해서는 , PREDIS 를 먼저 설치 해야합니다.

pear 가 어디에 있는지 find 명령어로 먼저 찾아 내고,

/pear의 위치/pear channel-discover pear.nrk.io 이후

/pear의 위치/pear install nrk/Predis 로 설치하면 끝.

저는 이 파일을 아파치에 옮겨 주었구요

php.ini 를 find해서 

extension=redis.so 

하면 php에서 redis를 사용이 가능합니다.

사용법은 
require('./redis-session.php');
RedisSession::start();

이고, 다음부터는 일반 session 사용하듯 사용하시면 됩니다.
redis-session.php 파일은 아래와 같습니다.



redis-session.php


if(!class_exists('\Predis\Client')){
  chdir(dirname(__FILE__)); 
  require_once('./Predis/Autoloader.php');
/*
./Predis/Autoloader.php 이 부분은 
redis-session.php 위치로 부터의 상대 경로입니다.
*/
  Predis\Autoloader::register();
}

function json_decode_array($d){
  return json_decode($d, true);
}

function redis_session_id_mutator($id){
  return $id;
}

class RedisSession{
  private $serializer;
  private $unserializer;
  private $unpackItems;
  private $id_mutator;

  static function start($redis_conf = array(), $unpackItems = array()){
    if(!defined('REDIS_SESSION_PREFIX'))
      define('REDIS_SESSION_PREFIX', 'session:php:');
    if(!defined('REDIS_SESSION_SERIALIZER'))
      define('REDIS_SESSION_SERIALIZER', 'json_encode');
    if(!defined('REDIS_SESSION_UNSERIALIZER'))
      define('REDIS_SESSION_UNSERIALIZER', 'json_decode_array');
    if(!defined('REDIS_SESSION_ID_MUTATOR'))
      define('REDIS_SESSION_ID_MUTATOR', 'redis_session_id_mutator');
    $obj = new self($redis_conf, $unpackItems);
    session_set_save_handler(
      array($obj, "open"),
      array($obj, "close"),
      array($obj, "read"),
      array($obj, "write"),
      array($obj, "destroy"),
      array($obj, "gc"));
    session_start(); 
    return $obj;
  }

  function __construct($redis_conf, $unpackItems){
    $this->serializer = function_exists(REDIS_SESSION_SERIALIZER) ? REDIS_SESSION_SERIALIZER : 'json_encode';
    $this->unserializer = function_exists(REDIS_SESSION_UNSERIALIZER) ? REDIS_SESSION_UNSERIALIZER : 'json_decode_array';
    $this->id_mutator = function_exists(REDIS_SESSION_ID_MUTATOR) ? REDIS_SESSION_ID_MUTATOR : 'redis_session_id_mutator';
    $this->unpackItems = $unpackItems;

    $this->redis = new \Predis\Client($redis_conf);
  }

  function serializer(){
    return call_user_func_array($this->serializer, func_get_args());
  }

  function unserializer(){
    return call_user_func_array($this->unserializer, func_get_args());
  }

  function id_mutator(){
    return call_user_func_array($this->id_mutator, func_get_args());
  }

  function read($id) {
    $d = $this->unserializer($this->redis->get(REDIS_SESSION_PREFIX . $this->id_mutator($id)));
    // Revive $_SESSION from our array
    $_SESSION = $d;
  }


  function write($id, $data) {
    
    $data = $_SESSION;
    $ttl = ini_get("session.gc_maxlifetime");
    $unpackItems = $this->unpackItems;
    $serializer = $this->serializer;
    $id_mutator = $this->id_mutator;

    $this->redis->pipeline(function ($r) use (&$id, &$data, &$ttl, &$unpackItems, &$serializer, &$id_mutator) {
      $r->setex(REDIS_SESSION_PREFIX . $id_mutator($id), $ttl, $serializer($data));

    });
  }


  function destroy($id) {
    $this->redis->del(REDIS_SESSION_PREFIX . $this->id_mutator($id));

  }

  function open($path, $name) {}
    function close() {}
    function gc($age) {}
}

register_shutdown_function('session_write_close');

?>


빨라지는 마법을 경험했습니다.

그래도... 앞으로는 PHP사용을 자제해야 겠습니다.


  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
이메일로 전송BlogThis!Twitter에서 공유Facebook에서 공유
최근 게시물 이전 게시물 홈

0 개의 댓글:

댓글 쓰기

페이지

  • 홈
  • Hobby

Categories

  • AI
  • android
  • AWS
  • Blockchain
  • Hardware
  • Javascript
  • mysql
  • Node.js
  • Plasma
  • review
  • Security
  • Study
  • Video
  • windows

Popular Posts

  • 회사 프록시와 인증서에 고통받는 그대를 위한 글 (Bash, Gradle, Python, wget, nodejs(npm), apt-get, cURL, git, yarn, androidStudio)
    대기업에 입사하면 장단점이 있는데, 단점 중에 하나가 회사에서 프록시를 사용하여 트래픽 감시를 하므로 프록시 설정을 해주어야 한다는 점 입니다. 특히, 회사에서는 https 트래픽도 감시를 하므로 인증서도 설정해 주어야 합니다. 그런데 문...
  • Termux 로 안드로이드에 우분투(GUI)와 VSCode설치하기
      많은 글들이 있지만 뭔가 대부분 잘 안됐다. 이번 기회에 정리한다. 0. 먼저 Termux와 Remote Desktop Manager를 설치한다. Remote Desktop Manager 대신 아래도 나쁘지 않다. 화면이 작지만 마우스 스크롤이나 ...
  • Node.js 에서 RSA 로 암복호화 하기
    Node.js 의 crypto 모듈은 기본적으로 제공되므로, npm 으로 설치할 필요가 없습니다. crypto 기본 모듈을 사용해 RSA 의 키로 암복호화 하는 방법을 알아 봅시다. 일단 그 전에 OpenSSL로 RSA Private Key...

Blog Archive

  • ►  2023 (1)
    • ►  1월 (1)
  • ►  2022 (10)
    • ►  12월 (1)
    • ►  11월 (3)
    • ►  9월 (1)
    • ►  8월 (1)
    • ►  6월 (2)
    • ►  3월 (2)
  • ►  2021 (9)
    • ►  12월 (3)
    • ►  11월 (1)
    • ►  6월 (1)
    • ►  5월 (2)
    • ►  4월 (2)
  • ►  2020 (12)
    • ►  10월 (1)
    • ►  9월 (2)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (5)
    • ►  4월 (1)
    • ►  2월 (1)
  • ►  2019 (14)
    • ►  10월 (2)
    • ►  7월 (1)
    • ►  3월 (4)
    • ►  2월 (2)
    • ►  1월 (5)
  • ►  2018 (14)
    • ►  12월 (2)
    • ►  11월 (4)
    • ►  10월 (1)
    • ►  8월 (2)
    • ►  5월 (4)
    • ►  1월 (1)
  • ►  2017 (12)
    • ►  10월 (2)
    • ►  9월 (9)
    • ►  5월 (1)
  • ►  2016 (8)
    • ►  10월 (2)
    • ►  8월 (1)
    • ►  6월 (1)
    • ►  1월 (4)
  • ►  2015 (6)
    • ►  12월 (3)
    • ►  10월 (1)
    • ►  6월 (1)
    • ►  5월 (1)
  • ►  2014 (10)
    • ►  11월 (1)
    • ►  9월 (1)
    • ►  7월 (1)
    • ►  6월 (1)
    • ►  5월 (3)
    • ►  4월 (1)
    • ►  3월 (2)
  • ▼  2013 (28)
    • ►  12월 (3)
    • ►  11월 (6)
    • ►  10월 (6)
    • ►  9월 (6)
    • ▼  8월 (1)
      • [PHP] Session 파일로 관리하지 마세요.
    • ►  7월 (3)
    • ►  6월 (3)

구독

글
Atom
글
댓글
Atom
댓글

로드 중입니다...

각오

직접 해보지 않은 것은 포스팅 하지 않겠습니다.

Copyright © 김보안의 블로깅 | Powered by Blogger
Design by Hardeep Asrani | Blogger Theme by NewBloggerThemes.com | Distributed By Gooyaabi Templates