# Redis에서 SQLite로 재구조화(Rearchitecting)

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

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16929](https://news.hada.io/topic?id=16929)
- GeekNews Markdown: [https://news.hada.io/topic/16929.md](https://news.hada.io/topic/16929.md)
- Type: news
- Author: [xguru](https://news.hada.io/@xguru)
- Published: 2024-09-26T09:31:01+09:00
- Updated: 2024-09-26T09:31:01+09:00
- Original source: [wafris.org](https://wafris.org/blog/rearchitecting-for-sqlite)
- Points: 12
- Comments: 7

## Summary

오픈 소스 웹 애플리케이션 방화벽 Wafris가 Redis에서 SQLite로 마이그레이션하여 성능과 사용자 경험을 크게 개선했습니다. SQLite는 네트워크 지연을 제거하고 로컬 데이터베이스로서 Redis보다 훨씬 빠른 성능을 제공했습니다. 또한, 새로운 아키텍처는 설치 성공률을 3배 증가시키고 사용자의 설정 부담을 줄여 더 안전하고 효율적인 웹 애플리케이션 방화벽을 구현했습니다.

## Topic Body

- Wafris는 Rails 미들웨어 클라이언트를 제공하는 오픈 소스 웹 애플리케이션 방화벽 회사임  
- v1 클라이언트는 로컬 Redis 데이터 저장소가 필요했으나, v2에서는 SQLite를 사용함  
- Redis에서 SQLite로 마이그레이션하기로 결정한 배경과 성능 고려사항, 아키텍처 변경 사항을 설명  
  
### TL;DR  
- SQLite는 잘하는 것과 못하는 것이 있음  
- Redis는 잘하는 것과 못하는 것이 있음   
- 전통적인 RDBMS(Postgres/MySQL)는 잘하는 것과 못하는 것이 있음  
- 이러한 데이터 저장소는 직접 교체할 수 없으며, 그렇게 하려고 하면 곤란해짐  
- 이 글은 Redis 기반 v1 클라이언트를 SQLite 기반 v2 클라이언트로 리아키텍팅하면서 거친 테스트와 의사 결정 과정을 설명함  
  
### 변경을 강제한 요인  
- Wafris의 목표는 개발자들이 쉽게 사이트를 보호할 수 있게 만드는 것임  
- Redis 배포 이슈로 인해 v1은 이 목표를 완전히 달성하지 못함  
- Heroku 등 Redis를 쉽게 사용할 수 있는 환경에서 작업했기에 Redis를 선택했으나, 많은 사용자가 Redis 배포 이슈를 겪음  
- Redis 같은 별도 DB를 사용하게 하는 건 사용자를 위한 게 아님  
  
### "속도"란 무엇인가?  
- Redis는 전통적 RDBMS보다 "빠르지만", 여전히 연결, 메모리, 프로세스 등을 관리해야 함  
- 클라우드 환경에서는 네트워크 지연이 큰 문제가 될 수 있음  
- 들어오는 HTTP 요청마다 Wafris 규칙을 평가해야 하므로 네트워크 지연이 애플리케이션 속도를 늦출 수 있음  
  
### 단일체(Monolith-ish) 가정  
- 완전 분산 애플리케이션도 있지만, 대부분 Rails 앱은 "장엄한 모놀리스(Majestic Monoliths,단일체)"임  
- 여러 영역에 배포되고, 기능이 겹치는 서버로 분할되거나, 부분적으로만 Rails인 앱은 Redis 사용 시 더 많은 문제가 발생함  
  
### 아키텍처에 대한 재고  
- Wafris는 Rails 미들웨어로 설치되는 웹 애플리케이션 방화벽임  
- 간단히 2단계로 나누면 1) HTTP 요청을 규칙과 비교하고, 2) 처리 결과를 보고함  
- 규칙 "읽기"(1단계)가 "쓰기"(2단계)보다 훨씬 중요함  
- 읽기는 순차적으로 처리되어야 하고, 실패하면 안되며, 사용자 체감 성능에 영향을 줌  
- 쓰기는 느리게, 일괄 처리하거나 비동기로 할 수 있음  
  
### Enter SQLite  
- SQLite가 적합한 용도에 대해서는 다른 이들이 잘 설명하고 있음  
- SQLite는 클라이언트/서버 DB와 경쟁하는 게 아니라 fopen()과 경쟁함  
- 네트워크 왕복을 제거하면 Redis보다 훨씬 빨라질 것으로 예상됨  
- SQLite와 Redis의 벤치마크 평가를 결정함  
  
### SQLite와 Redis 벤치마킹  
- 벤치마킹은 정밀한 숫자로 자신을 속이는 어두운 기술임  
- 데이터 저장소 벤치마킹은 더욱 까다로움  
- 절대적 속도를 구하려는 게 아니라 우리 데이터와 사용 사례에 특화된 벤치마크를 만듦  
- 최적화 트윅은 무시함. Wafris를 앱에 넣으면 바로 작동하길 원함  
- 이론적 벤치마크가 아닌 우리 앱의 주요 경로와 최악의 쿼리를 테스트함  
- IP 범위(IPv4, IPv6)를 범주에 매핑하는 복잡한 "lexical decimal" 자료구조 요청이 최악의 쿼리임  
- 범위 조회를 미리 계산해 SQLite 테이블과 Redis 정렬 집합에 씀  
- 들어오는 HTTP 요청마다 요청 IP를 허용/차단 사용자 지정 범위, GeoIP 범위, IP 평판 범위와 비교해야 함  
  
### 테스트 프로토콜  
- M2 맥북 에어에서 홈브루로 설치한 Redis와 로컬 SQLite DB로 테스트함  
- 기존 범위 데이터 세트(120만 개 항목)에 대해 테스트함  
- 여러 IP 세트를 SQLite와 Redis에 동일한 순서로 실행함  
- 각 배수마다 테스트를 5번 실행하고 평균을 냄  
  
### 테스트 결과  
- SQLite가 Redis를 압도적으로 이김(우리의 특수한 사용 사례에서)  
- SQLite는 로컬 Redis 인스턴스보다 약 3배 빨랐음  
- 네트워크 지연을 고려하기 전의 결과임  
- SQLite가 Redis와 동등하기만 해도 네트워크 시간을 없앨 수 있어 이득임  
  
### 차트에서 빠진 것  
- SQLite 성능이 벤치마크에서 2배 나빠도 실제로는 네트워크 지연 때문에 더 빠를 수 있음   
- Redis 서버를 아무리 강력하게 해도 네트워크 대역폭, 연결 등의 한계가 있고 지역 간 지연이 있음  
- SQLite는 "무료로" 거의 무한한 수평 확장이 가능함  
- SQLite로 온보딩이 훨씬 좋아짐. 사용자는 사용되는지도 모를 것임  
- Redis에서 더 많은 성능을 뽑아낼 수 있지만, 사용자가 Redis 설정을 변경하도록 설득하기 어려웠음  
  
### 결과는 시작에 불과함  
- SQLite가 Redis보다 빠르다고 입증했지만 실제 절충이 있음  
- 위 테스트에서는 쓰기를 고려하지 않음  
- 읽기와 쓰기가 경쟁하는 것을 관리하기 위해 DB에 연결, 연결 풀, 트랜잭션 등이 필요함  
- 마치 전기 슈퍼카가 콘크리트 블록을 싣고 가기 어려운 것처럼, SQLite를 적합하지 않은 역할에 쓰면 안 됨  
  
### 동기화 아키텍처 구축  
- v1(Redis)에서는 사용자가 Wafris Hub에서 규칙을 업데이트하면 Redis 데이터 저장소의 규칙이 업데이트됨   
- SQLite에서는 웹 서버로 "푸시"할 수 없으므로 작동하지 않음  
- v2(SQLite)에서는 1) 사용자가 Wafris Hub에서 규칙 업데이트 2) 일정 간격으로 클라이언트가 업데이트된 규칙 확인 3) 규칙이 업데이트되면 완전히 새로운 SQLite DB 다운로드  
- 이는 사용자의 설치 및 구성 책임을 크게 줄여줌  
- v2 클라이언트의 설치 성공률이 3배 증가함  
  
