-
-
Notifications
You must be signed in to change notification settings - Fork 328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reflector should not request the whole meta #1389
Comments
There might be some good points in here about making the bounds of the relfector's operation explicit, but from a purely memory optimisation POV, it feels a little unnecessary at the moment because of existing optimisations laid out in: https://kube.rs/controllers/optimization/#pruning-fields - have you seen this? The default behaviour of the reflector is to store everything it sees, and personally i think is a sensible default, because everything you see is ultimately going on the wire anyway. |
(this might not work for you if you absolutely need to implement |
Yep, pruning managedFields would probably help reduce half of the memory used, but I actually wanted to cache the entire generic object to execute some user-defined query operations, which still requires the entire object. Not sure how much this costs in Rust, but my experience in Go was that the unstructured object memory footprint is around four times as large as the raw JSON list. |
If you still need to cache the entire object, then the memory cost should be the cost of storing the full thing + the cost of getting a (possibly smaller) copy, no? In fact, if you are using We don't really do unstructured objects the same way as Go, so you should not see any particular memory gains by working on serialised data - rust is pretty efficient with its memory layout in general. The things we generally use instead of unstructured is |
Why would there be the cost of storing a copy? I assume I could deserialize the JSON into something like a As for the part of getting the object, most objects are only retrieved once or twice in practice for many applications, so we're just deferring the cost of deserialization from list/watch time to processing time. Could you elaborate further on "not doing unstructured objects the same way"? In the particular case I am trying to use right now, I need to pass the JSON to another library across an FFI boundary anyway, so getting the raw JSON is actually my intention, not just for memory optimization but also to avoid needing to reserialize it to pass the FFI. But I admit that FFI is a bit niche in the kube case so let's not focus on that. |
FWIW, the overhead cost of a blank use std::mem::size_of;
use kube::core::ObjectMeta;
struct ObjectIdentity {
namespace: Option<String>,
name: String,
resource_version: String,
uid: String,
}
fn main() {
dbg!(size_of::<ObjectMeta>()); // => 344
dbg!(size_of::<ObjectIdentity>()); // => 96
} That is... surprisingly non-neglegible, actually. |
This comment was marked as outdated.
This comment was marked as outdated.
We can always add the stricter bound to |
Fixes kube-rs#1389 Signed-off-by: SOFe <sofe2038@gmail.com>
Fixes kube-rs#1389 Signed-off-by: SOFe <sofe2038@gmail.com>
Motivation explained in kube-rs#1389 Depends on kube-rs#1393 to ease reflector bounds
Motivation explained in kube-rs#1389 Depends on kube-rs#1393 to ease reflector bounds
Motivation explained in kube-rs#1389 Depends on kube-rs#1393 to ease reflector bounds Signed-off-by: SOFe <sofe2038@gmail.com>
…1393) * Ease the bound for `reflector` to only request identifying metadata Fixes #1389 Signed-off-by: SOFe <sofe2038@gmail.com> * rename ToObjectRef to reflector::Lookup Signed-off-by: SOFe <sofe2038@gmail.com> * Apply suggestions from code review Co-authored-by: Eirik A <sszynrae@gmail.com> Signed-off-by: Jonathan Chan Kwan Yin <sofe2038@gmail.com> * Remove obsolete clippy warning suppression Signed-off-by: Jonathan Chan Kwan Yin <sofe2038@gmail.com> --------- Signed-off-by: SOFe <sofe2038@gmail.com> Signed-off-by: Jonathan Chan Kwan Yin <sofe2038@gmail.com> Co-authored-by: Eirik A <sszynrae@gmail.com>
Motivation explained in kube-rs#1389 Depends on kube-rs#1393 to ease reflector bounds Signed-off-by: SOFe <sofe2038@gmail.com>
Motivation explained in kube-rs#1389 Depends on kube-rs#1393 to ease reflector bounds Signed-off-by: SOFe <sofe2038@gmail.com>
Would you like to work on this feature?
yes
What problem are you trying to solve?
I want to reduce controller memory usage by only storing the raw JSON of dynamic objects in memory instead of allocating the entire
serde_json::Value
. Currently the reflector store expects a type parameter with boundK: Resource
, whereResource
has to provide (mutable) access to anObjectMeta
it caches internally. This makes it impossible to implementResource
on a JSON string wrapper.I do not want to extract out the entire metadata because the unused fields like
annotations
andlabels
may allocate a lot of heap memory and waste even more on pointers.Describe the solution you'd like
Not all fields in
ObjectMeta
are required for the reflector. In fact, a quickgit grep 'meta(' kube-runtime/src/reflector
reveals that the all fields used from theObjectMeta
is the namespace, resourceVersion and uid (and read-only).I am proposing that we change the bound of
K: 'static + Resource
inreflector::Store
to this:Describe alternatives you've considered
In the equivalent Go informer implementation, I implemented
metav1.Object
methods by returning zero values in unused getters and no-op in unused setters (which is obviously an undocumented hack), but the same trick is not possible to implement soundly due tometa_mut()
.Documentation, Adoption, Migration Strategy
This is possibly a BC break since the bounds of
reflector::Store
are widened, but should cause no impact to most users since all existingResource
implementors are blanket-impled for.Target crate for feature
kube-runtime
The text was updated successfully, but these errors were encountered: