DB Read / Write 분리

왱구·2024년 3월 20일
0

스터디

목록 보기
18/21

1. DB Read / Write?

  • 클라이언트(사용자)는 DB에 Read(Select), Write(Update, Insert, Delete) 요청을 하게된다.
  • Select문은 Update, Insert, Delete문 의 사전작업 이기도 하고
    상대적으로 Select문이 Update, Insert, Delete문 보다 요청도가 많을수 밖에 없다.
  • 또 DB에서 가용하는 리소스는 Update, Insert, Delete문에서 더 많이 잡아먹고 트래픽도 더 많이 발생한다

2. DB Read / Write 분리 (DB Replica)

그래서 DB Replica(복제DB)이라는 개념을 도입 하게 된다

  • Select문은 요청도가 많아도 DB입장에서는 라이트하고 데이터도 변형이 안되기 때문에 트랜잭션도 유지할 필요 없다
    따라서 복제된 DB에서 Select조회작업을 한다면 분산작업으로 DB의 부담이 덜게된다

  • 이 작업은 보안상의 이유로도 접근이 가능하다. 접근권한을 통제함으로서 일반적 데이터만 참고하는 개발자들에게는 DB Replica만 제공하고, 실질적 개발자들에게는 원본DB를 제공하여 개발인원 외의 인원이 함부로 DB를 위변조 하지 못하게 통제가 가능하다.

  • 그런데 백엔드 입장에서는 개발자가 실제로 원본DB 복제DB 구분을 해야하는데 이는 실수가 발생할 수 밖에 없게된다

  • 그래서 ORM에서는 보통 편의성으로 resolver를 제공하는데 여기서는golang의 ORM인 GROM의 resolver를 알아보겠다


3. DBResolver

https://gorm.io/ko_KR/docs/dbresolver.html
https://github.com/go-gorm/dbresolver

  • 개발자가 어떤 정책(Policy)을 세워놓으면 그 정책에 해당하는 쿼리에 대해서 DB를 구분해서 접속하게 해준다
  • 처음 생성한 DB하나로 작업하면 ORM이 알아서 DB접속을 분배해준다
import (
  "gorm.io/gorm"
  "gorm.io/plugin/dbresolver"
  "gorm.io/driver/mysql"
)

DB, err := gorm.Open(mysql.Open("db1_dsn"), &gorm.Config{})

DB.Use(dbresolver.Register(dbresolver.Config{
  // use `db2` as sources, `db3`, `db4` as replicas
  Sources:  []gorm.Dialector{mysql.Open("db2_dsn")},
  Replicas: []gorm.Dialector{mysql.Open("db3_dsn"), mysql.Open("db4_dsn")},
  // sources/replicas load balancing policy
  Policy: dbresolver.RandomPolicy{},
  // print sources/replicas mode in logger
  ResolverModeReplica: true,
}).Register(dbresolver.Config{
  // use `db1` as sources (DB's default connection), `db5` as replicas for `User`, `Address`
  Replicas: []gorm.Dialector{mysql.Open("db5_dsn")},
}, &User{}, &Address{}).Register(dbresolver.Config{
  // use `db6`, `db7` as sources, `db8` as replicas for `orders`, `Product`
  Sources:  []gorm.Dialector{mysql.Open("db6_dsn"), mysql.Open("db7_dsn")},
  Replicas: []gorm.Dialector{mysql.Open("db8_dsn")},
}, "orders", &Product{}, "secondary"))
* DSN data source naming : DB연동 시 데이터소스 - DB에 한정
* Connection String : DB연동 시 데이터소스 - DB에 한정되지 않는경우 있음
profile
늦깎이 애아빠 개발지망생

0개의 댓글