### SQLite 분산 아키텍처  
- 자동 확장이 활성화된 클라우드 제공업체에 배포된 Rails 앱을 고려해보자  
- 요청이 100req/s에서 10,000req/s로 증가하면 컴퓨팅 인스턴스는 확장되지만 DB는 그렇지 않음  
- 실제로 Rails 앱이 과부하로 인해 중단되는 주된 이유임  
- SQLite DB를 각 컴퓨팅 인스턴스에 동기화하면 모든 호출을 로컬로 유지할 수 있어 이 문제를 해결함  
  
### 쓰기는 어떻게 하나?  
- 앱을 읽기(규칙 평가)와 쓰기(보고) 경로로 분할한 다음 쓰기 경로는 무시했음  
- 쓰기 경로는 1) Wafris Hub에 비동기로 연결해 보고 2) 보고서 일괄 전송 3) 클라이언트에서 DB 쓰기 완전 제거로 재설계함  
- 다른 사람들에게는 작동하지 않겠지만, 우리는 배포가 쉽고 빠른 Wafris 클라이언트를 원하는 사용자만 신경 씀  
  
### 결론  
- SQLite를 사용하는 v2 아키텍처에 매우 만족함  
- 이미 많은 사이트가 공격을 견디고 온라인 상태를 유지하는 데 도움이 됨  
- 시작하기가 훨씬 쉬워져 우리의 지원 작업과 사용자의 번거로움이 줄어듦  
- 이는 더 안전하고 보안성 높은 인터넷을 위한 승리라고 생각함

