Skip to content

Commit 644e82a

Browse files
feat: Add PartitionManager and move this out of ingest_limits.go
This commit adds a PartitionManager that is responsible for tracking owned partitions. It moves this logic out of ingest_limits.go. In a follow up PR, I will also move kgo.onPartitionsAssigned, kgo.onPartitionsRevoked and kgo.onPartitionsLost to the PartitionManager.
1 parent 127b609 commit 644e82a

File tree

15 files changed

+2049
-228
lines changed

15 files changed

+2049
-228
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ require (
119119
github.com/IBM/ibm-cos-sdk-go v1.12.1
120120
github.com/axiomhq/hyperloglog v0.2.5
121121
github.com/buger/jsonparser v1.1.1
122+
github.com/coder/quartz v0.1.3
122123
github.com/d4l3k/messagediff v1.2.1
123124
github.com/dolthub/swiss v0.2.1
124125
github.com/efficientgo/core v1.0.0-rc.3

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySe
286286
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
287287
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
288288
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
289+
github.com/coder/quartz v0.1.3 h1:hA2nI8uUA2fNN9uhXv2I4xZD4aHkA7oH3g2t03v4xf8=
290+
github.com/coder/quartz v0.1.3/go.mod h1:vsiCc+AHViMKH2CQpGIpFgdHIEQsxwm8yCscqKmzbRA=
289291
github.com/containerd/containerd v1.7.25 h1:khEQOAXOEJalRO228yzVsuASLH42vT7DIo9Ss+9SMFQ=
290292
github.com/containerd/containerd v1.7.25/go.mod h1:tWfHzVI0azhw4CT2vaIjsb2CoV4LJ9PrMPaULAr21Ok=
291293
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=

pkg/limits/ingest_limits.go

Lines changed: 30 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ type IngestLimits struct {
140140
metadata map[string]map[int32][]streamMetadata // tenant -> partitionID -> streamMetadata
141141

142142
// Track partition assignments
143-
assignedPartitions map[int32]int64 // partitionID -> lastAssignedAt
143+
partitionManager *PartitionManager
144144
}
145145

146146
// Flush implements ring.FlushTransferer. It transfers state to another ingest limits instance.
@@ -156,10 +156,11 @@ func (s *IngestLimits) TransferOut(_ context.Context) error {
156156
func NewIngestLimits(cfg Config, logger log.Logger, reg prometheus.Registerer) (*IngestLimits, error) {
157157
var err error
158158
s := &IngestLimits{
159-
cfg: cfg,
160-
logger: logger,
161-
metadata: make(map[string]map[int32][]streamMetadata),
162-
metrics: newMetrics(reg),
159+
cfg: cfg,
160+
logger: logger,
161+
metadata: make(map[string]map[int32][]streamMetadata),
162+
metrics: newMetrics(reg),
163+
partitionManager: NewPartitionManager(logger),
163164
}
164165

165166
// Initialize internal metadata metrics
@@ -221,7 +222,7 @@ func (s *IngestLimits) Collect(m chan<- prometheus.Metric) {
221222
)
222223

223224
for partitionID, partition := range partitions {
224-
if _, assigned := s.assignedPartitions[partitionID]; !assigned {
225+
if !s.partitionManager.Has(partitionID) {
225226
continue
226227
}
227228

@@ -240,57 +241,40 @@ func (s *IngestLimits) Collect(m chan<- prometheus.Metric) {
240241
}
241242
}
242243

243-
func (s *IngestLimits) onPartitionsAssigned(_ context.Context, _ *kgo.Client, partitions map[string][]int32) {
244+
func (s *IngestLimits) onPartitionsAssigned(ctx context.Context, client *kgo.Client, partitions map[string][]int32) {
245+
s.partitionManager.Assign(ctx, client, partitions)
246+
}
247+
248+
func (s *IngestLimits) onPartitionsRevoked(ctx context.Context, client *kgo.Client, partitions map[string][]int32) {
244249
s.mtx.Lock()
245250
defer s.mtx.Unlock()
246-
247-
if s.assignedPartitions == nil {
248-
s.assignedPartitions = make(map[int32]int64)
249-
}
250-
251-
var assigned []string
251+
s.partitionManager.Remove(ctx, client, partitions)
252+
// TODO(grobinson): Use callbacks from partition manager to delete
253+
// metadata.
252254
for _, partitionIDs := range partitions {
253255
for _, partitionID := range partitionIDs {
254-
s.assignedPartitions[partitionID] = time.Now().UnixNano()
255-
assigned = append(assigned, strconv.Itoa(int(partitionID)))
256+
// Delete partition from tenant metadata.
257+
for _, tp := range s.metadata {
258+
delete(tp, partitionID)
259+
}
256260
}
257261
}
258-
259-
if len(assigned) > 0 {
260-
level.Debug(s.logger).Log("msg", "assigned partitions", "partitions", strings.Join(assigned, ","))
261-
}
262-
}
263-
264-
func (s *IngestLimits) onPartitionsRevoked(_ context.Context, _ *kgo.Client, partitions map[string][]int32) {
265-
s.removePartitions(partitions)
266262
}
267263

268-
func (s *IngestLimits) onPartitionsLost(_ context.Context, _ *kgo.Client, partitions map[string][]int32) {
269-
s.removePartitions(partitions)
270-
}
271-
272-
func (s *IngestLimits) removePartitions(partitions map[string][]int32) {
264+
func (s *IngestLimits) onPartitionsLost(ctx context.Context, client *kgo.Client, partitions map[string][]int32) {
273265
s.mtx.Lock()
274266
defer s.mtx.Unlock()
275-
276-
var dropped int
277-
267+
s.partitionManager.Remove(ctx, client, partitions)
268+
// TODO(grobinson): Use callbacks from partition manager to delete
269+
// metadata.
278270
for _, partitionIDs := range partitions {
279-
dropped += len(partitionIDs)
280271
for _, partitionID := range partitionIDs {
281-
// Unassign the partition from the ingest limits instance
282-
delete(s.assignedPartitions, partitionID)
283-
284-
// Remove the partition from the metadata map
285-
for _, partitions := range s.metadata {
286-
delete(partitions, partitionID)
272+
// Delete partition from tenant metadata.
273+
for _, tp := range s.metadata {
274+
delete(tp, partitionID)
287275
}
288276
}
289277
}
290-
291-
if dropped > 0 {
292-
level.Debug(s.logger).Log("msg", "removed partitions", "partitions", dropped)
293-
}
294278
}
295279

296280
func (s *IngestLimits) CheckReady(ctx context.Context) error {
@@ -449,7 +433,7 @@ func (s *IngestLimits) updateMetadata(rec *logproto.StreamMetadata, tenant strin
449433
}
450434

451435
// Partition not assigned to this instance, evict stream
452-
if _, assigned := s.assignedPartitions[partition]; !assigned {
436+
if assigned := s.partitionManager.Has(partition); !assigned {
453437
for i, stream := range s.metadata[tenant][partition] {
454438
if stream.hash == rec.StreamHash {
455439
s.metadata[tenant][partition] = append(s.metadata[tenant][partition][:i], s.metadata[tenant][partition][i+1:]...)
@@ -581,14 +565,10 @@ func (s *IngestLimits) ServeHTTP(w http.ResponseWriter, r *http.Request) {
581565
func (s *IngestLimits) GetAssignedPartitions(_ context.Context, _ *logproto.GetAssignedPartitionsRequest) (*logproto.GetAssignedPartitionsResponse, error) {
582566
s.mtx.RLock()
583567
defer s.mtx.RUnlock()
584-
585-
// Make a copy of the assigned partitions map to avoid potential concurrent access issues
586-
partitions := make(map[int32]int64, len(s.assignedPartitions))
587-
for k, v := range s.assignedPartitions {
588-
partitions[k] = v
568+
resp := logproto.GetAssignedPartitionsResponse{
569+
AssignedPartitions: s.partitionManager.List(),
589570
}
590-
591-
return &logproto.GetAssignedPartitionsResponse{AssignedPartitions: partitions}, nil
571+
return &resp, nil
592572
}
593573

594574
// GetStreamUsage implements the logproto.IngestLimitsServer interface.

0 commit comments

Comments
 (0)