강의 컨설팅 트레이닝 무료진단 무료책자 마케팅편지 마케팅정보공유 다이어리 서비스제휴 고객센터

URL Cache를 사용하여 웹을 더욱 빠르게
작성자 : 13 김영철
등록날짜 : 2009.01.13 10:33
979
사용자가 쉽고 편안하게 사이트를 조회 하기 위한 많은 조건 중에서 로딩속도와 성능은 가장 기본요소라고 할수 있습니다. 물론 국내의 경우는 빠른 회선 속도와 다른 나라에 비하여 적은 인구수와 언어의 제약성으로(약 5000만명) 인하여 소수의 사이트를 제외하고는 크게 문제가 되지 않고 있는 것이 사실입니다. 만약에 미국과 중국 등에서 웹서비스를 오픈하려고 한다면 웹개발자들은 이 문제를 좀 더 고민해야 할것입니다.

잠깐 국내의 웹서비스와 사용자에 대하여 간단하게 이야기 해 볼까요. 일방문자가 10,000명이 되는 사이트의 경우는 시간당 약 420명, 분당 7명, 초당 0.1명 정도가 방문하게 됩니다. 평균적으로 한명의 방문자가 10페이지를 조회한다고 했을 경우에도 해당 사이트는 시간당 4,200 정도의 Transaction이 발생하게 됩니다. Peak-Time을 고려한다고 해도 그렇게 큰 숫자는 되지 않습니다. 안정성을 고려하지 않고 일반 Content 기반의 서비스라고 생각할때 Intel Pentium4 [2.0G] 정도의 중저급의 서버면 충분히 서비스 할수 있는 숫자입니다. 그리고 일방문자가 만명정도 되는 사이트는 국내에는 약 1500개정도 밖에 되지 않구요.

위와 같은 이유로 대부분의 국내사이트는 크게 성능과 로딩 속도가 문제가 되지 않습니다. 만약 문제가 된다면 프로그램을 잘못 작성했거나 아님 많은 수익을 발생하거나 둘중 하나 일것입니다. 그러나 메인페이지,DB 접속을 통하여 다량의 자료 검색을 해야 하는 경우 그리고 복잡한 연산을 수행하는 경우와 같은 Web Application 은 단일 요청에 대하여도 많은 부하와 이에 따른 결과로 로딩 속도가 느려지게 되어 원할한 서비스를 제공하는데 문제가 있습니다. 이런 경우에 Cache 기술을 유용하게 사용할 수 있습니다.

Cahce 기술은 아래와 같은 제한점이 있지만 잘 응용하게 되면 경쟁 사이트 보다 10배 더 빠르게 고객에서 나가갈수 있습니다.

  • 일정 부분 실시간 서비스를 포기하여야 한다. ( lifetime 을 조정하여 페이지의 Refresh 간격을 설정하여야 한다. )
  • 검색서비스와 같이 다양한 Query를 사용하는 경우는 적용할 수 없다.
    본인의 경우는 검색 Query중에서 상위 N개에만 해당 기술을 적용하여 상당히 성능향상을 경험하였습니다.
  • 자료 등록과 MyPage 구현( 사용자별로 다른 페이지를 서비스하여야 하기 때문에 구현이 불가능하거나 상당히 복잡하다. )
1. Sample Code 및 웹사이트에 적용 방법

demo.php

<?php require "lib/jmrss/URLCache.php"; // Cache 적용하기 Cache(true,"./cache",3600); // Database 연결 $conn = mysql_connect("mysql.ihelpers.co.kr", "xxxxx", "xxxxx"); mysql_select_db("xxxxx",$conn); $sql = "SHOW TABLES"; $result = mysql_query($sql,$conn); echo "<pre>"; while($row = mysql_fetch_array($result)){ print_r($row); } echo "</pre>"; mysql_close($conn); ?>

