envoyproxy / envoyproxy/gateway

huge memory usage

Abierto
#4,516 2 comentarios 3 reacciones 0 asignados Ver en GitHub
area/performance stale
Lenguaje dominante
Go
Estrellas
3k
Forks
864
Merge medio
2 d 2 h
PR fusionados (30 d)
140

Descripción

follow #4181

The `resource` cached many resources. Any resource that changes will send a signal, and runners will subscribe to the change message. There are many `DeepCopy`.

I think that we should provide a global cache resource mapping, and the runners subscribe to the simple change signal. in the `HandleSubscription` function or `Translator` gets the resource in the global cache.

![image](https://github.com/user-attachments/assets/2ffdc9ed-7e9b-4086-8b75-a69219b39144)

![image](https://github.com/user-attachments/assets/d2514a71-ec17-4d06-b7e3-d1ed882941e3)

for the route status, the `DeepCopy` uses a huge memory. Can we remove this DeepCopy?for my analysis to compare the status change we just cmp the `val.Parents` and `obj.Status.Parents`. or move the data to the global cache?

like follows:

- remove `DeepCopy` and CMP the status directly

```golang
// HTTPRoute object status updater
go func() {
message.HandleSubscription(r.resources.HTTPRouteStatuses.Subscribe(ctx),
func(update message.Update[types.NamespacedName, *gwapiv1b1.HTTPRouteStatus]) {
// skip delete updates.
if update.Delete {
return
}
key := update.Key
val := update.Value
r.statusUpdater.Send(status.Update{
NamespacedName: key,
Resource: new(gwapiv1b1.HTTPRoute),
Mutator: status.MutatorFunc(func(obj client.Object) bool {
h, ok := obj.(*gwapiv1b1.HTTPRoute)
if !ok {
panic(fmt.Sprintf("unsupported object type %T", obj))
}
// remove DeepCopy
// hCopy := h.DeepCopy()
// hCopy.Status.Parents = val.Parents
// cmp the Parents
t := gwapiv1b1.HTTPRouteStatus{}
t.Parents = val.Parents
if isStatusEqualHTTPRoute(obj.Status, t) {
u.log.WithName(h.NamespacedName.Name).
WithName(h.NamespacedName.Namespace).
Info("status unchanged, bypassing update")
return true
}
h.Status.Parents = val.Parents
return false
}),
})
},
)
r.log.Info("httpRoute status subscriber shutting down")
}()

func isStatusEqualHTTPRoute(a gwapiv1b1.HTTPRouteStatus, b gwapiv1b1.HTTPRouteStatus) bool {
opts := cmp.Options{
cmpopts.IgnoreFields(metav1.Condition{}, "LastTransitionTime"),
cmpopts.IgnoreMapEntries(func(k string, _ any) bool {
return k == "lastTransitionTime"
}),
}
if cmp.Equal(a, b, opts) {
return true
}

return false
}
```

```golang
func (u *UpdateHandler) apply(update Update) {
if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
obj := update.Resource

// Get the resource.
if err := u.client.Get(context.Background(), update.NamespacedName, obj); err != nil {
if kerrors.IsNotFound(err) {
return nil
}
return err
}

if update.Mutator.Mutate(obj) {
return nil
}

return u.client.Status().Update(context.Background(), obj)
}); err != nil {
u.log.Error(err, "unable to update status", "name", update.NamespacedName.Name,
"namespace", update.NamespacedName.Namespace)
}
}
```

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.