2525 ReplicaMetricReport ,
2626 TargetCapacityDirection ,
2727 TimeSeries ,
28- TimeStampedValue ,
2928)
3029from ray .serve ._private .constants import (
3130 RAY_SERVE_MIN_HANDLE_METRICS_TIMEOUT_S ,
@@ -88,10 +87,8 @@ def __init__(self, deployment_id: DeploymentID):
8887 self ._replica_metrics : Dict [ReplicaID , ReplicaMetricReport ] = dict ()
8988 # Columnar per-replica running-requests arrays (wire-detected; producers
9089 # choose the format via should_encode_columnar).
91- self ._replica_running_arrays : Dict [ReplicaID , tuple ] = dict ()
9290 # Non-running columnar metrics per replica (custom autoscaling metrics):
9391 # replica_id -> {metric_name: (ts_arr, val_arr)}.
94- self ._replica_custom_arrays : Dict [ReplicaID , Dict [str , tuple ]] = dict ()
9592 # Unified per-replica "last accepted report timestamp" across BOTH wire formats.
9693 # Gates the object AND columnar ingest paths so a delayed report in either format
9794 # can't overwrite fresher data the other wrote. Cleared only on replica stop --
@@ -214,8 +211,6 @@ def register(self, info: DeploymentInfo, curr_target_num_replicas: int) -> int:
214211 def on_replica_stopped (self , replica_id : ReplicaID ):
215212 if replica_id in self ._replica_metrics :
216213 del self ._replica_metrics [replica_id ]
217- self ._replica_running_arrays .pop (replica_id , None )
218- self ._replica_custom_arrays .pop (replica_id , None )
219214 self ._replica_report_ts .pop (replica_id , None )
220215
221216 def get_num_replicas_lower_bound (self ) -> int :
@@ -293,68 +288,18 @@ def record_request_metrics_for_replica(
293288 self ._replica_report_ts [replica_id ] = send_timestamp
294289 # dedup-at-write: this source now reports via cloudpickle; drop any
295290 # columnar entries so the stores never double-count it.
296- self ._replica_running_arrays .pop (replica_id , None )
297- self ._replica_custom_arrays .pop (replica_id , None )
298-
299- def record_columnar_metrics_for_replica (
300- self , replica_id , metric_arrays , timestamp
301- ) -> None :
302- """Store columnar per-metric arrays for a replica (no per-point objects).
303- running_requests feeds the hot-path store; any other metrics feed the custom
304- store used by custom autoscaling policies (the columnar decode is lossless)."""
305- prev_ts = self ._replica_report_ts .get (replica_id )
306- if prev_ts is not None and timestamp <= prev_ts :
307- return
308- self ._replica_report_ts [replica_id ] = timestamp
309- running = metric_arrays .get (RUNNING_REQUESTS_KEY )
310- if running is not None :
311- self ._replica_running_arrays [replica_id ] = (
312- running [0 ],
313- running [1 ],
314- timestamp ,
315- )
316- else :
317- # A newer report that omits running_requests must drop the stale running
318- # timeseries -- the object path replaces the whole report, so missing
319- # running stops contributing there too.
320- self ._replica_running_arrays .pop (replica_id , None )
321- custom = {m : a for m , a in metric_arrays .items () if m != RUNNING_REQUESTS_KEY }
322- if custom :
323- self ._replica_custom_arrays [replica_id ] = custom
324- else :
325- self ._replica_custom_arrays .pop (replica_id , None )
326- # dedup-at-write: drop any cloudpickle entry for this source.
327- self ._replica_metrics .pop (replica_id , None )
328291
329292 def _columnar_aggregate_total_requests (self ) -> float :
330293 """Aggregate-mode total over pure-columnar stores: replica (direct-ingress)
331294 running arrays when a RUNNING replica reported, else handle running arrays,
332295 plus queued -- one fused numpy merge (no per-replica Python objects)."""
333- # Gate on whether a RUNNING replica actually reported, NOT on the store being
334- # non-empty: a lingering stopped-replica array (before on_replica_stopped
335- # clears it) must fall through to handle-running exactly like the object
336- # path, else handle-collected running is dropped (total reads queued-only).
337- replica_segments = self ._replica_columnar_segments ()
338- if replica_segments :
339- return self ._aggregate_segments (
340- replica_segments + self ._queued_columnar_segments ()
341- )
342296 if not self ._handle_arrays :
343297 return 0.0
344298 return self ._aggregate_segments (
345299 self ._handle_running_columnar_segments (self ._cached_running_replica_strs )
346300 + self ._queued_columnar_segments ()
347301 )
348302
349- def _replica_columnar_segments (self ):
350- """RUNNING replicas' columnar running-request arrays as (ts, val) segments."""
351- segs = []
352- for replica_id in self ._running_replicas :
353- a = self ._replica_running_arrays .get (replica_id )
354- if a is not None and a [0 ].size :
355- segs .append ((a [0 ], a [1 ]))
356- return segs
357-
358303 def _queued_columnar_segments (self ):
359304 """Columnar per-handle queued arrays as (ts, val) segments."""
360305 return [
@@ -811,7 +756,7 @@ def _calculate_total_requests_aggregate_mode(self) -> float:
811756 Total number of requests (average running + queued) calculated from
812757 timeseries data aggregation.
813758 """
814- has_columnar = bool (self ._replica_running_arrays or self . _handle_arrays )
759+ has_columnar = bool (self ._handle_arrays )
815760 has_object = bool (self ._replica_metrics or self ._handle_requests )
816761 # Homogeneous fleets keep their native fast path. Columnar arrays are used
817762 # whenever present -- the controller wire-detects the format from the frame
@@ -862,8 +807,7 @@ def _mixed_aggregate_total_requests(self) -> float:
862807 are converted to small arrays. Empty object series are dropped so they
863808 cannot flip metrics_collected_on_replicas and suppress handle-side running
864809 (mirrors the columnar empty-skip). Disjoint by dedup-at-write."""
865- segments = self ._replica_columnar_segments ()
866- segments += self ._series_segments (self ._collect_replica_running_requests ())
810+ segments = self ._series_segments (self ._collect_replica_running_requests ())
867811 metrics_collected_on_replicas = bool (segments )
868812 if not metrics_collected_on_replicas :
869813 segments += self ._handle_running_columnar_segments (
@@ -931,8 +875,6 @@ def _get_aggregated_custom_metrics(self) -> Dict[str, Dict[ReplicaID, float]]:
931875 Dict mapping metric name to dict of replica ID to aggregated metric value.
932876 """
933877 aggregated_metrics : Dict [str , Dict [ReplicaID , float ]] = defaultdict (dict )
934- now = time .time ()
935- agg = self ._config .aggregation_function
936878 for replica_id in self ._running_replicas :
937879 # A replica is in the object store OR the columnar stores (dedup-at-write).
938880 replica_metric_report = self ._replica_metrics .get (replica_id )
@@ -942,18 +884,6 @@ def _get_aggregated_custom_metrics(self) -> Dict[str, Dict[ReplicaID, float]]:
942884 replica_id
943885 ] = self ._merge_and_aggregate_timeseries ([timeseries ])
944886 continue
945- running = self ._replica_running_arrays .get (replica_id )
946- if running is not None and running [0 ].size :
947- aggregated_metrics [RUNNING_REQUESTS_KEY ][
948- replica_id
949- ] = self ._aggregate_single_array (running [0 ], running [1 ], now , agg )
950- custom = self ._replica_custom_arrays .get (replica_id )
951- if custom :
952- for metric_name , (ts , val ) in custom .items ():
953- if ts .size :
954- aggregated_metrics [metric_name ][
955- replica_id
956- ] = self ._aggregate_single_array (ts , val , now , agg )
957887 return dict (aggregated_metrics )
958888
959889 def _get_raw_custom_metrics (
@@ -971,19 +901,6 @@ def _get_raw_custom_metrics(
971901 for metric_name , timeseries in replica_metric_report .metrics .items ():
972902 raw_metrics [metric_name ][replica_id ] = timeseries
973903 continue
974- running = self ._replica_running_arrays .get (replica_id )
975- if running is not None and running [0 ].size :
976- raw_metrics [RUNNING_REQUESTS_KEY ][replica_id ] = [
977- TimeStampedValue (float (running [0 ][k ]), float (running [1 ][k ]))
978- for k in range (running [0 ].size )
979- ]
980- custom = self ._replica_custom_arrays .get (replica_id )
981- if custom :
982- for metric_name , (ts , val ) in custom .items ():
983- raw_metrics [metric_name ][replica_id ] = [
984- TimeStampedValue (float (ts [k ]), float (val [k ]))
985- for k in range (ts .size )
986- ]
987904 return dict (raw_metrics )
988905
989906
@@ -1236,15 +1153,6 @@ def record_request_metrics_for_replica(
12361153 dep_id
12371154 ].record_request_metrics_for_replica (replica_metric_report )
12381155
1239- def record_columnar_metrics_for_replica (
1240- self , replica_id , metric_arrays , timestamp
1241- ) -> None :
1242- dep_id = replica_id .deployment_id
1243- if dep_id in self ._deployment_autoscaling_states :
1244- self ._deployment_autoscaling_states [
1245- dep_id
1246- ].record_columnar_metrics_for_replica (replica_id , metric_arrays , timestamp )
1247-
12481156 def record_request_metrics_for_handle (
12491157 self , handle_metric_report : HandleMetricReport
12501158 ):
@@ -1441,15 +1349,6 @@ def record_request_metrics_for_replica(
14411349 if app_state :
14421350 app_state .record_request_metrics_for_replica (replica_metric_report )
14431351
1444- def record_columnar_metrics_for_replica (
1445- self , replica_id , metric_arrays , timestamp
1446- ) -> None :
1447- app_state = self ._app_autoscaling_states .get (replica_id .deployment_id .app_name )
1448- if app_state :
1449- app_state .record_columnar_metrics_for_replica (
1450- replica_id , metric_arrays , timestamp
1451- )
1452-
14531352 def record_request_metrics_for_handle (
14541353 self ,
14551354 handle_metric_report : HandleMetricReport ,
0 commit comments