2. 核心原理收银员与小本本把PostgreSQL想象成超市的总仓库每次查询都得跑大老远去取货。Redis就是收银员随身带的小本本记下最常卖的商品热点数据。下次顾客要直接从小本本查秒级响应。Elasticsearch呢它像个档案管理员把所有日志分门别类建索引你可以用关键词秒搜到任何请求的细节再也不用登录服务器翻文件了。3. 开干FastAPI Redis ES 集成假设你已经有个FastAPI项目连了PostgreSQL。咱们一步步加料。 3.1 安装依赖pip install redis elasticsearch[async] fastapi-cache2[redis]这里用了fastapi-cache库封装了缓存装饰器省得自己写重复代码。当然你也可以直接用aioredis看个人喜好。 3.2 Redis缓存装饰器实战创建一个缓存工具模块# app/cache.py from fastapi_cache import FastAPICache from fastapi_cache.backends.redis import RedisBackend from fastapi_cache.decorator import cache import redis.asyncio as redis async def init_cache(redis_url: str redis://localhost:6379): redis_client redis.from_url(redis_url, encodingutf-8, decode_responsesTrue) FastAPICache.init(RedisBackend(redis_client), prefixfastapi-cache)然后在启动事件中调用# main.py from app.cache import init_cache app.on_event(startup) async def startup(): await init_cache()重点来了在需要缓存的接口上加cache()装饰器app.get(/items/{item_id}) cache(expire60) # 缓存60秒 async def get_item(item_id: int, db: Session Depends(get_db)): # 这里是数据库查询 item db.query(Item).filter(Item.id item_id).first() return item就这么简单同样的请求60秒内直接走Redis数据库连看都不看一眼。⚠️ 这里我踩过一个坑如果接口参数里有db session这种不可哈希的对象fastapi-cache会报错。解决办法是把依赖项移到装饰器外面或者用cache(…, key_builder…)自定义键。 3.3 Elasticsearch日志中间件日志不能只打控制台要统一送ES。我们写一个中间件记录每次请求的方法、路径、状态码、耗时等。# app/log_middleware.py from elasticsearch import AsyncElasticsearch import time import json es AsyncElasticsearch([http://localhost:9200]) app.middleware(http) async def log_to_es(request: Request, call_next): start time.time() response await call_next(request) duration time.time() - start log_data { method: request.method, url: str(request.url), status_code: response.status_code, duration: round(duration, 4), client_ip: request.client.host, timestamp: time.strftime(%Y-%m-%dT%H:%M:%SZ, time.gmtime()) } # 异步发送日志别阻塞请求 await es.index(indexfastapi-logs, documentlog_data) return response注意生产环境千万别每个请求都同步发ES得用批量发送缓冲或者用background tasks。上面只是demo实际要优化。4. 那些年我踩过的坑必看集成完了别急下面这几个坑我挨个帮你排雷。 坑1缓存穿透— 查询一个不存在的id每次都会穿透到数据库。解决方案缓存空值或布隆过滤器。 坑2ES索引爆炸— 如果不管理索引生命周期日志会把磁盘撑爆。一定要用ILM索引生命周期管理或定时删除旧索引。 坑3异步Redis连接未关闭— 服务停止时忘记关闭Redis连接导致警告。在shutdown事件里加await FastAPICache.clear()和redis_client.close()。 坑4ES连接失败导致请求阻塞— 日志中间件里要加try-except否则ES挂掉整个API也挂了。是不是以为这样就完了No no no还有进阶操作✅ 用缓存预热在启动时加载热门商品到Redis。✅ 给ES日志加上APM trace ID配合链路追踪。✅ 把缓存装饰器封装成统一custom_cache自动处理异常和降级。