sqlrelay (Queue 서버 설치)

 
 

0. Overview
SQL Relay는 강력한 데이터베이스 연결 관리 솔루션입니다SQL Relay를 사용하면 데이터베이스 중심 웹 기반 응용 프로그램의 확장성을 향상시키고 지원되지 않는 플랫폼에서 데이터베이스에 액세스하고데이터베이스 액세스를 제한하고클러스터 된 또는 복제 된 데이터베이스에서로드를 분산하고쿼리를 라우팅하고 한 데이터베이스에서 다른 데이터베이스로 응용 프로그램을 마이그레이션 할 수 있습니다.

- 상황
현재 PHP를 MySQL 직접 연결하여 CRUD 작업이 진행되는데 어떤 순간에는 connection이 대량으로 들어와 DB에 Connection Pool이 발생할 수도 있습니다.
그래서 PHP와 MySQL 사이에 Connection을 Pooling할 수 있는 미들웨어를 두고자 조건을 검색해 보니 php소스를 접속 정보 외에 변경하지 않고 할 수 있는 게 sqlrelay가 있어서 소개하고자 합니다.


1. 장점
- Persistent Connection Pooling : 데이터베이스 기반 웹 기반 응용 프로그램을보다 빠르고 효율적으로 만듭니다.

- Throttling : 데이터베이스가 과부하가되지 않도록 합니다.
- Proxying : 지원되지 않는 플랫폼의 데이터베이스에 대한 액세스를 제공합니다.

- Connection Schedules : 지정된 시간에 데이터베이스 액세스 제한
- Query Routing : 쿼리를 조건부로 하나의 데이터베이스 또는 여러 데이터베이스로 보냅니다.

- Query Filtering : 특정 패턴과 일치하는 쿼리가 전혀 실행되지 않도록 합니다.

- Substitution and Bind Variables : 자주 실행되는 쿼리를 더 빠르고 효율적으로 만듭니다.

- Multi-Row Fetches : 네트워크 왕복 횟수를 줄입니다.

- Suspended Transactions : 단일 트랜잭션을 여러 웹 페이지로 확장 할 수 있습니다.
- High Availability : 복제 또는 클러스터 된 데이터베이스를 사용하여 Load balancing 및 failover 제공
- Database Support : 다양한 상용 및 오픈 소스 데이터베이스가 지원됩니다.
(Oracle, MySQL, PostgreSQL, SAP / Sybase, IBM DB2, Informix, Firebird  SQLite 데이터베이스)

- Abstraction Layer Support  : 가장 널리 사용되는 데이터베이스 추상화 계층의 드라이버가 제공됩니다.
- Native API : 강력한 native SQL Relay 클라이언트 API는 다양한 프로그래밍 언어를 지원합니다.
(C, C ++, .NET 언어, Java, Perl, Python, PHP, Ruby, TCL, Erlang  node.js)

- Client-Side Result Set Caching : 페이징을 보다 빠르고 쉽게 만듭니다.

 
- Drop-In Replacement Libraries : 많은 native MySQL 또는 PostgreSQL 응용 프로그램이 수정 없이 SQL Relay를 사용할 수 있습니다.

2. 우선 사항
설치된 mysql과 동일한 버전의 mysql을 해당 서버에 설치 
(sqlrelay configure시 summary에 mysql : no가 아닌 mysql : dynamic이라는 메시지가 나타나야 나중에 sqlrelay 기동이 가능함.)
- python 2.7 설치 (python 3.X 사용 안함)
- node.js 설치 되어 있지 않아야 함(호환성문제로 sqlrelay make 시 grp error 발생)
- php나 perl등 소스설치가 아닌 yum으로 설치했을 경우 해당 위치 경로를 찾지 못하므로
php를 직접 소스 설치한 후 sqlrelay 설치 시 해당 경로 configure 옵션으로 지정


3. Source 설치
1) sqlrelay에 php와 mysql에 대한 socket 파일을 설치하기 위해 mysql과 php에 대한 소스 설치가 진행합니다.
- mysql 설치
  . mysql binary 파일 업로드(mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz) 
  . my.cnf 파일 작성

