RDBMS 즉 관계형 데이터베이스 시스템는 DBMS 즉 데이터베이스의 한 종류로써, 테이블 기반의 데이터 베이스이다. 일반적으로 우리가 흔히 사용하는 MySQL을 생각하면 된다. 테이블과 칼럼으로 구성되어 있고, 그 테이블 간에 관계 설정(외래키, JOIN 등의 개념)이 가능한 것이다.
데이터베이스에 대한 개념들 중 transaction에 대해서는 이미 정리한 적이 있다.(블로그 링크 참고)
서비스의 사용자가 늘어나면서, 자연스레 서버와 데이터베이스간의 통신이 늘어날 것이다. 따라서 데이터베이스도 이에 대응하여야 한다. 따라서 Database의 scalability, techniques to Sclae 를 정리해 보려 한다.
Replication
Master-Slave replication
일종의 메인DB와 이를 복제한 보조DB 개념으로 생각해보면 된다. 메인은 읽기와 쓰기가 가능한 DB이며, 해당 DB의 부하를 방지하기 위해 복제한 보조DB는 읽기 기능만 제공한다. 이 때 보조DB는 마치 나무처럼 또 다른 보조DB를 복제생성할 수 있다. 이 때 메인 DB가 오프라인 상태가 되면 해당 서비스는 읽기 기능만 제공하게 된다.(보조DB만 남게되므로)
이러한 문제를 해결하려면 보조 DB가 메인 DB로 승격되거나 새로운 메인DB가 등장해야 한다. 이 때 해당 기술의 단점이 드러나는데, 보조DB가 메인 DB로 승격될 때 추가적인 로직이
Master-master replication
서로 협력해서 작동하는 메인 DB가 복제되어 생기는 것이다. 따라서 하나의 DB가 다운되어도, 서비스의 기능은 문제없이 작동될 수 있다.
문제점
- 어느 DB에서 write 작업이 이루어 저야 하는지를 결정하기 위해서, 로드밸런서를 사용하거나 로직을 바꾸어야 한다,
- 대부분의 Master-master system은 트랜잭션의 특징 중 하나인 일관성이 약화될 수 있으며, 동기화되는 과정으로 인해 write작업에 지연될 가능성이 있다.
- 위의 문제점들로 인해 충돌이 발생하고 이를 해결해야할 경우가 늘어난다.
Replication 방식의 공통 문제점
- 새롭게 작성된 데이터가 다른 노드로 복사되기 전에 메인 DB가 다운되면, 데이터를 잃을 가능성이 존재한다.
- write 작업은 read replicas에서 재생되는데. 이로인해, write 작업이 많은 경우, write 작업의 실행이 지연되게 되고, 이에 따라서 read 작업에도 문제가 발생할 수 있다.
- read slaves node가 많을 수록, 복제에 걸리는 시간이 많이 소요된다.
- 어떠한 시스템에서, write작업은 병렬적으로 실행될 수 있도록 멀티스레드가 가능하지만, read replicas에서는 싱글스레드를 통한 순차적인 write작업만 가능하다
- 하드웨어와 이의 복잡한 작업이 요구된다.
Federation
이는 데이터베이스를 기능에 따라 나누어서 관리하는 분산형 시스템이라고 볼 수 있다. 하나의 통합된 데이터베이스가 아닌, 기능에 따라 여러개의 데이터베이스를 운영하는 것이다. 이로 인해서 각 데이터베이스에 몰릴 수 있는 트래픽을 분산하는 것이다. 하나의 큰 데이터베이스에 순차적으로 작업이 진행되는것이 아니라, 기능에 따라서 동시에 병렬적으로 데이터 통신이 가능하다.
문제점
- 만약에 우리가 하나의 큰 기능을 하는 테이블을 필요로 하는 스키마를 짠다면 federation은 효과적이지 않다.
- 어느 데이터베이스와 통신을 해야하는지를 결정하기 위한 로직을 설정해야 한다.
- 두개의 데이터베이스 간에 Join 하는 것은 매우 복잡하다.
- federation 또한 replication처럼 더 많은 하드웨어와 함께 복잡성이 더해진다.
Sharding
federation과 비슷하지만 다른 개념이다. 위의 그림을 보면 확실히 이해가 될 것이다. federation은 기능에 따라 데이터베이스를 나누어서 관리한다면, sharding은 같은 데이터베이스 내에서 데이터들을 조각내서 분산하여 관리하는 것이다. 확실히 federation에 비해서 인덱스 사이즈가 줄고, 트래픽과 replication이 줄게된다. 하나의 shard node가 다운되도, 다른 shard 덕분에 어떠한 기능도 무리없이 잘 작동될 수 있다.
문제점
- 이를 실행하기 위한 sql 쿼리가 복잡해진다.
- sharding을 실행하기 위한 sharding function이 consistent hashing을 기반으로 한다. shard key를 어떻게 정의해서 각 노드를 rebalancing 하는 것이 중요하다.
따라서 가능한 sharding을 안할 수 있는 방법을 고려해야 한다.
- Scale-in
- Hardware Spec이 더 좋은 컴퓨터를 사용.
- Read 부하가 크다면?
- Cache나 Database의 Replication을 적용
- Table의 일부 컬럼만 자주 사용한다면?
- Vertically Partition
Denormalization
write 작업의 실행을 희생하고, read 작업의 효율을 향상시키는 것. 데이터를 중복하여 복제함으로써 join으로 인한 비용을 줄이려 한다. 예로, PostgresSQL 및 ORCLE 등에서 중복저장을 저장하고 중복 복사본의 일관성을 유지하는 작업을 처리하게 된다. federation이나 sharding을통해 데이터베이스를 분산하게 되면, join을 실행하려 할때 복잡해진다. denormalization은 이러한 복잡한 join을 피해갈 수 있게 한다. 대부분의 시스템에서 read 작업의 join이 복잡해지면, 엄청난 비용을 필요로 하게 되므로 이럴 때 denormalization을 고려할 수 있다.
문제점
- 중복된 데이터가 있을수 있다.
- 데이터베이스 디자인이 복잡해진다.
SQL tuning
-> 말그대로 SQL 조건 값들을 효율적으로 변경시키는 것이다. 이에 대해서는 이런 저런 정보가 많이 있으므로, 해당 링크의 자료들을 그대로 참고하여 정리했다.
스키마 강화
- MySQL dumps to disk in contiguous blocks for fast access.
- Use CHAR instead of VARCHAR for fixed-length fields.
- CHAR effectively allows for fast, random access, whereas with VARCHAR, you must find the end of a string before moving onto the next one.
- Use TEXT for large blocks of text such as blog posts. TEXT also allows for boolean searches. Using a TEXT field results in storing a pointer on disk that is used to locate the text block.
- Use INT for larger numbers up to 2^32 or 4 billion.
- Use DECIMAL for currency to avoid floating point representation errors.
- Avoid storing large BLOBS, store the location of where to get the object instead.
- VARCHAR(255) is the largest number of characters that can be counted in an 8 bit number, often maximizing the use of a byte in some RDBMS.
- Set the NOT NULL constraint where applicable to improve search performance.
좋은 index 사용하기.
-> 데이터베이스 인덱스에 대한 블로그 글(링크)
- Columns that you are querying (SELECT, GROUP BY, ORDER BY, JOIN) could be faster with indices.
- Indices are usually represented as self-balancing B-tree that keeps data sorted and allows searches, sequential access, insertions, and deletions in logarithmic time.
- Placing an index can keep the data in memory, requiring more space.
- Writes could also be slower since the index also needs to be updated.
- When loading large amounts of data, it might be faster to disable indices, load the data, then rebuild the indices.
복잡한 join 피하기
테이블 쪼개기
- Break up a table by putting hot spots in a separate table to help keep it in memory.
쿼리캐시 조정하기
Reference
'CS STUDY > Database' 카테고리의 다른 글
Partitioning(파티셔닝)과 Sharding(샤딩) (0) | 2022.08.21 |
---|---|
Database_Index(인덱스)란? (2) | 2022.03.24 |
OLTP VS OLAP 기본비교 (0) | 2022.03.24 |
Database_Application Cache 정리 (1) | 2021.02.07 |
Database transaction이란?(기본적이면서 중요한🌟) (0) | 2021.01.12 |