강좌게시판

제목 CI4에서 Database Master / Replica(Slave) 나눠서 사용하기
글쓴이 ☞한빛★가람 작성시각 2021/10/09 09:04:02
댓글 : 4 추천 : 0 스크랩 : 0 조회수 : 18467   RSS

안녕하세요, 이번에 아직 오픈하지 않은 대규모 서비스(?)를 CI4로 운용하게 되면서 DB분리를 진행하며 겪게 된 고충에 대해서 강좌 게시판에 털어보고자 합니다.

그리고 아이디를 제가 잊어버려서 비밀번호 찾기를 눌렀더니 아이디를 입력하라고 해서 그냥 아이디를 시원하게 하나 다시 팠습니다.

프레임워크에서 DB분리, 참 쉽지가 않은데요.

Pure한 PHP를 사용할 때와 달리 CI에서는 MVC 방식으로 접근을 해야하고, 프레임워크가 정해주는 방식을 따라가야 하기 때문에 참 어려움이 많았습니다.

관련하여 해결한 방법을 여기에 남겨드립니다.

 

해외 쪽에서도 CI로 DB를 분리해서 사용한다는 글은 있지만, 다 CI3까지로 한정되는게 제가 3를 써보질 않아서 잘 모르겠습니다.

 

각설하고 시작하겠습니다.

 

1. 먼저 .env 파일을 수정을 진행해야합니다.

<>

database.default.hostname =
database.default.database =
database.default.username =
database.default.password =
database.default.DBDriver = MySQLi

<>

이 부분 아래에 다음과 같은 부분을 추가합니다.

<>

database.default.hostname =
database.default.database =
database.default.username =
database.default.password =
database.default.DBDriver = MySQLi

# 대충 여기가 아래입니당
database.replica.hostname =
database.replica.database =
database.replica.username =
database.replica.password =
database.replica.DBDriver = MySQLi

<>

 

저는 세션을 사용하지 않고 RestAPI 방식의 토큰을 차용하여 사용했기 때문에 기본을 Replica로 잡았는데요.

이렇게 잡으면 DB세션 등을 사용하는 분들께 문제가 있습니다.

 

그래서 저는 Master를 그냥 기본으로 잡고 글을 적습니다.

안되면 알아서 적당히 수정해서 쓰시면 됩니다

각 DB와 마스터/레플리카를 구현하는 부분은 생략하겠습니다. 이거 쓰면 제가 글을 쓰다가 말 것 같습니다.

 

그 다음! Config/Database.php 에 들어가서 다음 구절을 추가합니다.

public $default = [

대충 기본 DB 설정하는 부분이 끝나면...

<>

/**
     * The Replica database connection.
     *
     * @var array
     */
    public $replica = [
        'DSN'      => '',
        'hostname' => 'localhost',
        'username' => '',
        'password' => '',
        'database' => '',
        'DBDriver' => 'MySQLi',
        'DBPrefix' => '',
        'pConnect' => false,
        'DBDebug'  => (ENVIRONMENT !== 'production'),
        'charset'  => 'utf8',
        'DBCollat' => 'utf8_general_ci',
        'swapPre'  => '',
        'encrypt'  => false,
        'compress' => false,
        'strictOn' => false,
        'failover' => [],
        'port'     => 3306,
    ];

<>

 

네, 이제 모든 준비는 끝났습니다.

Replica를 위한 전용 모델을 구축해야합니다.

App/Model 에 ReplicaModel.php 를 생성합니다.

<>

<?php
namespace App\Models;
use CodeIgniter\Database\ConnectionInterface;
use CodeIgniter\Model;
use CodeIgniter\Validation\ValidationInterface;
use Config\Database;

class ReplicaModel extends Model{
    protected $DBGroup = 'replica';
    public function __construct(ConnectionInterface &$db = null, ValidationInterface $validation = null)
    {
        parent::__construct($db, $validation);
    }
}

<>

 

이렇게 하면 Replica와 Master를 나눠서 관리하 수 있습니다.

대신 상속을 해줘야해서 모델을 나눠서 관리해야하기 때문에 불편한데요.

 

이럴 때를 위한 해답이 있습니다... 만 추천하지는 않습니다.

<>

<?php
namespace App\Models;
use CodeIgniter\Database\ConnectionInterface;
use CodeIgniter\Model;
use CodeIgniter\Validation\ValidationInterface;
use Config\Database;

class BaseModel extends Model{
    protected $validation = null;
    public function __construct(ConnectionInterface &$db = null, ValidationInterface $validation = null)
    {
        $this->validation = $validation;
        parent::__construct($db, $validation);
    }

    public function databaseToReplica()
    {
        $db = Database::connect('replica');
        parent::__construct($db, $this->validation);
    }

    public function databaseToMaster()
    {
        $db = Database::connect('default');
        parent::__construct($db, $this->validation);
    }
}

<>

 

선택은 여러분의 몫입니다. 감사합니다.

 

 다음글 빠른시작 시즌2 php8.1 & CI4 (1)
 이전글 PHP 서킷브레이커, ganesha 구현 방법입니다. (3)

댓글

테러보이 / 2021/10/09 09:34:49 / 추천 0
좋은 자료 감사합니다!
PureAni / 2021/11/04 12:16:32 / 추천 0

https://github.com/yks118/Manana-CMS-for-Codeigniter/blob/master/app/Models/BaseModel.php

이렇게 BaseModel 하나 만드셔서 쓰셔도 괜찮습니다.

☞한빛★가람 / 2021/11/04 12:53:31 / 추천 0
@PureAni 게시물 맨 아래에 베이스 모델 있습니다!
일단 제가 기본적으로 모델을 나눠서 관리하고 통합적으로 베이스모델을 바꾸지 않는 이유가..
CI버전이 증가함에 따라 언제든지 내부 로직이 바뀔 수 있다는 점을 감안하여 위에 올려주신 리포지토리 주소처럼 진행하지는 아니하였습니다.
프레드윤 / 2021/12/31 00:55:05 / 추천 0
오! 가람님! 좋은팁 감사해요