[client] port=3306 socket=/tmp/mysql.sock [mysqld_safe] socket = /tmp/mysql.sock nice = 0 [mysqld] user=mysql port=3306 sql-mode=ANSI_QUOTES,STRICT_ALL_TABLES,STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION lc_messages_dir = /mysql/share/ lc_messages = en_US basedir=/mysql socket=/tmp/mysql.sock pid-file=/data/tmp/mysql.pid datadir=/data/var tmpdir=/data/tmp log-error=/data/var/mysql.err slow_query_log_file=/data/var/slow.log slow_query_log=1 long_query_time=3 innodb_data_home_dir=/data/ibdata innodb_log_group_home_dir=/data/ibdata #lower_case_table_names=1 # Character set Config character-set-client-handshake=FALSE character-set-server=utf8 init_connect=SET collation_connection = utf8_general_ci init_connect=SET NAMES utf8 skip-name-resolve=1 log_timestamps=SYSTEM log_error_verbosity=1 # Common Config back_log=1024 ft_min_word_len=4 interactive_timeout=600 join_buffer_size=2M max_allowed_packet=16M max_heap_table_size=1G max_connections=500 max_connect_errors=999999 performance_schema read_buffer_size=2M read_rnd_buffer_size=20M skip-external-locking sort_buffer_size=2M max_length_for_sort_data=1024 tmp_table_size=1024M table_open_cache=2000 transaction-isolation= REPEATABLE-READ open_files_limit = 1024 slave-net-timeout=3 # Innodb config innodb_checksum_algorithm=NONE innodb_buffer_pool_size = 512M innodb_data_file_path=ibdata1:1G;ibdata2:1G;ibdata3:1024M:autoextend innodb_file_per_table=1 innodb_flush_method=O_DSYNC innodb_lock_wait_timeout=10 innodb_log_buffer_size=8M innodb_log_file_size=256M innodb_log_files_in_group=2 innodb_thread_sleep_delay=0 innodb_fast_shutdown innodb_autoinc_lock_mode=1 innodb_thread_concurrency = 4 innodb_read_io_threads = 2 innodb_write_io_threads = 2 innodb_open_files = 1024 innodb_doublewrite=0 innodb_flush_log_at_trx_commit=1 # Query Cache Disable query_cache_type=0 query_cache_size=0 # Replication related settings log-bin=/data/binlog/mysql-bin log_bin_trust_function_creators = 1 expire_logs_days=5 max_binlog_size=100M sync_binlog=1 binlog_cache_size=1M binlog_format=row binlog_row_image=minimal binlog_checksum=none log_slave_updates=1 server-id=1851 gtid_mode=off enforce_gtid_consistency=off binlog-ignore-db=performance_schema binlog-ignore-db=information_schema binlog-ignore-db=sys local-infile=0 [mysqldump] quick max_allowed_packet=64M [mysqladmin] user = root

  . mysql 설치 스크립트 ( setup_binary.sh )

