ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Feast Java 组件开发指南:Feast Serving 与 Serving Client 的构建、测试与调试实战

2026/9/17 22:27:37 拓冰建站 浏览量
Feast Java 组件开发指南:Feast Serving 与 Serving Client 的构建、测试与调试实战 Feast Java 组件开发指南Feast Serving 与 Serving Client 的构建、测试与调试实战【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast本文面向希望为 Feast 的 Java 侧组件Feast Serving 与 Feast Serving Client贡献代码的开发者系统梳理 feast-java 子仓库的目录结构、环境准备、代码规范、Makefile 快捷命令、IDE 配置并结合仓库源码深入讲解 Feast Serving 的本地构建、配置编写、gRPC 查询验证与远程调试流程。读完本文你将能够独立完成从拉取代码、编译打包到本地启动 Feast Serving 并跑通在线特征读取的全过程。一、feast-java 子仓库的定位与贡献范围Feast 是一个面向 AI/ML 的开源特征存储Feature Store其代码库分布在多个仓库中。当前仓库中的java/目录对应独立的 feast-java 组件仓库贡献范围聚焦于两个核心组件见 java/README.mdFeast Serving一个基于 gRPC 的服务用于向模型在线提供最新特征值serving the latest feature values to models依赖在线存储如 Redis读取特征Feast Serving Client一个轻量 Java 客户端通过 gRPC 从运行中的 Feast Serving 实例检索特征。注意feast-java 组件仓库只覆盖上述两个 Java 组件。如果读者想贡献的是 Feast 其他组件Python SDK、Go 特征服务器等应参考仓库根目录的 docs/project/development-guide.md那里说明了 Feast 各组件如何跨多个仓库分布。架构前提写读解耦根据 java/README.md 的架构说明Feast Serving 依赖在线存储以 Redis 为例来检索特征而将数据写入在线存储的过程与从在线存储读取的过程是解耦的。这意味着贡献者在开发 Serving 组件时通常不需要关心特征如何被物化materialize进在线存储只需要保证读取链路正确即可——这也是本地开发时可以只准备一个 Redis 实例、一份注册表文件就能跑起 Serving 的原因。二、仓库结构四个顶层 Maven 模块feast-java 共包含四个顶层 Maven 模块在 java/pom.xml 中以modules声明模块目录作用servingjava/servingFeast Serving一个用于在线提供特征的 gRPC 服务serving-clientjava/serving-clientFeast Serving Client与 Serving 通过 gRPC 通信的轻量 Java 客户端datatypesjava/datatypes整体项目 protos 的链接包含核心 serving gRPC protos 以及 Feast registry 中所有对象的 proto 表示coveragejava/coverage生成 JaCoCo 覆盖率报告从 java/pom.xml 可以看到父 POM 的关键信息groupId 为dev.feastartifactId 为feast-parent当前 revision 版本为0.66.0Java 编译目标为 11release11/release依赖版本集中管理gRPC1.63.0、protobuf3.25.5、protoc3.12.2、Jackson2.15.0、Guava32.0.0-jre等通过maven-enforcer-plugin强制构建环境Maven 版本必须满足[3.6,4.0)Java 版本必须 11.0并要求reactorModuleConvergence模块间依赖收敛、禁止重复依赖版本集成spotless-maven-plugingoogleJavaFormat 1.7GOOGLE 风格并配置了 Apache-2.0 license header 检查其 check 阶段被提前到process-test-classes以便更早暴露格式问题。Feast Serving 内部包结构Feast Serving 的源码树围绕主入口ServingGuiceApplication组织为以下关键包对应原文档的 Feast Serving 一节connectors在线存储连接器例如 Redis见 connectors/redis 下的RedisClient、RedisClusterClient、RedisOnlineRetriever、EntityKeySerializer等exceptionFeast Serving 抛出的面向用户的异常例如SpecRetrievalExceptionregistry将 Feast 文件型注册表位于 GCS、S3 或本地解析为Registryproto 对象的逻辑并自动重新同步注册表。对应实现包括Registry、RegistryRepository、RegistryFile接口及其LocalRegistryFile、GSRegistryFile、S3RegistryFile、AzureRegistryFile四种实现service支撑 serving API 的核心逻辑包括与特征转换服务器transformation server通信以执行按需转换on-demand transformations根代码创建主入口ServingServiceV2它被注入到grpc/下的OnlineServingGrpcServiceV2中实现 gRPC 服务config为服务器和配置提供支撑的 Guice 模块其中ServerModule包含服务器配置与 Guice 模块ApplicationPropertiesModule与ApplicationProperties负责把 Feast Serving 的整体用户配置从 Java 映射到 YAMLcontroller服务器控制器目前只有一个 gRPC 健康检查HealthServiceControllergrpcgRPC serving 服务的实现OnlineServingGrpcServiceV2interceptorsgRPC 拦截器目前用于为每个 gRPC 请求生成指标见GrpcMonitoringInterceptor、GrpcMonitoringContext。说明代码中存在对 metrics 收集的引用这些目前未实际使用属于历史遗留源自早期基于 Spring Boot 的实现在发布到 StatsD / Prometheus Pushgateway 之前会保留在代码中。从源码结构看Feast Serving 采用Guice 依赖注入组装应用ServingGuiceApplication.java 的main方法要求通过 CLI 传入应用配置文件路径随后创建 Injector注册ServingServiceV2Module、RegistryConfigModule、InstrumentationConfigModule、ServerModule、ApplicationPropertiesModule获取Server实例并start()/awaitTermination()。三、通用环境准备Common Setup所有 feast-java 组件都需要以下开发工具对应原文档 Common Setup 一节Java SE Development Kit 11在 macOS 上可能需要export JAVA_HOME$(/usr/libexec/java_home -v 11)Maven 3.6父 POM 的 enforcer 规则明确要求[3.6,4.0)版本区间make用于调用仓库根目录 Makefile 提供的快捷任务。这些版本约束并非随意指定而是由 java/pom.xml 中maven-enforcer-plugin的valid-build-environment规则强制执行Java 11、Maven[3.6,4.0)一旦环境不满足构建会直接失败。四、代码风格Google Java Style GuideFeast 的 Java 代码遵循 Google Java Style Guide。自动化格式化命令为# 格式化 feast-java 仓库中的所有代码 make format-java该命令在 Makefile 中的实际定义是${MVN} spotless:apply即通过前面提到的 spotless-maven-plugingoogleJavaFormat、GOOGLE 风格完成格式化。对应的 lint 校验命令是make lint-javaspotless:checkCI 会使用它来把关。如果使用 IntelliJ IDEA可以导入 Google 官方的intellij-java-google-style.xml代码风格设置以便直接使用 IDE 的 Reformat 功能。五、Makefile 开发快捷命令仓库根目录的 Makefile 为常见的 Java 开发任务提供了速记命令原文档强调这些命令依赖本地已安装的 Python 版feast命令作用实际执行内容make test-java运行所有 Java 单元测试mvn --no-transfer-progress -DskipITstrue testmake test-java-integration运行所有 Java 集成测试mvn --no-transfer-progress -Dmaven.javadoc.skiptrue -Dgpg.skip -DskipUTstrue clean verifymake test-java-with-coverage运行带覆盖率统计的单元测试mvn --no-transfer-progress -DskipITstrue test jacoco:report-aggregatemake build-java完整构建含测试mvn clean verifymake build-java-no-tests跳过测试构建mvn clean package跳过 UT/IT、javadoc、gpg构建 Feast Serving 的 Docker 镜像make build-docker REGISTRYgcr.io/kf-feast VERSIONdevelopmake build-docker在 Makefile 中聚合了多个子任务其中包含build-feature-server-java-docker即 Java 特征服务器的镜像构建REGISTRY与VERSION用于控制镜像的仓库地址与版本标签。六、IntelliJ IDE 设置让 proto 生成代码可被索引由于 proto 生成的代码不会被 IntelliJ 自动索引直接打开项目时自动补全可能失效。修复方式对应原文档 IDE Setup 一节打开Project Structure Modules datatypes-java将以下目录标记为Source目录target/generated-sources/protobuf/grpc-javatarget/generated-sources/protobuf/javatarget/generated-sources/annotations这些目录正是protobuf-maven-plugin生成的 gRPC stub、Java proto message 以及注解处理器产物所在位置。在标记为 Source 之前任何引用feast.proto.serving.ServingServiceGrpc等生成类的代码都无法获得跳转与补全能力。七、Feast Serving 本地开发从构建到跑通Feast Serving 的开发者指南 提供了完整的本地开发流程下面按步骤展开。7.1 前置条件Maven 3.6.x一个 Feast 特征仓库feature repo例如 feast-demo 这类示例仓库用于提供注册表文件一个正在运行的在线存储实例例如本地 Redisredis-server。7.2 构建步骤在仓库根目录依次执行# 1. 安装全部 Java 模块跳过测试 mvn -f java/pom.xml install -Dmaven.test.skiptrue # 2. 为 serving 打包可执行 jar跳过测试 mvn -f java/serving/pom.xml package -Dmaven.test.skiptrue第二步会通过maven-assembly-plugin生成feast-serving-[版本号]-jar-with-dependencies.jarfat jar其 Main-Class 配置为feast.serving.ServingGuiceApplication见 java/serving/pom.xml。7.3 编写 application-override.yaml 配置创建一个名为application-override.yaml的覆盖配置指定 Feast 项目名与注册表路径。使用本地注册表的最小示例feast: project: feast_demo registry: /Users/[your username]/GitHub/feast-demo/feature_repo/data/registry.db entityKeySerializationVersion: 3如果使用远程注册表如 GCS 上的gs://...也是支持的。结合 Redis 在线存储与远程注册表的完整示例feast: project: feast_java_demo registry: gs://[YOUR BUCKET]/demo-repo/registry.db entityKeySerializationVersion: 3 activeStore: online stores: - name: online type: REDIS config: host: localhost port: 6379 password: [YOUR PASSWORD]这些配置项的语义可以在源码中找到确切依据ApplicationProperties.java 中的FeastProperties定义了registry、project、registryRefreshInterval、entityKeySerializationVersion、activeStore、stores、tracing、transformationServiceEndpoint等字段其中registry、project、activeStore标注了NotBlank启动时通过PostConstruct validate()使用 JSR-303 校验Store类的type枚举支持REDIS与REDIS_CLUSTERStoreTypegetActiveStore()会遍历stores列表按activeStore名称匹配找不到对应 store 时抛出RuntimeException(Active store is misconfigured...)Redis 单机配置getRedisConfig()读取host、port、可选ssl默认 false与password默认空串Redis 集群配置getRedisClusterConfig()读取connection_string、read_from默认UPSTREAM、timeoutISO-8601 格式必填、ssl默认 false与password默认配置模板见 application.yml其中展示了REDISonline与REDIS_CLUSTERonline_cluster两个示例 store并注明 gRPC 服务默认监听6566端口避开 Feast Core 默认的 6565 端口tracing 默认关闭仅支持 Jaeger tracerserviceName 为feast_serving。7.4 启动 Feast Serving运行打包出的带依赖 jar版本号以实际构建为准java \ -Xms1g \ -Xmx4g \ -jar java/serving/target/feast-serving-[YOUR VERSION]-jar-with-dependencies.jar \ classpath:/application.yml,file:./application-override.yaml启动成功后本地即有一个运行在6566端口的 Feast Serving gRPC 服务。这里传入的classpath:/application.yml,file:./application-override.yaml是配置源列表先加载内置默认配置再用工作目录下的application-override.yaml覆盖同名键。结合 7.3 中ApplicationProperties的校验逻辑可以推断如果覆盖配置缺少必填项如project、registry、activeStore服务会在启动阶段因ConstraintViolationException而失败。7.5 用 grpc_cli 验证在线特征读取如果安装了grpc_cli可以先列出服务确认 Feast Serving 已就绪grpc_cli ls localhost:6566发起一次GetOnlineFeatures调用验证特征读取grpc_cli call localhost:6566 GetOnlineFeatures features { val: driver_hourly_stats:conv_rate val: driver_hourly_stats:acc_rate } entities { key: driver_id value { val { int64_val: 1001 } val { int64_val: 1002 } } } 示例输出每个实体返回一组特征值、状态与事件时间戳connecting to localhost:6566 metadata { feature_names { val: driver_hourly_stats:conv_rate val: driver_hourly_stats:acc_rate } } results { values { float_val: 0.812357187 } values { float_val: 0.379484832 } statuses: PRESENT statuses: PRESENT event_timestamps { seconds: 1631725200 } event_timestamps { seconds: 1631725200 } } results { values { float_val: 0.840873241 } values { float_val: 0.151376978 } statuses: PRESENT statuses: PRESENT event_timestamps { seconds: 1631725200 } event_timestamps { seconds: 1631725200 } } Rpc succeeded with OK status从输出可见每个请求的结果包含results列表按实体维度组织、feature_names元数据以及每条特征值对应的statuses如PRESENT与event_timestamps。请求-响应的消息结构定义在feast.proto.serving.ServingAPIProto源码引用见 serving-client 中的使用proto 源文件位于 protos/feast/serving。7.6 远程调试 Feast ServingFeast Serving 与普通 Java 可执行程序一样支持调试。把上面的启动命令替换为java \ -Xdebug \ -Xrunjdwp:transportdt_socket,address5005,servery,suspendy \ -Xms1g \ -Xmx4g \ -jar java/serving/target/feast-serving-[YOUR VERSION]-jar-with-dependencies.jar \ classpath:/application.yml,file:./application-override.yaml然后在 IntelliJ 中配置 Remote Debugger 连接到 5005 端口即可打断点调试。suspendy表示 JVM 会在等待调试器连接期间挂起。八、Feast Serving 的测试体系单元测试与集成测试除了 Makefile 提供的命令Feast Serving 的开发者指南 还给出了针对serving模块的 Maven 级命令# 运行单元测试 mvn test -pl serving --also-make # 运行集成测试 mvn verify -pl serving --also-make # 以调试模式运行集成测试 mvn -Dmaven.failsafe.debug verify -pl serving --also-make测试代码的组织可以从 java/serving/src/test 中看到清晰的划分单元测试位于feast/serving/service/包例如OnlineServingServiceTest、FeaturesTest、RequestHelperTest配合 Mockito见父 POM 的mockito-core依赖与测试目录下的mockito-extensions/org.mockito.plugins.MockMaker进行 mock 验证集成测试位于feast/serving/it/包例如ServingRedisLocalRegistryIT、ServingRedisGSRegistryIT、ServingRedisS3RegistryIT、ServingRedisAzureRegistryIT、TransformationServiceIT覆盖本地 / GCS / S3 / Azure 注册表与 Redis 在线存储的组合场景集成测试会通过 java/serving/pom.xml 中exec-maven-plugin的feast_test_apply执行src/test/resources/docker-compose/feast10/setup_it.py即先feast apply准备特征仓库并使用 docker-compose-redis-it.yml 拉起测试用 Redis依赖embedded-redis、Testcontainers、s3mock-testcontainers等测试依赖。九、Feast Serving Client 开发9.1 环境与构建Feast Serving Client 是一个用于从运行中的 Feast Serving 实例检索特征的客户端开发前先完成前面的 Common Setup。获取运行中的 Serving 实例的方法见上一节。构建 / 编译客户端mvn package -pl sdk/java --also-make -Dmaven.test.skiptrue说明原文档中的sdk/java是早期模块路径。在当前仓库结构中客户端模块位于 java/serving-client父 POM 中注册的模块名为serving-clientartifactId 为feast-serving-client因此基于当前仓库应使用mvn package -pl serving-client --also-make -Dmaven.test.skiptrue。9.2 单元测试mvn package -pl sdk/java test --also-make同样地在当前仓库中对应mvn test -pl serving-client --also-make。客户端测试见 FeastClientTest.java 与 RequestUtilTest.java。9.3 客户端 API 速览从源码结构看FeastClient.java 是客户端的主入口实现了AutoCloseable关键 API 包括FeastClient.create(String host, int port)创建无安全配置的客户端FeastClient.create(String host, int port, long requestTimeout)可指定请求超时毫秒0 表示不设超时FeastClient.createSecure(...)通过SecurityConfigTLS 等见 SecurityConfig.java创建安全连接客户端内部使用ManagedChannelNetty与ServingServiceBlockingStub调用GetOnlineFeatures等 gRPC 方法支持 OpenTracing 拦截器与基于证书的 TLSGrpcSslContexts。与客户端配套的还有Row.java在线特征请求的行结构封装与RequestUtil.java请求构建工具。十、与 Helm Charts / Java Demo 的联调如果想要在 Kubernetes 环境、基于 Helm 部署的方式下开发可参考 examples/java-demo 了解如何修改 Helm chart 或 Java 逻辑并验证二者交互。整体 Helm Charts 位于 infra/charts/feast对应 java/README.md 中 Installing using Helm 的说明。小结从贡献者视角回顾关键路径定位feast-java 只覆盖 Feast Serving 与 Serving Client 两个 Java 组件其余组件参考 docs/project/development-guide.md环境JDK 11 Maven 3.6 make父 POM 的 enforcer 会强制校验规范Google Java Stylemake format-javaspotless一键格式化make lint-java校验构建与测试make test-java/make test-java-integration或模块级mvn test/verify -pl serving --also-make本地运行mvn -f java/serving/pom.xml package打包 fat jar配合application-override.yamlproject、registry、activeStore、stores启动默认监听 6566 端口可用grpc_cli验证GetOnlineFeatures支持 JDWP 5005 远程调试配置真相来源所有配置字段的语义、默认值与校验规则都可以在 ApplicationProperties.java 与 application.yml 中一一对应查证。【免费下载链接】feastThe Open Source Feature Store for AI/ML项目地址: https://gitcode.com/GitHub_Trending/fe/feast创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考