기존의 Web Application에 Cache 모듈을 적용하는 방법은 상당히 간단합니다. URLCache.php 파일을 include 하고 Cache함수를 호출하면 됩니다. URLCache.php 파일은 사용자가 원하는 디렉토리에 두면 됩니다. Cache 함수의 첫번째 인자는 Cache 여부이며 두번째 인자는 Cache 디렉토리입니다. 해당 디렉토리 역시 원하는 곳으로 설정하면 됩니다. 셋번째 인자는 Cache의 lifetime 입니다.

require "lib/jmrss/URLCache.php";
Cache(true,"./cache",3600);

위와 같이 설정 후에 최초로 URL이 호출이 되면 Cache디렉토리에 아래와 같이 Cache된 파일이 저장됩니다. 주의 할것은 저장하기 원하는 Cache 디렉토리는 미리 생성되어 있어야 합니다. 당연히 권한은 웹사용자의 쓰기 권한( chmod 766 ./cache )이 있어야 합니다. 사용자가 설정한 lifetime에 따라서 일정 시간 동안 Cache된 파일을 통하여 서비스가 되며, Cache파일은 설정된 lifetime을 주기로 갱신됩니다. Cache 파일명은 호출된 URL를 MD5 함수로 인코딩한 값입니다.

lsh804:~/www/cache$ ls -al total 12 drwxr-sr-x 2 ihelpers ihelpers 4096 11¿u 2 00:17 ./ drwxr-s--x 26 ihelpers ihelpers 4096 11¿u 2 00:15 ../ -rw-r--r-- 1 ihelpers ihelpers 2526 11¿u 2 00:17 0736bf2173b64ba30a47079fd0670e54

2. URLCache.php Class

URLCache.php 파일은 URLCache 클래스Cache 함수로 이루어져 있습니다. URLCache 클래스는 Cache 파일의 상태를 점검하고 Cache파일에 객체정보를 쓰고 읽는 역할을 수행합니다. Cache 함수는 URLCache 클래스를 기반으로 Cache 여부를 점검하여 Cache읽거나 아님 URL 정보를 읽어와 Cache 파일에 저장하는 함수입니다. Cache 함수는 기존에 사용하고 있는 WebApplication 에 Cache 기술을 쉽게 적용하기 위한 함수입니다.