#!/bin/bash stty erase ^H mysql_filename=`ls mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz` mysql_filename2=`echo "${mysql_filename}" |sed "s/.tar.gz//g"` echo "mysql version : ${mysql_filename2}" echo -e "mysql configuration directory : default) /etc" read conf_dir echo -e "mysql configuration file name : default) my.cnf" read conf_file if [ -z ${conf_dir} ]; then conf_dir="/etc" fi if [ -z ${conf_file} ]; then conf_file="my.cnf" fi basedir=`cat my.cnf | grep basedir | cut -d "=" -f 2 | sed 's/ //g'` charset=`cat my.cnf | grep character-set-server | cut -d "=" -f 2 | sed 's/ //g'` datadir=`cat my.cnf | grep datadir | cut -d "=" -f 2 | sed 's/ //g'` datadir2=`cat my.cnf | grep datadir | cut -d "=" -f 2 | sed 's/ //g' | cut -d "/" -f 2` binlog_fullpath=`cat my.cnf | grep log-bin | cut -d "=" -f 2 | sed 's/ //g'` binlog_path=`cat my.cnf | grep log-bin | cut -d "=" -f 2 | sed 's/mysql-bin//g'` echo "========================" echo "configuration " echo "========================" echo "conf_dir : ${conf_dir}" echo "conf_file : ${conf_file}" echo "basedir : ${basedir}" echo "charset : ${charset}" echo "datadir_fullpath : ${datadir}" echo "datadir_name : ${datadir2}" echo "binlog_fullpath : ${binlog_fullpath}" echo "========================" echo -e "Is it correct? (y/n)" read sucess_yn if [ ${sucess_yn} == "n" ]; then exit 0; elif [ ${sucess_yn} == "y" ]; then continue; else echo "not correct stop" exit 0; fi yum -y install zlib curl yum -y install gcc g++ cpp gcc-c++ yum -y install openssl openssl-devel yum -y install libtermcap-devel ncurses-devel libc-client-devel bzip2-devel yum -y install bison yum -y install libaio cp -f my.cnf ${conf_dir}/${conf_file} tar xvzf ${mysql_filename2}.tar.gz if [ -d ${basedir} ]; then mv ${mysql_filename2}/* ${basedir}/ else mv ${mysql_filename2} ${basedir} fi mkdir -p /${datadir2}/ibdata mkdir -p /${datadir2}/tmp mkdir -p /${datadir2}/var mkdir -p /${binlog_path} mysql_group_cnt=`cat /etc/group | grep mysql | wc -l` if [ ${mysql_group_cnt} -eq 0 ]; then groupadd mysql useradd -r -g mysql mysql fi chown -R mysql.mysql ${basedir} chown -R mysql.mysql /${datadir2}/ibdata chown -R mysql.mysql /${datadir2}/tmp chown -R mysql.mysql ${datadir} chown -R mysql.mysql ${binlog_path} ${basedir}/bin/mysqld --defaults-file=${conf_dir}/${conf_file} --basedir=${basedir} --datadir=${datadir} --explicit_defaults_for_timestamp --initialize /mysql/bin/mysqld_safe --defaults-file=${conf_dir}/${conf_file} &

. 하나의 폴더에 위에 3개의 파일이 존재하는지 확인 후 setup_binary.sh 파일 실행

$ ls -al -rw-r--r-- 1 root root 2765 Jul 9 13:57 my.cnf -rw-r--r-- 1 root root 2605 Jul 9 13:55 setup_binary.sh -rw-rw-r-- 1 han han 641798603 Apr 9 14:15 mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz $ /bin/bash ./setup_binary.sh mysql version : mysql-5.7.21-linux-glibc2.12-x86_64 mysql configuration directory : default) /etc mysql configuration file name : default) my.cnf ======================== configuration ======================== conf_dir : /etc conf_file : my.cnf basedir : /mysql charset : utf8 datadir_fullpath : /data/var datadir_name : data binlog_fullpath : /data/binlog/mysql-bin ======================== Is it correct? (y/n)
'y'를 누르면 my.cnf에 환경설정에 맞춰 바이너리파일로 mysql을 설치하게 된다.

- php 설치(가능하다면 실제 웹서버에서 실행되는 버전과 동일한 버전으로 설치)

