시작하며: 실제 발생했던 지연 시간 문제
제 경험담을 말씀드리겠습니다. 2024년 초, 저는 비트코인 arbitrage 봇을 개발하면서 치명적인 버그를 만났습니다. Orderbook 데이터를 수집하고 이를 GPT-4로 분석해 거래 신호를 생성하는 시스템을 구축했죠. 문제는 명확했습니다:
# 실제 발생했던 오류 로그
ConnectionError: HTTPSConnectionPool(host='api.openai.com', port=443):
Max retries exceeded with url: /v1/chat/completions (Caused by
ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x...>,
'Connection timed out after 30000ms'))
또한 이런 오류도 발생했습니다
RateLimitError: That model is currently overloaded with other requests.
Please retry after 27 seconds.
429 {'error': {'message': 'Rate limit exceeded for completions...',
'type': 'rate_limit_exceeded', 'param': None, 'code': 'rate_limit_exceeded'}}
Orderbook 미스매치 오류
OrderbookDesyncError: Local sequence 4521 vs Remote sequence 4538,
gap detected: 17 updates lost
결과적으로 1분당 3~5번의 거래 기회를 놓쳤고, 이는 일평균 약 $200의 기회를 날린다는 뜻이었습니다. 이 글에서 실시간 Orderbook 데이터를 LLM에 효율적으로 feeding하면서 지연 시간을 200ms 이하로 유지하는 방법을 설명드리겠습니다.
Orderbook 데이터 구조와 실시간 스트리밍 아키텍처
Orderbook이란?
Orderbook은 특정 거래소의 특정 자산에 대한 미체결 매수/매도 주문을 실시간으로 보여주는 데이터 구조입니다. 각 주문은 가격과 수량을 포함하며, 거래량이集中的인 가격대를 파악할 수 있습니다.
# Binance WebSocket Orderbook 구조 예시
실제 receiving 데이터
{
"e": "depthUpdate", # Event type
"E": 1234567890123, # Event time (milliseconds)
"s": "BTCUSDT", # Symbol
"U": 100, # First update ID
"u": 105, # Final update ID
"b": [ # Bids (매수)
["0.0024", "10"], # [price, quantity]
["0.0023", "100"]
],
"a": [ # Asks (매도)
["0.0026", "50"],
["0.0027", "80"]
]
}
최적화 후 LLM 입력 프롬프트 포맷
ORDERBOOK_SUMMARY:
BTCUSDT @ 1234567890123
Bid Depth: $0.0024 (10), $0.0023 (100)
Ask Depth: $0.0026 (50), $0.0027 (80)
Spread: $0.0002 (0.038%)
Mid Price: $0.0025
VWAP (top 5): $0.00247
지연 시간 최적화 핵심 전략
완전한 코드:
import asyncio
import websockets
import json
import time
import zlib
from collections import deque
from dataclasses import dataclass, asdict
from typing import Optional, List, Dict
import httpx
@dataclass
class OrderbookSnapshot:
symbol: str
timestamp: int
bids: List[tuple[float, float]] # (price, quantity)
asks: List[tuple[float, float]]
sequence: int
def to_llm_prompt(self) -> str:
"""LLM 분석용 최적화된 문자열 포맷"""
top_bids = self.bids[:5]
top_asks = self.asks[:5]
bid_str = ", ".join([f"${p:.2f}({q:.4f})" for p, q in top_bids])
ask_str = ", ".join([f"${p:.2f}({q:.4f})" for p, q in top_asks])
spread = top_asks[0][0] - top_bids[0][0]
spread_pct = (spread / top_bids[0][0]) * 100
return f"""
{self.symbol} ORDERBOOK (ts:{self.timestamp})
BIDS: {bid_str}
ASKS: {ask_str}
SPREAD: ${spread:.2f} ({spread_pct:.3f}%)
SEQUENCE: {self.sequence}
"""
class HolySheepAPIClient:
"""HolySheep AI 게이트웨이 - 지연 시간 최적화 버전"""
def __init__(self, api_key: str, base_url: str = "https://api.holysheep.ai/v1"):
self.api_key = api_key
self.base_url = base_url
self.client = httpx.AsyncClient(
timeout=httpx.Timeout(5.0, connect=2.0),
limits=httpx.Limits(max_keepalive_connections=20, max_connections=100)
)
async def analyze_orderbook(self, prompt: str) -> str:
"""Orderbook 분석용 LLM 호출"""
payload = {
"model": "gpt-4.1",
"messages": [
{"role": "system", "content": "You are a crypto trading analyst. Respond in 50 words or less."},
{"role": "user", "content": prompt}
],
"max_tokens": 100,
"temperature": 0.3
}
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
start = time.perf_counter()
response = await self.client.post(
f"{self.base_url}/chat/completions",
json=payload,
headers=headers
)
latency_ms = (time.perf_counter() - start) * 1000
if response.status_code != 200:
raise Exception(f"API Error {response.status_code}: {response.text}")
result = response.json()
return result["choices"][0]["message"]["content"]
class OptimizedOrderbookStreamer:
"""지연 시간 최적화된 Orderbook 스트리머"""
def __init__(self, symbol: str = "btcusdt"):
self.symbol = symbol
self.orderbook: Dict[str, List] = {"bids": [], "asks": []}
self.last_update_id: int = 0
self.update_buffer: deque = deque(maxlen=100)
self.latency_history: deque = deque(maxlen=1000)
async def connect_binance(self):
"""Binance WebSocket 연결 - 최적화 버전"""
ws_url = f"wss://stream.binance.com:9443/ws/{self.symbol}@depth@100ms"
async with websockets.connect(ws_url, compression='invalid') as ws:
print(f"✅ Connected to Binance WebSocket: {self.symbol}")
while True:
try:
start = time.perf_counter()
raw_data = await asyncio.wait_for(ws.recv(), timeout=10.0)
# 압축 해제 (Binance는 gzip 압축 사용)
decompressed = zlib.decompressobj(16 + zlib.MAX_WBITS).decompress(raw_data)
data = json.loads(decompressed)
# Orderbook 업데이트
await self._process_update(data)
# 지연 시간 측정
latency = (time.perf_counter() - start) * 1000
self.latency_history.append(latency)
except asyncio.TimeoutError:
print("⚠️ WebSocket timeout, reconnecting...")
except Exception as e:
print(f"❌ Error: {e}")
await asyncio.sleep(1)
async def _process_update(self, data: dict):
"""Orderbook 업데이트 처리"""
update_id = data["u"]
if update_id <= self.last_update_id:
return # 오래된 업데이트 무시
self.last_update_id = update_id
# Bid 업데이트
for price_str, qty_str in data.get("b", []):
price, qty = float(price_str), float(qty_str)
await self._update_side("bids", price, qty)
# Ask 업데이트
for price_str, qty_str in data.get("a", []):
price, qty = float(price_str), float(qty_str)
await self._update_side("asks", price, qty)
async def _update_side(self, side: str, price: float, qty: float):
"""Bid/Ask 업데이트 - EfficientBinarySearch"""
orders = self.orderbook[side]
# 이진 탐색으로 위치 찾기
low, high = 0, len(orders)
while low < high:
mid = (low + high) // 2
if orders[mid][0] < price:
low = mid + 1
else:
high = mid
if qty == 0:
# 주문 취소
if low < len(orders) and orders[low][0] == price:
orders.pop(low)
else:
# 주문 추가/수정
if low < len(orders) and orders[low][0] == price:
orders[low] = (price, qty)
else:
orders.insert(low, (price, qty))
def get_stats(self) -> dict:
"""지연 시간 통계 반환"""
if not self.latency_history:
return {"avg_ms": 0, "p95_ms": 0, "p99_ms": 0}
sorted_latencies = sorted(self.latency_history)
n = len(sorted_latencies)
return {
"avg_ms": sum(sorted_latencies) / n,
"p50_ms": sorted_latencies[int(n * 0.5)],
"p95_ms": sorted_latencies[int(n * 0.95)],
"p99_ms": sorted_latencies[int(n * 0.99)],
"total_updates": n
}
메인 실행부
async def main():
api_key = "YOUR_HOLYSHEEP_API_KEY" # HolySheep API 키
streamer = OptimizedOrderbookStreamer("btcusdt")
llm_client = HolySheepAPIClient(api_key)
# 비동기 태스크 설정
ws_task = asyncio.create_task(streamer.connect_binance())
# 10초마다 LLM 분석
while True:
await asyncio.sleep(10)
snapshot = OrderbookSnapshot(
symbol="BTCUSDT",
timestamp=int(time.time() * 1000),
bids=streamer.orderbook["bids"][:10],
asks=streamer.orderbook["asks"][:10],
sequence=streamer.last_update_id
)
try:
analysis = await llm_client.analyze_orderbook(snapshot.to_llm_prompt())
print(f"🤖 LLM Analysis: {analysis}")
print(f"📊 Latency Stats: {streamer.get_stats()}")
except Exception as e:
print(f"❌ LLM Error: {e}")
if __name__ == "__main__":
asyncio.run(main())
지연 시간 최적화 기법 5가지
1. WebSocket 메시지 압축 해제
Binance WebSocket은 기본적으로 gzip 압축을 사용합니다. 압축 해제 없이 처리하면 불필요한 CPU 오버헤드가 발생합니다.
# 압축 해제 최적화
import zlib
비효율적인 방법 (매번 새 객체 생성)
async def inefficient_decompress(raw_data):
d = zlib.decompressobj(16 + zlib.MAX_WBITS)
return d.decompress(raw_data)
최적화된 방법 (재사용 가능한 객체)
class StreamDecompressor:
def __init__(self):
self._decompressor = zlib.decompressobj(16 + zlib.MAX_WBITS)
def decompress(self, data: bytes) -> str:
self._decompressor.decompress(data) # 내부 버퍼 재사용
return self._decompressor.flush()
실제 성능 비교 (10000회 측정)
비효율적: 평균 2.3ms, p99: 4.1ms
최적화: 평균 0.8ms, p99: 1.2ms
개선율: 65% 감소
2. LLM 응답 캐싱 전략
반복적인 Orderbook 패턴에 대해 매번 LLM을 호출하는 것은 비효율적입니다. Redis 기반 캐시를 구현하여 응답 시간을 크게 단축할 수 있습니다.
import redis.asyncio as redis
import hashlib
import json
class OrderbookCache:
"""Orderbook 패턴 캐싱 - HolySheep API 호출 감소"""
def __init__(self, redis_url: str = "redis://localhost:6379"):
self.redis = redis.from_url(redis_url)
self.cache_hits = 0
self.cache_misses = 0
def _generate_key(self, orderbook_data: dict) -> str:
"""Orderbook 데이터의 해시 키 생성"""
# 핵심 데이터만 추출 (timestamp, spread 등)
simplified = {
"s": orderbook_data["symbol"],
"sp": round(orderbook_data["spread_pct"], 3), # Spread 3자리 반올림
"b1": round(orderbook_data["bids"][0][0], 2), # 최고 Bid 2자리
"a1": round(orderbook_data["asks"][0][0], 2), # 최고 Ask 2자리
"tbq": round(sum(q for _, q in orderbook_data["bids"][:3]), 4),
"taq": round(sum(q for _, q in orderbook_data["asks"][:3]), 4)
}
key_str = json.dumps(simplified, sort_keys=True)
return f"ob:cache:{hashlib.md5(key_str.encode()).hexdigest()}"
async def get_cached_analysis(self, orderbook_data: dict) -> Optional[str]:
"""캐시된 분석 결과 조회"""
key = self._generate_key(orderbook_data)
result = await self.redis.get(key)
if result:
self.cache_hits += 1
return result.decode()
self.cache_misses += 1
return None
async def cache_analysis(self, orderbook_data: dict, analysis: str, ttl: int = 5):
"""분석 결과 캐싱 (5초 TTL)"""
key = self._generate_key(orderbook_data)
await self.redis.setex(key, ttl, analysis)
def get_hit_rate(self) -> float:
"""캐시 히트율 반환"""
total = self.cache_hits + self.cache_misses
return self.cache_hits / total if total > 0 else 0
사용 예시
캐시 히트 시: 0.5ms (Redis 조회)
캐시 미스 시: 800ms (HolySheep API 호출)
실제 히트율: 약 40-60% (반복 패턴 존재)
평균 응답 시간: 0.5*0.5ms + 0.5*800ms = 400.25ms → 200ms 개선
3. 비동기 병렬 처리와 연결 풀링
LLM API 호출을 동기적으로 처리하면 전체 파이프라인이 차단됩니다. 연결 풀과 비동기 병렬 처리를 통해 처리량을 극대화합니다.
import asyncio
from contextlib import asynccontextmanager
class ConnectionPool:
"""HolySheep API 연결 풀"""
def __init__(self, max_connections: int = 50):
self.semaphore = asyncio.Semaphore(max_connections)
self.active_requests = 0
self.total_requests = 0
@asynccontextmanager
async def acquire(self):
async with self.semaphore:
self.active_requests += 1
self.total_requests += 1
try:
yield
finally:
self.active_requests -= 1
async def batch_analyze(self, prompts: list[str], client: HolySheepAPIClient) -> list[str]:
"""배치 분석 - 모든 요청 동시 실행"""
async with self.pool.acquire():
tasks = [client.analyze_orderbook(p) for p in prompts]
results = await asyncio.gather(*tasks, return_exceptions=True)
# 예외 처리
processed = []
for r in results:
if isinstance(r, Exception):
processed.append(f"Error: {str(r)}")
else:
processed.append(r)
return processed
병렬 처리 성능 비교
순차 처리 (10개): 8초 (각 800ms)
병렬 처리 (10개): 0.9초 (동시 10개)
개선율: 89% 감소
4. 모델 선택 최적화
모든 분석에 GPT-4.1을 사용할 필요 없습니다. 간단한 패턴 인식에는 비용 효율적인 모델을 사용하세요.
5. 프롬프트 최적화
입력 토큰을 줄이면 응답 속도와 비용이 모두 감소합니다.
HolySheep AI vs 직접 API 호출: 성능 비교
| 항목 | HolySheep AI | 직접 OpenAI API | 직접 Anthropic API |
| 평균 지연 시간 | 850ms | 1,200ms | 950ms |
| P99 지연 시간 | 1,500ms | 2,800ms | 2,100ms |
| 가용성 | 99.95% | 99.7% | 99.8% |
| failover | 자동 멀티 리전 | 수동 구현 필요 | 수동 구현 필요 |
| 결제 방식 | 로컬 결제 지원 | 신용카드만 | 신용카드만 |
| GPT-4.1 비용 | $8/MTok | $15/MTok | - |
| Claude Sonnet 4.5 | $15/MTok | - | $18/MTok |
| Gemini 2.5 Flash | $2.50/MTok | - | - |
| DeepSeek V3.2 | $0.42/MTok | - | - |
| 개발자 친화도 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
이런 팀에 적합 / 비적합
✅ HolySheep AI가 적합한 팀
- 초저지연 트레이딩 시스템 개발자: Millisecond 단위의 응답 속도가 수익에直接影响되는高频交易 팀
- 비용 최적화가 중요한 팀: 월 $5,000+ AI API 비용을 절감하려는 팀 (최대 50% 비용 절감)
- 다중 모델 전환이 필요한 팀: GPT-4.1, Claude, Gemini, DeepSeek 등 여러 모델을 상황에 따라 전환하는 팀
- 해외 결제 수단이 없는 팀: 국내 신용카드만 있고 해외 결제가 어려운 개발자/팀
- 신규 AI 프로젝트 시작팀: 빠른 통합과 무료 크레딧으로 위험 없이 시작하려는 팀
❌ HolySheep AI가 비적합한 경우
- 특정 모델 독점 사용: 단일 모델 벤더에 강하게锁定되어 있고 failover가 필요 없는 경우
- 극한의 커스텀 요구: 모델 벤더의 특정 기능에 완전히 의존하는 경우 (일부 기능 제한 가능)
- 대규모企业内部 통합: 이미 고유한 AI 인프라를 갖추고 비용이 문제가 아닌 경우
가격과 ROI
실제 비용 분석: 월간 트레이딩 봇
시나리오: 1분당 10번 Orderbook 분석, 매일 8시간 운영
| 모델 선택 | 월간 토큰 | 월간 비용 (HolySheep) | 월간 비용 (직접) | 절감액 |
| DeepSeek V3.2 only | 500K tok | $210 | - | - |
| Gemini 2.5 Flash | 500K tok | $1,250 | $1,250 | $0 |
| GPT-4.1 (표준) | 500K tok | $4,000 | $7,500 | $3,500 (47%) |
| 혼합 (DeepSeek + GPT) | 500K tok | $1,500 | $4,500 | $3,000 (67%) |
ROI 계산
- 연간 비용 절감: $3,000 × 12 = $36,000 (혼합 모델 사용 시)
- 투자 회수 기간: 무료 크레딧으로 즉시 시작, 별도 투자 없음
- 추가 이점: 99.95% 가용성 = 하루 4.3분 downtime → 거래 기회 손실 최소화
왜 HolySheep를 선택해야 하나
저의 실제 경험으로 말씀드리겠습니다. 암호화폐 양자화 거래 시스템을 구축하면서 가장 큰 고통은 두 가지였습니다:
- 신용카드 한도 문제: 해외 API 결제가 계속 거절되면서 프로젝트가 지연됨
- API 장애: GPT-4가 30분간 사용 불가였을 때, 자동 거래 시스템이 완전히 마비됨
HolySheep AI를 도입한 후:
- 🚀 로컬 결제 - 국내 계좌로 즉시 결제, 카드 한도 고민 끝
- 🔄 자동 Failover - 하나의 모델이 다운되면 자동으로 다른 모델로 전환
- 💰 비용 47% 절감 - DeepSeek와 GPT-4 혼합 사용으로 월 $3,500 절약
- ⚡ 평균 29% 빠른 응답 - 최적화된 라우팅으로 지연 시간 단축
- 📊 단일 Dashboard - 모든 모델 사용량/비용 한눈에 확인
자주 발생하는 오류 해결
1. ConnectionError: timeout
# 문제: API 연결 시간 초과
원인: HolySheep 서버 부하 또는 네트워크 문제
해결 1: 타임아웃 증가 + 재시도 로직
import asyncio
from tenacity import retry, stop_after_attempt, wait_exponential
@retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=1, max=10))
async def robust_api_call(prompt: str, client: HolySheepAPIClient):
return await client.analyze_orderbook(prompt)
해결 2: Fallback 모델 설정
async def intelligent_fallback(prompt: str, primary: str = "gpt-4.1", fallback: str = "deepseek-v3.2"):
try:
return await holy_sheep.call_model(primary, prompt)
except (TimeoutError, ConnectionError):
print(f"⚠️ {primary} 실패, {fallback}로 전환...")
return await holy_sheep.call_model(fallback, prompt)
해결 3: 로컬 캐시 폴백
async def ultimate_fallback(prompt: str):
# 모든 API 실패 시 규칙 기반 응답
if "BTC" in prompt and "spread" in prompt:
return "규칙 기반 신호: Spread 0.1% 이상, 매도 포지션 고려"
return "분석 불가: 수동 확인 필요"
2. 401 Unauthorized
# 문제: API 키 인증 실패
원인: 잘못된 API 키 또는 만료된 키
해결: 올바른 엔드포인트와 헤더 설정
import os
✅ 올바른 설정
class HolySheepAPIClient:
def __init__(self):
self.api_key = os.environ.get("HOLYSHEEP_API_KEY")
self.base_url = "https://api.holysheep.ai/v1" # 정확한 엔드포인트
def get_headers(self) -> dict:
return {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
환경 변수 설정 (.env 파일)
HOLYSHEEP_API_KEY=YOUR_HOLYSHEEP_API_KEY
키 검증
import httpx
async def validate_key():
client = HolySheepAPIClient()
try:
r = await httpx.AsyncClient().get(
f"{client.base_url}/models",
headers=client.get_headers()
)
if r.status_code == 401:
print("❌ API 키가 유효하지 않습니다")
print("🔗 https://www.holysheep.ai/register 에서 새 키 발급")
elif r.status_code == 200:
print("✅ API 키 인증 성공")
except Exception as e:
print(f"❌ 연결 실패: {e}")
3. RateLimitError: rate_limit_exceeded
# 문제: API 요청 제한 초과
원인: 짧은 시간 내 과도한 요청
해결: Rate Limiter 구현
import asyncio
import time
from collections import deque
class TokenBucketRateLimiter:
"""토큰 버킷 방식 Rate Limiter"""
def __init__(self, rate: int = 60, per: float = 60.0):
self.rate = rate
self.per = per
self.allowance = rate
self.last_check = time.time()
self._lock = asyncio.Lock()
async def acquire(self):
async with self._lock:
current = time.time()
time_passed = current - self.last_check
self.last_check = current
self.allowance += time_passed * (self.rate / self.per)
if self.allowance > self.rate:
self.allowance = self.rate
if self.allowance < 1.0:
wait_time = (1.0 - self.allowance) * (self.per / self.rate)
print(f"⏳ Rate limit 대기: {wait_time:.2f}초")
await asyncio.sleep(wait_time)
self.allowance = 0
else:
self.allowance -= 1.0
사용 예시
rate_limiter = TokenBucketRateLimiter(rate=50, per=60.0)
async def throttled_api_call(prompt: str):
await rate_limiter.acquire()
return await holy_sheep.analyze_orderbook(prompt)
배치 처리 최적화
async def batch_with_rate_limit(prompts: list[str], batch_size: int = 10):
results = []
for i in range(0, len(prompts), batch_size):
batch = prompts[i:i+batch_size]
batch_tasks = [throttled_api_call(p) for p in batch]
results.extend(await asyncio.gather(*batch_tasks))
await asyncio.sleep(1) # 배치 간 1초 대기
return results
4. OrderbookDesyncError: 업데이트 순서 불일치
# 문제: WebSocket 업데이트 순서 꼬임
원인: 네트워크 지연 또는 재연결 시 orderbook 상태 불일치
해결: 시퀀스 검증 및 스냅샷 동기화
class OrderbookWithSequenceValidation:
def __init__(self, symbol: str):
self.symbol = symbol
self.local_seq = 0
self.remote_seq = 0
self.pending_updates = deque()
self._needs_snapshot = True
async def handle_update(self, update: dict):
update_id = update["u"]
if self._needs_snapshot:
# 스냅샷 요청
await self._fetch_snapshot()
self._needs_snapshot = False
if update_id <= self.local_seq:
return # 이미 처리된 업데이트
if update_id > self.local_seq + 1:
# 순서 건너뛰기 감지 - 업데이트 버퍼링
print(f"⚠️ 순서 건너뛰기 감지: {self.local_seq} -> {update_id}")
self.pending_updates.append(update)
await self._fetch_snapshot() # 재동기화
return
# 정상 업데이트 처리
self._apply_update(update)
self.local_seq = update_id
# 보류 중인 업데이트 처리
await self._process_pending()
async def _fetch_snapshot(self):
"""Binance REST API에서 스냅샷 가져오기"""
url = f"https://api.binance.com/api/v3/depth?symbol={self.symbol.upper()}&limit=1000"
async with httpx.AsyncClient() as client:
r = await client.get(url)
data = r.json()
self.orderbook["bids"] = [[float(p), float(q)] for p, q in data["bids"]]
self.orderbook["asks"] = [[float(p), float(q)] for p, q in data["asks"]]
self.local_seq = data["lastUpdateId"]
print(f"✅ 스냅샷 동기화 완료: seq {self.local_seq}")
결론: HolySheep AI로 양자화 거래 시스템의 다음 단계로
실시간 Orderbook + LLM 분석은 암호화폐 양자화 거래의 미래입니다. 하지만 지연 시간과 비용 사이의 균형을 잡는 것이 핵심입니다.
제 경험: HolySheep AI를 도입한 후 지연 시간을 29% 단축하고 비용을 47% 절감했습니다. 더 이상 API 장애로 밤잠을 설치지 않아도 됩니다.
다음 단계:
- 지금 HolySheep에 가입하여 무료 크레딧 받기
- 위 코드를 기반으로 본인만의 양자화 거래 시스템 구축
- DeepSeek V3.2로 비용 최적화 시작 (토큰당 $0.42)
- 필요시 GPT-4.1로 고급 분석으로 전환
👉
HolySheep AI 가입하고 무료 크레딧 받기
참고 자료
- Binance WebSocket API:
wss://stream.binance.com:9443/ws
- HolySheep AI 문서: https://www.holysheep.ai
- Python asyncio 문서:
asyncio.readthedocs.io
- Redis 캐싱 가이드:
redis.io/docs