Um servidor de arquivos comum para todas as suas instâncias é uma ideia problemática porque pode se tornar um gargalo e um único ponto de falha. Dessa forma, pode acabar por derrotar o propósito de usar um balanceador de carga em primeiro lugar.
Para recomendar uma solução, seria necessário saber muito mais sobre a arquitetura do seu sistema. Eu posso dar algumas sugestões que podem ou não funcionar dependendo da sua arquitetura.
- Verifique se suas instâncias podem responder a todas as solicitações, mesmo que a VM do cache não esteja respondendo. Se os caches estiverem lá apenas para melhorias de desempenho, as instâncias provavelmente poderão responder sem depender dos caches - não com a mesma eficiência.
- Shard o cache. Se você puder calcular um hash da identidade do recurso que está sendo armazenado em cache e usá-lo para escolher entre várias VMs de cache, seu design será mais escalonável. E, usando o mesmo hash, você ainda pode se beneficiar de seus backends de LB com acesso a resultados armazenados em cache por outras instâncias.
- Cache nos backends de LB também. Mesmo se você tiver um cache compartilhado, é uma boa idéia fazer o cache nos backends de LB também. Ele pode proteger contra pontos de acesso em suas VMs de cache e torna seu serviço mais resiliente se uma das VMs de cache estiver indisponível.
Sua escolha de protocolo deve ser orientada por quão bem você pode atender aos requisitos acima. Eu não acho que o NFS é a melhor escolha porque é difícil para a camada de aplicação implementar tempos limite quando um dos servidores NFS não responde. E a possibilidade de um servidor NFS não responder, fazendo com que vários backends de LB se comportem mal, é um risco que eu preferiria não ter.
Um protocolo no qual o lado do cliente (executado nos backends de LB) é implementado no modo de usuário é provavelmente uma escolha melhor porque é mais provável que qualquer encadeamento fique preso por causa de um servidor de cache não respondente. E é mais simples implementar tempos limites no acesso às VMs de cache quando implementadas no modo de usuário.