## module 설치 $ yum -y install gcc gcc-c++ libxml2-devel bzip2-devel libcurl-devel \ gdbm-devel libvpx libvpx-devel libjpeg-turbo-devel libpng-devel libXpm \ libXpm-devel freetype-devel t1lib t1lib-devel gmp-devel libc-client \ libc-client-devel pam-devel libicu libicu-devel openldap-devel \ readline-devel libedit-devel libtidy libtidy-devel libxslt libxslt-devel \ expat* krb5-devel openssl-devel db4-devel ## libmcrypt-2.5.8 설치 $ cd /usr/local/src/ $ wget http://www.atblog.co.kr/file/package/libmcrypt-2.5.8.tar.gz $ tar zxvf libmcrypt-2.5.8.tar.gz $ cd libmcrypt-2.5.8 $ ./configure $ make $ make install $ ln -s /usr/local/lib/libmcrypt.so.4 /usr/local/lib64/libmcrypt.so.4 ## php-5.6.36 설치 $ cd /usr/local/src $ wget http://mirror.cogentco.com/pub/php/php-5.6.36.tar.gz $ tar xzvf php-5.6.36.tar.gz $ cd php-5.6.36 $ ./configure --prefix=/usr/local/php \ --with-config-file-path=/usr/local/php/etc \ --with-mysqli=/mysql/bin/mysql_config \ --with-mysql-sock=/data/tmp \ --with-mcrypt --with-curl --with-openssl \ --with-pcre-regex --with-pdo-mysql \ --with-mysqli --with-mysql=/mysql \ --with-pdo-mysql=shared,/mysql \ --with-mysql --with-zlib --with-gd --with-mhash \ --enable-calendar --enable-exif --enable-ftp \ --enable-mbstring --enable-shmop --enable-soap \ --enable-sockets --enable-wddx --enable-zip \ --enable-dba=shared --enable-mod-charset $ make test $ make install ## php 설정 $ cp php.ini-production /usr/local/php/etc/php.ini $ vi /usr/local/php/etc/php.ini -------------------------------------------------- # 변경전 short_open_tag = Off ;date.timezone = error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT ;error_log = php_errors.log # 변경후 short_open_tag = On date.timezone = Asia/Seoul error_reporting = E_ALL & ~E_NOTIC error_log = /usr/local/php/logs/php_errors.log -------------------------------------------------- # phpinfo 정보 확인 $ vi phpinfo.php <?php phpinfo() ?> # phpinfo 정보 확인 $ /usr/local/php/bin/php ./phpinfo.php > phpinfo.csv # php.ini 폴더 및 extensions 폴더 확인 $ cat phpinfo.csv | grep Configuration -- php.ini 폴더 $ cat phpinfo.csv | grep extensions -- php extensions 폴더

2) sqlrelay 설치
- python 2.7 설치 및 다운로드

#python 2.X로 설치 $ wget https://repo.anaconda.com/archive/Anaconda2-5.1.0-Linux-x86_64.sh $ /bin/bash ./Anaconda2-5.1.0-Linux-x86_64.sh $ wget http://downloads.sourceforge.net/rudiments/rudiments-1.0.7.tar.gz $ wget http://downloads.sourceforge.net/sqlrelay/sqlrelay-1.3.0.tar.gz $ tar xvf rudiments-1.0.7.tar.gz $ tar xvf sqlrelay-1.3.0.tar.gz

- rudiments 설치

$ cd rudiments-1.0.7 $ ./configure --prefix=/app/rudiments $ make $ make install

- sqlrelay 설치

$ cd sqlrelay-1.3.0 $ ./configure --enable-small-code \ --enable-mysql-rpath \ --enable-php-rpath \ --prefix=/app/sqlrelay \ --with-mysql-prefix=/mysql/ \ --with-php-prefix=/usr/local/php/ \ --with-rudiments-prefix=/app/rudiments \ --with-php-ext-dir=/usr/local/php/lib/php/extensions/no-debug-non-zts-20131226 ## --with-mysql-prefix는 my.cnf의 basedir 값을 넣어 준다. ## configure 중 --with-php-ext-dir 옵션이 필요한 이유는 sqlrelay 가 ## PHP의 확장모듈 형태로 설치하기 때문이다. make install 후 php확장 모듈 dir를 ## 살펴보면 sql_relay.so 라는 모듈이 만들어진걸 확인할 수 있다 $ make $ make install

4. 설정

1) sqlrelay 설정파일 수정

