발 완료 후 메모용도로 작성한 글임.

자세한 내용은 알지 못함으로 질문은 받지 않는 글임.



#convert 사용하기 위해서 일단 설치


[root@localhost ~]# yum install ImageMagick


convert 를 이용해서 파일 변환


#convert 옵션( 출처 : http://openwiki.kr/tech/imagemagick ) 시작


파일포맷변경

convert image_org.gif image_out.jpg 

[설명] image_org.gif 이미지를 image_out.jpg로 바꾼다.


convert image_org.png image_out.jpg 

[설명] image_org.png 이미지를 image_out.jpg로 바꾼다.



확대,축소,리사이즈

convert image_org.jpg -resize 25%x25% -quality 100 image_out.jpg

[설명] image_org.jpg 이미지를 1/4 축소한 image_out.jpg로 바꾼다.


convert image_org.jpg -resize 800x600 -quality 100 image_out.jpg 

[설명] image_org.jpg 이미지를 800x600픽셀로 리사이즈 하지만 비율을 유지하며 큰사이즈 비율 기준으로 image_out.jpg를 생성한다.


convert image_org.jpg -resize 800x600\! -quality 100 image_out.jpg 

[설명] image_org.jpg 이미지를 800x600픽셀로 강제적으로 바꾸어 image_out.jpg를 생성한다.



[설명] "-quality 100"이란 옵션을 주면 품질을 최대한 좋게한다.



회전

convert image_org.png -matte -background none -rotate 90 image_out.png 

[설명] 이미지를 90도 회전하고 나머지 영역은 투명하게한다.


convert image_org.png -matte -background none -rotate -15 image_out.png 

[설명] 이미지를 -15도 회전하고 나머지 영역은 투명하게한다.



좌우반전,상하반전

convert -flop image_org.jpg image_out.jpg 

[설명] image_org.jpg 이미지를 좌우반전시켜 image_out.jpg 이미지를 생성한다.


convert -flip image_org.jpg image_out.jpg 

[설명] image_org.jpg 이미지를 상하반전시켜 image_out.jpg 이미지를 생성한다.



흑백,갈색 효과

convert image_org.jpg -colorspace gray image_out.jpg 

[설명] image_org.jpg 이미지를 흑백효과를 적용하고 image_out.jpg 이미지를 생성한다.


convert image_org.jpg -sepia-tone 80% image_out.jpg 

[설명] image_org.jpg 이미지를 갈색효과를 적용하고 image_out.jpg 이미지를 생성한다.



밝게,어둡게

convert image_org.jpg -sigmoidal-contrast 3,0% image_out.jpg

[설명] image_org.jpg 이미지를 밝게하여 image_out.jpg 이미지를 생성한다.


convert image_org.jpg -sigmoidal-contrast 3,100% image_out.jpg 

[설명] image_org.jpg 이미지를 어둡게하여 image_out.jpg 이미지를 생성한다.



자르기(crop)

convert image_org.jpg -crop 800x600+10+20 image_out.jpg 

[설명] image_org.jpg를 Left 10픽셀 Top 20픽셀 부터 800x600픽셀까지 자르고 그 결과로 image_out.jpg 이미지를 생성한다.


convert image_org.jpg -crop 800x600+10-30 image_out.jpg 

[설명] image_org.jpg를 Left 10픽셀 Top -30픽셀 부터 800x600픽셀까지 자르고 그 결과로 image_out.jpg 이미지를 생성한다.



캔버스생성

convert -size 800x600 xc:white image_out.jpg 

[설명] 800x600픽셀인 흰색 image_out.jpg 이미지를 생성한다.


convert -size 800x600 xc:skyblue image_out.gif 

[설명] 800x600픽셀인 하늘색 image_out.jpg 이미지를 생성한다.


convert -size 800x600 xc:none image_out.png 

[설명] 800x600픽셀인 투명 image_out.png 이미지를 생성한다.



글자이미지생성

convert -background white -fill black -font batang.ttf -pointsize 36 label:"Test\n한글" image_out.png 

[설명] "Test\n한글"이란 글자로 image_out.png 이미지를 생성한다. (이미지배경은 흰색, 글자색은 검정색, 폰트는 바탕, 폰트사이즈는 36pt)



이미지합성

composite -dissolve 60 -geometry +50+100 image_temp.png image_org.jpg image_out.jpg 

[설명] image_temp.png 이미지를 투명도 60%로 하여 image_org.jpg의 50,100 픽셀 좌표에 올려 합성후 image_out.jpg 이미지를 생성한다.


#convert 옵션( 출처 : http://openwiki.kr/tech/imagemagick ) 끝



#php 를 이용한 convert 실행 샘플

--> pdf 파일은 png 파일로 변환

--> include 나 path 의 경우 절대경로로 적었음

--> 해당 파일을 ~/convert.php 로 저장했음

--> 실행은 콘솔창에서 php '~/convert.php'; 로 실행했음.

--> db에 저장된 파일중 pdf 파일만 선택하여 변환함.


<?php

$debug = true;

include_once('/var/www/html/common.php');


$bo_table = 'vfxx';


$directory = '/var/www/html/data/file/'.$bo_table;


$input_path = '/var/www/html/data/file/'.$bo_table;  //원본 파일 경로

$output_path = '/var/www/html/data/file/'.$bo_table.'/output'; // 변환되어 저장될 파일의 경로


$inputPath = $input_path;

$outputPath = $output_path;



@mkdir($output_path, 0755);

@chmod($output_path, 0644);


$sdate = date('Ymd')-1;


$sql = "select * from mfile

where bo_table = '$bo_table'

and file_name like '%.pdf'

";


$result = mysql_query($sql);


while($row = mysql_fetch_assoc($result)){


$tmp_path = $outputPath.'/'.$row['file_idx'];


if(is_dir($tmp_path)){

shell_exec('rm -rf '.$tmp_path);

}

@mkdir($tmp_path, 0755);

@chmod($tmp_path, 0644);



$file_ext = '';

$file_name = '';

$file_ext = explode('.', $row['file_name ']);


for($i = 0; $i<count($file_ext) - 1;  $i++){

$file_name .= $file_ext[$i];

}


if(strtolower($file_ext[count($file_ext)-1]) == 'pdf'

&& !file_exists($tmp_path.'/'.$file_name.'0.png')

){

convertImg($directory.'/'.$row['file_name'], $tmp_path.'/'.$file_name.'.png');

}


}



