最近一直在优化自己的 NewAPI 中转站,目前用户大概 9000 人左右,服务器是一台 Google Cloud,6 核 CPU、16GB 内存、100GB SSD,全站 Docker 容器部署。
刚开始的时候觉得一台机器应该没什么压力,后来随着用户越来越多,发现数据库压力越来越明显,特别是 MySQL。CPU 其实一直不高,但是数据库写入越来越频繁,尤其是调用日志,logs 表增长得特别快,查询速度也开始下降。
后来整个思路调整了一下,不再想着一上来就 Kubernetes、Redis Cluster、MySQL 主从这些大架构,而是先把单机资源利用到极致。
首先就是增加 NewAPI 节点。
因为我本身就是 Docker 部署,所以没有再去买第二台服务器,而是在当前服务器直接再跑一个 NewAPI 容器。
现在结构变成了:
Cloudflare
↓
Nginx
↓
NewAPI Node1
NewAPI Node2
↓
共享 MySQL
↓
共享 Redis
两个容器完全使用同一套数据库和 Redis,由 Nginx 做负载均衡。
这样做最大的好处不是性能翻倍,而是一个容器出现问题的时候,另一个容器还能继续处理请求,而且后面如果增加服务器,也不用重新调整架构,直接把第二个节点迁移过去就可以了。
第二个比较大的优化就是日志。
我发现 NewAPI 默认记录的调用日志其实非常多。
对于大部分中转站来说,真正需要保存的数据其实只有:
用户信息
余额
Token 消耗
渠道信息
真正占数据库空间的是调用日志。
如果你的后台并不需要长期查看每一次请求,其实可以把详细调用日志关闭,或者只保留最近几天。
这样 MySQL 的压力会小很多。
100GB 硬盘看起来不少,但是 logs 表增长速度非常快,如果一直不清理,后面数据库会越来越大,备份速度也越来越慢。
Redis 这边我没有做特别复杂的配置。
目前只负责缓存、限流以及一些临时数据,2GB 内存完全够用。
另外建议开启 AOF 持久化,避免 Redis 重启以后缓存全部丢失。
数据库方面没有采用主从,因为目前 9000 用户这个规模还没有必要。
主要做了几个简单优化:
开启慢查询。
合理建立索引。
控制最大连接数。
不要把 max_connections 调到几千,那样反而容易把内存吃满。
Nginx 这边主要开启 KeepAlive 和 gzip,同时提高 worker_connections。
对于 AI 中转来说,请求基本都是长连接,合理配置 KeepAlive 可以减少 TCP 建立连接带来的消耗。
另外一点很多人容易忽略,就是限流。
不要觉得用户少就不用限流。
实际上一个用户就可能把整个节点打满。
我目前按照 Token、用户和 IP 三层做限制,普通用户和高级用户的限制也不同,这样基本可以避免恶意刷接口。
目前整个架构还是一台服务器,没有做真正意义上的集群。
不过已经预留好了扩展能力。
后面如果用户增长到两万以上,我准备增加第二台服务器,把第二个 NewAPI 节点迁移过去。
届时整个架构就变成:
Nginx
↓
服务器1:NewAPI
服务器2:NewAPI
↓
共享 MySQL
↓
共享 Redis
如果以后做到数量级用户,再考虑 Redis Cluster、MySQL 主从、Kafka、ClickHouse 这些组件也不迟。
我一直觉得,中转站的优化应该循序渐进。
很多人用户只有几百、几千,就把 Kubernetes、消息队列、数据库集群全部堆上去了,最后维护成本比服务器成本还高。
对于目前一般规模来说,一台配置不错的服务器,加上双 NewAPI 节点、Redis 缓存、MySQL 优化、日志减负,再配合 Cloudflare 和合理的限流,其实已经能够稳定运行。
等真正遇到瓶颈,再逐步拆分数据库、日志和节点,会比一次性上大架构更省心,也更容易维护。