$ vi /app/sqlrelay/etc/sqlrelay.conf <?xml version="1.0"?> <!DOCTYPE instances SYSTEM "sqlrelay.dtd"> <instances> <instance id="mysqltest" port="9000" socket="/tmp/mysqltest.sock" dbase="mysql" connections="3" maxconnections="5" maxqueuelength="0" growby="1" ttl="60" endofsession="commit" sessiontimeout="600" runasuser="nobody" runasgroup="nobody" cursors="5" authtier="listener" handoff="pass" deniedips="" allowedips="" debug="none"> <users> <user user="PHP접속ID" password="PHP접속PW"/> </users> <connections> <connection connectionid="mysqltest" string="host='DB_IP';user='DB_ID';password='DB_PW';db='testdb';" metric="1"/> </connections> </instance> </instances>
sqlrelay.conf 설정화일 설명
instance id="mysqltest"
mysqltest라는 id  sqlrelay로 접속하는 것을 의미한다
port="9000"
mysqlrelay가 실행되는 port이며 php에서 접속 시에 이용된다.
socket="/tmp/mysql_relay.socket"
sqlrelay  socket 위치
dbase="mysql"
DB명을 의미하며 사용할 수 있는 DB sqlrelay.dtd에 정의한다.
connections="3"
초기 연결개수를 의미하며,
sqlrelay를 실행시키면 프로세서가 3개가 실행된다는 걸 의미한다.
maxconnections="5"
최대 연결개수를 의미한다.
user="sqltest"
php sqlrelay에 접속할 userid를 의미한다.
password="sqltest"
php sqlrelay 에 접속할 userid 의 패스워드를 의미한다.
string="host:localhost;user=MysqlUser;password=MysqlUserPass;db=MysqlDB;port=3306;
socket=/home/tmp/mysql.sock"
sqlrelay mysql에 접속하는 환경을 설정한다.

- bash 설정

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

$ vi ~/.bash_profile PATH=$PATH:$HOME/bin:/app/sqlrelay/bin/

 2) sqlrelay 시작

# mysql 권한 설정 mysql> create user 'DB_ID'@'DB_IP' identified by 'DB_PW'; mysql> grant all on *.* to 'DB_ID'@'DB_IP'; $ cd /app/sqlrelay/bin $ ./sqlr-start -config ../etc/sqlrelay.conf -id mysqltest ## Process Kill #$ ./sqlr-stop -config ../etc/sqlrelay.conf
Warning
sqlrelay 프로세스를 종료할 때 kill 명령어로 하지 않아야 합니다. kill로 종료시 여분의 파일이 남아 sqlr-start시 제대로 수행이 되지 않을 수 있습니다. 어떤 경우에는 sqlrelay를 재설치해야만 하는 경우도 있음으로 sqlr-stop으로 해당 프로세스를 종료하여 주시기 바랍니다.

3) php 서버 설정 ( sqlr-start에 이상이 없다면 php.ini 설정 )

$ vi /usr/local/php/etc/php.ini ; extension=/path/to/extension/msql.so ; ; If you only provide the name of the extension, PHP will look for it in its ; default extension directory. extension=sql_relay.so

5. 테스트
1)  테스트 php code 작성

<?php $con = sqlrcon_alloc("localhost", 9000, "", "PHP접속ID", "PHP접속PW", 0, 1); $cur = sqlrcur_alloc($con); if(!sqlrcur_sendQuery($cur, "select * from sbtest1 limit 1")) { echo sqlrcur_errorMessage($cur); echo "n"; } sqlrcon_endSession($con); for($row=0; $row<sqlrcur_rowCount($cur); $row++) { for($col=0; $col<sqlrcur_colCount($cur); $col++) { echo sqlrcur_getField($cur,$row,$col); echo ","; } echo "n"; } sqlrcur_free($cur); sqlrcon_free($con); ?>

2) 결과 수행

$ /usr/local/php/bin/php /data/theswice/test_select.php 1,856657,83868641912-28773972837-60736120486-75162659906-27563526494-20381887404-41576422241-93426793964-56405065102-33518432330,67847967377-48000963322-62604785301-91415491898-96926520291,n

!!conclusion
정상적으로 데이터가 수행된 것을 확인 할 수 있다delete쿼리와 insert쿼리로도 변경하여 수행해 보니 쿼리문은 sqlrelay를 통해 정상적으로 수행되었다마지막으로세션이 단번에 여러개를 가지고 들어올 때 큐에 풀링하는지 테스트가 필요하다.

참조
http://sqlrelay.sourceforge.net/sqlrelay/admin/configguide.html

[출처] https://m.blog.naver.com/PostView.nhn?blogId=theswice&logNo=221288060773&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED