Для интеграции Memcached в FastAPI можно использовать библиотеки вроде pymemcache (синхронный) или aiomcache (асинхронный). Вот подробное руководство:
pip install fastapi pymemcache aiomcachefrom pymemcache.client.base import Client
from fastapi import FastAPI
app = FastAPI()
# Подключение к Memcached
memcached_client = Client(("localhost", 11211))import aiomcache
from fastapi import FastAPI
app = FastAPI()
# Асинхронный клиент
async def get_memcached_client():
return aiomcache.Client("localhost", 11211)@app.get("/cache/{key}")
def get_cached_data(key: str):
value = memcached_client.get(key)
if value:
return {"cached_value": value.decode()}
else:
# Имитация долгой операции
result = f"Data for {key}"
memcached_client.set(key, result, expire=300) # TTL = 5 минут
return {"result": result}@app.get("/async-cache/{key}")
async def get_async_cache(key: str):
client = await get_memcached_client()
value = await client.get(key)
if value:
return {"cached_value": value.decode()}
else:
result = f"Data for {key}"
await client.set(key, result, exptime=300)
return {"result": result}from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
@app.post("/cache-item/{item_id}")
def cache_item(item_id: str, item: Item):
memcached_client.set(
f"item:{item_id}",
item.json(), # Сериализация в JSON
expire=300
)
return {"status": "cached"}@app.delete("/cache/{key}")
def delete_cache(key: str):
memcached_client.delete(key)
return {"status": "deleted"}from fastapi import Request, Response
from pymemcache.client.base import Client
memcached_client = Client(("localhost", 11211))
@app.middleware("http")
async def cache_middleware(request: Request, call_next):
response_key = f"cache:{request.url}"
cached_response = memcached_client.get(response_key)
if cached_response:
return Response(content=cached_response, media_type="application/json")
response = await call_next(request)
if response.status_code == 200:
memcached_client.set(response_key, response.body, expire=300)
return responseimport os
from pymemcache.client.base import Client
MEMCACHED_HOST = os.getenv("MEMCACHED_HOST", "localhost")
MEMCACHED_PORT = int(os.getenv("MEMCACHED_PORT", 11211))
memcached_client = Client((MEMCACHED_HOST, MEMCACHED_PORT))import aiomcache
from fastapi import FastAPI, Depends
app = FastAPI()
async def get_async_client():
return aiomcache.Client("localhost", 11211)
@app.get("/async/{key}")
async def get_async(key: str, client=Depends(get_async_client)):
value = await client.get(key.encode())
return {"value": value.decode() if value else "Not found"}version: '3.8'
services:
api:
build: .
ports:
- "8000:8000"
environment:
- MEMCACHED_HOST=memcached
depends_on:
- memcached
memcached:
image: memcached:latest
ports:
- "11211:11211"from fastapi import FastAPI, Request
from pymemcache.client.base import Client
from pydantic import BaseModel
app = FastAPI()
memcached_client = Client(("localhost", 11211))
class Item(BaseModel):
name: str
price: float
@app.get("/items/{item_id}")
def get_item(item_id: str):
cached_item = memcached_client.get(item_id)
if cached_item:
return {"item": cached_item.decode()}
# Имитация БД-запроса
item = {"id": item_id, "name": "Sample", "price": 9.99}
memcached_client.set(item_id, str(item), expire=300)
return item
@app.delete("/items/{item_id}")
def delete_item(item_id: str):
memcached_client.delete(item_id)
return {"status": "deleted"}def generate_key(endpoint: str, **kwargs) -> str:
return f"{endpoint}:{'_'.join([f'{k}_{v}' for k, v in kwargs.items()])}"try:
value = memcached_client.get(key)
except Exception as e:
print(f"Memcached error: {str(e)}")
value = None# Для сложных объектов
import json
def set_cached_data(key: str, data: dict, ttl: int = 300):
memcached_client.set(key, json.dumps(data), expire=ttl)memcached_client = Client(
("localhost", 11211),
connect_timeout=0.5,
timeout=0.5,
no_delay=True,
ignore_exc=True
)from aiomcache import Client
import asyncio
async def get_async_pool():
return await Client.create_pool("localhost", 11211)from pydantic import BaseModel
import json
class Product(BaseModel):
id: str
name: str
price: float
@app.get("/products/{product_id}", response_model=Product)
def get_product(product_id: str):
cached = memcached_client.get(f"product:{product_id}")
if cached:
return Product.parse_raw(cached)
# Имитация БД-запроса
product = Product(id=product_id, name="Example", price=19.99)
memcached_client.set(f"product:{product_id}", product.json(), expire=300)
return productfrom sqlalchemy import create_engine
from sqlalchemy.orm import Session
from fastapi import Depends
engine = create_engine("sqlite:///./test.db")
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users/{user_id}")
def get_user(user_id: str, db: Session = Depends(get_db)):
cached_user = memcached_client.get(f"user:{user_id}")
if cached_user:
return json.loads(cached_user.decode())
user = db.query(UserModel).filter(UserModel.id == user_id).first()
memcached_client.set(f"user:{user_id}", json.dumps(user.__dict__), expire=300)
return user@app.post("/clear-cache/{prefix}")
def clear_cache(prefix: str):
# Удаляет все ключи, начинающиеся с prefix
keys = memcached_client.behaviors["binary"] = True
keys = memcached_client.get_multi([f"{prefix}*"])
for key in keys:
memcached_client.delete(key)
return {"status": "cache cleared"}# Memcached
memcached.sock
- pymemcache: Официальный синхронный клиент.
- aiomcache: Асинхронный клиент.
- fastapi-memcached: Дополнительные инструменты для FastAPI (если есть).
from fastapi.testclient import TestClient
import pytest
def test_cache():
client = TestClient(app)
response = client.get("/items/123")
assert response.status_code == 200
assert memcached_client.get("items/123") is not None- Используйте асинхронные клиенты (aiomcache) для асинхронных приложений.
- Ограничьте размер данных: Memcached хранит данные до 1 МБ.
- Используйте префиксы для ключей, чтобы избежать конфликтов.
- Настройте TTL согласно политике кэширования.
- Избегайте хранения больших объектов: Используйте сериализацию (JSON) для сложных структур.
FROM python:3.9-slim
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]Для работы с Memcached в FastAPI:
- Используйте aiomcache для асинхронных приложений.
- Настройте TTL для автоматической очистки устаревших данных.
- Сериализуйте данные (например, в JSON) перед сохранением.
- Интегрируйте через middleware для автоматического кэширования ответов.
- Используйте Docker для локального тестирования и деплоя.
Это ускорит работу приложения и снизит нагрузку на БД.