-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Adott projektünkben vannak csomópontok, amik nem látszanak az admin felületen, IntegrityChecker segítségével ezeket felderítettük és megpróbáltuk a beépített index javító odata megoldásokkal javítani. Azt tapsztaltuk, hogy egy elem esetén a javítás sikeres volt, a nagyobb NotInIndex subtree-k essetén a RefreshIndex/RebuildIndex megoldások ResourceExhausted hibát dobnak.
Hibaüzenet:
Error status code 'ResourceExhausted' with detail '"Received message exceeds the maximum configured message size."' raised.
trace:
StackTrace
at Grpc.Net.Client.Internal.HttpClientCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method2 method, String host, CallOptions options, TRequest request) at Grpc.Core.Interceptors.InterceptingCallInvoker.<BlockingUnaryCall>b__3_0[TRequest,TResponse](TRequest req, ClientInterceptorContext2 ctx) at Grpc.Core.ClientBase.ClientBaseConfiguration.ClientBaseConfigurationInterceptor.BlockingUnaryCall[TRequest,TResponse](TRequest request, ClientInterceptorContext2 context, BlockingUnaryCallContinuation2 continuation) at Grpc.Core.Interceptors.InterceptingCallInvoker.BlockingUnaryCall[TRequest,TResponse](Method2 method, String host, CallOptions options, TRequest request) at SenseNet.Search.Lucene29.Centralized.GrpcService.GrpcSearch.GrpcSearchClient.WriteIndex(WriteIndexRequest request, CallOptions options) at SenseNet.Search.Lucene29.Centralized.GrpcService.GrpcSearch.GrpcSearchClient.WriteIndex(WriteIndexRequest request, Metadata headers, Nullable1 deadline, CancellationToken cancellationToken) at SenseNet.Search.Lucene29.Centralized.GrpcClient.GrpcServiceClient.WriteIndex(SnTerm[] deletions, DocumentUpdate[] updates, IndexDocument[] additions)
A megoldás lépései:
- Meg kell fontolni hogy a DataContractSerializert mezei JSON-ra cseréljük
- Az IndexValue _typesStrings mezője is szerializálva van. Ezért legyen statikus.
- A grpcClient-nek ismernie kell a grpcService által fogadott maximális message méretét.
- Ha WriteIndex által küldött request hosszabb lenne a service által fogadott max méretnél, akkor kisebb partíciókban kell küldeni az anyagot. Tehát a message particionálás ne darabra, hanem méretre történjen. A méret ellenőrzéskor a MaxSendMessageSize értékből le kell vonni valamennyit infrastruktúrális célokból (5-10%?), mert nem csak a nyers adat, hanem paraméterek, tömbök és függvénynevek is utazhatnak.
- Ha egyetlen dokumentum haladná meg a maximális méretet, akkor az IndexDocument-et split-elni kell (meg kell fontolni annak a lehetőségét, hogy egy VersionId-hez több lucene document tartozik).
- Az IndexWriter ne maximálja a term-ek számát a field-ekben (MaxFieldLength.UNLIMITED-et kell használni a MaxFieldLength.LIMITED helyett).
- Minden sliced Document-nek tartalmaznia kell a VersionId, InTree, Path, Id term-eket, hogy a Content törlések ne hagyjanak orphaned dokumentumokat az indexben.
- Minden sliced Document-nek stored-ként tartalmaznia kell az Id, IsLastDraft, IsLastPublic term-eket, hogy a permission checker rendben lefuthasson.
- A LuceneSearchManager.WriteIndex metódusa ne töröljön szimplán VersionId alapján, mert kitörli az éppen létrehozott slice-okat. Helyette valami mást kell kitalálni az activity idempotency megőrzéséhez (többlábas környezetben az addition könnyen content-dplikációhoz vezethet).
- Az IQueryExecutor implementációkban felül kell vizsgálni az ablakozást, a hit collection-ban a versionid-ket distinct-elni kell. Ez megváltoztatja a jelenlegi collector algoritmusokat.
-
A Binary mező szövege megismétlődik a "_Text" mezőben. Ez is kettőzi a szerializált méretet. Meg kell fontolni, hogy a szerializált IndexDocument-nek nincs "_Text" mezője, csak egy felsorolás, hogy deszerializáláskor mely mezők tartalmából kell reprodukálni a text-extract azaz a _Text mező tartalmát. - Az IndexDocument IndexField-eket tartalmaz amelyek a StringValue-t szerializáláskor megismétlik a ValueAsString-ben. Ez kétszerezi az adat méretet. Ezért ValueAsString ne property, hanem method legyen és ne a konstruktorban, hanem lekérdezéskor legyen kiértékelve. Ekkor szerializáláskor ez az adat nem kerül bele az adatfolyamba.