function convertImg($ffilename, $tfilename){

$output = shell_exec('rm -rf /tmp/magick*');

$output = shell_exec('convert -size 2481x3508 xc:white -verbose -density 200 -trim '.$ffilename.' -quality 100 -sharpen 0x1.0 '.$tfilename);

// 2481x3508 사이즈로

// quality 100 --> 최대 품질

// density 200 --> 압축율은 적당히

// sharpen --> 이미지는 원본 수준으로



}


?>


#변환된 파일의 출력

--> output 디렉토리의 파일을 읽어 존재하는 모든 파일 출력



<div style="text-align:center; ">

    <div style="margin:auto;text-align:center; height:100%;overflow:hidden"><div>

<?php

      $bo_table = 'vfxx'

$dir = '/file/'.$bo_table.'/output/'.$file_idx;

$url = '/file/'.$bo_table.'/output/'.$file_idx;

$handler = opendir($dir); 


while ($filek[] = readdir($handler));

natsort($filek);


closedir($handler); 


foreach ($filek as $file){

if(stristr ( $file , 'png', false )){

echo '<div style="text-align:left; background-color:#fff;">';

echo "<img src='".$url.'/'.$file."' style='background-color:#fff;'/>";

echo '</div>';

}

}




?>

</div>

</div>


'프로그래밍 > PHP' 카테고리의 다른 글

PHP 서버에서 GCM 멀티캐스트 발송하는 방법  (0) 2014.12.05
by 차까꿍 2016. 7. 17. 09:11

corontab 옵션을 보면 최소 1분 단위 밖에 없다.

 

1분단위의 경우

 

*/1 * * * * 명령어

 

이렇게 하면 1분단위가 되는데 30초 단위로 명령이 실행되고자 한다면 sleep 을 이용하면 된다.

 

* * * * * * 명령어 & sleep 30; 명령어

 

이렇게 하면 명령어가 실행된뒤 30초간 sleep 한뒤 다시 명령어를 실행 그렇게 계속 반복하도록 하는 것이다.

문론 수정후 데몬을 재시작 해주셔야겠죠


/etc/init.d/crond restart

 

 

참조 : http://www.saybox.co.kr/bbs/board.php?bo_table=board01&wr_id=182

by 차까꿍 2016. 7. 2. 02:50

디비 쿼리 최적화는 정말 끝나지 않는 싸움같다.
실전에서 사용하고 있는 쿼리도 여러번 바뀌었는데 다 기억은 못하고..

 

글 내용을 말하기에 앞서 테이블 구조부터 소개를 하자면,
아래와 같이 생겼다. 아주 심플한 테이블이라 할 수 있다.

 

CREATE TABLE `TABLE` (  
`index` int(11) NOT NULL AUTO_INCREMENT,  
`date` varchar(10) NOT NULL,  
`time` varchar(10) NOT NULL,  
`nick` varchar(30) NOT NULL,  
`data` varchar(200) NOT NULL, 
 PRIMARY KEY (`index`),  
 KEY `indx_date` (`date`),  
 KEY `indx_nick` (`nick`) )
 ENGINE=InnoDB AUTO_INCREMENT=4016741 DEFAULT CHARSET=utf8

 

 

사실 처음에 몇만건 몇십만건 됐을때는 아무렇게나 짜도 무리가 없었는데 백만단위로 들어가면서부터 검색 범위를 제한하게 됐다.
유쾌하지 않은건 사실이다. 성능 때문이라는 변명에 괜히 숨는 느낌이라고 해야하나...
그래서 항상 고민이 많다. 이 글을 작성하는 시점에는 멀쩡한데 저녁에 서비스가 몰리는 시간엔 어찌될지...

 

 

검색 쿼리는 다음 조건을 가진다.


1. 날짜 범위 지정
2. 닉네임은 매칭 / 내용은 와일드카드 검색
3. 최근 순서대로 정렬

 

 

이를 간단히 생각하면 다음과 같이 작성해볼 수 있을 것 같다.
(실제로 생활코딩에 질문을 올렸을때 어떤 누가 이런식으로 쿼리를 짜서 주었음)
select `index`, `date`,`time`, `nick`, `data` from TABLE
where `date` BETWEEN '20150709' AND '20150716'  and `data` like '%검색어%' OR `nick` = '검색어'
order by date desc
별 다른 특이사항이 보이지 않는 쿼리이다. 과연 성능은 어떨까?

 

 

Explain extended 를 사용하여 쿼리가 어떻게 수행되는지 확인을 해보자.
SIMPLE    TABLE    ALL    indx_date,indx_nick                387809    100.00    Using where; Using filesort
검색은 SIMPLE하고, possible한 key도 기재가 되지만, 실제로는 인덱스를 타지 않는다.
왜냐면 컬럼중에 인덱싱 범주에 포함되지 않는것들이 다수 있기때문이다.
또한 검색에 소요되는 Row의 수도 거의 테이블 전체를 seeking 해야하는 수준이며, 검색 조건중 반드시 배제되어야 된다는 filesort를 통해 order by를 수행한다.

 

 

따라서, 위 쿼리로 서비스를 했다간 그냥 db가 뻗어버릴것이다

 

그래서 두번째로 생각한것이 서브쿼리를 이용해보는것이었다.
내 착안은 이렇다.

 

1. 날짜 범위별로 검색범위를 제한한다.
2. 서브쿼리에서 배달된 (delivered) 쿼리중에서만 추가검색을 진행한다.

 

 

결론부터 말하자면 근접한 방법이긴한데 정답은 아니다.
쿼리를 보면서 계속하자
SELECT `index`, `date`,`time`, `nick`, `data`
FROM     (        
                 select `index`, `date`,`time`, `nick`, `data` from TABLE
                 WHERE `date` BETWEEN '20150700' AND '20150716'
              ) as origindata
