SpringAI完整学习指南-涉及Redis相关问题(二)

发布时间:2026/7/2 4:09:09
SpringAI完整学习指南-涉及Redis相关问题(二) 目录一、排查本地 Redis 是否支持 RediSearch / RedisStack方法 1:MODULE LIST(最权威)方法 2:直接发 FT 命令方法 3:Docker 场景快速自查二、常见问题org.springframework.ai.vectorstore.VectorStore that could not be found三、Lettuce 和 Jedis 对比四、为什么 Spring AI 的 RedisVectorStore 强依赖 Jedis?五、常见问题redis.clients.jedis.exceptions.JedisDataException: ERR unknown command FT._LIST, with args beginning with:一、排查本地 Redis 是否支持 RediSearch / RedisStack方法 1:MODULE LIST(最权威)redis-cli MODULE LIST支持 RedisStack 的实例会返回若干模块,关键是看有没有 search(RediSearch)、ReJSON、timeseries、bf、redisvector 等: 1) 1) name 2) search ← RediSearch(Spring AI 必需) 3) ver 4) (integer) 20810 2) 1) name 2) ReJSON ...只要 search 模块在列表里,Spring AI 的 RedisVectorStore 就能用。 列表为空说明你跑的是普通 Redis。方法 2:直接发 FT 命令redis-cli FT._LIST返回空数组 (empty array) → 支持 RediSearch,只是还没建索引报错 ERR unknown command FT._LIST → 不支持方法 3:Docker 场景快速自查如果是 Docker 启的,直接看镜像名:docker ps --format table {{.Image}}\t{{.Names}}如果是 redis:7-alpine 这类精简镜像,几乎肯定不带 Stack。换成:docker run -d --name redis-stack -p 6379:6379 \ redis/redis-stack-server:latest二、常见问题org.springframework.ai.vectorstore.VectorStore that could not be foundParameter 2 of method chatClient in com.study.config.ChatConfig required a bean of type org.springframework.ai.vectorstore.VectorStore that could not be found. Action: Consider defining a bean of type org.springframework.ai.vectorstore.VectorStore in your configuration.原因Spring Data Redis 用了 Lettuce,但 RedisVectorStore 强依赖 JedisSpring Boot 中 lettuce.pool 配置 classpath 上有 lettuce(被 spring-boot-starter-data-redis 默认带入)→ 自动装配LettuceConnectionFactory,不创建 JedisConnectionFactory。从源码来看RedisVectorStoreAutoConfiguration 的匹配条件包含JedisConnectionFactory必须有 Jedis 连接工厂、EmbeddingModel必须有嵌入模型。由于容器里只有LettureConnectionFactory,ConditionalOnBean(JedisConnectionFactory.class) 不满足 → 自动装配跳过 →RedisVectorStore bean 不注册 → Spring 报 VectorStore bean not found。三、Lettuce 和 Jedis 对比维度Lettuce Jedis ⚔️底层 IONetty(异步非阻塞,NIO)原生 Socket(同步阻塞,BIO)线程安全✅ 单连接天然线程安全,多线程共享❌ 非线程安全,必须配连接池连接复用单个物理连接复用多 logical connection每个线程占用一个物理连接API 风格同步 异步(Future) 响应式(Flux/Mono)三套同步为主,API 简单直接连接池可选(默认不用)必须用(JedisPool)集群支持好且自动刷新 slot好,但 slot 变更需要手动处理性能(高并发) 更优(少建连接,事件驱动) 一般(依赖连接池大小)依赖体积大(带 Netty)小(几十 KB)Spring Boot 默认✅ 2.x 起默认❌ 需手动引Spring AI RedisVectorStore❌ 不支持✅ 强依赖Lettuce 的共享单连接一个连接就能扛多线程并发,因为命令在 Netty pipeline 里被序列化省掉了连接池的开销(建连是很贵的)高并发下性能稳定Jedis 的一连接一线程简单粗暴,每个线程独占一个物理连接连接不够用时阻塞等待API 简单,适合中小项目Lettuce(异步 响应式) RedisClient client RedisClient.create(redis://localhost); StatefulRedisConnectionString, String conn client.connect(); // 同步 conn.sync().set(key, value); // 异步 RedisFutureString future conn.async().get(key); // 响应式(Mono/Flux) MonoString mono conn.reactive().get(key);Jedis(纯同步) JedisPool pool new JedisPool(localhost, 6379); try (Jedis jedis pool.getResource()) { // 必须从池里拿 jedis.set(key, value); String v jedis.get(key); }四、为什么 Spring AI 的 RedisVectorStore 强依赖 Jedis?RedisVectorStore 内部直接用了 Jedis 的 UnifiedJedis.ftCreate() / ftSearch() 这类 RediSearch 专属 API:// Spring AI 源码片段 public class RedisVectorStore implements VectorStore { private final UnifiedJedis jedis; // ← 直接持有 Jedis 客户端 public void add(ListDocument documents) { jedis.ftAdd(indexName, ...); // 调 RediSearch 命令 } }Lettuce 虽然也支持 RediSearch 命令(通过 dispatch() 自定义命令),但 Spring AI 团队选择了 Jedis——因为 Jedis 对 RediSearch的 API 封装更完整。这是历史选择,短期内不会改。五、常见问题redis.clients.jedis.exceptions.JedisDataException: ERR unknown command FT._LIST, with args beginning with:原因redis的版本以及redis不支持redisSearch导致解决方案下载支持redisSearch的版本例如redis/redis-stack-server:latest举例WSL环境**下载redis** docker pull redis/redis-stack-server:latest **启动redis** docker run -d \ --name redis-search \ -p 6379:6379 \ -v ~/redis-data:/data \ --restart always \ redis/redis-stack-server:latest **验证** **进入redis客户端** docker exec -it redis-search redis-cli **查看加载模块必须出现search** MODULE LIST **测试检索命令** FT.CREATE test_idx ON HASH PREFIX 1 doc: SCHEMA title TEXT **取镜像慢解决国内镜像加速** sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [ https://mirror.ccs.tencentyun.com, https://docker.mirrors.ustc.edu.cn ] } EOF sudo service docker restart **权限问题兜底若还报 socket 权限拒绝** sudo usermod -aG docker $USER newgrp docker 删除冲突的旧容器 docker rm redis-search 如果容器正在运行加 -f 强制删除 docker rm -f redis-searchs作者筱白爱学习欢迎关注转发评论点赞沟通您的支持是筱白的动力