opensearch-project / k-NN

🆕 Find the k-nearest neighbors (k-NN) for your vector data
https://opensearch.org/docs/latest/search-plugins/knn/index/
Apache License 2.0
155 stars 114 forks source link

[Enhancement] Having a reference to the state in KNN990 vector reader, then construct cache keys to invalidate in close method. #2223

Open 0ctopus13prime opened 4 days ago

0ctopus13prime commented 4 days ago

Description

In NativeEngine990KnnVectorsReader's constructor, we construct cache keys for invalidating with the given segment reader state. But this is unnecessary, we can always construct with field infos and segment info when closing.

    private final List<String> cacheKeys;

    public NativeEngines990KnnVectorsReader(final SegmentReadState state, final FlatVectorsReader flatVectorsReader) {
        this.flatVectorsReader = flatVectorsReader;
        this.segmentReadState = state;
        this.cacheKeys = getVectorCacheKeysFromSegmentReaderState(state); <---------- This!
        loadCacheKeyMap();
    }

    @Override
    public void close() throws IOException {
        // Clean up allocated vector indices resources from cache.
        final NativeMemoryCacheManager nativeMemoryCacheManager = NativeMemoryCacheManager.getInstance();
        cacheKeys.forEach(nativeMemoryCacheManager::invalidate); <------- This!
        ...

Not for sure, but once I tried to change it to have a reference in constructor and build a cache key in close method, I bumped into this exceptions during testing.

Suppressed: java.lang.AssertionError: should not be called by a cluster state applier. reason [the applied cluster state is not yet available]
»               at org.opensearch.cluster.service.ClusterApplierService.assertNotCalledFromClusterStateApplier(ClusterApplierService.java:446) ~[opensearch-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
»               at org.opensearch.cluster.service.ClusterApplierService.state(ClusterApplierService.java:230) ~[opensearch-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
»               at org.opensearch.cluster.service.ClusterService.state(ClusterService.java:183) ~[opensearch-3.0.0-SNAPSHOT.jar:3.0.0-SNAPSHOT]
»               at org.opensearch.knn.indices.ModelDao$OpenSearchKNNModelDao.getMetadata(ModelDao.java:457) ~[?:?]
»               at org.opensearch.knn.indices.ModelUtil.getModelMetadata(ModelUtil.java:52) ~[?:?]
»               at org.opensearch.knn.common.FieldInfoExtractor.extractKNNEngine(FieldInfoExtractor.java:41) ~[?:?]
»               at org.opensearch.knn.index.codec.util.KNNCodecUtil.getNativeKNNEngine(KNNCodecUtil.java:126) ~[?:?]
»               at org.opensearch.knn.index.codec.util.KNNCodecUtil.getNativeEngineFileFromFieldInfo(KNNCodecUtil.java:106) ~[?:?]

Looks like it is relying on cluster state service to get KNN engine info, and it raised the exception which was not thrown if the logic was in constructor.

TO-BE :

    ~~private final List<String> cacheKeys;~~ <------- This will be gone

    @Override
    public void close() throws IOException {
        // Clean up allocated vector indices resources from cache.
        final NativeMemoryCacheManager nativeMemoryCacheManager = NativeMemoryCacheManager.getInstance();
        getVectorCacheKeysFromSegmentReaderState().forEach(nativeMemoryCacheManager::invalidate); <------- This!
0ctopus13prime commented 4 days ago

cc @shatejas for visibility. could you change the tag to enhancement? Thank you.

0ctopus13prime commented 1 day ago

Since this will be a very straightforward refactor, will be included in PR that introduces a writing layer in native engines. RFC : https://github.com/opensearch-project/k-NN/issues/2033