WHERE (    `data` like '%검색어%' OR `nick` = '검색어' )
ORDER BY `index` DESC

 

 

서브쿼리를 이용해서 인덱싱이 되어있는 Date 컬럼을 이용해 범위를 제한하고,
나온 결과에서만 검색을 수행하겠다는 계획이고, 실제로 위 쿼리로 서비스를 오래 했다.

 

이 쿼리의 explain은 다음과 같다.
1    PRIMARY    <derived2>    ALL                    177838    100.00    Using where; Using filesort
2    DERIVED    TABLE    ALL    indx_date                386966    45.96    Using where
읽는 순서는 역순으로..
인덱스를 타라고 일부러 서브쿼리로 나눠놨는데 위에서 언급한것과 마찬가지로 인덱싱이 되지 않는 컬럼을 select하기때문에 결국 전체 테이블을 seeking하게 된다.

 

 

결과적으로 놓고보면, 첫번째 쿼리와 다를게 없다....
filesort도 그대로 사용하고 있고, 인덱스도 여전히 이용하지 않고 있다.

 

 

그럼 어떻게 해야할까? 우선 인덱스를 타게 해야겠다고 생각했다.
그래서 쿼리를 좀 고쳐봤다. 요렇게
select b.`index`, `date`,`time`, `nick`, `data` from TABLE as b
left join (
   select `index` from TABLE where `date` BETWEEN '20150709' AND '20150716' ) a
on a.`index` = b.`index`
where a.`index` = b.`index` and  `data` like '%검색어%' OR `nick` = '검색어'
ORDER BY b.`index` DESC


위 쿼리는 인덱싱이 되어있는 `index`컬럼과 `date`컬럼을 사용해보자고 생각을 했다.
그래서 서브쿼리 조인을 사용해서, 날짜에 해당하는 index들만 뽑아낸 후 바깥 테이블에서 해당 primary index에 해당하는 녀석들에서만 검색을 해보자고 시도를 해봤다. 결과는 실패였지만 과정은 괜찮았다.
1    PRIMARY    b    index    PRIMARY,indx_nick    PRIMARY    4        387047    100.00    Using where
1    PRIMARY    <derived2>    ref    <auto_key0>    <auto_key0>    4    lute.b.index    10    100.00    Using where; Using index
2    DERIVED    TABLE    range    indx_date    indx_date    32        179508    100.00    Using where; Using index

드디어 Extra에 using index가 등장하기 시작했다.
하지만 결국 b 테이블은 전체 테이블을 seek해서 배달되는 index랑 비교를 해야되기때문에 컬럼수가 무자비했고, 간혹 돌리다보니 using filesort뿐 아니라 using temporary까지 .....
오히려 더 안좋은 결과가 되었다. 실제 쿼리타임도 쿼리를 두번 돌려야되는 꼴이기때문에 더 느린건 두말할것도 없다

 

 

하지만 아이디어 자체가 나쁘다고 생각하지 않았기때문에 using temporary라는 키워드로 검색해보다가 이곳을 발견하게 되었다.
이제 내가 해결해야될 문제는 명확했다.

 

1. using index를 무조건 띄워야된다.
2. filesort 및 temporary가 뜨면 안된다
3. 최소한의 Row를 사용해야한다

 

 

링크한 블로그의 커버링 인덱스(covering index)를 참조하여 다시 작성한 쿼리는 다음과 같다.
select a.`index`, a.`date`,a.`time`, a.`nick`, a.`data`
from (     
       select `index`  from TABLE
       where  `date` BETWEEN '20150700' AND '20150716'
       order by `date` desc
       ) b
join TABLE a
on b.`index` = a.`index`
where a.`data` like '%검색어%' OR a.`nick` = '검색어'
사실 뭐가 다른지도 잘 구분이 안된다만 엄연히 다르니 잘 보자
따로 말로 설명하면 길어질것 같으니 성능부터 보자
1    PRIMARY    <derived2>    ALL                    193547    100.00   
1    PRIMARY    a    eq_ref    PRIMARY,indx_nick    PRIMARY    4    b.index    1    100.00    Using where
2    DERIVED    TABLE    range    indx_date    indx_date    32        193547    100.00    Using where; Using index
확연한 차를 보이고 있고, 제시한 모든 문제가 다 해결되었다.
최소한의 Row를 사용하고, index를 이용해 order by 까지 처리하는걸 볼 수 있다.

 

 

이번글에서는 엄청난 내용을 소개한것은 아니다.
하지만 쿼리 한개라도 아무렇게나 작성하면 안되고 충분한 테스트 및 성능 검증이 필요하다고 말하고 싶었다.
그래서 일일히 삽질한 쿼리도 공개를 해보면서 풀어나가듯이 작성해봤다.
어쨌든 디비쿼리와의 전쟁은 계속되겠고 최적화를 위해서 계속 삽질을 하자.

 

 


Reference
http://gywn.net/2012/04/mysql-covering-index/


출처 : http://b.fantazm.net/entry/Mysql-Query-Optimization-using-Covering-Index

'프로그래밍 > SQL' 카테고리의 다른 글

[DBMS] Mysql Query Cache 매뉴얼 번역문  (0) 2015.01.02
mySql 명령어 간략 정리  (0) 2014.11.22
SQL 순위(랭킹)구하기 팁  (0) 2014.08.21
[MySQL] Explain(실행계획)  (0) 2014.07.17
by 차까꿍 2016. 7. 2. 02:49

리눅스에서 디렉토리내의 많은 파일을 삭제하려고 하면,

삭제되지 않을수 있습니다.

그럴때 아래와 같이 삭제 합니다.

 

// 현재디렉토리내에 sess_ 로 시작되는 파일 모두삭제
# find . -maxdepth 1 -name "sess_*" -print | xargs rm -rf


// 현재디렉토리내에 sess_ 로 시작되는 파일 모두삭제 (1개씩 삭제 느림)
# fori in sess_*; do rm -rf "$i"; done


