김보안의 블로깅
  • 🏠 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사용을 자제해야 겠습니다.


Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
최근 게시물 이전 게시물 홈

페이지

  • 홈
  • Hobby

Categories

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

Popular Posts

  • 블랙보드 강의 녹화 영상 다운로드 가능한 방법 (노설치)
    별도의 설치도 필요 없고 아주 쉽습니다. 구글 크롬브라우저 에서 블랙보드 녹화 영상에  다운로드 가능한 메뉴가 나오게 하는 코드입니다.  먼저 블랙보드 강의자료에 입장하고, 재생 버튼을 클릭 하지 않은 상태로 F12 를 입력합니다. 재생을 클릭하지 마세요.
  • 회사 프록시와 인증서에 고통받는 그대를 위한 글 (Bash, Gradle, Python, wget, nodejs(npm), apt-get, cURL, git, yarn, androidStudio)
    대기업에 입사하면 장단점이 있는데, 단점 중에 하나가 회사에서 프록시를 사용하여 트래픽 감시를 하므로 프록시 설정을 해주어야 한다는 점 입니다. 특히, 회사에서는 https 트래픽도 감시를 하므로 인증서도 설정해 주어야 합니다. 그런데 문...
  • [Node.js] Redis 의 hmset
    Redis 의 hmset 사용하기 var redis = require('redis'); var client=redis.createClient(포트,호스트,null); /* * MySQL을 사용하다가 Redis를 사용해보니 신세...

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