>백엔드 개발 >PHP 튜토리얼 >phalapi에서 데이터베이스 읽기와 쓰기를 분리하는 방법

phalapi에서 데이터베이스 읽기와 쓰기를 분리하는 방법

*文
*文원래의
2017-12-23 16:41:182036검색

읽기-쓰기 분리는 많은 대규모 프로젝트에서 일반적으로 사용되는 솔루션으로, 대량의 읽기 작업이 발생할 때 데이터베이스 병목 현상 문제를 해결할 수 있습니다. 그렇다면 읽기 및 쓰기 분리를 통해 데이터베이스 배포를 구축하는 방법과 터미널은 읽기 및 쓰기 분리 작업을 어떻게 수행합니까? 이 기사에서는 예제를 통해 phalapi를 기반으로 읽기 및 쓰기 분리 구현을 설명합니다.

1. 읽기와 쓰기의 분리

우리는 퇴근 후 출퇴근 시간의 교통 문제와 같은 동시성 문제에 직면합니다. 사람들은 문제의 일부를 해결하기 위해 신호등을 사용합니다(하지만 매우 고통스럽습니다. (질의시 차단과 동일), 업데이트 작업은 10초, 선택 작업은 10초 소요됩니다.) 그러면 사람들은 고가도로의 경로가 일반 경로와 일치하는 방식으로 생각하게 됩니다. (데이터는 동일합니다.) 고가도로는 두 개의 도로로 나누어져 있고 한 도로의 자동차는 다른 도로로 이동할 수 없습니다(읽기와 쓰기가 분리되어 있음). 이는 우리의 일반적인 동시성 문제를 해결합니다

실제로는 위의 솔루션이 더 좋지만 이렇지는 않습니다. 두 개의 도로가 있지만 실제로는 그 너비가 다릅니다. 여기서는 하나를 쓰기 경로라고 부르고 다른 하나를 읽기 경로라고 부릅니다. 기하급수적으로 넓어지는 것은 매우 간단한 문제(즉, 여러 개의 슬레이브 라이브러리)이지만 쓰기 경로를 설정하는 것은 가능하지만 이 쓰기 경로를 확장하는 것은 어렵습니다.

1.1 mysql 마스터-슬레이브 구성

저는 Alibaba Cloud의 다중 읽기 라이브러리 서비스를 사용합니다. 여기서는 Baidu의 mysql 마스터-슬레이브 처리 경험을 인용합니다


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


MYSQL [한 호스트의 여러 인스턴스에 대한 마스터-슬레이브 구성]

1. 계정 만들기

mysql 데이터베이스에 들어가서 슬레이브 데이터베이스 백업 계정을 만듭니다

mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave_test'@'10.19.194.57' IDENTIFIED BY 'Password@123456';
mysql>FLUSH PRIVILEGES;   ---刷新

이 명령에 대한 자세한 내용은 grant create user 명령을 참조하세요


2. 이미 실행 중인 인스턴스가 있으면(mysql이 처음에 설치되어 있으므로 기본 인스턴스가 있음) 다른 인스턴스를 시작합니다. 방법은 다음과 같습니다.

(1) shell>cd /usr/ local/mysql/

(2) 쉘>mkdir -pv /data/mysql2

(3) 쉘>chown -R mysql.mysql /data/mysql2

(4) 쉘>./scripts/mysql_install_db --user =mysql --datadir=/data/mysql2 이 단계는 디렉토리를 초기화하고 인스턴스를 생성하는 것을 의미합니다.

3. /etc/my.cnf 구성, 구성 방법은 다음과 같습니다