// 현 디렉토리내에 파일갯수 확인
# ls -l | grep ^- | wc -l

by 차까꿍 2016. 7. 2. 02:43

리눅스 사용하다보면 전체경로 입력하면서 프로세스를 사용하기 귀찮을때가 많이 있습니다.

그럴때는 아래와 같은 형태로 별칭을 등록해주면, 편하게 사용 가능합니다.

 

 

# alias httpd='/usr/local/apache/bin/httpd'
# alias php='/usr/local/php/bin/php'
# alias mysql='/usr/local/mysql/bin/mysql'

by 차까꿍 2016. 7. 2. 02:34

리눅스 시스템 시작시에 자동 실행할 파일 등록하기

여러가지 방법이 있으나, 각기 알맞는 방법을 사용하는 것이 가장 좋다.
 
① # vi /etc/rc.local 에서 바로 실행하기
   - 해당 파일 하단에 실행 명령을 바로 넣어준다.
   - 가능하면 실행 명령의 풀패스를 모두 적어주는 것이 좋다.
   - 시스템(H/W)와 관련된 명령을 입력할 경우에는 부팅시 rc.local의 실행 순서가 빠르기 때문에 실행되지 않는 경우가 있을 수 있다. (이 경우에는 해당 시스템을 먼저 띄우는 방법을 사용하도록 한다.)
 
② # vi /etc/rc.local 에 스크립트 파일을 등록하고, /etc/rc.d/ 경로에 해당 스크립트 파일 넣고 실행하기
   - rc.local에서는 스크립트 파일을 불러오기만 하는 방법
   - 작성할 스크립트 파일은 실행할 쉘을 먼저 지정해야 한다.
   - 시스템(H/W)와 관련된 명령을 입력할 경우에는 부팅시 rc.local의 실행 순서가 빠르기 때문에 실행되지 않는 경우가 있을 수 있다. (이 경우에는 해당 시스템을 먼저 띄우는 방법을 사용하도록 한다.)
 
③ /etc/profile.d/ 경로에 자동실행할 스크립트 파일을 넣어 둔다.
   - 위 경로에 있는 스크립트 파일들은 부팅시에 자동실행되는 파일들이다.
   - 보통의 프로그램들을 가동하는데 많이 사용한다.
 
④ /usr/share/autostart/ 경로에 자동실행할 프로그램 파일을 생성한다.
   - 위 경로에 있는 *.desktop 파일들은 부팅시에 자동실행되는 파일들이다.
   - 기존에 있는 파일들과 같은 형식으로 원하는 파일을 만들어서 사용할 수 있다.
   ※ 만약 특정 계정에서만 위의 사항을 적용하고자 할때는, ~/kde/Autostart/ 경로에 설정한다.
 
 
[예제]
 
#===============================================================================
# vi /etc/rc.d/auto_start.sh
#===============================================================================
#!/bin/bash
# IEEE Mount
# /sbin/modprobe usbcore
# /sbin/modprobe usb-uhci
/sbin/modprobe ohci1394
/sbin/modprobe sbp2
/sbin/modprobe ieee1394
echo "scsi add-single-device 1 0 0 0" > /proc/scsi/scsi
echo "scsi add-single-device 1 0 1 0" > /proc/scsi/scsi
/bin/mount /dev/sdb1 /mnt/backup1
/bin/mount /dev/sdc1 /mnt/backup2
# Time Sync
/usr/bin/rdate -s time.nuri.net
 
#===============================================================================
# vi /etc/rc.local
#===============================================================================
#!/bin/sh
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
sh /etc/rc.d/auto_start.sh
 
#===============================================================================
# vi /etc/profile.d/
#===============================================================================

by 차까꿍 2016. 7. 2. 02:30

아파치 httpd.conf 파일에 ErrorDocument 을 이용하여 에러코드에 대한 결과를 재설정 할수있다.

Http Code 404(Page Not Found)에 대해 설정하는 방식을 보겠습니다.

 


1) planet text:
ErrorDocument 404 "없는페이지입니다."
=> 404 메세지를 "없는페이지입니다."로 바꿔줍니다. return되는 http code는 그래로 404입니다.

 

2) local redirect
ErrorDocument 404 "/error.html"
=> 404 메세지를 error.html의 내용으로 바꿔줍니다. return되는 http code는 그대로 404입니다.

 

3) external redirect
ErrorDocument 404 "http://localhost/error.html"
=> 해당 페이지로 redirect요청합니다. return되는 http code는 302로 client가 다시 메세지 Page를 호출하게됩니다. 


물론 .htaccess파일에서도 지정해줄수있다,.

 

100 : Continue
101 : Switching protocols
200 : OK, 에러없이 전송 성공
201 : Created, POST 명령 실행 및 성공
202 : Accepted, 서버가 클라이언트 명령을 받음
203 : Non-authoritative information, 서버가 클라이언트 요구 중 일부만 전송
204 : No content, 클라언트 요구을 처리했으나 전송할 데이터가 없음
205 : Reset content
206 : Partial content
300 : Multiple choices, 최근에 옮겨진 데이터를 요청
301 : Moved permanently, 요구한 데이터를 변경된 임시 URL에서 찾았음
302 : Moved temporarily, 요구한 데이터가 변경된 URL에 있음을 명시
303 : See other, 요구한 데이터를 변경하지 않았기 때문에 문제가 있음
304 : Not modified
305 : Use proxy
400 : Bad request, 클라이언트의 잘못된 요청으로 처리할 수 없음
401 : Unauthorized, 클라이언트의 인증 실패
402 : Payment required, 예약됨
403 : Forbidden, 접근이 거부된 문서를 요청함
404 : Not found, 문서를 찾을 수 없음
405 : Method not allowed, 리소스를 허용안함
406 : Not acceptable, 허용할 수 없음
407 : Proxy authentication required, 프록시 인증 필요
408 : Request timeout, 요청시간이 지남
409 : Conflict
410 : Gone, 영구적으로 사용할 수 없음
411 : Length required
412 : Precondition failed, 전체조건 실패
413 : Request entity too large,
414 : Request-URI too long, URL이 너무 김
415 : Unsupported media type
500 : Internal server error, 내부서버 오류(잘못된 스크립트 실행시)
501 : Not implemented, 클라이언트에서 서버가 수행할 수 없는 행동을 요구함
502 : Bad gateway, 서버의 과부하 상태
503 : Service unavailable, 외부 서비스가 죽었거나 현재 멈춤 상태
504 : Gateway timeout
505 : HTTP version not supported

by 차까꿍 2016. 7. 2. 02:18

MYSQL 매뉴얼중 Query cache에 대한 내용만을 Study 하기 위해 비공식적으로 

번역한 것을 도움이 될것 같아 올립니다. Tip&Tech 부분이 가장 적당할 것 같아

Tip&Tech에 올립니다. 저자권에 문제가 되는 경우는 바로 삭제 하겠습니다.


정리하면서 수정해서 다시 올립니다. 허접으로 번역해서 도움이 될지 모르겠습니다.


6.9 MySQL Query Cache

==============================

MYSQL 4.0.1 버전부터 Query Cache 개념이 도입되었다.

Query Cache가 사용되면 SELECT Query문과 SELECT 결과를 캐싱처리하고

나중에 동일한 Query 요청이 들어오면 Query문을 실행하지 않고

Query Cache에서 결과를 전달하는 식으로 동작 한다.


Query Cache는 동적인 내용을 많이 사용하는 웹서버 등에서 데이터 변경이 빈번하지

않는 테이블을 대상으로 동일한 Query를 중복해서 사용하는 경우 

매우 유용하다.


아래는 Query Cache의 성능에 대한 일부 자료 이다.

( OS: Linux Alpha  CPU: 2x500 MHZ  RAM: 2GB  Query Cache:64MB 환경의 

      서버에서 MySQL benchmark 에서 생성되었음)

  

  . 실행한 모든 쿼리문들이 단순하지만 (ex 한 레코드만 있는 테이블에서 레코드를 선택하는 쿼리)

    쿼리문이 모두 달라 캐시가 될 수 없는 경우는 Query Cache를 하기 위한 오버헤드가 13%

    증가 했다. 이 경우는 최악의 시나리오로 볼 수 있다. 일반적인 경우 현업에서 Query문은 훨씬 

    복잡하기 때문에 오버헤드는 현저히 줄어든다.

  . 레코드가 하나 있는 테이블의 레코드가 캐시된 후 검색은 238% 빨라졌다. 이는 Query가 캐시된 후

    예상할 수 있는 최소한의 성능향상에 근접한 결과라고 볼 수 있다.

  . Query Cache를 사용하지 않고자 하는 경우 Query_Cache_size=0으로 my.cnf 파일에 설정하면

    된다. Query Cache를 사용하지 않으면 눈에 띄는 오버헤드는 없다.

    ( Query Cache는 컴파일시에 --without-Query-Cache 옵션을 사용해서 제외할 수도 있다.)

    


6.9.1 Query Cache 동작 방식

==============================


동일한 Query문이란?


  MYSQL 서버에 Query문 처리 요청이 들어 오면 Query Cache된 Query문과 같은 Query문 인지 

  비교하는 작업이 먼저 이루어 지는데 이때 Query문의 모든 문자가 일치해야 동일 

  Query문으로 간주 된다.

  따라서 SELECT * FROM TABLE 과 Select * from table 은 다른 쿼리로 간주한다.


  Query문이 일치하더라도 각각 다른 Query문으로 간주되어 따로 캐시 처리 되는 경우도 있는데

  database,프로토콜 버젼,디폴트 character set이 다른 경우이다.

  이때는 각각 다른 Query로 간주되어 각각 캐시 처리 된다.

  


Query Cache의 제외 대상 


   특정 SELECT문은 Query Cache 대상이 되지 않는 경우도 있는데 

      SELECT CALC_ROWS ... 유형의 쿼리와  

      SELECT FOUND_ROWS () ... 유형의 쿼리는 

   Query Cache의 대상이 되지 않는다.


   아래의 함수를 포함하고 있는 SELECT Query문은 캐시 되지 않는다.


   Function 

   -----------------------

   User-Defined Functions        

   CONNECTION_ID       

   FOUND_ROWS

   GET_LOCK  

   RELEASE_LOCK  

   LOAD_FILE  

   MASTER_POS_WAIT  

   NOW  

   SYSDATE  

   CURRENT_TIMESTAMP  

   CURDATE  

   CURRENT_DATE  

   CURTIME  

   CURRENT_TIME  

   DATABASE  

   ENCRYPT (with one parameter)  

   LAST_INSERT_ID  

   RAND  

   UNIX_TIMESTAMP (without parameters)  

   USER  

   BENCHMARK  

   

   Query문에 사용자 변수가 있는 경우와

   SELECT ... IN SHARE MODE 유형의 쿼리

   SELECT * FROM AUTOINCREMENT_FIELD IS NULL(마지막 INSERT된 ID를 가져오기 위해)

   유형의 쿼리도 캐시되지 않는다.

 

   참고로 이전의 Query문의 결과가 캐시에서 가져온 경우라도 FOUND_ROWS()는 정확한 값을 리턴한다.


   또 SELECT Query가 테이블을 대상으로 하지 않는 경우, 

   임시 테이블을 사용하는 경우,

   접속 클라이언트가 Query문 대상의 테이블들중 한 테이블에 대해 컬럼 권한(Column Privilege)을 

   가지고 있는 경우에도 쿼리가 캐시되지 않는다.


Query Cache에 저장된 캐시의 삭제


    테이블이 변경되는 경우(INSERT, UPDATE, DELETE, TRUNCATE, ALTER, DROP TABLE|DATABASE)는 

    해당 테이블(MRG_MyISAM table를 통한 경우도)을 참조한 모든 캐시 데이터가 삭제 되고,

    InnoDb 테이블에서  트랜잭션이 이루어지는 단계에서는 테이블이 변경되는 경우는 

    COMMIT이 실행될때 캐시 데이터가 삭제 된다.


