[Database] Sharding
파티셔닝은 하나의 데이터베이스 서버에서 논리적이나 물리적으로 데이터를 분할해 데이터를 관리하는 방식이다.
반면 샤딩은 데이터를 여러 데이터베이스 서버에 걸쳐 분산시켜 저장하는 방식으로, 각 샤드는 전체 데이터의 부분집합을 가지고 있어 데이터베이스를 수평적으로 확장할 때 유용하다.
샤딩으로 같은 스키마를 가지는 데이터베이스를 여러 서버에 분산시킨 후 각 데이터베이스 서버에 값이 균등하게 저장되도록 하기 위해 Consistent Hashing 기법을 함께 사용한다.
데이터를 분산시키는 기준을 해시 함수가 정하고 해시 값으로 데이터가 저장될 샤드를 결정한다.
const HashRing = require("hashring");
const hr = new HashRing();
app.get("/:urlId", async (req, res) => {
const urlId = req.params.urlId;
const server = hr.get(urlId)
const result = await clients[server].query("SELECT * FROM URL_TABLE WHERE URL_ID = $1", [urlId]);
if (result.rowCount > 0) {
res.send({
"urlId": urlId,
"url": result.rows[0],
"server": server
})
}
else
res.sendStatus(404)
})
app.post("/", async (req, res) => {
const url = req.query.url;
const hash = crypto.createHash("sha256").update(url).digest("base64")
const urlId = hash.substr(0, 5);
const server = hr.get(urlId)
await clients[server].query("INSERT INTO URL_TABLE (URL, URL_ID) VALUES ($1,$2)", [url, urlId]);
res.send({
"urlId": urlId,
"url": url,
"server": server
})
})
hashring 라이브러리를 사용해 Consistent Hashing을 구현하는 예시이다.
INSERT와 SELECT 모두 같은 해시 함수를 사용해 시스템은 정확히 어느 샤드에서 데이터를 조회하고 어느 샤드에 데이터를 삽입할지 알 수 있다.
샤딩은 특정 기준에 따라 데이터를 균일하게 분산시키고 데이터베이스를 분산시켜 성능을 끌어낼 수 있어 유용하다.
한 데이터베이스 서버에 TCP 연결 요청이 감당하지 못 할 정도로 많은 경우 파티셔닝으로도 해결할 수 없는데, 샤딩은 데이터베이스 서버를 여러 개 사용해 TCP 연결도 분산시킬 수 있다.
예시처럼 해시를 사용하는 해시 샤딩, 데이터를 지역별로 구분하는 지리적 샤딩, 시계열 데이터를 다루는 경우 날짜 기반 샤딩을 사용하는 등 상황에 따라 다양한 기준으로 샤딩을 사용할 수 있지만...
샤딩은 다루기 어렵고 복잡한 확장 전략으로 잘못 도입하면 오버엔지니어링으로 이어지기 쉽고 시스템의 유지보수성을 저해시키기 쉬워 데이터베이스 확장에서 최후의 수단으로 활용해야 한다.
데이터베이스를 여러 샤드로 분할하면 트랜잭션을 다루기가 매우 복잡해진다.
여러 샤드에 걸쳐 있는 데이터의 일관성과 무결성을 유지해야 해 모든 샤드에서 트랜잭션이 성공했는지 추적하고 관리해야 하고, 롤백이 필요한 경우 여러 샤드에 걸쳐서 롤백을 수행해야 해 복잡하다.
또 데이터베이스의 스키마가 변경되는 경우 관련된 모든 샤드에도 일관적으로 적용해 줘야 하고..
분산 기준을 변경하는 경우 쿼리를 보내는 클라이언트의 로직도 함께 변경해 줘야 해 유지보수가 매우 힘들어진다.
샤딩을 도입할 수 밖에 없는 상황이라면 샤딩을 사용하는게 맞지만, 도입하기 전 다른 방법으로 문제를 최대한 해결해보자.
쿼리 속도가 느린 경우 파티셔닝을 도입한다던지..
Master-Slave 레플리카 모델을 사용한다던지..
'Database > Database' 카테고리의 다른 글
[Database] Database Engine (0) | 2024.04.17 |
---|---|
[Database] 동시성 처리 (0) | 2024.04.13 |
[Database] Partitioning (0) | 2024.04.04 |
[Database] B+Tree 자료구조 (0) | 2024.03.30 |
[Database] 내부 저장 구조 (0) | 2024.01.29 |
댓글
이 글 공유하기
다른 글
-
[Database] Database Engine
[Database] Database Engine
2024.04.17 -
[Database] 동시성 처리
[Database] 동시성 처리
2024.04.13 -
[Database] Partitioning
[Database] Partitioning
2024.04.04 -
[Database] B+Tree 자료구조
[Database] B+Tree 자료구조
2024.03.30