<? /*/////////////////////////////////////////////////////////////// 작성자 : 손상모<smson@ihelpers.co.kr> 웹사이트 : http://www.ihelpers.co.kr 최초작성일 : 2004.10.25 변경내용 : 2004.11.01 Class외에 Cache 함수 추가 /////////////////////////////////////////////////////////////////*/ /** * URLCache Class * * URL 정보를 Cache 하는 Class입니다. * * @author Sang Mo,Son <smson@ihelpers.co.kr> * @version 0.9 beta * @access public */ class URLCache { var $CacheDir; var $Interval; /** * Constructor * * @param String Cache Directory * @param int Url Stale Time(s) * @access public * @return void */ function URLCache($CacheDir = './cache',$Interval = 3600){ $this->CacheDir = $CacheDir; $this->Interval = $Interval; } /** * Set Cache Directory * * @param int Url Stale Time * @access public * @return void */ function setCacheDir($CacheDir){ $this->CacheDir = $CacheDir; } /** * Set Url Stale Time(s) * * @access public * @return void */ function setInterval($Interval){ $this->Interval = $Interval; } /** * URL 정보에 해당하는 정보를 저장 * * @param string url * @param object content * @access public * @return void */ function set($url,$obj){ $fname = $this->_makeFileName($url); $fp = fopen($fname,'w'); if($fp){ fwrite($fp,$this->_serialize($obj)); fclose($fp); return true; } else { $this->Error("Unable to open file for writing : $fname"); return false; } } /** * URL 정보에 해당하는 정보 읽기 * * @param string url * @access public * @return object */ function get($url){ $fname = $this->_makeFileName($url); $fp = fopen($fname,'r'); if($fp){ $data = fread($fp,filesize($fname)); fclose($fp); return $this->_unserialize($data); } else { $this->Error("Cache doesn't contain : $url"); return false; } } /** * Cache 파일 점검 * * @param string url * @access public * @return int( -1 : not found, 0 : Stale, 1 : Hit ) */ function CheckCache($url){ $fname = $this->_makeFileName($url); if(file_exists($fname)){ if((time()- filemtime($fname)) >= $this->Interval){ return 0; } else { return 1; } } else { return -1; } } /** * URL 정보를 파일명으로 변경 * * @param string url * @access private * @return string */ function _makeFileName($url){ return $this->CacheDir."/".md5($url); } /** * Serialize The Content * * @param object content * @access private * @return string */ function _serialize($object){ return serialize($object); } /** * Unserialize The Content * * @param string content * @access private * @return object */ function _unserialize($content){ return unserialize($content); } /** * Error 정보 처리 * * @param string error message * @access public * @return void */ function Error($errmsg){ printf($errmsg); } } /** * URL 정보에 대한 Cache 함수 * * @access public * @param boolean isCache * @param string Cache Directory * @param int lifetime * @return boolean */ function Cache($iscache = true,$cachedir = './cache',$lifetime = 3600){ global $HTTP_GET_VARS,$HTTP_POST_VARS,$HTTP_SERVER_VARS; if($iscache == true && $HTTP_GET_VARS['CACHE'] != "NOCACHE" && count($HTTP_POST_VARS) == 0){ $url = sprintf("http://%s%s",$HTTP_SERVER_VARS['HTTP_HOST'],$HTTP_SERVER_VARS['REQUEST_URI']); $urlcache = new URLCache($cachedir,$lifetime); $result = $urlcache->CheckCache($url); if($result == 1){ // lifetime 이전 $html = $urlcache->get($url); } else { // lfietime 이후 또는 Cache파일이 없을 경우 $curl = sprintf("http://%s%s?CACHE=NOCACHE&%s",$HTTP_SERVER_VARS['HTTP_HOST'], $HTTP_SERVER_VARS['PHP_SELF'],$HTTP_SERVER_VARS['QUERY_STRING']); $fd = fopen ("$curl", "r"); $content = ""; while (!feof ($fd)) { $buffer = fgets($fd, 4096); $content .= $buffer; } $html['body'] = $content; $urlcache->set($url,$html); } echo $html['body']; exit; } else { return false; } } ?>

URLCache 클래스는 자세히 살펴 보면 크게 어려운 부분이 없습니다. CheckCache,set,get Method만 잘 살면보면 그 원리를 쉽게 이해할수 있습니니다. CheckCache Method는 위의 코드에서 보는 것 처럼 호출된 URL를 MD5함수로 인코딩한 후에 Cache 디렉토리에 Cache 파일의 존재 여부 확인하고 파일의 수정된 시간을 기반으로 설정된 lifetime의 만료여부를 확인 해 줍니다. set method 는 object 정보를 serialize 함수를 이용하여 직렬화 하여 Cache 파일에 저장하고 get method는 반대로 해당 내용을 읽어옵니다.

Cache 함수는 URLCache 클래스의 CheckCache 함수를 통하여 Cache 파일의 상태를 구분하여 lifetime 이전인 경우는 Cache파일에서 자료를 읽고 Cache파일이 존재하지 않거나 lifetime 보다 오래 되었을 경우는 Cache파일을 새롭게 갱신해 줍니다.

$curl = sprintf("http://%s%s?CACHE=NOCACHE&%s",$HTTP_SERVER_VARS['HTTP_HOST'], $HTTP_SERVER_VARS['PHP_SELF'],$HTTP_SERVER_VARS['QUERY_STRING']);

Parameter 값중에 "CACHE=NOCACHE" 를 전달하여 해당 Page가 Cache 기술을 사용하지 않고 직접 실행되도록 한 부분을 주의깊게 살펴보기 바랍니다. 잘못 사용하게 되면 무한반복실행을 하게 됩니다.

Cache를 사용하므로써 매번 복잡한 연산과 DB 접속을 해야 하는 페이지가 Cache 된 파일을 엑세스만 하여 저장된 내용을 출력해 주므로써 서버의 부하를 줄여주고 사용자에게 빠른 로딩속도를 제공할수 있게 되는 것입니다. DB에서 많은 양의 자료를 실시간으로 조회하는 것이 문제가 되어 시간 또는 일단위로 배치작업을 하여 Summary Table에서 자료를 조회하는 방법과 비슷하다고 할수 있겠습니다.

3. 성능 및 속도 비교

다음은 웹사이트 성능 분석 프로그램을 이용하여 Cache를 사용할때와 사
용하지 않을 경우의 성능 및 속도를 비교한 결과입니다.

Active Users 1 5 10 15 20 25
No Cache TPS 3.7 11.9 14.7 15.8 15.7 16.0
Total Requests 222 713 881 949 944 962
Average RPS 0.076 0.262 0.558 0.816 1.190 1.429
Cache TPS 5.4 16.0 19.1 20.3 21.2 20.9
Total Requests 325 962 1148 1216 1272 1251
Average RPS 0.084 0.212 0.368 0.627 0.797 1.071

* TPS(Transaction Per Second, Request Per Second), RPS(Response Second)
* 테스트 조건 : Thinking Time - 0.1 초, 단위테스트 시간 - 1분

1993967238_30086608_image003.gif

[출처]
웹디황용

"쇼핑몰·홈페이지·오픈마켓
블로그·페이스북·이메일 등의 각종 마케팅 글쓰기,
각종 광고, 영업, 판매, 제안서, 전단지
반응율 3배×10배 이상 높이는 마법의 8단계 공식"
자세히보기

Comments

번호 제목 글쓴이 날짜 조회
열람중 URL Cache를 사용하여 웹을 더욱 빠르게 13 김영철 01.13 980
3284 php5 99 단국강토 01.02 1054
3283 php 세션css 99 단국강토 12.30 1066
3282 [hatelove님의 JBBS 알고리즘 강좌 9] 13 김영철 01.14 1069
3281 reset , foreach 13 김영철 01.13 1106
3280 png 99 단국강토 12.30 1120
3279 플래시로 만든 php 함수 사전 13 김영철 01.13 1162
3278 PHP강좌】PHP URL함수 13 김영철 01.13 1166
3277 foreach 와 배열 13 김영철 01.14 1172
3276 주화면의 최신글을 preload로 빠르게 13 김영철 01.13 1184
3275 [php] 내장함수 13 김영철 01.13 1189
3274 태그 허용 함수???? 이제 개념을 바꾸자 13 김영철 01.14 1206
3273 플래쉬 Panels 에 대한 기본개념들 99 단국강토 01.06 1212
3272 foreach 13 김영철 01.13 1213
3271 파일관련함수 13 김영철 01.13 1213
3270 [hatelove님의 JBBS 알고리즘 강좌 7] 13 김영철 01.14 1215
3269 PHP도 객체지향형 프로그램이다..!!(클래스,상속동...) 13 김영철 01.13 1216
3268 PHP입문 - 함수 13 김영철 01.13 1216
3267 플래시에서 pc cam 영상보여주기 99 단국강토 02.16 1218
3266 php기본함수 정리!! 13 김영철 01.13 1219
3265 시스템콜인 open 계열 함수와 스트림기반의 fopen 계열.. 13 김영철 01.13 1221
3264 소스를 간편하게 만들어 주는 with문 99 단국강토 02.10 1225
3263 객체 정의하기[이론,예제] 99 단국강토 01.29 1229
3262 php 파일 업, 다운로드 13 김영철 01.13 1232
3261 역인덱스 게시판 | 13 김영철 01.14 1241
3260 파일업로드 썸네일 제작 class 13 김영철 01.13 1244
3259 초보자용 이것저것 몇가지 팁 13 김영철 01.14 1246
3258 간단 날짜계산 99 단국강토 02.16 1249
3257 window 객체 M 최고의하루 12.20 1249
3256 디렉토리 폴더 모든파일 표시 [php] 13 김영철 01.14 1250
마케팅
특별 마케팅자료
다운로드 마케팅자료
창업,경영
기획,카피,상품전략
동기부여,성취