Query Cache 적용시

    Query Cache를 적용시에는 접속클라이언트가 적용할 캐시에 관계된 모든 데이터베이스들과

    테이블들에 대해 SELECT 권한이 있을때만 적용 된다.


6.9.2 Query Cache 환경설정

==============================

Query Cache를 사용하기 위해서는 환경파일의 mysqld 부분이나 mysqld를 커맨트라인에서 실행하는 경우

모두 추가해야 할 사항이 있다.


   . query_qache_limit  결과가 이 값보다 큰 경우 결과를 캐시하지 않는다. ( default 1M)

   . query_qache_size   캐시 하기 위해 메모리상에 확보해야할 메모리 크기

                        이 값이 0이면 Query Cache가 사용되지 않는다.   ( default 0)

   . query_qache_type   숫자형식이며 다음값중 하나가 사용됨

                        0 :  (OFF, 캐시하지 않으며 캐시에서 결과를 가져오지도 않음)

                        1 :  (ON, SELECT SQL_NO_Cache ... 를 제외한 모든 Query 

                                  결과를 캐시함)

                        2 :  (DEMAND, SELECT SQL_Cache ... 쿼리들만 캐시 한다.)

                        


런타임에 thread(connection)에서 동적으로 Query Cache의 기본 동작 방식을 변경할 수도 있는데

문법은 다음과 같다.


Query_Cache_TYPE = OFF | ON | DEMAND 

Query_Cache_TYPE = 0 | 1 | 2 


      (   0 or OFF  : 캐시하지 않으며 캐시에서 결과를 가져오지도 않음

          1 or ON   : SELECT SQL_NO_Cache ... 를 제외한 모든 Query 결과를 캐시함

          2 or DEMAND : SELECT SQL_Cache ... 쿼리들만 캐시 한다.)

          


6.9.3 SELECT 문에서 Query Cache 옵션들

========================================


SELECT문에 Query Cache와 관련되서 두가지 옵션이 첨가 될 수 있다.


SQL_CACHE : Query_Cache_TYPE이 DEMAND인 경우는 Query를 캐시 한다.

            Query_Cache_TYPE이 ON인 경우 default

            Query_Cache_TYPE이 OFF인 경우 의미 없음


 ex> SELECT SQL_CACHE .....

 

SQL_NO_CACHE : Query문이 캐시에 저장되지 못하도록 함.


 ex> SELECT SQL_NO_CACHE ...

 


6.9.4 Query Cache 상태와 유지관리

========================================

FLUSH QUERY CACHE

  FLUSH QUERY CACHE는 Query Cache의 메모리를 조각모음해서 메모리 사용 효율을

  높일때 사용 한다.


FLUSH TABLES

  FLUSH TABLES는 Query Cache를 비운다.


RESET QUERY CACHE

  RESET QUERY CACHE는 Query Cache의 캐시된 모든 쿼리결과를 제거 한다.



Query Cache 지원 여부 확인

  현재 사용하고 있는 MYSQL Version에서 Query Cache가 있는지 여부를 다음과 같이 

  확인 할 수 있다.



  mysql> SHOW VARIABLES LIKE 'have_Query_Cache';

  +------------------+-------+

  | Variable_name    | Value |

  +------------------+-------+

  | have_Query_Cache | YES   |

  +------------------+-------+

  1 row in set (0.00 sec)


Query Cache 성능 모니터

    

 SHOW STATUS 문을 통해 Query Cache의 성능을 모니터 할 수 있다.


 변수                        설명

 ------------------------    ------------------------------------

 QCache_queries_in_Cache    캐시에 등록된 쿼리 갯수. 

 QCache_inserts             캐시에 추가된 쿼리 갯수. 

 QCache_hits                캐시 Hit(적용된) 갯수. 

 QCache_lowmem_prunes       메모리 부족으로 캐시에서 삭제된 쿼리 갯수. 

 QCache_not_Cached          캐시 불가능한 쿼리 갯수(캐시 불가능 하거나 Query_Cache_TYPE에 의해). 

 QCache_free_memory         Query Cache의 비할당 메모리양. 

 QCache_free_blocks         Query Cache의 비할당 메모리 블럭의 갯수. 

 QCache_total_blocks        Query Cache의 총 메모리 블럭 갯수. 


 총 쿼리 수 = QCache_inserts + QCache_hits + QCache_not_Cached


 Query Cache는 동적인 크기의 블럭을 사용하기 때문에  QCache_total_blocks 과

 QCache_free_blocks은 Query Cache의 메모리의 조각화 현상을 보여 준다.

 FLUSH Query Cache 후에는 QCache_free_blocks의 값이 1이 된다.


 NOTE: 각 Query는 최소한 두 블럭(Query문과 Query결과값)을 사용한다. 

       또, Query에 사용된 각 테이블은 한 블럭을 사용하지만, 여러 Query에서 

       같은 테이블이 사용되는 경우에는 한 블럭만 할당 된다.

      

 QCache_lowmem_prunes 값을 참조해서 Query Cache의 크기를 튜닝할 수 있다.

 이 값은 새로운 쿼리를 캐시하기 위해 캐시에서 삭제된 쿼리 갯수인데 Query Cache는

 least recently used(LRU : 최근에 가장 사용빈도가 적음) 전략을 통해 Cache에서

 제거할 쿼리를 결정 한다.

by 차까꿍 2015. 1. 2. 22:36

유행어는 IT업계에서 피할 수 없는 현실이다. 업계에서 30년을 종사한 사람이나(WYSIWYG을 기억하는가?) 5년을 종사한 사람(‘네티켓’ 아는 사람?) 모두 잘 알지도 못하는 IT 용어가 난무하는 일상적인 대화에 참여하고 있을 것이다. 오늘은 현재 사용되고 있는 최신 유행어 8가지를 살펴보도록 하자. 




1. IoT (사물인터넷) 또는 IoE (만물인터넷(Internet of Everything))

