분산 데이터베이스(쿼리 빌더 20)


분산 지원

데이터 액세스 계층은 읽기-쓰기 분리를 포함하여 분산 데이터베이스를 지원합니다. 분산 데이터베이스를 활성화하려면 데이터베이스 구성 파일에서 배포 매개변수를 활성화해야 합니다.

return [
    // 启用分布式数据库
    'deploy'    =>  1,
    // 数据库类型
    'type'        => 'mysql',
    // 服务器地址
    'hostname'    => '192.168.1.1,192.168.1.2',
    // 数据库名
    'database'    => 'demo',
    // 数据库用户名
    'username'    => 'root',
    // 数据库密码
    'password'    => '',
    // 数据库连接端口
    'hostport'    => '',
];

분산 데이터베이스를 활성화한 후 호스트 이름 매개변수는 호스트 이름의 수에 따라 분산 데이터베이스의 수를 결정합니다. 기본적으로 첫 번째 주소는 주 서버입니다.

마스터 및 슬레이브 서버는 다음을 포함한 다양한 연결 매개변수 설정을 지원합니다.

데이터베이스문자 집합

마스터 서버와 슬레이브 서버의 위 매개변수가 일치하는 경우 하나만 설정하면 됩니다. 다른 매개변수의 경우 별도로 설정할 수 있습니다. 예:

return [
    // 启用分布式数据库
    'deploy'   => 1,
    // 数据库类型
    'type'     => 'mysql',
    // 服务器地址
    'hostname' => '192.168.1.1,192.168.1.2,192.168.1.3',
    // 数据库名
    'database' => 'demo',
    // 数据库用户名
    'username' => 'root,slave,slave',
    // 数据库密码
    'password' => '123456',
    // 数据库连接端口
    'hostport' => '',
    // 数据库字符集
    'charset'  => 'utf8',
];

동일하거나 각각 설정해야 합니다.

분산 데이터베이스 매개변수는 배열 정의 사용을 지원합니다(일반적으로 여러 계정과 비밀번호의 구문 분석 오류를 방지하기 위해). 예:

return [
    // 启用分布式数据库
    'deploy'   => 1,
    // 数据库类型
    'type'     => 'mysql',
    // 服务器地址
    'hostname' =>[ '192.168.1.1','192.168.1.2','192.168.1.3'],
    // 数据库名
    'database' => 'demo',
    // 数据库用户名
    'username' => 'root,slave,slave',
    // 数据库密码
    'password' => ['123456','abc,def','hello']
    // 数据库连接端口
    'hostport' => '',
    // 数据库字符集
    'charset'  => 'utf8',
];

읽기 및 쓰기 분리

분산 데이터베이스의 읽기 및 쓰기 여부도 설정할 수 있습니다. 기본적으로 읽기와 쓰기는 분리되지 않습니다. 즉, 마스터-슬레이브 데이터베이스의 경우 읽기와 쓰기 분리를 설정해야 합니다. 이는 다음 설정을 통해 수행할 수 있습니다. :

    'rw_separate' => true,

읽기 및 쓰기 분리의 경우 이 경우 기본 첫 번째 데이터베이스 구성은 데이터 쓰기를 담당하는 마스터 서버의 구성 정보입니다. master_num 매개변수를 설정하면 다중 쓰기를 지원할 수 있습니다. 마스터 서버(매번 마스터 서버 중 하나가 무작위로 연결됨) 다른 주소는 모두 데이터베이스에서 가져온 것이며 데이터 읽기를 담당하며 개수에는 제한이 없습니다. 슬레이브 서버에 연결하고 읽기 작업을 수행할 때마다 시스템은 슬레이브 서버에서 무작위로 선택합니다. 동일한 데이터베이스 연결에 대한 각 요청은 마스터 서버와 슬레이브 서버를 한 번만 연결합니다. 특정 요청에 대한 슬레이브 서버가 연결되지 않으면 쿼리 작업을 위해 자동으로 마스터 서버로 전환됩니다.

임의의 읽기를 원하지 않거나 어떤 경우에는 다른 슬레이브 서버를 일시적으로 사용할 수 없는 경우, 읽기 작업을 위한 고정 서버를 지정하기 위해slave_no를 설정할 수도 있습니다. 호스트 이름은 0부터 시작합니다.

쿼리 클래스나 모델의 CURD 작업을 호출하면 시스템은 현재 실행 중인 메서드가 읽기 작업인지 쓰기 작업인지 자동으로 확인하고 기본 SQL을 사용하는 경우 마스터-슬레이브 서버에 자동으로 연결합니다. 시스템의 기본 규칙에 주의해야 합니다. 쓰기 작업은 데이터베이스의 실행 방법을 사용해야 하며, 읽기 작업은 데이터베이스의 쿼리 방법을 사용해야 합니다. 그렇지 않으면 마스터-슬레이브 읽기 및 쓰기 혼란이 발생합니다.

다음 상황이 발생하면 메인 서버가 자동으로 연결됩니다.

1. 데이터베이스의 쓰기 작업 방법(실행/삽입/업데이트/삭제 및 파생 방법)이 사용됩니다.

2. 메소드가 호출되면 자동으로 마스터 서버에 연결됩니다.

3. 슬레이브 서버의 연결이 실패하면 자동으로 마스터 서버에 연결됩니다.

5. 쿼리 생성자의 master/readMaster 메소드를

Master라고 합니다. 데이터베이스의 데이터 동기화 작업은 프레임워크에서 구현되지 않으며 데이터베이스는 자체 동기화 또는 복제 메커니즘을 고려해야 합니다. 대용량 데이터나 특별한 상황으로 데이터를 쓴 후 동기화 지연이 발생할 수 있는 경우 master() 메서드를 호출하여 기본 데이터베이스를 쿼리할 수 있습니다.

실제 프로덕션 환경에서는 많은 클라우드 호스트의 데이터베이스 분산 구현 메커니즘이 로컬 개발과 다르지만 일반적으로 다음 두 가지 방법이 사용됩니다.

첫 번째: 쓰기 IP 및 읽기 IP 제공(일반적으로 가상 IP) 데이터베이스에서 읽기-쓰기 분리 작업을 수행합니다.

두 번째: 데이터베이스에 연결하기 위해 항상 동일한 IP를 유지하며 읽기-쓰기 분리 IP 스케줄링이 내부적으로 수행됩니다(Alibaba Cloud는 이 방법을 채택합니다).

대도서관 독서

어떤 경우에는 기본 데이터베이스에서 직접 데이터를 읽어야 합니다. 예를 들어 데이터가 방금 작성된 후 슬레이브 데이터베이스 데이터가 동기화될 시간이 없었습니다.

Db::name('user')
    ->where('id', 1)
    ->update(['name' => 'thinkphp']);
Db::name('user')
    ->master(true)
    ->find(1);

그러나 실제 상황은 다음과 같습니다. 후속 메서드에 여전히 관련된 쿼리 작업이 있는지 여부가 분명하기 때문에 이보다 훨씬 더 복잡합니다. 이 때 데이터베이스를 열도록 read_master 구성 매개변수를 구성할 수 있습니다.

// 开启自动主库读取
'read_master' => true,

설정한 후 특정 데이터 테이블에 쓰기 작업을 수행하면 현재 요청의 테이블에 대한 모든 후속 쿼리는 기본 라이브러리를 사용하여 읽습니다.

dsn