# Discord가 네트웍 디스크의 지연시간을 최소화한 방법

> Clean Markdown view of GeekNews topic #7198. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=7198](https://news.hada.io/topic?id=7198)
- GeekNews Markdown: [https://news.hada.io/topic/7198.md](https://news.hada.io/topic/7198.md)
- Type: news
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2022-08-17T10:19:47+09:00
- Updated: 2022-08-17T10:19:47+09:00
- Original source: [discord.com](https://discord.com/blog/how-discord-supercharges-network-disks-for-extreme-low-latency)
- Points: 29
- Comments: 3

## Topic Body

- 초당 200만개의 메시지를 처리하는 NoSQL DB 클러스터(ScyllaDB)를 운용 중  
- DB성능에 가장 큰 영향을 미치는 것은 피지컬 디스크 하드웨어의 레이턴시   
→ 쿼리량이 낮은 수준에서는 상관없지만, 특정 시점을 초과하면 1~2ms가 걸리는 읽기 시간 만으로도 디스크에서 읽는 대기열이 발생하며 쿼리 자체에 대해 시간 초과가 발생   
- 디스크 레이턴시는 보통 마이크로세컨드 단위인데, 왜 디스크 오퍼레이션에 1~2ms가 걸릴까 ?  
- 디스코드는 대부분의 하드웨어를 Google Cloud에서 운용  
  - NVMe 기반의 로컬 SSD를 지원하지만 자체적으로 테스트해보니 안정성 문제가 있어서 중요한 데이터 저장소로 사용하기엔 맘이 편하지 않았음  
  - Persistent Disk는 서버에 실시간으로 연결/분리 가능하며, 다운타임 없이 리사이즈 가능, 언제나 스냅샷 생성가능하고, 기본으로 복제되게 설계됨  
  → 문제는 서버에 직접 붙어있지 않고 네트웍으로 연결 된다는 것  
- 로컬 네트웍 커넥션 레이턴시가 아무리 낮아도, PCI/SATA 보다 낮지는 않음  
→ 네트워크는 1~2ms, 직접연결된 디스크는 0.5ms  
- 로컬 SSD는 HDD처럼 하드웨어 문제가 생기면 그 디스크의 데이터를 잃어버리게 되며, 호스트 자체가 문제가 생기면 스냅샷도 불가능 해서 아예 데이터를 잃어 버리는 상황이 발생  
→ 그래서 디스코드는 Local SSD 를 이용하지 않고, Persistent Disk 를 사용  
### 문제 분석   
- 로컬 SSD와 Persistent Disk 의 장점만 모은 저장 장치가 있다면 최고겠지만 그런 것은 없음. 장점중 일부만 가져온다면?  
- 디스코드는 쓰기 지연시간은 문제가 아님. 성능에 영향을 미치는 것은 "읽기 지연시간"  
- "다운타임 없는 디스크 리사이징"은 필수 기능은 아님. 사이즈는 미리 예측 가능   
- 최종 요구 사항은   
  - GCP 에 그대로 있으면서  
  - 데이터 백업을 위해서 Point-in-Time 스냅샷 사용   
  - 읽기 지연시간 최소화를 최우선 순위로   
  - 기존 데이터베이스 업타임 보장을 희생하지 않을 것   
- 읽기는 GCP의 Local SSD를 활용하고, 쓰기는 Persistent Disk에 하면 좋을 것 같음  
→ 소프트웨어 수준에서 이런 Super-disk를 만들 수 있을까?  
### Super-Disk 만들기   
- 요구사항은 기본적으로 Write-Through 캐쉬였음. GCP의 로컬 SSD를 캐쉬로 사용하고, PD를 저장 레이어로 사용   
- DB서버로 Ubunut를 사용하고 있어서, 리눅스 커널단에서 디스크 레벨의 캐쉬 적용 가능(dm-cache, lvm-cache, bcache 같은 모듈)  
- 하지만, 실험해보니 캐쉬디스크에 배드섹터 발생시 전체 읽기 작업이 실패함  
  - 배드섹터가 발생하면 스토리지 레이어에서 읽어다 엎어써야 하는데, 평가한 디스크 캐슁 솔루션들은 이런 기능이 없었음   
  - 배드섹터 발생시 데이터베이스가 데이터 안정성 문제로 셧다운 되어버림   
- 추가 요구사항으로 "로컬 SSD에 배드섹터가 발생해도 살아남아야 함"이 추가됨   
- 그래서 리눅스 커널의 "md"를 조사   
  - md는 소프트웨어 RAID를 생성할수 있도록 지원   
  - SSD와 PD를 미러링 하는 것으로는 문제가 해결 되지 않음. 절반이상의 읽기는 PD에서 될 것이기 때문에   
  - md에는 전통적인 RAID에는 없는 "write-mostly" 가 있음   
    - 특정 디스크를 write-mostly로 지정하면 일반 읽기에서는 제외되며, 다른 옵션이 없을 때만 읽기가 실행됨. "느리게 연결된 기기에 유용"  
    - 즉, SSD와 PD를 RAID1으로 묶고, PD를 write-mostly로 세팅하면 요구사항을 맞출 수 있음  
- 마지막 남은 문제는 GCP의 Local SSD는 크기가 딱 375GB라는 것  
- 디스코드는 특정 어플리케이션에 대해서는 DB 인스턴스당 1TB 이상이 필요하기도 함   
- 그래서 여러개의 SSD를 RAID0로 묶기로   
- 최종 모습은   
  - RAID0 로 묶인 로컬 SSD 4개를 md0  
  - md0 와 Persistent Disk를 RAID1으로 묶은 md1 을 구성   
### DB 성능   
- 딱 예상한 결과가 나왔음  
- 피크시에도 디스크 오퍼레이션들이 큐에 쌓이지 않으며, 쿼리 레이턴시가 변하지 않음   
- 성능 향상이 일어나서 각 서버당 처리 쿼리량이 더 늘어남   
- RAID 사용해본 사람들은 이게 "그냥 동작할까?" 라는 의구심이 들겠지만, 실제로는 다양한 일이 있었고, 나머지는 따로 상세히 소개할 예정

## Comments



### Comment 11871

- Author: eajrezz
- Created: 2022-08-19T11:02:02+09:00
- Points: 1

이전에는 golang의 퍼포먼스에 만족을 못해서 rust로 서버도 짜는 것 보면 discord 회사의 geek함도 대단한 것 같아요.

### Comment 11833

- Author: psyrenpark
- Created: 2022-08-17T18:08:25+09:00
- Points: 1

몬가 가래로 막을 것을 호미로 막는 느낌입니다.

### Comment 11827

- Author: xguru
- Created: 2022-08-17T10:20:00+09:00
- Points: 1

HN에서는 그거 그냥 GCP 문제 아냐? 라는 얘기도 있기는 합니다만..   
https://news.ycombinator.com/item?id=32474093  
이런 시도도 가능하구나 정도로 알아두면 좋을 것 같아요.