IoT는 우리가 일상적으로 사용하는 자동차, 온도계, 가전제품, 피트니스 밴드, 칫솔 등의 기기와 소위 말하는 "사물"이 임베디드(Embedded) 기술과 웹 연결성을 통해 서로 대화를 나누면서 형성된 복잡한 네트워크이다. 이 용어가 10년 이상 사용되기는 했지만 일반 대중은 최근에야 일상 생황에서 그 영향을 느끼기 시작했다.

애디슨 그룹(Addison Group)의 IT 사업부 지사장 제르 레미스는 "머지 않은 미래에 소비자들은 이동 중에 차 안에서 집이 조명을 끄거나 문을 열거나 차고를 열거나 냉장고에 우유가 얼마나 남아 있는지 보고하도록 명령을 내릴 수 있을 것"이라며, "기술이 계속해서 진화하면서 우리 삶의 모든 면이 더욱 연결되고 자동화될 것”이라고 말했다.

이 때문에 IoT는 업계 전문가들이 "파괴적인" 기술 트렌드를 논할 때 빠지지 않고 항상 등장한다. 에릭슨(Ericsson)의 전략 및 고용 책임자 사무엘 사티아나단은 "에릭슨에서 근무하면서 거의 매일 듣고 있다. 커넥티드 차량, M2M 같은 아이디어와 매우 관련성이 깊다"고 설명했다.

ABI 리서치(ABI Research)에 따르면 2014년 무선 통신 기기가 2013년보다 20% 증가한 160억 개를 초과하면서, 어떤 이들은 ‘사물인터넷’ 대신 ‘만물인터넷’이란 용어를 선호하고 있다. 실제로 ABI는 2020년까지 연결형 기기의 수가 지금의 두 배인 409억 개에 다다를 것으로 전망하고 있다. 하지만 MRE 컨설팅(MRE Consulting)의 CIO 켄 피딩턴은 이 용어가 "휴대폰, 전자제품, 차량부터 동물까지 만물이 연결형 기기화되고 있다는 점을 강조하기 위해 ‘사물인터넷’의 의미를 확장한 것에 지나지 않는다"고 지적했다.

2. BYOE (Bring Your Own Everything) 

물론 직원들이 자신의 개인용 휴대폰, 태블릿, 노트북으로 업무를 처리할 수 있도록 허용하는 기업들의 트렌드인 BYOD(Bring Your Own Device)라는 말은 들어 보았을 것이다. 피딩턴은 “웨어러블 기술을 포함하여 모바일 기기가 성장하고 있는 가운데, 일각에서는 새로운 포괄적인 용어로 BYOE(Bring Your Own Everything)를 주창하고 있다"고 말했다.

실제로, 이미 코그니전트 테크놀로지 솔루션즈(Cognizant Technology Solutions)는 환자가 생명 징후, 유전학, 보건 이력, 건강 정도, 신체 용적 지수, 수면 패턴 등에 관한 데이터를 수집할 수 있는 임베디드형 또는 웨어러블 기기의 숫자가 증가하고 있음을 반영하여 BYOHD(Bring Your Own Health Device)"라는 용어를 만들어 내기까지 했다.

3. 듀얼 페르소나(Dual Persona) 

BYOE 덕분에 사람들이 동일한 기기에서 개인 및 비즈니스 용도를 위한 환경을 분리할 수 있는 휴대폰을 의미하는 "듀얼 페르소나"란 말이 등장하게 되었다. 클라우드 IT 관리 솔루션 업체 베리스믹 소프트웨어(Verismic Software)의 사장 겸 CEO 애슐리 레오나드는 "사용자는 업무 및 가정용 프로필을 동시에 보유할 수 있으며, 2개의 페르소나를 분리함으로써 개인 및 기업용 데이터를 분류하고 보호할 수 있다"고 말했다.

4. 웨어러블(Wearable)

구글이 처음으로 증강현실 안경 구글 글래스(Google Glass)에 관한 계획을 공개했을 때, 회의론과 함께 많은 패러디 영상이 등장했다. 심지어 지금도 많은 이들이 기기를 "이상하지만 흥미로운" 것으로 생각하고 있다. 하지만 오늘날 대부분의 웨어러블 기술이 상업적인 성공을 거두지는 못했지만 자동으로 필수적인 정보를 소비, 공유, 전송, 분석, 제공하는 착용형 기기는 더 이상 비현실적이라는 인식이 사라지게 되었다.

"현재로써는 의료 기기부터 새로운 모바일 기술까지 다각도로 개발되고 있는 기술이며 빠르게 확장 및 발전하고 있다."고 레오나드가 말했다.

손목이 웨어러블을 착용하기에 가장 현실적인 부위로 간주되고 있다. 삼성, 소니, 애플 등의 대기업들이 활동 트랙커와 스마트워치 등을 속속 선보이고 있다. 하지만 기업들이 스마트 귀걸이,깔창 센서, 피부 아래에 삽입하는 혈당 측정기, 자세 감지 핀 등을 개발하면서 신체의 모든 부위가 고려되고 있다. IDC에 따르면 웨어러블은 얼리 어답터의 수준을 넘어 섰으며 2014 년 출고량이 1,900만 대를 넘어 지난 해 대비 3배로 증가했으며 2018년에는 1억1천190만 대로 CAGR 의 78.4% 를 차지할 것이라고 한다.

 

5. 자가측정(Quantified Self) 

웨어러블 기술을 둘러 싼 유행이 일각에서 말하는 내 일상에 관한 데이터를 수집하고 이 정보를 이용해 행보를 최적화하려는 움직임인 "자가측정"에 대한 관심을 불러 일으키고 있다. 크리스 댄시는 이 트렌드의 지지자로서 수면, 식사, 감정 등을 포함한 자신의 일상에 관한 데이터를 기록하고 분석하여 100 파운드를 감량하고 하루 2갑씩 피우던 담배를 끊었다고 말했다. 많은 모임과 포럼에서 자신의 삶을 측정하는데 관심이 있는 사람들을 지원하고 있다.

6. XaaS (Everything as a Service) 