## Comments



### Comment 29250

- Author: aer0700
- Created: 2024-09-26T23:40:12+09:00
- Points: 1

Sqlite가 충분히 좋긴 한데, 이 경우는 어쩐지 그냥 redis에 적합하지 않은 use case였던 것이 아닌지... 싶네요.

### Comment 29230

- Author: kandk
- Created: 2024-09-26T11:58:20+09:00
- Points: 1

벤치마크를 M2에서 했다는건 좀..

### Comment 29456

- Author: colossus
- Created: 2024-09-29T18:55:20+09:00
- Points: 1
- Parent comment: 29230
- Depth: 1

그러면 aws 인스턴스마다 다 측정해봐야하나요? 오픈소스에 바라는게 너무 많으시네요

### Comment 29254

- Author: toru123
- Created: 2024-09-27T08:27:59+09:00
- Points: 1
- Parent comment: 29230
- Depth: 1

같은 서버 환경에서 진행을 한건데 문제가 되나요?   
벤치마크에는 특정 CPU를 써야하는 건지...?

### Comment 29248

- Author: superwoou
- Created: 2024-09-26T21:56:18+09:00
- Points: 2
- Parent comment: 29230
- Depth: 1

m2에서 한것이 어떤점이 문제가 될 수 있을까요? (실제 서비스 환경이 m2프로세서가 아니라는 점 외에)

### Comment 29249

- Author: kandk
- Created: 2024-09-26T22:07:56+09:00
- Points: 1
- Parent comment: 29248
- Depth: 2

그게 문제죠. 실험실에서 실험하고, 이건 상업용으로 완벽하다! 라고 주장하는것.

### Comment 29244

- Author: [hidden]
- Created: 2024-09-26T17:35:23+09:00
- Points: 1
- Parent comment: 29230
- Depth: 1

[숨김 처리된 댓글입니다]
