将检索增强生成系统投入生产时,确保系统持续运行变得非常重要。一个RAG系统,由于其分布式特性,由多个相互协作的组件构成,包括检索引擎、语言模型推理端点、数据管道和编排层。单个组件的故障在这样的复杂系统中并非是否会发生的问题,而是何时会发生的问题。因此,高可用性(HA)和容错性(FT)设计并非事后考虑,而是任何大规模部署的基本要求。
高可用性指系统在大部分时间内保持运行并对用户可用的能力,通常通过量化指标来衡量(例如,“五个九”或99.999%的正常运行时间)。容错性是指系统在其一个或多个组件发生故障时,仍能继续正常运行的特性,即便可能是在性能降低的情况下(优雅降级)。对于专业人士而言,这意味着构建的系统能够预测并自动处理故障,从而最大限度地减少或消除对用户的影响。
弹性RAG系统的核心原则
分布式系统设计中的一些既定原则可直接应用于构建高可用和容错的RAG架构:
-
消除单点故障(SPOFs): 单点故障是指任何一个组件的故障都可能导致整个系统或其大部分无法运行。在RAG应用中:
- 检索: 不使用单个向量数据库实例,而应采用分片和复制的集群。如果使用自定义索引,请确保其服务层具有水平扩展性并进行负载均衡。
- 生成: 在负载均衡器后部署多个LLM推理服务器实例。一个推理服务器的故障不应导致查询处理中断。
- API网关/编排器: 运行这些重要入口点和控制点的多个实例。
-
冗余: 冗余指提供重复的组件,以便在主组件发生故障时进行接管。
- 服务冗余: 运行每个微服务(查询解析器、检索器、排序器、生成器)的多个活动实例。使用多个副本的Kubernetes部署是常见的模式。
- 数据冗余: 在不同的故障域(例如,不同的服务器、机架,甚至可用区)之间复制向量索引、文档存储和LLM权重。对于向量数据库,这通常涉及复制分片。
-
自动化故障转移: 当组件发生故障时,系统必须自动检测到此故障并在无需人工干预的情况下切换到冗余组件。
- 主动-被动模式: 当主动组件发生故障时,备用组件接管。这在有状态系统中很常见,因为在主动-主动节点之间维护一致性较为复杂。
- 主动-主动模式: 多个组件同时处理流量。如果其中一个发生故障,其负载将重新分配给其余的活动实例。这非常适合无状态服务或状态可以轻松低延迟复制的服务。
-
隔离与舱壁: 故障应被限制在系统的特定部分,以防止级联故障。
- 如果重排序组件出现高延迟或故障,系统可能会绕过它,直接从初始检索中提供结果,实现优雅降级而不是完全崩溃。
- 为不同的RAG服务设置资源限制(CPU、内存,例如使用Kubernetes资源配额)可以防止一个服务中的失控进程影响其他服务。
RAG组件弹性策略
让我们来考虑分布式RAG系统主要组件的特定策略:
检索系统(向量搜索):
检索骨干,通常是向量数据库,非常重要。
- 复制: 现代向量数据库(例如Weaviate、Milvus、Pinecone)提供内置复制功能。分片在多个节点之间复制。如果承载主分片的节点发生故障,另一节点上的副本分片可以被提升为主分片。复制因子(每份数据的副本数量)是一个主要配置参数。
- 分片: 虽然主要用于可扩展性,但分片也有助于容错。如果分片损坏或承载特定分片的节点发生故障,只有部分数据受到影响,不需要这些分片的请求仍可得到处理。
- 多可用区部署: 对于基于云的部署,将向量数据库节点和副本分布在多个可用区(AZ)可以防止可用区级别的中断。流量应可路由到健康的可用区。
一个跨两个可用区部署的分片和复制向量数据库的简易视图。检索器API对请求进行负载均衡,数据分片被复制以实现容错。
LLM生成服务:
LLM推理可能资源密集,并且容易出现偶发故障或速度变慢。
- 多个推理端点: 在负载均衡器后部署LLM到多个服务器(如果需要,最好配备专用GPU)。Kubernetes等容器编排平台可以管理这些副本并自动重启失败的实例。
- LLM健康检查: 负载均衡器应使用有意义的健康检查。简单的TCP ping不足够;健康检查理想情况下应发送一个小型、有代表性的推理请求,以确保模型已加载并正常运行。
- 备用模型: 考虑使用一个更小、更快或更有效的LLM作为备用。如果主要的、大型LLM服务出现问题或高延迟,系统可以将请求路由到备用模型,以提供(可能细节较少但无错误的)响应。
- 请求排队和重试: 对于非交互式RAG任务(例如批量文档摘要),应实现请求排队。如果LLM端点暂时不可用,请求可以排队并使用指数退避策略重试。
数据摄取和索引管道:
这些管道为RAG系统提供最新信息。
- 幂等操作: 确保数据摄取管道中的所有步骤(分块、嵌入、索引)都是幂等的。这意味着,如果一个步骤在相同输入下多次执行(例如,由于故障后重试),它会产生相同的结果,而不会产生意外的副作用。
- 检查点: 对于长时间运行的批量摄取作业,应实现检查点。如果作业失败,它可以从上次成功的检查点恢复,而不是从头开始。
- 分布式任务队列: 使用具有持久性和复制功能的消息队列(例如Apache Kafka、RabbitMQ、Redis Streams)来管理嵌入生成和索引任务。如果处理任务的工作程序失败,另一个工作程序可以从队列中接管该任务。
健康监控、优雅降级和恢复
全系统策略非常重要。
全面健康监控:
高可用性/容错性有效实施依赖于对故障的快速检测。为每个服务实施详细的健康检查。这些不仅仅是“进程是否正在运行?”的检查,而是“服务能否执行其核心功能?”的检查。对于检索器,这可能意味着对它的索引执行一个示例查询。对于LLM服务器,这意味着成功运行一次最小推理。必须持续监控每个组件的延迟、错误率和资源利用率指标,并对异常情况进行自动警报。
优雅降级:
并非所有故障都需要完全的服务中断。设计您的RAG系统以实现优雅降级:
- 功能降级: 如果高级重排序模型失败,系统可以回退到直接提供检索结果。如果个性化检索失败,可以回退到全局检索。
- 陈旧数据: 如果实时索引更新失败,系统可能会暂时从最后一个已知良好索引中提供略微陈旧的数据,并在必要时附带指示。
- 流量限制: 在极端负载或部分故障下,系统可能会限制不那么重要的请求,或减少每次查询检索到的文档数量。
断路器模式:
在服务之间实现断路器。如果下游服务(例如LLM)开始持续失败或超时,断路器“跳闸”,并在一段时间内停止向其发送请求。这可以防止调用服务(例如RAG编排器)在徒劳的尝试上浪费资源,并避免其自身也可能过载。经过一段冷静期后,断路器会允许少量测试请求;如果成功,它会关闭并恢复正常运行。
断路器模式通过暂时停止向不健康的下游组件发送请求,并在关闭、打开和半开状态之间循环,从而保护RAG服务免受级联故障影响。
恢复时间目标(RTO)和恢复点目标(RPO):
- RTO: 可接受的最长中断持续时间。系统需要多快恢复?
- RPO: 可接受的最大数据丢失量,以时间衡量(例如,15分钟的数据)。
定义这些目标有助于指导备份、复制和故障转移策略的设计。例如,向量索引的低RPO可能需要近实时复制,而高RPO可能允许每晚备份。
可用性量化与目标设定
可用性通常用“几个九”来表示:
- 99%(两个九):每年约3.65天停机时间。
- 99.9%(三个九):每年约8.76小时停机时间。
- 99.99%(四个九):每年约52.56分钟停机时间。
- 99.999%(五个九):每年约5.26分钟停机时间。
目标可用性级别(A)可以计算为:
A=平均故障间隔时间+平均修复时间平均故障间隔时间
其中MTBF是平均故障间隔时间,MTTR是平均修复时间(或恢复时间)。提高可用性包括增加MTBF(使组件更可靠)和减少MTTR(使恢复更快)。对于专业系统,通过自动化最小化MTTR通常是主要关注点,因为故障不可避免。例如,要达到99.999%的可用性,每年总允许停机时间约为(1−0.99999)×365×24×60≈5.26 分钟。
达到更高的“九”意味着更高的复杂性和成本,因为需要更复杂的冗余、更快的故障转移机制以及可能进行地理分布式部署。将可用性目标与业务需求和RAG应用的重要性保持一致非常重要。例如,面向客户的RAG聊天机器人将比内部知识查询工具具有更严格的可用性要求。
建设高可用和容错系统是一个持续的过程。它需要细致的设计、可靠的实施、持续的监控以及对故障场景的定期测试(例如混沌工程原则),以确保在组件不可避免地发生故障时系统能够按预期运行。这种积极主动的姿态是区分实验性RAG设置与生产级、可靠AI系统的要点。