การกระจายโหลดและกลยุทธ์หลายคีย์
ใช้การกระจายโหลดแบบวนรอบและแบบถ่วงน้ำหนักระหว่างคีย์ API กับบัญชีหลายรายการ เพื่อเพิ่มพื้นที่รองรับก่อนถึงขีดจำกัดอัตราการเรียกใช้และลดการพุ่งสูงของเวลาแฝง p99
การกระจายโหลดและกลยุทธ์หลายคีย์ เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดคีย์ API เดียวจึงไม่เพียงพอ
คีย์ OpenAI API เดียวมีขีดจำกัดอัตราคงที่ ซึ่งวัดเป็นจำนวนคำขอต่อนาที (RPM) และจำนวนโทเค็นต่อนาที (TPM) ที่ระดับ Tier 1, GPT-4o รองรับ 500 RPM และ 30,000 TPM สำหรับแอปพลิเคชันที่ใช้งานจริงและมีผู้ใช้พร้อมกันหลายร้อยคน คีย์เดียวจะชนขีดจำกัดเหล่านี้อยู่ตลอด คีย์ API หลายรายการ ช่วยเพิ่มพื้นที่รองรับที่พร้อมใช้งานตามสัดส่วน
การสร้างคีย์ API หลายรายการ
คุณสามารถสร้างคีย์ API หลายรายการภายในองค์กร OpenAI เดียว หรือสร้างบัญชี OpenAI หลายบัญชี (แต่ละบัญชีจะเรียกเก็บเงินแยกกัน) จัดเก็บคีย์แต่ละรายการไว้ในการกำหนดค่าสภาพแวดล้อม และจัดการคีย์เหล่านั้นเป็น พูล เก็บคีย์ไว้ในตัวจัดการข้อมูลลับ เช่น AWS Secrets Manager หรือ HashiCorp Vault แทนการใส่ไว้ในซอร์สโค้ดหรือไฟล์ .env ที่ส่งเข้าไปในระบบควบคุมเวอร์ชัน
import os
API_KEYS = [
os.environ['OPENAI_KEY_1'],
os.environ['OPENAI_KEY_2'],
os.environ['OPENAI_KEY_3'],
os.environ['OPENAI_KEY_4'],
]
# Total effective RPM = 500 * 4 = 2000 RPM
# Total effective TPM = 30000 * 4 = 120000 TPMการกระจายภาระแบบวนรอบ
การกระจายแบบวนรอบ จะแจกจ่ายคำขออย่างสม่ำเสมอไปยังคีย์ทั้งหมด โดยวนเลือกตามลำดับ วิธีนี้นำไปใช้งานได้ง่าย และทำให้คีย์แต่ละรายการรับภาระใกล้เคียงกันเมื่อเวลาผ่านไป ใช้ตัวนับที่ปลอดภัยต่อเธรดหรือจำนวนเต็มแบบอะตอมิก เพื่อป้องกันไม่ให้คำขอพร้อมกันสองคำขอเลือกคีย์เดียวกันในเวลาเดียวกัน การวนรอบเหมาะเมื่อคีย์ทั้งหมดมีขีดจำกัดอัตราเหมือนกัน
import itertools
import threading
from openai import OpenAI
class RoundRobinPool:
def __init__(self, keys: list):
self._clients = [OpenAI(api_key=k) for k in keys]
self._cycle = itertools.cycle(range(len(self._clients)))
self._lock = threading.Lock()
def get_client(self) -> OpenAI:
with self._lock:
idx = next(self._cycle)
return self._clients[idx]
pool = RoundRobinPool(API_KEYS)
client = pool.get_client()การกระจายภาระแบบถ่วงน้ำหนัก
การกระจายภาระแบบถ่วงน้ำหนัก จะจัดสรรสัดส่วนการรับส่งข้อมูลให้คีย์ระดับสูงกว่า (ซึ่งมีขีดจำกัดอัตราสูงกว่า) มากขึ้นตามความสามารถในการรองรับ หากคีย์ A อยู่ Tier 3 (10,000 RPM) และคีย์ B อยู่ Tier 1 (500 RPM) คีย์ A ควรได้รับคำขอประมาณ 95% การกระจายแบบถ่วงน้ำหนักช่วยป้องกันไม่ให้คีย์ระดับต่ำกว่าเป็นคอขวดเมื่อใช้งานร่วมกับคีย์ระดับสูงกว่า
import random
class WeightedPool:
def __init__(self, key_configs: list):
# key_configs = [{'key': '...', 'weight': 10}, ...]
self._clients = [OpenAI(api_key=c['key']) for c in key_configs]
self._weights = [c['weight'] for c in key_configs]
def get_client(self) -> OpenAI:
return random.choices(self._clients, weights=self._weights, k=1)[0]
pool = WeightedPool([
{'key': os.environ['OPENAI_KEY_TIER3'], 'weight': 20},
{'key': os.environ['OPENAI_KEY_TIER1'], 'weight': 1},
])การติดตามสถานะขีดจำกัดอัตราของแต่ละคีย์
OpenAI API ส่งส่วนหัวขีดจำกัดอัตรากลับมาพร้อมการตอบกลับทุกครั้ง ได้แก่ x-ratelimit-remaining-requests และ x-ratelimit-remaining-tokens ติดตามส่วนหัวเหล่านี้แยกตามคีย์เพื่อดูว่าคีย์ใดใกล้ใช้งานจนหมด เมื่อคีย์รายงานว่ามีคำขอเหลือน้อยกว่า 10 รายการในนาทีปัจจุบัน ให้หยุดส่งการรับส่งข้อมูลไปยังคีย์นั้นชั่วคราว เพื่อป้องกันข้อผิดพลาด 429 ก่อนที่จะเกิดขึ้น
class SmartPool:
def __init__(self, keys: list):
self._clients = [OpenAI(api_key=k) for k in keys]
self._remaining = {i: 500 for i in range(len(keys))} # initial RPM
def get_best_client(self):
# Pick key with most remaining capacity
best_idx = max(self._remaining, key=lambda i: self._remaining[i])
return self._clients[best_idx], best_idx
def update_remaining(self, idx: int, response_headers: dict):
remaining = int(response_headers.get('x-ratelimit-remaining-requests', 0))
self._remaining[idx] = remainingการจัดการข้อผิดพลาดขีดจำกัดอัตรา 429
เมื่อคีย์ส่งคืนข้อผิดพลาด 429 ให้ถอดคีย์นั้นออกจากพูลทันทีเป็นระยะเวลาที่ระบุในส่วนหัว Retry-After (โดยทั่วไปคือ 60 วินาที) ทำเครื่องหมายว่ากำลัง พักเพื่อฟื้นตัว และส่งการรับส่งข้อมูลทั้งหมดไปยังคีย์ที่เหลือ เมื่อช่วงพักสิ้นสุดลง ให้คืนคีย์กลับเข้าสู่พูล วิธีนี้ช่วยป้องกันความล้มเหลวต่อเนื่องที่การลองใหม่บนคีย์เดิมทำให้สถานการณ์แย่ลง
import time
from openai import RateLimitError
class CooldownPool:
def __init__(self, keys: list):
self._clients = [(OpenAI(api_key=k), None) for k in keys] # (client, cooldown_until)
def get_available_clients(self):
now = time.time()
return [
(i, c) for i, (c, until) in enumerate(self._clients)
if until is None or until <= now
]
def mark_cooling(self, idx: int, retry_after: int = 60):
client, _ = self._clients[idx]
self._clients[idx] = (client, time.time() + retry_after)
print(f'Key {idx} cooling down for {retry_after}s')การใช้ OpenRouter เป็นตัวรวมบริการ
OpenRouter เป็นบริการพร็อกซีที่เปิดให้เข้าถึงโมเดลหลายร้อยรายการผ่านปลายทาง API เดียวที่เข้ากันได้กับ OpenAI การส่งคำขอผ่าน OpenRouter ทำให้คุณได้รับการกระจายภาระระหว่างบัญชีผู้ให้บริการเบื้องหลังหลายบัญชีโดยอัตโนมัติ การสลับไปยังผู้ให้บริการสำรอง และการเข้าถึงโมเดลโอเพนซอร์สเพื่อใช้เป็นตัวสำรอง ค่าบริการที่บวกเพิ่มมีเพียงเล็กน้อยเมื่อเทียบกับความเรียบง่ายในการดำเนินงานที่ได้รับ
from openai import OpenAI
# OpenRouter uses the same OpenAI SDK interface
client = OpenAI(
api_key=os.environ['OPENROUTER_API_KEY'],
base_url='https://openrouter.ai/api/v1'
)
response = client.chat.completions.create(
model='openai/gpt-4o', # OpenRouter model name format
messages=[{'role': 'user', 'content': prompt}]
)
# Automatic failover if OpenAI is downการติดตามสุขภาพของคีย์ด้วยเมตริก
ติดตามเมตริกแยกตามคีย์ ซึ่งรวมถึงจำนวนคำขอที่ส่ง จำนวนข้อผิดพลาด 429 ที่ได้รับ และเวลาพักเพื่อฟื้นตัวในชั่วโมงที่ผ่านมา คีย์ที่มีอัตรา 429 สูงจำเป็นต้องลดการรับส่งข้อมูลหรืออัปเกรดระดับ เปิดเผยเมตริกเหล่านี้ผ่านปลายทาง /metrics ในรูปแบบ Prometheus เพื่อให้ระบบติดตามของคุณแจ้งเตือนเมื่อคีย์ใดก็ตามชนขีดจำกัดอย่างต่อเนื่อง
from dataclasses import dataclass, field
from collections import defaultdict
@dataclass
class KeyMetrics:
requests_sent: int = 0
rate_limit_errors: int = 0
total_tokens_used: int = 0
cooldown_count: int = 0
class MetricPool:
def __init__(self, keys: list):
self._clients = [OpenAI(api_key=k) for k in keys]
self._metrics = [KeyMetrics() for _ in keys]
def report(self):
for i, m in enumerate(self._metrics):
error_rate = m.rate_limit_errors / max(m.requests_sent, 1)
print(f'Key {i}: {m.requests_sent} req, {error_rate:.1%} 429 rate')การกระจายคีย์ตามภูมิศาสตร์
หากผู้ใช้ของคุณกระจายอยู่ทั่วโลก ให้พิจารณาดูแลคีย์ API แยกตามภูมิภาคทางภูมิศาสตร์ และส่งคำขอไปยังคีย์ที่อยู่ใกล้ผู้ใช้ที่สุด การลดเวลาไปกลับของเครือข่ายช่วยปรับปรุง TTFT ให้ดีขึ้น ติดตั้งตัวกระจายภาระน้ำหนักเบาในแต่ละภูมิภาค (AWS Lambda@Edge หรือ Cloudflare Worker) เพื่อเลือกคีย์ที่เหมาะสมและส่งคำขอผ่านพร็อกซี ซึ่งช่วยป้องกันไม่ให้ไคลเอนต์เข้าถึงคีย์ของคุณ
REGIONAL_KEYS = {
'us-east': os.environ['OPENAI_KEY_US_EAST'],
'eu-west': os.environ['OPENAI_KEY_EU_WEST'],
'ap-southeast': os.environ['OPENAI_KEY_AP'],
}
def get_key_for_region(user_region: str) -> str:
# Default to us-east if region unknown
return REGIONAL_KEYS.get(user_region, REGIONAL_KEYS['us-east'])การทดสอบตัวกระจายภาระ
เขียนการทดสอบภาระงานที่ส่งคำขอพร้อมกัน 100 รายการผ่านพูลสำหรับกระจายภาระ และวัดการกระจาย อัตราข้อผิดพลาด และเปอร์เซ็นไทล์ของเวลาแฝง ตรวจสอบว่าไม่มีคีย์ใดรับภาระเกินสัดส่วนที่ควรได้รับ และข้อผิดพลาด 429 ต่ำกว่า 0.1% ใช้ asyncio.gather หรือเครื่องมืออย่าง Locust เพื่อจำลองภาระพร้อมกันที่ระบบใช้งานจริงของคุณจะพบ
import asyncio
import time
async def load_test(pool, concurrency=100, total=1000):
sem = asyncio.Semaphore(concurrency)
results = []
async def one_request():
async with sem:
client = pool.get_client()
start = time.perf_counter()
try:
await client.chat.completions.create(
model='gpt-4o-mini',
messages=[{'role': 'user', 'content': 'Ping'}],
max_tokens=5
)
results.append(('ok', time.perf_counter() - start))
except Exception as e:
results.append(('error', str(e)))
await asyncio.gather(*[one_request() for _ in range(total)])
ok = [r for r in results if r[0] == 'ok']
print(f'Success rate: {len(ok)/total:.1%}')
return resultsการเลือกกลยุทธ์การกระจายภาระที่เหมาะสม
เลือกกลยุทธ์การกระจายภาระให้สอดคล้องกับโครงสร้างขีดจำกัดอัตรา ใช้ การวนรอบ เมื่อคีย์ทั้งหมดมีขีดจำกัดระดับเดียวกันและการรับส่งข้อมูลกระจายอย่างสม่ำเสมอ ใช้ การกระจายแบบถ่วงน้ำหนัก เมื่อคีย์มีขีดจำกัดระดับต่างกัน ใช้ การส่งตามสถานะสุขภาพ (ข้ามคีย์ที่ใกล้ใช้งานจนหมด) เมื่อต้องการลดข้อผิดพลาด 429 ภายใต้การรับส่งข้อมูลแบบพุ่งสูง สำหรับระบบที่ใช้งานจริงส่วนใหญ่ การส่งตามสถานะสุขภาพร่วมกับการหน่วงเวลาเพิ่มขึ้นแบบทวีคูณให้สมดุลที่ดีที่สุดระหว่างความเรียบง่ายและความทนทาน
# Strategy selection guide:
# Scenario A: 4 keys all Tier 2 (same limits)
# -> Round-robin: simple, even distribution
#
# Scenario B: 1 Tier 3 key + 3 Tier 1 keys
# -> Weighted: Tier 3 gets 10x weight
#
# Scenario C: Variable traffic with burst periods
# -> Health-aware: track remaining headers, skip near-limit keys
#
# Scenario D: Multi-region, latency-sensitive
# -> Geographic: regional keys, route by user locationตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับกลยุทธ์การกระจายภาระสำหรับ LLM API
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า การกระจายแบบวนรอบและแบบถ่วงน้ำหนัก ช่วยกระจายการรับส่งข้อมูลไปยังคีย์ API หลายรายการเพื่อเพิ่มพื้นที่รองรับของขีดจำกัดอัตรา, การติดตามช่วงพักเพื่อฟื้นตัว ช่วยป้องกันข้อผิดพลาด 429 ต่อเนื่องด้วยการนำคีย์ที่ถูกจำกัดอัตราออกชั่วคราว และ OpenRouter เป็นตัวเลือกการรวมบริการแบบมีการจัดการพร้อมการสลับไปยังตัวสำรองโดยอัตโนมัติ บทถัดไป เราจะนำผู้ให้บริการสำรองและตัวตัดวงจรมาใช้งาน
เรียนรู้ Python ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “การกระจายโหลดและกลยุทธ์หลายคีย์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การกระจายโหลดและกลยุทธ์หลายคีย์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การกระจายโหลดและกลยุทธ์หลายคีย์”
ใช้การกระจายโหลดแบบวนรอบและแบบถ่วงน้ำหนักระหว่างคีย์ API กับบัญชีหลายรายการ เพื่อเพิ่มพื้นที่รองรับก่อนถึงขีดจำกัดอัตราการเรียกใช้และลดการพุ่งสูงของเวลาแฝง p99 คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การกระจายโหลดและกลยุทธ์หลายคีย์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม
ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การวัดเวลาแฝงของ LLM: TTFT และ TPOT
- การกระจายโหลดและกลยุทธ์หลายคีย์
- ผู้ให้บริการสำรองและตัวตัดวงจร
- งบประมาณเวลาและการลดระดับบริการอย่างราบรื่น