[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = root
[mysqld] ## 本来mysql配置
server-id = 1
port = 3306
socket = /data/mysql/mysql.sock
datadir = /data/mysql
pid-file = /data/mysql/wzj.pid
log-error = /data/mysql/wzj.err
log-bin = /data/mysql/log/bin-log
log-bin-index = /data/mysql/log/mysql-bin.index
user = mysql
[mysqld2]  ##创建实例配置
server-id = 2
port = 3307
socket = /tmp/mysql2.sock
datadir = /data/mysql2/                         //mysql2存储数据库的地方,也就是实例
pid-file = /data/mysql2/mysql2.pid       //mysql2的pid文件记录
log-error = /data/mysql2/mysql2.err     //为错误日志文件的地方
user = mysql
#master-host =10.19.194.57
#master-user ='wzj_slave_test'
#master-pass ='Password@123456'
#master-port =3306
#master_connect_retry=60
#replicate-do-db =mysql_wzj
#replicate-ignore-db=mysql--------该段已注释,因为新版本中,需要用CHANGE MASTER TO 命令去设置

[참고]: 위 파일의 디렉터리는 모두 수동이 아닌 시스템에서 생성됩니다. 구성 파일을 설정한 후 mysql을 다시 시작하면 파일이 자동으로 생성됩니다.


4. 다시 시작하면 msyql_multi 명령을 사용하여 시작할 수 있습니다. 그런 다음 마스터 기본 데이터베이스의 상태를 확인합니다. Binlog_Do_DB는 백업할 데이터베이스를 나타내고, Binlog_Ignore_DB는 백업하지 않는 데이터베이스를 나타냅니다.

shell>/etc/rc.d/init.d/mysqld start/stop/restart
shell>/usr/local/mysql/bin/mysqld_multi start 1-2  启动实例 (1-2表示启动1、2两个实例)
shell>mysql master: mysql -P 3306 -u root -p -S /data/mysql/mysql.sock (密码:1)
mysql>show master status; or show master status \G;   显示主库的状态,其中File 和Position 数值要记住,下面的mysql语句要用到,用于设置从库

5.

shell>slave:mysql -P 3307 -u root -p -S /tmp/mysql2.sock (密码:回车)   ---另外开个远程
mysql>CHANGE MASTER TO
mysql> MASTER_HOST='10.19.194.57',  ---主库的地址
mysql>MASTER_USER='wzj_slave_test',  ---主库用户
mysql>MASTER_PASSWORD='Password@123456',   ---主库的密码
mysql>MASTER_LOG_FILE='bin-log.000013' ,  ---此参数为master status中的File值
mysql>MASTER_LOG_POS=120;   ---此数值为Position数值

6. 설정 후 startslave를 실행하세요. 아래 그림의 빨간색 선이 YES이면 성공한 것입니다. 그렇지 않으면 구성 파일이 올바른지 확인하세요.

slave_io_running  :yes
slave_sql_running :yes

7. 슬레이브 라이브러리에서 mysql 프로세스 정보를 확인할 수 있습니다.

mysql>show processlist;

8. Test

메인 라이브러리에 새 데이터베이스를 생성한 후 슬레이브 라이브러리에 동기화가 되는지 확인해보세요~

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


1.2가 구현되기 시작했습니다

생각에 대한 논의가 끝났고 모두가 어느 정도 이해했다고 생각합니다. 그런데 phalapi에서 읽기와 쓰기의 분리를 어떻게 구현합니까?

1. dbs.php와 마찬가지로 php는 이 읽기 라이브러리의 구성 항목만 연결하고 등록합니다

//读库
DI()->read = function (){
    $debug = !empty($_GET['__sql__']) ? true : false;
    return new PhalApi_DB_NotORM(DI()->config->get('read'), $debug);
};

2. PhalApi_Model_NotORM 파일

/**
 * 快速获取ORM实例,注意每次获取都是新的实例
 */
protected function getORM($id = NULL){
    $table = $this->getTableName($id);
    if($id == 'read'){
        return DI()->read->$table;
    }
    return DI()->notorm->$table;
}

3에서 getORM을 수정합니다. $this->getORM('모델 레이어에서 읽기')를 사용하면 읽기 라이브러리가 사용되고 $this->getORM()은 기본적으로 쓰기 라이브러리를 사용합니다

//select操作
$this->getORM('read')->select('*')->where('aId', $aId)->fetchAll();
//insert,update,delete操作
$this->getORM()->insert();

2.

멀티 라이브러리 처리가 왜 필요하냐고 물으시는 분들도 계실텐데요. 모든 테이블이 배치되어 있으니 빨리 라이브러리가 있으면 좋을까요?

남의 아웃소싱 프로젝트를 리팩토링하던 중, 테이블이 100개가 넘는데 노트도 없는 라이브러리를 만났습니다. 문서가 없고 읽기가 거의 불가능합니다. 상대적으로 큰 프로젝트를 수행할 때 우리는 업무에 따라 라이브러리를 하위 라이브러리로 분해하는 방법도 고려했습니다. 혼란스러운 구조로 인해 언제든지 하위 라이브러리를 이식할 수 있습니다. MySQL에 많은 부담이 가해지면 mysql의 이 하위 라이브러리를 여러 mysql로 ​​분해하여 부담을 덜어줄 수 있습니다.

위의 소개를 읽은 후, 그렇게 하면 얻을 수 있는 이점은 모두가 이해한다고 생각하지만, 어떻게 구현하면 스마트하게 위와 같이 추가 데이터베이스 연결을 곧 등록할 것이라고 생각할 수도 있습니다. 사실 절반은 맞습니다. 이러한 유형의 작업을 사용하려면 통합 사양이 필요합니다


1. 데이터베이스 연결을 초기화하고 동일한 dbs.php 복사본을 복사하여 개발자 라이브러리

//开发者库
DI()->developers = function (){
    $debug = !empty($_GET['__sql__']) ? true : false;
    return new PhalApi_DB_NotORM(DI()->config->get('developers'), $debug);
};

2에 연결하도록 drivers.php를 구성합니다. PhalApi_Model_NotORM 파일

/**
 * 快速获取ORM实例,注意每次获取都是新的实例
 */
protected function getORM($id = NULL){
    $table = $this->getTableName($id);
    if($id == 'developers'){
        return DI()->developers->$table;
    }
    return DI()->notorm->$table;
}

3. 이전에 공개 일반 파일을 만들지 않았나요?
--General                   //公用目录
    --developers                //通用项目库目录
        --Domain                //项目库Domain层
        --Model             //项目库Model层

然后我们在这里的Model进行的操作都是使用$this->getORM('developers')进行操作


这样规范的好处就是在与共享和模块化 让正常的一个Model层不会使用到任何不同库的操作,我们多个项目用到其他的一个库可以进行代码复用,

相关推荐:

详解MySQL的主从复制、读写分离、备份恢复

php实现带读写分离功能的MySQL类完整实例

phalapi-缓存的使用以及redis拓展

위 내용은 phalapi에서 데이터베이스 읽기와 쓰기를 분리하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.