피딩턴은 "SaaS(Software as a Service)"부터 시작되었지만 서비스형에 관한 트렌드는 곧 서비스형 플랫폼, 인프라, 스토리지, 통신, 네트워크, 모니터링, 비즈니스 프로세스 등 다양한 영역으로 확산되었다. 이제 많은 사람들이 XaaS("자스"로 발음)라고 말하는 것도 당연하다. 기술 외의 부문에서 "'만물'을 서비스로 사용할 수 있게 되면서 이 용어가 더욱 널리 확산될 것이라 생각한다”고 말했다. 이어, "차(ZIP 카스(ZIP Cars)), 주거공간(에어BnB(AirBnB)), 법률(리걸줌(LegalZoom)) 등이 있으며, 계속해서 더 많이 생겨날 것”이라고 덧붙였다.

한편, 어떤 사람들은 XaaS 보다는 더 전통적인 명명법을 선호한다. 사티아나단은 "개인적으로 이 용어를 좋아하지 않으며 SaaS, PaaS 등 좀 더 구체적으로 사용하는 것이 좋다"고 말했다. 피딩턴은 SaaS를 좋아하는 사람들에게 전통적인 직접설치 애플리케이션을 가져다가 클라우드로 이동하거나 서비스로 제공하는 과정인 "SaaS화(SaaSfied)"라는 동사형을 제안하며 "자사의 핵심 제품을 클라우드로 이동하는 것에 대해 설명하는 벤더로부터 이 용어를 처음 들었다. 그 이후로 이 용어를 사용하고 있다"고 강조했다. 최소한 클라우드화보다는 좀 더 구체적이다.

7. 스몰 데이터(Small Data)

유행어가 절정기에 도달하게 되면 업계 전문가들은 해당 용어 이면의 의미를 다시 생각하고 관련된 더 많은 파생어를 만들어 내는 것이 일반적이다. 피딩턴은 “이 때문에 ‘스몰 데이터’ 또는 ‘다크 데이터(Dark Data)’라는 용어를 들어 보았을 것”이라고 덧붙였다. 때로는 빅데이터가 특정 목적에 과분하기 때문에 많은 사람들이 ‘시의 적절하고 유의미하며, 시각적으로 정리 및 패키지화되어 일상 활동에서 접근, 이해, 실행할 수 있는’ 스몰 데이터에 관해 이야기하기 시작했다.

한편, 패딩턴에 따르면 다크 데이터는 기업들이 수집하지만 경쟁을 목적으로 최적화하지 않는 운영 데이터다. 가트너(Gartner)와 기타 출처에 따르면 다크 데이터의 위험은 비즈니스 기회 상실과 필요 이상의 스토리지 비용부터 보안 위험에 까지 이른다고 한다.

8. 랜섬웨어(Ransomware) 

랜섬웨어란 사용자의 컴퓨터를 감염시키고 일반적으로 몸값을 지불할 때까지 민감한 데이터를 암호화하는 악성 소프트웨어를 의미한. 한 예로 크립토록커(CryptoLocker)는 암호화를 이용해 피해 사용자의 소중한 파일 대부분을 잠근다. 레오나드는 “현재 많은 악성 소프트웨어 변종이 개발되고 있기 때문에 가정 사용자 및 기업들에게 랜섬웨어는 계속해서 골칫거리로 남아있을 것"이라고 말했다.

기업들에게 있어서 이런 종류의 공격은 로컬 드라이브 및 기업 네트워크 데이터가 잠재적으로 암호화될 수 있기 때문에 굉장히 치명적이다. 레오나드는 "추후에 대가를 지불한 많은 피해자들이 데이터를 결국 되찾은 적이 없다고 밝혔다. 모든 네트워크 종점을 능동적으로 관리하고 패치할 수 있는 뛰어난 보안 활동과 탄탄한 IT 관리 기술이 필요하다"고 덧붙였다.

다음 유행어는 어디에서 나올까? 기술 마케터들이 아니라면 ‘디지털 유목민(Digital Native)’ 또는 지속적이며 손쉬운 웹 연결성이 없는 세상이 어떤 곳인지 전혀 모르는 젊은 세대에 답이 있을 것이다. 이 부분과 관련하여 피딩턴은 자신의 12살 아들과 친구들의 대화에 귀를 기울이고 있다. 그래서 그는 ‘느린(Laggy)’이라는 말을 사용한다. 패딩턴은 "아들과 친구들이 인터넷 연결이 느릴 때 이 말을 사용한다. 여러 명이 마인크래프트(Minecraft)를 즐길 때 이 말을 여러 번 들었다"고 말했다.


출처 : http://www.rcy.co.kr/xeb/study/8478

by 차까꿍 2014. 12. 29. 05:25

PHP에서 GCM 멀티캐스트로 발송하는 방법은 정말 간단하게 구현할 수 있습니다.

GCM에서는 한번 발송에 1000개의 디바이스 토큰을 일괄 발송할 수 있는 멀티캐스트 기능이 포함되어 있어, 무척 편리해 졌는데요


100만건을 발송하더라도, 1000회만 커넥션을 맺으면 되므로 발송 속도가 무척이나 빠르겠죠..


우선, PHP에서 GCM발송 라이브러리를 작성합니다.

아래 라이브러리는 Github에서 가져왔습니다.  


GCMPushMessage.php


발송은 send 페이지에서 다음과 같이 작성합니다.


$devices는 Array변수로 디바이스 토큰값을 담아주면 됩니다. (최대 1000개)


만약, 등록건수가 1만건이다...  어떻게 1000으로 나눌수가 있을까요??


PHP에서는 아주 간단한 Array함수를 가지고 있더군요..


1만건을 $devices에 담아 array_chunk 함수로 나누면 되는거죠... 1000건씩...


array_chunk 함수는 아주 간편하게...나눠주니.. 계산할 필요없이 아주 편리하게 사용하면 됩니당@!!


http://php.net/manual/en/function.array-chunk.php


출처 : http://nonstop.pe.kr/php/1674

'프로그래밍 > PHP' 카테고리의 다른 글

PHP ImageMagick convert 를 이용한 이미지 변환  (0) 2016.07.17
by 차까꿍 2014. 12. 5. 09:05
| 1 2 |