enhance: extend the stats manage at streaming shard manager for L0 (#43371)

issue: #42416

- Rename the InsertMetric into ModifiedMetric.
- Add L0 control configuration.
- Add some L0 current state collect.

Signed-off-by: chyezh <chyezh@outlook.com>
This commit is contained in:
Zhen Ye 2025-08-18 20:41:46 +08:00 committed by GitHub
parent dada00a81c
commit a86b6f2a54
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 1595 additions and 1247 deletions

View File

@ -1313,6 +1313,16 @@ streaming:
# growing segment flush process will try to flush some growing segment into sealed
# until the total bytes of growing segment is less than this threshold, 0.1 by default.
growingSegmentBytesLwmThreshold: 0.1
l0:
# The max lifetime of l0 segment, 10 minutes by default.
# If the l0 segment is older than this time, it will be flushed.
maxLifetime: 10m
# The max row num of l0 segment, 500000 by default.
# If the row num of l0 segment is greater than this num, it will be flushed.
maxRowNum: 500000
# The max size of l0 segment, 32m by default.
# If the binary size of l0 segment is greater than this size, it will be flushed.
maxSize: 32m
walRecovery:
# The interval of persist recovery info, 10s by default.
# Every the interval, the recovery info of wal will try to persist, and the checkpoint of wal can be advanced.

View File

@ -57,6 +57,13 @@ func (impl *msgHandlerImpl) HandleCreateSegment(ctx context.Context, createSegme
}
func (impl *msgHandlerImpl) createNewGrowingSegment(ctx context.Context, vchannel string, h *message.CreateSegmentMessageHeader) error {
if h.Level == datapb.SegmentLevel_L0 {
// L0 segment should not be flushed directly, but not create than flush.
// the create segment operation is used to protect the binlog from garbage collection.
// L0 segment's binlog upload and flush operation is handled once.
// so we can skip the create segment operation here. (not strict promise exactly)
return nil
}
// Transfer the pending segment into growing state.
// Alloc the growing segment at datacoord first.
mix, err := resource.Resource().MixCoordClient().GetWithContext(ctx)

View File

@ -148,7 +148,7 @@ func (impl *shardInterceptor) handleInsertMessage(ctx context.Context, msg messa
req := &shards.AssignSegmentRequest{
CollectionID: header.GetCollectionId(),
PartitionID: partition.GetPartitionId(),
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: partition.GetRows(),
BinarySize: partition.GetBinarySize(),
},

View File

@ -124,8 +124,8 @@ func (m *partitionManager) FlushAndDropPartition(policy policy.SealPolicy) []int
segment.Flush(policy)
m.metrics.ObserveSegmentFlushed(
string(segment.SealPolicy().Policy),
int64(segment.GetFlushedStat().Insert.Rows),
int64(segment.GetFlushedStat().Insert.BinarySize),
int64(segment.GetFlushedStat().Modified.Rows),
int64(segment.GetFlushedStat().Modified.BinarySize),
)
segmentIDs = append(segmentIDs, segment.GetSegmentID())
}
@ -146,8 +146,8 @@ func (m *partitionManager) FlushAndFenceSegmentUntil(timeTick uint64) []int64 {
segment.Flush(policy.PolicyFenced(timeTick))
m.metrics.ObserveSegmentFlushed(
string(segment.SealPolicy().Policy),
int64(segment.GetFlushedStat().Insert.Rows),
int64(segment.GetFlushedStat().Insert.BinarySize),
int64(segment.GetFlushedStat().Modified.Rows),
int64(segment.GetFlushedStat().Modified.BinarySize),
)
segmentIDs = append(segmentIDs, segment.GetSegmentID())
}
@ -174,8 +174,8 @@ func (m *partitionManager) AsyncFlushSegment(signal utils.SealSegmentSignal) err
sm.Flush(signal.SealPolicy)
m.metrics.ObserveSegmentFlushed(
string(sm.SealPolicy().Policy),
int64(sm.GetFlushedStat().Insert.Rows),
int64(sm.GetFlushedStat().Insert.BinarySize),
int64(sm.GetFlushedStat().Modified.Rows),
int64(sm.GetFlushedStat().Modified.BinarySize),
)
m.asyncFlushSegment(m.ctx, sm)
}

View File

@ -115,7 +115,7 @@ func TestPartitionManager(t *testing.T) {
result, err := m.AssignSegment(&AssignSegmentRequest{
TimeTick: 125,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 120,
},
@ -125,7 +125,7 @@ func TestPartitionManager(t *testing.T) {
result, err = m.AssignSegment(&AssignSegmentRequest{
TimeTick: 135,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 120,
},
@ -135,7 +135,7 @@ func TestPartitionManager(t *testing.T) {
result.Ack()
req := &AssignSegmentRequest{
TimeTick: 136,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 120,
},

View File

@ -12,6 +12,7 @@ import (
"github.com/milvus-io/milvus/internal/streamingnode/server/wal"
"github.com/milvus-io/milvus/internal/util/streamingutil/status"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/message"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
)
@ -112,7 +113,7 @@ func (w *segmentAllocWorker) generateNewGrowingSegmentMessage() error {
storageVersion = storage.StorageV2
}
// Getnerate growing segment limitation.
limitation := getSegmentLimitationPolicy().GenerateLimitation()
limitation := getSegmentLimitationPolicy().GenerateLimitation(datapb.SegmentLevel_L1)
// Create a new segment by sending a create segment message into wal directly.
w.msg = message.NewCreateSegmentMessageBuilderV2().
WithVChannel(w.vchannel).
@ -121,7 +122,9 @@ func (w *segmentAllocWorker) generateNewGrowingSegmentMessage() error {
PartitionId: w.partitionID,
SegmentId: int64(segmentID),
StorageVersion: storageVersion,
MaxRows: limitation.SegmentRows,
MaxSegmentSize: limitation.SegmentSize,
Level: datapb.SegmentLevel_L1,
}).
WithBody(&message.CreateSegmentMessageBody{}).
MustBuildMutable()

View File

@ -1,8 +1,11 @@
package shards
import (
"fmt"
"math"
"math/rand"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
)
@ -15,19 +18,18 @@ func getSegmentLimitationPolicy() SegmentLimitationPolicy {
// segmentLimitation is the limitation of the segment.
type segmentLimitation struct {
PolicyName string
SegmentRows uint64
SegmentSize uint64
ExtraInfo interface{}
}
// SegmentLimitationPolicy is the interface to generate the limitation of the segment.
type SegmentLimitationPolicy interface {
// GenerateLimitation generates the limitation of the segment.
GenerateLimitation() segmentLimitation
GenerateLimitation(lv datapb.SegmentLevel) segmentLimitation
}
// jitterSegmentLimitationPolicyExtraInfo is the extra info of the jitter segment limitation policy.
type jitterSegmentLimitationPolicyExtraInfo struct {
Jitter float64
JitterRatio float64
Proportion float64
MaxSegmentSize uint64
@ -38,25 +40,60 @@ type jitterSegmentLimitationPolicyExtraInfo struct {
type jitterSegmentLimitationPolicy struct{}
// GenerateLimitation generates the limitation of the segment.
func (p jitterSegmentLimitationPolicy) GenerateLimitation() segmentLimitation {
func (p jitterSegmentLimitationPolicy) GenerateLimitation(lv datapb.SegmentLevel) segmentLimitation {
switch lv {
case datapb.SegmentLevel_L0:
return p.generateL0Limitation()
case datapb.SegmentLevel_L1:
return p.generateL1Limitation()
default:
panic(fmt.Sprintf("invalid segment level: %s", lv))
}
}
// generateL0Limitation generates the limitation of the L0 segment.
func (p jitterSegmentLimitationPolicy) generateL0Limitation() segmentLimitation {
rows := paramtable.Get().StreamingCfg.FlushL0MaxRowNum.GetAsUint64()
size := paramtable.Get().StreamingCfg.FlushL0MaxSize.GetAsUint64()
jitterRatio := p.getJitterRatio()
if rows <= 0 {
rows = uint64(math.MaxUint64)
} else {
rows = uint64(jitterRatio * float64(rows))
}
if size <= 0 {
size = uint64(math.MaxUint64)
} else {
size = uint64(jitterRatio * float64(size))
}
return segmentLimitation{
PolicyName: "jitter_segment_limitation",
SegmentRows: rows,
SegmentSize: size,
}
}
// generateL1Limitation generates the limitation of the L1 segment.
func (p jitterSegmentLimitationPolicy) generateL1Limitation() segmentLimitation {
// TODO: It's weird to set such a parameter into datacoord configuration.
// Refactor it in the future
jitter := paramtable.Get().DataCoordCfg.SegmentSealProportionJitter.GetAsFloat()
jitterRatio := 1 - jitter*rand.Float64() // generate a random number in [1-jitter, 1]
if jitterRatio <= 0 || jitterRatio > 1 {
jitterRatio = 1
}
jitterRatio := p.getJitterRatio()
maxSegmentSize := uint64(paramtable.Get().DataCoordCfg.SegmentMaxSize.GetAsInt64() * 1024 * 1024)
proportion := paramtable.Get().DataCoordCfg.SegmentSealProportion.GetAsFloat()
segmentSize := uint64(jitterRatio * float64(maxSegmentSize) * proportion)
return segmentLimitation{
PolicyName: "jitter_segment_limitation",
SegmentRows: math.MaxUint64,
SegmentSize: segmentSize,
ExtraInfo: jitterSegmentLimitationPolicyExtraInfo{
Jitter: jitter,
JitterRatio: jitterRatio,
Proportion: proportion,
MaxSegmentSize: maxSegmentSize,
},
}
}
func (p jitterSegmentLimitationPolicy) getJitterRatio() float64 {
jitter := paramtable.Get().DataCoordCfg.SegmentSealProportionJitter.GetAsFloat()
jitterRatio := 1 - jitter*rand.Float64() // generate a random number in [1-jitter, 1]
if jitterRatio <= 0 || jitterRatio > 1 {
jitterRatio = 1
}
return jitterRatio
}

View File

@ -149,7 +149,7 @@ func (s *segmentAllocManager) AllocRows(req *AssignSegmentRequest) (*AssignSegme
return nil, ErrNotGrowing
}
err := resource.Resource().SegmentStatsManager().AllocRows(s.GetSegmentID(), req.InsertMetrics)
err := resource.Resource().SegmentStatsManager().AllocRows(s.GetSegmentID(), req.ModifiedMetrics)
if err != nil {
return nil, err
}

View File

@ -72,7 +72,7 @@ func TestSegmentAllocManager(t *testing.T) {
result, err = m.AllocRows(&AssignSegmentRequest{
TimeTick: 120,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 120,
},
@ -83,7 +83,7 @@ func TestSegmentAllocManager(t *testing.T) {
result, err = m.AllocRows(&AssignSegmentRequest{
TimeTick: 120,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 50,
},
@ -97,7 +97,7 @@ func TestSegmentAllocManager(t *testing.T) {
result, err = m.AllocRows(&AssignSegmentRequest{
TimeTick: 120,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 70,
},
@ -108,7 +108,7 @@ func TestSegmentAllocManager(t *testing.T) {
result, err = m.AllocRows(&AssignSegmentRequest{
TimeTick: 120,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 100,
BinarySize: 50,
},

View File

@ -12,11 +12,11 @@ import (
// AssignSegmentRequest is a request to allocate segment.
type AssignSegmentRequest struct {
CollectionID int64
PartitionID int64
InsertMetrics stats.InsertMetrics
TimeTick uint64
TxnSession TxnSession
CollectionID int64
PartitionID int64
ModifiedMetrics stats.ModifiedMetrics
TimeTick uint64
TxnSession TxnSession
}
// AssignSegmentResult is a result of segment allocation.
@ -135,7 +135,7 @@ func (m *shardManagerImpl) AssignSegment(req *AssignSegmentRequest) (*AssignSegm
}
result, err := pm.AssignSegment(req)
if err == nil {
m.metrics.ObserveInsert(req.InsertMetrics.Rows, req.InsertMetrics.BinarySize)
m.metrics.ObserveInsert(req.ModifiedMetrics.Rows, req.ModifiedMetrics.BinarySize)
return result, nil
}
return nil, err

View File

@ -79,7 +79,7 @@ func TestShardManager(t *testing.T) {
StorageVersion: 2,
Stat: &streamingpb.SegmentAssignmentStat{
MaxBinarySize: 100,
InsertedBinarySize: 50,
ModifiedBinarySize: 50,
CreateSegmentTimeTick: 101,
},
},
@ -91,7 +91,7 @@ func TestShardManager(t *testing.T) {
StorageVersion: 2,
Stat: &streamingpb.SegmentAssignmentStat{
MaxBinarySize: 100,
InsertedBinarySize: 0,
ModifiedBinarySize: 0,
CreateSegmentTimeTick: 100,
},
},
@ -103,7 +103,7 @@ func TestShardManager(t *testing.T) {
StorageVersion: 2,
Stat: &streamingpb.SegmentAssignmentStat{
MaxBinarySize: 100,
InsertedBinarySize: 0,
ModifiedBinarySize: 0,
CreateSegmentTimeTick: 100,
},
},
@ -273,7 +273,7 @@ func TestShardManager(t *testing.T) {
CollectionID: 4,
PartitionID: 5,
TimeTick: 800,
InsertMetrics: stats.InsertMetrics{
ModifiedMetrics: stats.ModifiedMetrics{
Rows: 1,
BinarySize: 20,
},

View File

@ -0,0 +1,76 @@
package stats
import (
"fmt"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
)
// aggregatedMetrics is the metrics of a channel.
type aggregatedMetrics struct {
Insert ModifiedMetrics
Delete ModifiedMetrics
}
// newAggregatedMetrics creates a new aggregated metrics.
func newAggregatedMetrics() *aggregatedMetrics {
return &aggregatedMetrics{
Insert: ModifiedMetrics{},
Delete: ModifiedMetrics{},
}
}
// IsZero returns true if the metrics is zero.
func (c *aggregatedMetrics) IsZero() bool {
return c.Insert.IsZero() && c.Delete.IsZero()
}
// Total returns the total metrics of a channel.
func (c *aggregatedMetrics) Total() ModifiedMetrics {
return ModifiedMetrics{
Rows: c.Insert.Rows + c.Delete.Rows,
BinarySize: c.Insert.BinarySize + c.Delete.BinarySize,
}
}
// Collect collects the metrics of a level.
func (c *aggregatedMetrics) Collect(level datapb.SegmentLevel, metrics ModifiedMetrics) {
switch level {
case datapb.SegmentLevel_L0:
c.Delete.Collect(metrics)
case datapb.SegmentLevel_L1:
c.Insert.Collect(metrics)
default:
panicIfInvalidLevel(level)
}
}
// Subtract subtracts the metrics of a level.
func (c *aggregatedMetrics) Subtract(level datapb.SegmentLevel, metrics ModifiedMetrics) {
switch level {
case datapb.SegmentLevel_L0:
c.Delete.Subtract(metrics)
case datapb.SegmentLevel_L1:
c.Insert.Subtract(metrics)
default:
panicIfInvalidLevel(level)
}
}
// GetByLevel returns the metrics of a level.
func (c *aggregatedMetrics) Get(level datapb.SegmentLevel) ModifiedMetrics {
switch level {
case datapb.SegmentLevel_L0:
return c.Delete
case datapb.SegmentLevel_L1:
return c.Insert
default:
panicIfInvalidLevel(level)
}
return ModifiedMetrics{}
}
// panicIfInvalidLevel panics if the level is invalid.
func panicIfInvalidLevel(level datapb.SegmentLevel) {
panic(fmt.Sprintf("invalid level: %s", level))
}

View File

@ -0,0 +1,53 @@
package stats
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
)
func TestNewAggregatedMetrics(t *testing.T) {
am := newAggregatedMetrics()
assert.NotNil(t, am)
assert.True(t, am.IsZero())
}
func TestAggregatedMetrics_CollectAndSubtract(t *testing.T) {
am := newAggregatedMetrics()
metricsL0 := ModifiedMetrics{Rows: 10, BinarySize: 100}
metricsL1 := ModifiedMetrics{Rows: 20, BinarySize: 200}
// Collect L0 (should go to Delete)
am.Collect(datapb.SegmentLevel_L0, metricsL0)
assert.Equal(t, metricsL0, am.Delete)
assert.True(t, am.Insert.IsZero())
// Collect L1 (should go to Insert)
am.Collect(datapb.SegmentLevel_L1, metricsL1)
assert.Equal(t, metricsL1, am.Insert)
assert.Equal(t, metricsL0, am.Delete)
// Subtract L0 (should zero Delete)
am.Subtract(datapb.SegmentLevel_L0, metricsL0)
assert.True(t, am.Delete.IsZero())
assert.Equal(t, metricsL1, am.Insert)
// Subtract L1 (should zero Insert)
am.Subtract(datapb.SegmentLevel_L1, metricsL1)
assert.True(t, am.Insert.IsZero())
assert.True(t, am.Delete.IsZero())
assert.True(t, am.IsZero())
}
func TestAggregatedMetrics_PanicIfInvalidLevel(t *testing.T) {
am := newAggregatedMetrics()
defer func() {
if r := recover(); r == nil {
t.Errorf("expected panic for invalid level, but did not panic")
}
}()
// Use an invalid level
am.Collect(datapb.SegmentLevel(-1), ModifiedMetrics{Rows: 1, BinarySize: 1})
}

View File

@ -18,29 +18,33 @@ func newStatsConfig() statsConfig {
memory := float64(hardware.GetMemoryCount())
segmentMaxBinlogFileNum := paramtable.Get().DataCoordCfg.SegmentMaxBinlogFileNumber.GetAsInt()
maxLifetime := paramtable.Get().DataCoordCfg.SegmentMaxLifetime.GetAsDuration(time.Second)
maxIdleTime := paramtable.Get().DataCoordCfg.SegmentMaxIdleTime.GetAsDuration(time.Second)
minSizeFromIdleTime := paramtable.Get().DataCoordCfg.SegmentMinSizeFromIdleToSealed.GetAsInt64() * 1024 * 1024
l1MaxLifetime := paramtable.Get().DataCoordCfg.SegmentMaxLifetime.GetAsDuration(time.Second)
l1MaxIdleTime := paramtable.Get().DataCoordCfg.SegmentMaxIdleTime.GetAsDuration(time.Second)
l1MinSizeFromIdleTime := paramtable.Get().DataCoordCfg.SegmentMinSizeFromIdleToSealed.GetAsInt64() * 1024 * 1024
l0MaxLifetime := params.StreamingCfg.FlushL0MaxLifetime.GetAsDurationByParse()
return statsConfig{
maxBinlogFileNum: segmentMaxBinlogFileNum,
memoryThreshold: memoryTheshold,
growingBytesHWM: int64(hwmThreshold * memory),
growingBytesLWM: int64(lwmThreshold * memory),
maxLifetime: maxLifetime,
maxIdleTime: maxIdleTime,
minSizeFromIdleTime: minSizeFromIdleTime,
maxBinlogFileNum: segmentMaxBinlogFileNum,
memoryThreshold: memoryTheshold,
growingBytesHWM: int64(hwmThreshold * memory),
growingBytesLWM: int64(lwmThreshold * memory),
l1MaxLifetime: l1MaxLifetime,
l1MaxIdleTime: l1MaxIdleTime,
l1MinSizeFromIdleTime: l1MinSizeFromIdleTime,
l0MaxLifetime: l0MaxLifetime,
}
}
// statsConfig is the configuration for the stats manager.
type statsConfig struct {
maxBinlogFileNum int
memoryThreshold float64
growingBytesHWM int64
growingBytesLWM int64
maxLifetime time.Duration
maxIdleTime time.Duration
minSizeFromIdleTime int64
maxBinlogFileNum int
memoryThreshold float64
growingBytesHWM int64
growingBytesLWM int64
l1MaxLifetime time.Duration
l1MaxIdleTime time.Duration
l1MinSizeFromIdleTime int64
l0MaxLifetime time.Duration
}
// Validate checks if the config is valid.
@ -49,10 +53,11 @@ func (c statsConfig) Validate() error {
c.growingBytesHWM <= 0 ||
c.growingBytesLWM <= 0 ||
c.growingBytesHWM <= c.growingBytesLWM ||
c.maxLifetime <= 0 ||
c.maxIdleTime <= 0 ||
c.minSizeFromIdleTime <= 0 ||
c.maxBinlogFileNum <= 0 {
c.l1MaxLifetime <= 0 ||
c.l1MaxIdleTime <= 0 ||
c.l1MinSizeFromIdleTime <= 0 ||
c.maxBinlogFileNum <= 0 ||
c.l0MaxLifetime <= 0 {
return errors.Errorf("invalid stats config, cfg: %+v", c)
}
return nil

View File

@ -15,9 +15,9 @@ func TestNewStatConfig(t *testing.T) {
assert.Greater(t, cfg.memoryThreshold, float64(0))
assert.Greater(t, cfg.growingBytesHWM, int64(0))
assert.Greater(t, cfg.growingBytesLWM, int64(0))
assert.Greater(t, cfg.maxIdleTime, time.Duration(0))
assert.Greater(t, cfg.maxLifetime, time.Duration(0))
assert.Greater(t, cfg.minSizeFromIdleTime, int64(0))
assert.Greater(t, cfg.l1MaxIdleTime, time.Duration(0))
assert.Greater(t, cfg.l1MaxLifetime, time.Duration(0))
assert.Greater(t, cfg.l1MinSizeFromIdleTime, int64(0))
}
func TestStatsConfig_Validate(t *testing.T) {
@ -29,104 +29,126 @@ func TestStatsConfig_Validate(t *testing.T) {
{
name: "ValidConfig",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
maxLifetime: time.Hour,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 512,
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: false,
},
{
name: "InvalidMemoryWatermark",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 0,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
maxLifetime: time.Hour,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 512,
maxBinlogFileNum: 100,
memoryThreshold: 0,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "InvalidGrowingBytesHWM",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 0,
growingBytesLWM: 1024,
maxLifetime: time.Hour,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 512,
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 0,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "GrowingBytesHWM_LessThan_LWM",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 1024,
growingBytesLWM: 2048,
maxLifetime: time.Hour,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 512,
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 1024,
growingBytesLWM: 2048,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "InvalidMaxLifetime",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
maxLifetime: 0,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 512,
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: 0,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "InvalidMaxIdleTime",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
maxLifetime: time.Hour,
maxIdleTime: 0,
minSizeFromIdleTime: 512,
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: 0,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "InvalidMinSizeFromIdleTime",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
maxLifetime: time.Hour,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 0,
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 0,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "InvalidMaxBinlogFileNum",
config: statsConfig{
maxBinlogFileNum: 0,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
maxLifetime: time.Hour,
maxIdleTime: time.Minute,
minSizeFromIdleTime: 0,
maxBinlogFileNum: 0,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 0,
l0MaxLifetime: 10 * time.Minute,
},
wantErr: true,
},
{
name: "InvalidL0MaxLifetime",
config: statsConfig{
maxBinlogFileNum: 100,
memoryThreshold: 1024,
growingBytesHWM: 2048,
growingBytesLWM: 1024,
l1MaxLifetime: time.Hour,
l1MaxIdleTime: time.Minute,
l1MinSizeFromIdleTime: 512,
l0MaxLifetime: 0,
},
wantErr: true,
},

View File

@ -3,8 +3,8 @@ package stats
import (
"github.com/prometheus/client_golang/prometheus"
"github.com/milvus-io/milvus/internal/streamingnode/server/wal/interceptors/shard/utils"
"github.com/milvus-io/milvus/pkg/v2/metrics"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
)
@ -27,17 +27,19 @@ type metricsHelper struct {
}
// ObservePChannelBytesUpdate updates the bytes of a pchannel.
func (m *metricsHelper) ObservePChannelBytesUpdate(pchannel string, insertMetrics utils.InsertMetrics) {
if insertMetrics.BinarySize <= 0 {
metrics.WALGrowingSegmentBytes.DeletePartialMatch(prometheus.Labels{metrics.WALChannelLabelName: pchannel})
} else {
m.growingBytes.WithLabelValues(pchannel).Set(float64(insertMetrics.BinarySize))
}
if insertMetrics.Rows <= 0 {
metrics.WALGrowingSegmentRowsTotal.DeletePartialMatch(prometheus.Labels{metrics.WALChannelLabelName: pchannel})
} else {
m.growingRowsTotal.WithLabelValues(pchannel).Set(float64(insertMetrics.Rows))
func (m *metricsHelper) ObservePChannelBytesUpdate(pchannel string, am *aggregatedMetrics) {
for _, lv := range []datapb.SegmentLevel{datapb.SegmentLevel_L0, datapb.SegmentLevel_L1} {
metric := am.Get(lv)
if metric.BinarySize <= 0 {
metrics.WALGrowingSegmentBytes.DeletePartialMatch(prometheus.Labels{metrics.WALChannelLabelName: pchannel, metrics.WALSegmentLevelLabelName: lv.String()})
} else {
m.growingBytes.WithLabelValues(pchannel, lv.String()).Set(float64(metric.BinarySize))
}
if metric.Rows <= 0 {
metrics.WALGrowingSegmentRowsTotal.DeletePartialMatch(prometheus.Labels{metrics.WALChannelLabelName: pchannel, metrics.WALSegmentLevelLabelName: lv.String()})
} else {
m.growingRowsTotal.WithLabelValues(pchannel, lv.String()).Set(float64(metric.Rows))
}
}
}

View File

@ -11,12 +11,13 @@ import (
"github.com/milvus-io/milvus/internal/streamingnode/server/wal/interceptors/shard/policy"
"github.com/milvus-io/milvus/internal/streamingnode/server/wal/interceptors/shard/utils"
"github.com/milvus-io/milvus/pkg/v2/log"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
)
type (
SegmentStats = utils.SegmentStats
InsertMetrics = utils.InsertMetrics
ModifiedMetrics = utils.ModifiedMetrics
SegmentBelongs = utils.SegmentBelongs
SyncOperationMetrics = utils.SyncOperationMetrics
SealOperator = utils.SealOperator
@ -35,9 +36,9 @@ type StatsManager struct {
worker *sealWorker
mu sync.Mutex
cfg statsConfig
totalStats InsertMetrics
pchannelStats map[string]*InsertMetrics
vchannelStats map[string]*InsertMetrics
totalStats *aggregatedMetrics
pchannelStats map[string]*aggregatedMetrics
vchannelStats map[string]*aggregatedMetrics
segmentStats map[int64]*SegmentStats // map[SegmentID]SegmentStats
segmentIndex map[int64]SegmentBelongs // map[SegmentID]channels
pchannelIndex map[string]map[int64]struct{} // map[PChannel]SegmentID
@ -60,9 +61,9 @@ func NewStatsManager() *StatsManager {
m := &StatsManager{
mu: sync.Mutex{},
cfg: cfg,
totalStats: InsertMetrics{},
pchannelStats: make(map[string]*InsertMetrics),
vchannelStats: make(map[string]*InsertMetrics),
totalStats: newAggregatedMetrics(),
pchannelStats: make(map[string]*aggregatedMetrics),
vchannelStats: make(map[string]*aggregatedMetrics),
segmentStats: make(map[int64]*SegmentStats),
segmentIndex: make(map[int64]SegmentBelongs),
pchannelIndex: make(map[string]map[int64]struct{}),
@ -155,24 +156,24 @@ func (m *StatsManager) registerNewGrowingSegment(belongs SegmentBelongs, stats *
m.pchannelIndex[belongs.PChannel] = make(map[int64]struct{})
}
m.pchannelIndex[belongs.PChannel][segmentID] = struct{}{}
m.totalStats.Collect(stats.Insert)
m.totalStats.Collect(stats.Level, stats.Modified)
if _, ok := m.pchannelStats[belongs.PChannel]; !ok {
m.pchannelStats[belongs.PChannel] = &InsertMetrics{}
m.pchannelStats[belongs.PChannel] = newAggregatedMetrics()
}
m.pchannelStats[belongs.PChannel].Collect(stats.Insert)
m.pchannelStats[belongs.PChannel].Collect(stats.Level, stats.Modified)
if _, ok := m.vchannelStats[belongs.VChannel]; !ok {
m.vchannelStats[belongs.VChannel] = &InsertMetrics{}
m.vchannelStats[belongs.VChannel] = newAggregatedMetrics()
}
m.vchannelStats[belongs.VChannel].Collect(stats.Insert)
m.vchannelStats[belongs.VChannel].Collect(stats.Level, stats.Modified)
m.metricHelper.ObservePChannelBytesUpdate(belongs.PChannel, *m.pchannelStats[belongs.PChannel])
m.metricHelper.ObservePChannelBytesUpdate(belongs.PChannel, m.pchannelStats[belongs.PChannel])
}
// AllocRows alloc number of rows on current segment.
// AllocRows will check if the segment has enough space to insert.
// Must be called after RegisterGrowingSegment and before UnregisterGrowingSegment.
func (m *StatsManager) AllocRows(segmentID int64, insert InsertMetrics) error {
func (m *StatsManager) AllocRows(segmentID int64, insert ModifiedMetrics) error {
if insert.Rows == 0 || insert.BinarySize == 0 {
panic(fmt.Sprintf("insert rows or binary size cannot be 0, rows: %d, binary: %d", insert.Rows, insert.BinarySize))
}
@ -189,7 +190,7 @@ func (m *StatsManager) AllocRows(segmentID int64, insert InsertMetrics) error {
}
// allocRows allocates number of rows on current segment.
func (m *StatsManager) allocRows(segmentID int64, insert InsertMetrics) (bool, error) {
func (m *StatsManager) allocRows(segmentID int64, insert ModifiedMetrics) (bool, error) {
m.mu.Lock()
defer m.mu.Unlock()
@ -203,17 +204,17 @@ func (m *StatsManager) allocRows(segmentID int64, insert InsertMetrics) (bool, e
// update the total stats if inserted.
if inserted {
m.totalStats.Collect(insert)
m.totalStats.Collect(stat.Level, insert)
if _, ok := m.pchannelStats[info.PChannel]; !ok {
m.pchannelStats[info.PChannel] = &InsertMetrics{}
m.pchannelStats[info.PChannel] = newAggregatedMetrics()
}
m.pchannelStats[info.PChannel].Collect(insert)
m.pchannelStats[info.PChannel].Collect(stat.Level, insert)
if _, ok := m.vchannelStats[info.VChannel]; !ok {
m.vchannelStats[info.VChannel] = &InsertMetrics{}
m.vchannelStats[info.VChannel] = newAggregatedMetrics()
}
m.vchannelStats[info.VChannel].Collect(insert)
m.vchannelStats[info.VChannel].Collect(stat.Level, insert)
m.metricHelper.ObservePChannelBytesUpdate(info.PChannel, *m.pchannelStats[info.PChannel])
m.metricHelper.ObservePChannelBytesUpdate(info.PChannel, m.pchannelStats[info.PChannel])
return stat.ShouldBeSealed(), nil
}
if stat.IsEmpty() {
@ -225,7 +226,7 @@ func (m *StatsManager) allocRows(segmentID int64, insert InsertMetrics) (bool, e
// notifyIfTotalGrowingBytesOverHWM notifies if the total bytes is over the high water mark.
func (m *StatsManager) notifyIfTotalGrowingBytesOverHWM() {
m.mu.Lock()
size := m.totalStats.BinarySize
size := m.totalStats.Total().BinarySize
notify := size > uint64(m.cfg.growingBytesHWM)
m.mu.Unlock()
@ -299,7 +300,7 @@ func (m *StatsManager) unregisterSealedSegment(segmentID int64) *SegmentStats {
stats := m.segmentStats[segmentID]
m.totalStats.Subtract(stats.Insert)
m.totalStats.Subtract(stats.Level, stats.Modified)
delete(m.segmentStats, segmentID)
delete(m.segmentIndex, segmentID)
if _, ok := m.pchannelIndex[info.PChannel]; ok {
@ -310,15 +311,15 @@ func (m *StatsManager) unregisterSealedSegment(segmentID int64) *SegmentStats {
}
if _, ok := m.pchannelStats[info.PChannel]; ok {
m.pchannelStats[info.PChannel].Subtract(stats.Insert)
m.metricHelper.ObservePChannelBytesUpdate(info.PChannel, *m.pchannelStats[info.PChannel])
m.pchannelStats[info.PChannel].Subtract(stats.Level, stats.Modified)
m.metricHelper.ObservePChannelBytesUpdate(info.PChannel, m.pchannelStats[info.PChannel])
if m.pchannelStats[info.PChannel].IsZero() {
// If the binary size is 0, it means the segment is empty, we can delete it.
delete(m.pchannelStats, info.PChannel)
}
}
if _, ok := m.vchannelStats[info.VChannel]; ok {
m.vchannelStats[info.VChannel].Subtract(stats.Insert)
m.vchannelStats[info.VChannel].Subtract(stats.Level, stats.Modified)
if m.vchannelStats[info.VChannel].IsZero() {
delete(m.vchannelStats, info.VChannel)
}
@ -334,13 +335,21 @@ func (m *StatsManager) selectSegmentsWithTimePolicy() map[int64]policy.SealPolic
now := time.Now()
sealSegmentIDs := make(map[int64]policy.SealPolicy, 0)
for segmentID, stat := range m.segmentStats {
if now.Sub(stat.CreateTime) > m.cfg.maxLifetime {
sealSegmentIDs[segmentID] = policy.PolicyLifetime(m.cfg.maxLifetime)
continue
}
if stat.Insert.BinarySize > uint64(m.cfg.minSizeFromIdleTime) && now.Sub(stat.LastModifiedTime) > m.cfg.maxIdleTime {
sealSegmentIDs[segmentID] = policy.PolicyIdle(m.cfg.maxIdleTime, uint64(m.cfg.minSizeFromIdleTime))
continue
switch stat.Level {
case datapb.SegmentLevel_L1:
if now.Sub(stat.CreateTime) > m.cfg.l1MaxLifetime {
sealSegmentIDs[segmentID] = policy.PolicyLifetime(m.cfg.l1MaxLifetime)
continue
}
if stat.Modified.BinarySize > uint64(m.cfg.l1MinSizeFromIdleTime) && now.Sub(stat.LastModifiedTime) > m.cfg.l1MaxIdleTime {
sealSegmentIDs[segmentID] = policy.PolicyIdle(m.cfg.l1MaxIdleTime, uint64(m.cfg.l1MinSizeFromIdleTime))
continue
}
case datapb.SegmentLevel_L0:
if now.Sub(stat.CreateTime) > m.cfg.l0MaxLifetime {
sealSegmentIDs[segmentID] = policy.PolicyLifetime(m.cfg.l0MaxLifetime)
continue
}
}
}
return sealSegmentIDs
@ -349,7 +358,7 @@ func (m *StatsManager) selectSegmentsWithTimePolicy() map[int64]policy.SealPolic
// selectSegmentsUntilLessThanLWM selects segments until the total size is less than the threshold.
func (m *StatsManager) selectSegmentsUntilLessThanLWM() []int64 {
m.mu.Lock()
restSpace := int64(m.totalStats.BinarySize) - m.cfg.growingBytesLWM
restSpace := int64(m.totalStats.Total().BinarySize) - m.cfg.growingBytesLWM
m.mu.Unlock()
if restSpace <= 0 {
@ -376,10 +385,10 @@ func (m *StatsManager) createStatsSlice() []segmentWithBinarySize {
stats := make([]segmentWithBinarySize, 0, len(m.segmentStats))
for id, stat := range m.segmentStats {
if stat.Insert.BinarySize > 0 {
if stat.Modified.BinarySize > 0 {
stats = append(stats, segmentWithBinarySize{
segmentID: id,
binarySize: stat.Insert.BinarySize,
binarySize: stat.Modified.BinarySize,
})
}
}

View File

@ -13,6 +13,7 @@ import (
"github.com/milvus-io/milvus/internal/mocks/streamingnode/server/wal/interceptors/shard/mock_utils"
"github.com/milvus-io/milvus/internal/streamingnode/server/wal/interceptors/shard/utils"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/streaming/util/types"
"github.com/milvus-io/milvus/pkg/v2/util/paramtable"
"github.com/milvus-io/milvus/pkg/v2/util/typeutil"
@ -80,40 +81,40 @@ func TestStatsManager(t *testing.T) {
m.RegisterNewGrowingSegment(SegmentBelongs{PChannel: "pchannel", VChannel: "vchannel", CollectionID: 1, PartitionID: 2, SegmentID: 3}, createSegmentStats(100, 100, 300))
})
err := m.AllocRows(3, InsertMetrics{Rows: 50, BinarySize: 50})
err := m.AllocRows(3, ModifiedMetrics{Rows: 50, BinarySize: 50})
assert.NoError(t, err)
stat := m.GetStatsOfSegment(3)
assert.Equal(t, uint64(150), stat.Insert.BinarySize)
assert.Equal(t, uint64(150), stat.Modified.BinarySize)
err = m.AllocRows(5, InsertMetrics{Rows: 250, BinarySize: 250})
err = m.AllocRows(5, ModifiedMetrics{Rows: 250, BinarySize: 250})
assert.ErrorIs(t, err, ErrNotEnoughSpace)
err = m.AllocRows(6, InsertMetrics{Rows: 150, BinarySize: 150})
err = m.AllocRows(6, ModifiedMetrics{Rows: 150, BinarySize: 150})
assert.NoError(t, err)
assert.Equal(t, uint64(250), m.vchannelStats["vchannel3"].BinarySize)
assert.Equal(t, uint64(100), m.vchannelStats["vchannel2"].BinarySize)
assert.Equal(t, uint64(250), m.vchannelStats["vchannel"].BinarySize)
assert.Equal(t, uint64(250), m.vchannelStats["vchannel3"].Insert.BinarySize)
assert.Equal(t, uint64(100), m.vchannelStats["vchannel2"].Insert.BinarySize)
assert.Equal(t, uint64(250), m.vchannelStats["vchannel"].Insert.BinarySize)
assert.Equal(t, uint64(350), m.pchannelStats["pchannel"].BinarySize)
assert.Equal(t, uint64(250), m.pchannelStats["pchannel2"].BinarySize)
assert.Equal(t, uint64(350), m.pchannelStats["pchannel"].Insert.BinarySize)
assert.Equal(t, uint64(250), m.pchannelStats["pchannel2"].Insert.BinarySize)
m.UpdateOnSync(3, SyncOperationMetrics{BinLogCounterIncr: 100})
m.UpdateOnSync(1000, SyncOperationMetrics{BinLogCounterIncr: 100})
err = m.AllocRows(3, InsertMetrics{Rows: 400, BinarySize: 400})
err = m.AllocRows(3, ModifiedMetrics{Rows: 400, BinarySize: 400})
assert.ErrorIs(t, err, ErrNotEnoughSpace)
err = m.AllocRows(5, InsertMetrics{Rows: 250, BinarySize: 250})
err = m.AllocRows(5, ModifiedMetrics{Rows: 250, BinarySize: 250})
assert.ErrorIs(t, err, ErrNotEnoughSpace)
err = m.AllocRows(6, InsertMetrics{Rows: 400, BinarySize: 400})
err = m.AllocRows(6, ModifiedMetrics{Rows: 400, BinarySize: 400})
assert.ErrorIs(t, err, ErrNotEnoughSpace)
err = m.AllocRows(7, InsertMetrics{Rows: 400, BinarySize: 400})
err = m.AllocRows(7, ModifiedMetrics{Rows: 400, BinarySize: 400})
assert.ErrorIs(t, err, ErrTooLargeInsert)
assert.Panics(t, func() {
// alloc rows on a sealed segment should panic
m.AllocRows(1000, InsertMetrics{Rows: 0, BinarySize: 0})
m.AllocRows(1000, ModifiedMetrics{Rows: 0, BinarySize: 0})
})
m.UnregisterSealedSegment(3)
@ -128,7 +129,7 @@ func TestStatsManager(t *testing.T) {
assert.NotEmpty(t, m.sealOperators)
assert.Panics(t, func() {
m.AllocRows(100, InsertMetrics{Rows: 100, BinarySize: 100})
m.AllocRows(100, ModifiedMetrics{Rows: 100, BinarySize: 100})
})
assert.Panics(t, func() {
@ -181,7 +182,7 @@ func TestConcurrentStasManager(t *testing.T) {
}()
rows := 100 + rand.Int63n(100)
binarySize := 100 + rand.Int63n(100)
_ = m.AllocRows(segment.SegmentID, InsertMetrics{Rows: uint64(rows), BinarySize: uint64(binarySize)})
_ = m.AllocRows(segment.SegmentID, ModifiedMetrics{Rows: uint64(rows), BinarySize: uint64(binarySize)})
if rand.Int31n(2) > 0 {
m.UpdateOnSync(segment.SegmentID, SyncOperationMetrics{BinLogCounterIncr: 100})
@ -232,8 +233,8 @@ func TestConcurrentStasManager(t *testing.T) {
break
}
}
assert.Equal(t, m.totalStats.Rows, uint64(0))
assert.Equal(t, m.totalStats.BinarySize, uint64(0))
assert.Equal(t, m.totalStats.Insert.Rows, uint64(0))
assert.Equal(t, m.totalStats.Insert.BinarySize, uint64(0))
assert.Empty(t, m.segmentStats)
assert.Empty(t, m.vchannelStats)
assert.Empty(t, m.pchannelStats)
@ -243,7 +244,7 @@ func TestConcurrentStasManager(t *testing.T) {
func createSegmentStats(row uint64, binarySize uint64, maxBinarSize uint64) *SegmentStats {
return &SegmentStats{
Insert: InsertMetrics{
Modified: ModifiedMetrics{
Rows: row,
BinarySize: binarySize,
},
@ -251,5 +252,6 @@ func createSegmentStats(row uint64, binarySize uint64, maxBinarSize uint64) *Seg
CreateTime: time.Now(),
LastModifiedTime: time.Now(),
BinLogCounter: 0,
Level: datapb.SegmentLevel_L1,
}
}

View File

@ -2,9 +2,11 @@ package utils
import (
"fmt"
"math"
"time"
"github.com/milvus-io/milvus/pkg/v2/common"
"github.com/milvus-io/milvus/pkg/v2/proto/datapb"
"github.com/milvus-io/milvus/pkg/v2/proto/streamingpb"
)
@ -37,15 +39,16 @@ func (s *SegmentBelongs) PartitionUniqueKey() PartitionUniqueKey {
}
// SegmentStats is the usage stats of a segment.
// The SegmentStats is imprecise, so it is not promised to be recoverable for performance.
type SegmentStats struct {
Insert InsertMetrics
Modified ModifiedMetrics
MaxRows uint64 // MaxRows of current segment should be assigned, it's a fixed value when segment is transfer int growing.
MaxBinarySize uint64 // MaxBinarySize of current segment should be assigned, it's a fixed value when segment is transfer int growing.
CreateTime time.Time // created timestamp of this segment, it's a fixed value when segment is created, not a tso.
LastModifiedTime time.Time // LastWriteTime is the last write time of this segment, it's not a tso, just a local time.
BinLogCounter uint64 // BinLogCounter is the counter of binlog (equal to the binlog file count of primary key), it's an async stat not real time.
BinLogFileCounter uint64 // BinLogFileCounter is the counter of binlog files, it's an async stat not real time.
ReachLimit bool // ReachLimit is a flag to indicate the segment reach the limit once.
Level datapb.SegmentLevel
}
// NewSegmentStatFromProto creates a new segment assignment stat from proto.
@ -53,15 +56,28 @@ func NewSegmentStatFromProto(statProto *streamingpb.SegmentAssignmentStat) *Segm
if statProto == nil {
return nil
}
lv := datapb.SegmentLevel_L1
if statProto.Level != datapb.SegmentLevel_Legacy {
lv = statProto.Level
}
if lv != datapb.SegmentLevel_L0 && lv != datapb.SegmentLevel_L1 {
panic(fmt.Sprintf("invalid level: %s", lv))
}
maxRows := uint64(math.MaxUint64)
if statProto.MaxRows != 0 {
maxRows = statProto.MaxRows
}
return &SegmentStats{
Insert: InsertMetrics{
Rows: statProto.InsertedRows,
BinarySize: statProto.InsertedBinarySize,
Modified: ModifiedMetrics{
Rows: statProto.ModifiedRows,
BinarySize: statProto.ModifiedBinarySize,
},
MaxRows: maxRows,
MaxBinarySize: statProto.MaxBinarySize,
CreateTime: time.Unix(statProto.CreateTimestamp, 0),
BinLogCounter: statProto.BinlogCounter,
LastModifiedTime: time.Unix(statProto.LastModifiedTimestamp, 0),
Level: lv,
}
}
@ -71,34 +87,41 @@ func NewProtoFromSegmentStat(stat *SegmentStats) *streamingpb.SegmentAssignmentS
return nil
}
return &streamingpb.SegmentAssignmentStat{
MaxRows: stat.MaxRows,
MaxBinarySize: stat.MaxBinarySize,
InsertedRows: stat.Insert.Rows,
InsertedBinarySize: stat.Insert.BinarySize,
ModifiedRows: stat.Modified.Rows,
ModifiedBinarySize: stat.Modified.BinarySize,
CreateTimestamp: stat.CreateTime.Unix(),
BinlogCounter: stat.BinLogCounter,
LastModifiedTimestamp: stat.LastModifiedTime.Unix(),
Level: stat.Level,
}
}
// AllocRows alloc space of rows on current segment.
// Return true if the segment is assigned.
func (s *SegmentStats) AllocRows(m InsertMetrics) bool {
if m.BinarySize > s.BinaryCanBeAssign() {
if s.Insert.BinarySize > 0 {
func (s *SegmentStats) AllocRows(m ModifiedMetrics) bool {
if m.BinarySize > s.BinaryCanBeAssign() || m.Rows > s.RowsCanBeAssign() {
if s.Modified.BinarySize > 0 {
// if the binary size is not empty, it means the segment cannot hold more data, mark it as reach limit.
s.ReachLimit = true
}
return false
}
s.Insert.Collect(m)
s.Modified.Collect(m)
s.LastModifiedTime = time.Now()
return true
}
// BinaryCanBeAssign returns the capacity of binary size can be inserted.
func (s *SegmentStats) BinaryCanBeAssign() uint64 {
return s.MaxBinarySize - s.Insert.BinarySize
return s.MaxBinarySize - s.Modified.BinarySize
}
// RowsCanBeAssign returns the capacity of rows can be inserted.
func (s *SegmentStats) RowsCanBeAssign() uint64 {
return s.MaxRows - s.Modified.Rows
}
// ShouldBeSealed returns if the segment should be sealed.
@ -108,7 +131,7 @@ func (s *SegmentStats) ShouldBeSealed() bool {
// IsEmpty returns if the segment is empty.
func (s *SegmentStats) IsEmpty() bool {
return s.Insert.Rows == 0
return s.Modified.Rows == 0
}
// UpdateOnSync updates the stats of segment on sync.
@ -123,25 +146,25 @@ func (s *SegmentStats) Copy() *SegmentStats {
return &s2
}
// InsertMetrics is the metrics of insert operation.
type InsertMetrics struct {
// ModifiedMetrics is the metrics of insert/delete operation.
type ModifiedMetrics struct {
Rows uint64
BinarySize uint64
}
// IsZero return true if InsertMetrics is zero.
func (m *InsertMetrics) IsZero() bool {
// IsZero return true if ModifiedMetrics is zero.
func (m *ModifiedMetrics) IsZero() bool {
return m.Rows == 0 && m.BinarySize == 0
}
// Collect collects other metrics.
func (m *InsertMetrics) Collect(other InsertMetrics) {
func (m *ModifiedMetrics) Collect(other ModifiedMetrics) {
m.Rows += other.Rows
m.BinarySize += other.BinarySize
}
// Subtract subtract by other metrics.
func (m *InsertMetrics) Subtract(other InsertMetrics) {
func (m *ModifiedMetrics) Subtract(other ModifiedMetrics) {
if m.Rows < other.Rows {
panic(fmt.Sprintf("rows cannot be less than zero, current: %d, target: %d", m.Rows, other.Rows))
}

View File

@ -10,7 +10,7 @@ import (
func TestStatsConvention(t *testing.T) {
assert.Nil(t, NewProtoFromSegmentStat(nil))
stat := &SegmentStats{
Insert: InsertMetrics{
Modified: ModifiedMetrics{
Rows: 1,
BinarySize: 2,
},
@ -21,39 +21,39 @@ func TestStatsConvention(t *testing.T) {
}
pb := NewProtoFromSegmentStat(stat)
assert.Equal(t, stat.MaxBinarySize, pb.MaxBinarySize)
assert.Equal(t, stat.Insert.Rows, pb.InsertedRows)
assert.Equal(t, stat.Insert.BinarySize, pb.InsertedBinarySize)
assert.Equal(t, stat.Modified.Rows, pb.ModifiedRows)
assert.Equal(t, stat.Modified.BinarySize, pb.ModifiedBinarySize)
assert.Equal(t, stat.CreateTime.Unix(), pb.CreateTimestamp)
assert.Equal(t, stat.LastModifiedTime.Unix(), pb.LastModifiedTimestamp)
assert.Equal(t, stat.BinLogCounter, pb.BinlogCounter)
stat2 := NewSegmentStatFromProto(pb)
assert.Equal(t, stat.MaxBinarySize, stat2.MaxBinarySize)
assert.Equal(t, stat.Insert.Rows, stat2.Insert.Rows)
assert.Equal(t, stat.Insert.BinarySize, stat2.Insert.BinarySize)
assert.Equal(t, stat.Modified.Rows, stat2.Modified.Rows)
assert.Equal(t, stat.Modified.BinarySize, stat2.Modified.BinarySize)
assert.Equal(t, stat.CreateTime.Unix(), stat2.CreateTime.Unix())
assert.Equal(t, stat.LastModifiedTime.Unix(), stat2.LastModifiedTime.Unix())
assert.Equal(t, stat.BinLogCounter, stat2.BinLogCounter)
stat3 := stat2.Copy()
stat3.Insert.Subtract(InsertMetrics{
stat3.Modified.Subtract(ModifiedMetrics{
Rows: 1,
BinarySize: 2,
})
assert.Equal(t, stat3.Insert.Rows, stat2.Insert.Rows-1)
assert.Equal(t, stat3.Insert.BinarySize, stat2.Insert.BinarySize-2)
assert.Equal(t, stat.Insert.Rows, stat2.Insert.Rows)
assert.Equal(t, stat.Insert.BinarySize, stat2.Insert.BinarySize)
assert.Equal(t, stat3.Modified.Rows, stat2.Modified.Rows-1)
assert.Equal(t, stat3.Modified.BinarySize, stat2.Modified.BinarySize-2)
assert.Equal(t, stat.Modified.Rows, stat2.Modified.Rows)
assert.Equal(t, stat.Modified.BinarySize, stat2.Modified.BinarySize)
assert.Panics(t, func() {
stat3.Insert.Rows = 0
stat3.Insert.Subtract(InsertMetrics{
stat3.Modified.Rows = 0
stat3.Modified.Subtract(ModifiedMetrics{
Rows: 1,
BinarySize: 0,
})
})
assert.Panics(t, func() {
stat3.Insert.BinarySize = 0
stat3.Insert.Subtract(InsertMetrics{
stat3.Modified.BinarySize = 0
stat3.Modified.Subtract(ModifiedMetrics{
Rows: 0,
BinarySize: 1,
})
@ -66,7 +66,7 @@ func TestStatsConvention(t *testing.T) {
func TestSegmentStats(t *testing.T) {
now := time.Now()
stat := &SegmentStats{
Insert: InsertMetrics{
Modified: ModifiedMetrics{
Rows: 100,
BinarySize: 200,
},
@ -77,26 +77,26 @@ func TestSegmentStats(t *testing.T) {
BinLogFileCounter: 4,
}
insert1 := InsertMetrics{
insert1 := ModifiedMetrics{
Rows: 60,
BinarySize: 120,
}
inserted := stat.AllocRows(insert1)
assert.True(t, inserted)
assert.Equal(t, stat.Insert.Rows, uint64(160))
assert.Equal(t, stat.Insert.BinarySize, uint64(320))
assert.Equal(t, stat.Modified.Rows, uint64(160))
assert.Equal(t, stat.Modified.BinarySize, uint64(320))
assert.True(t, time.Now().After(now))
assert.False(t, stat.IsEmpty())
assert.False(t, stat.ShouldBeSealed())
insert1 = InsertMetrics{
insert1 = ModifiedMetrics{
Rows: 100,
BinarySize: 100,
}
inserted = stat.AllocRows(insert1)
assert.False(t, inserted)
assert.Equal(t, stat.Insert.Rows, uint64(160))
assert.Equal(t, stat.Insert.BinarySize, uint64(320))
assert.Equal(t, stat.Modified.Rows, uint64(160))
assert.Equal(t, stat.Modified.BinarySize, uint64(320))
assert.False(t, stat.IsEmpty())
assert.True(t, stat.ShouldBeSealed())
@ -110,11 +110,11 @@ func TestSegmentStats(t *testing.T) {
func TestIsZero(t *testing.T) {
// Test zero insert metrics
zeroInsert := InsertMetrics{}
zeroInsert := ModifiedMetrics{}
assert.True(t, zeroInsert.IsZero())
// Test non-zero insert metrics
nonZeroInsert := InsertMetrics{
nonZeroInsert := ModifiedMetrics{
Rows: 1,
BinarySize: 2,
}
@ -124,13 +124,13 @@ func TestIsZero(t *testing.T) {
func TestOversizeAlloc(t *testing.T) {
now := time.Now()
stat := &SegmentStats{
Insert: InsertMetrics{},
Modified: ModifiedMetrics{},
MaxBinarySize: 400,
CreateTime: now,
LastModifiedTime: now,
}
// Try to alloc a oversized insert metrics.
inserted := stat.AllocRows(InsertMetrics{
inserted := stat.AllocRows(ModifiedMetrics{
BinarySize: 401,
})
assert.False(t, inserted)

View File

@ -44,13 +44,15 @@ func NewSegmentAssignmentMetaFromCreateSegmentMessage(msg message.ImmutableCreat
StorageVersion: header.StorageVersion,
CheckpointTimeTick: msg.TimeTick(),
Stat: &streamingpb.SegmentAssignmentStat{
MaxRows: header.MaxRows,
MaxBinarySize: header.MaxSegmentSize,
InsertedRows: 0,
InsertedBinarySize: 0,
ModifiedRows: 0,
ModifiedBinarySize: 0,
CreateTimestamp: now,
LastModifiedTimestamp: now,
BinlogCounter: 0,
CreateSegmentTimeTick: msg.TimeTick(),
Level: header.Level,
},
}
}
@ -73,12 +75,12 @@ func (info *segmentRecoveryInfo) CreateSegmentTimeTick() uint64 {
// Rows returns the number of rows in the segment.
func (info *segmentRecoveryInfo) Rows() uint64 {
return info.meta.Stat.InsertedRows
return info.meta.Stat.ModifiedRows
}
// BinarySize returns the binary size of the segment.
func (info *segmentRecoveryInfo) BinarySize() uint64 {
return info.meta.Stat.InsertedBinarySize
return info.meta.Stat.ModifiedBinarySize
}
// ObserveInsert is called when an insert message is observed.
@ -89,8 +91,8 @@ func (info *segmentRecoveryInfo) ObserveInsert(timetick uint64, assignment *mess
// Consistent state is guaranteed by the recovery storage's mutex.
return
}
info.meta.Stat.InsertedBinarySize += assignment.BinarySize
info.meta.Stat.InsertedRows += assignment.Rows
info.meta.Stat.ModifiedBinarySize += assignment.BinarySize
info.meta.Stat.ModifiedRows += assignment.Rows
info.meta.Stat.LastModifiedTimestamp = tsoutil.PhysicalTime(timetick).Unix()
info.meta.CheckpointTimeTick = timetick
info.dirty = true

View File

@ -72,7 +72,7 @@ func TestSegmentRecoveryInfo(t *testing.T) {
assert.False(t, shouldBeRemoved)
assert.False(t, info.dirty)
assert.Equal(t, uint64(10), snapshot.Stat.InsertedBinarySize)
assert.Equal(t, uint64(10), snapshot.Stat.ModifiedBinarySize)
snapshot, shouldBeRemoved = info.ConsumeDirtyAndGetSnapshot()
assert.Nil(t, snapshot)
assert.False(t, shouldBeRemoved)

View File

@ -33,6 +33,7 @@ const (
WALRecoveryStorageStateLabelName = "state"
WALStateLabelName = "state"
WALChannelLabelName = channelNameLabelName
WALSegmentLevelLabelName = "lv"
WALSegmentSealPolicyNameLabelName = "policy"
WALMessageTypeLabelName = "message_type"
WALChannelTermLabelName = "term"
@ -251,12 +252,12 @@ var (
WALGrowingSegmentRowsTotal = newWALGaugeVec(prometheus.GaugeOpts{
Name: "growing_segment_rows_total",
Help: "Rows of segment growing on wal",
}, WALChannelLabelName)
}, WALChannelLabelName, WALSegmentLevelLabelName)
WALGrowingSegmentBytes = newWALGaugeVec(prometheus.GaugeOpts{
Name: "growing_segment_bytes",
Help: "Bytes of segment growing on wal",
}, WALChannelLabelName)
}, WALChannelLabelName, WALSegmentLevelLabelName)
WALGrowingSegmentHWMBytes = newWALGaugeVec(prometheus.GaugeOpts{
Name: "growing_segment_hwm_bytes",

View File

@ -5,6 +5,7 @@ package milvus.proto.messages;
option go_package = "github.com/milvus-io/milvus/pkg/v2/proto/messagespb";
import "schema.proto";
import "data_coord.proto"; // for SegmentLevel, but it's a basic type should not be in datacoord.proto.
// MessageID is the unique identifier of a message.
message MessageID {
@ -152,8 +153,10 @@ message CreateSegmentMessageHeader {
int64 collection_id = 1;
int64 partition_id = 2;
int64 segment_id = 3;
int64 storage_version = 4; // the storage version of the segment.
int64 storage_version = 4; // the storage version of the segment.
uint64 max_segment_size = 5; // the max size bytes of the segment.
uint64 max_rows = 6; // the max rows of the segment.
data.SegmentLevel level = 7; // the level of the segment.
}
message ManualFlushMessageHeader {

View File

@ -8,6 +8,7 @@ package messagespb
import (
schemapb "github.com/milvus-io/milvus-proto/go-api/v2/schemapb"
datapb "github.com/milvus-io/milvus/pkg/v2/proto/datapb"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
@ -1042,11 +1043,13 @@ type CreateSegmentMessageHeader struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
CollectionId int64 `protobuf:"varint,1,opt,name=collection_id,json=collectionId,proto3" json:"collection_id,omitempty"`
PartitionId int64 `protobuf:"varint,2,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"`
SegmentId int64 `protobuf:"varint,3,opt,name=segment_id,json=segmentId,proto3" json:"segment_id,omitempty"`
StorageVersion int64 `protobuf:"varint,4,opt,name=storage_version,json=storageVersion,proto3" json:"storage_version,omitempty"` // the storage version of the segment.
MaxSegmentSize uint64 `protobuf:"varint,5,opt,name=max_segment_size,json=maxSegmentSize,proto3" json:"max_segment_size,omitempty"` // the max size bytes of the segment.
CollectionId int64 `protobuf:"varint,1,opt,name=collection_id,json=collectionId,proto3" json:"collection_id,omitempty"`
PartitionId int64 `protobuf:"varint,2,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"`
SegmentId int64 `protobuf:"varint,3,opt,name=segment_id,json=segmentId,proto3" json:"segment_id,omitempty"`
StorageVersion int64 `protobuf:"varint,4,opt,name=storage_version,json=storageVersion,proto3" json:"storage_version,omitempty"` // the storage version of the segment.
MaxSegmentSize uint64 `protobuf:"varint,5,opt,name=max_segment_size,json=maxSegmentSize,proto3" json:"max_segment_size,omitempty"` // the max size bytes of the segment.
MaxRows uint64 `protobuf:"varint,6,opt,name=max_rows,json=maxRows,proto3" json:"max_rows,omitempty"` // the max rows of the segment.
Level datapb.SegmentLevel `protobuf:"varint,7,opt,name=level,proto3,enum=milvus.proto.data.SegmentLevel" json:"level,omitempty"` // the level of the segment.
}
func (x *CreateSegmentMessageHeader) Reset() {
@ -1116,6 +1119,20 @@ func (x *CreateSegmentMessageHeader) GetMaxSegmentSize() uint64 {
return 0
}
func (x *CreateSegmentMessageHeader) GetMaxRows() uint64 {
if x != nil {
return x.MaxRows
}
return 0
}
func (x *CreateSegmentMessageHeader) GetLevel() datapb.SegmentLevel {
if x != nil {
return x.Level
}
return datapb.SegmentLevel(0)
}
type ManualFlushMessageHeader struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -2075,241 +2092,247 @@ var file_messages_proto_rawDesc = []byte{
0x0a, 0x0e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x12, 0x15, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x1a, 0x0c, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1b, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
0x69, 0x64, 0x22, 0xb2, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x18,
0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d,
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f,
0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf6, 0x01, 0x0a, 0x10, 0x49, 0x6d, 0x6d, 0x75,
0x74, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30, 0x0a, 0x02,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75,
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18,
0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x57, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70,
0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6d,
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x73, 0x2e, 0x49, 0x6d, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
0x22, 0x12, 0x0a, 0x10, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x42, 0x6f, 0x64, 0x79, 0x22, 0x18, 0x0a, 0x16, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x46, 0x6c,
0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x1a,
0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x15, 0x0a, 0x13, 0x42, 0x65,
0x67, 0x69, 0x6e, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64,
0x79, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x78, 0x6e, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x18, 0x0a, 0x16, 0x52, 0x6f, 0x6c,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42,
0x6f, 0x64, 0x79, 0x22, 0x4c, 0x0a, 0x0e, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x22, 0x17, 0x0a, 0x15, 0x54, 0x69, 0x6d, 0x65, 0x54, 0x69, 0x63, 0x6b, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x8d, 0x01, 0x0a, 0x13, 0x49,
0x6e, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64,
0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6d, 0x69,
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67,
0x6d, 0x65, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x0a,
0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xcd, 0x01, 0x0a, 0x1a, 0x50,
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x41,
0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x72,
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73,
0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18,
0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x53, 0x69, 0x7a,
0x65, 0x12, 0x57, 0x0a, 0x12, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x61, 0x73, 0x73,
0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x10, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x63, 0x6f, 0x6f, 0x72,
0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1b, 0x0a, 0x09, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x69, 0x64, 0x22, 0xb2, 0x01, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x4e, 0x0a, 0x0a, 0x70, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e,
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50,
0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a,
0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf6, 0x01, 0x0a, 0x10, 0x49, 0x6d,
0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x30,
0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x69, 0x6c,
0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x49, 0x44, 0x52, 0x02, 0x69, 0x64,
0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x57, 0x0a, 0x0a, 0x70, 0x72,
0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37,
0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x49, 0x6d, 0x6d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69,
0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74,
0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
0x38, 0x01, 0x22, 0x12, 0x0a, 0x10, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x18, 0x0a, 0x16, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c,
0x46, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79,
0x22, 0x1a, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x15, 0x0a, 0x13,
0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42,
0x6f, 0x64, 0x79, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x78, 0x6e,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x18, 0x0a, 0x16, 0x52,
0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x42, 0x6f, 0x64, 0x79, 0x22, 0x4c, 0x0a, 0x0e, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x69, 0x6c, 0x76,
0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x73, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x22, 0x17, 0x0a, 0x15, 0x54, 0x69, 0x6d, 0x65, 0x54, 0x69, 0x63, 0x6b, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x8d, 0x01, 0x0a,
0x13, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65,
0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c,
0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x51, 0x0a, 0x0a, 0x70, 0x61, 0x72,
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e,
0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x73, 0x73,
0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x11, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x32, 0x0a, 0x11, 0x53, 0x65,
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12,
0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x4e,
0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48,
0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f,
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x6f,
0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x22, 0x7b,
0x0a, 0x12, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65,
0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53,
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74,
0x52, 0x0a, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xcd, 0x01, 0x0a,
0x1a, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e,
0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x70,
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12,
0x0a, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x72, 0x6f,
0x77, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x7a,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x53,
0x69, 0x7a, 0x65, 0x12, 0x57, 0x0a, 0x12, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x61,
0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x28, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x41,
0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x11, 0x73, 0x65, 0x67, 0x6d, 0x65,
0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x32, 0x0a, 0x11,
0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e,
0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64,
0x22, 0x4e, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c,
0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04,
0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73,
0x22, 0x7b, 0x0a, 0x12, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70,
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d,
0x0a, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01,
0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xa8, 0x02,
0x0a, 0x1a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d,
0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f,
0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e,
0x74, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x76,
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74,
0x6f, 0x72, 0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10,
0x6d, 0x61, 0x78, 0x5f, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65,
0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x53, 0x65, 0x67, 0x6d, 0x65,
0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x6f,
0x77, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x6d, 0x61, 0x78, 0x52, 0x6f, 0x77,
0x73, 0x12, 0x35, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e,
0x32, 0x1f, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4c, 0x65, 0x76, 0x65,
0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x7b, 0x0a, 0x18, 0x4d, 0x61, 0x6e, 0x75,
0x61, 0x6c, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65,
0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c,
0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x75,
0x73, 0x68, 0x5f, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x6c, 0x75,
0x73, 0x68, 0x54, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f,
0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65,
0x6e, 0x74, 0x49, 0x64, 0x73, 0x22, 0x69, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70,
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x03, 0x52, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73,
0x22, 0x42, 0x0a, 0x1b, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12,
0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x64, 0x22, 0x66, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61,
0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65,
0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c,
0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x72,
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52,
0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a,
0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xd6, 0x01, 0x0a, 0x1a,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73,
0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x64, 0x0a, 0x1a,
0x44, 0x72, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f,
0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12,
0x21, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18,
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64,
0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49,
0x64, 0x12, 0x27, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x5f, 0x76, 0x65, 0x72,
0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x72,
0x61, 0x67, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61,
0x78, 0x5f, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x05,
0x20, 0x01, 0x28, 0x04, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74,
0x53, 0x69, 0x7a, 0x65, 0x22, 0x7b, 0x0a, 0x18, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x46, 0x6c,
0x75, 0x73, 0x68, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
0x49, 0x64, 0x22, 0x4e, 0x0a, 0x15, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x6e, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x16, 0x6b,
0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65,
0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6b, 0x65, 0x65,
0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e,
0x64, 0x73, 0x22, 0x18, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x78, 0x6e, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x1a, 0x0a, 0x18,
0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x12, 0x0a, 0x10, 0x54, 0x78, 0x6e, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x15, 0x0a, 0x13,
0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61,
0x64, 0x65, 0x72, 0x22, 0x70, 0x0a, 0x19, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61,
0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x74,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x54, 0x73,
0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18,
0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64,
0x73, 0x22, 0x69, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64,
0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x72, 0x74, 0x69,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0c,
0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x22, 0x42, 0x0a, 0x1b,
0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65,
0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64,
0x22, 0x66, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x70, 0x61, 0x72,
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x64, 0x0a, 0x1a, 0x44, 0x72, 0x6f, 0x70,
0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63,
0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70,
0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x4e,
0x0a, 0x15, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,
0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x35, 0x0a, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x61,
0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69,
0x76, 0x65, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x18,
0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x6f, 0x6c, 0x6c,
0x62, 0x61, 0x63, 0x6b, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65,
0x61, 0x64, 0x65, 0x72, 0x22, 0x12, 0x0a, 0x10, 0x54, 0x78, 0x6e, 0x4d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x15, 0x0a, 0x13, 0x49, 0x6d, 0x70, 0x6f,
0x72, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22,
0x70, 0x0a, 0x19, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d,
0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x23, 0x0a, 0x0d,
0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49,
0x64, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x67,
0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x11,
0x66, 0x6c, 0x75, 0x73, 0x68, 0x65, 0x64, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64,
0x73, 0x22, 0x58, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x3d, 0x0a, 0x06,
0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d,
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x73, 0x63, 0x68, 0x65,
0x6d, 0x61, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x68,
0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22, 0x3b, 0x0a, 0x18, 0x4d,
0x61, 0x6e, 0x75, 0x61, 0x6c, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x67, 0x6d, 0x65,
0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x73, 0x65,
0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x22, 0x5a, 0x0a, 0x0a, 0x54, 0x78, 0x6e, 0x43,
0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x74, 0x78, 0x6e, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x78, 0x6e, 0x49, 0x64, 0x12, 0x35, 0x0a,
0x16, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x69, 0x6c, 0x6c, 0x69,
0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x6b,
0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63,
0x6f, 0x6e, 0x64, 0x73, 0x22, 0xc4, 0x01, 0x0a, 0x10, 0x52, 0x4d, 0x51, 0x4d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79,
0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x12, 0x57, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e,
0x52, 0x4d, 0x51, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74,
0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79,
0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x1a, 0x3d, 0x0a, 0x0f,
0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9b, 0x01, 0x0a, 0x0f,
0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12,
0x21, 0x0a, 0x0c, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74,
0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x76, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73, 0x18,
0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x76, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x73,
0x12, 0x47, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6b, 0x65, 0x79,
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x2e,
0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0c, 0x52, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x5e, 0x0a, 0x0b, 0x52, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x06, 0x64, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75,
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73,
0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x52,
0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x88, 0x01, 0x0a, 0x0c, 0x43, 0x69,
0x70, 0x68, 0x65, 0x72, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x13, 0x0a, 0x05, 0x65, 0x7a,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x7a, 0x49, 0x64, 0x12,
0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x61, 0x66, 0x65, 0x5f, 0x6b, 0x65, 0x79,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x61, 0x66, 0x65, 0x4b, 0x65, 0x79, 0x12,
0x23, 0x0a, 0x0d, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x42,
0x79, 0x74, 0x65, 0x73, 0x2a, 0x9a, 0x02, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10,
0x00, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x69, 0x6d, 0x65, 0x54, 0x69, 0x63, 0x6b, 0x10, 0x01, 0x12,
0x0a, 0x0a, 0x06, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x6c, 0x75, 0x73, 0x68,
0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x72, 0x6f, 0x70,
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x06, 0x12, 0x13, 0x0a, 0x0f,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x10,
0x07, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69,
0x6f, 0x6e, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x46, 0x6c,
0x75, 0x73, 0x68, 0x10, 0x09, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53,
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x0a, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x6d, 0x70, 0x6f,
0x72, 0x74, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43, 0x68,
0x61, 0x6e, 0x67, 0x65, 0x10, 0x0c, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x65, 0x67, 0x69, 0x6e, 0x54,
0x78, 0x6e, 0x10, 0x84, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x54,
0x78, 0x6e, 0x10, 0x85, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63,
0x6b, 0x54, 0x78, 0x6e, 0x10, 0x86, 0x07, 0x12, 0x08, 0x0a, 0x03, 0x54, 0x78, 0x6e, 0x10, 0xe7,
0x07, 0x2a, 0x74, 0x0a, 0x08, 0x54, 0x78, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0e, 0x0a,
0x0a, 0x54, 0x78, 0x6e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0f, 0x0a,
0x0b, 0x54, 0x78, 0x6e, 0x49, 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x10, 0x01, 0x12, 0x0f,
0x0a, 0x0b, 0x54, 0x78, 0x6e, 0x4f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x10, 0x02, 0x12,
0x10, 0x0a, 0x0c, 0x54, 0x78, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x74, 0x65, 0x64, 0x10,
0x03, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x78, 0x6e, 0x4f, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61,
0x63, 0x6b, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x78, 0x6e, 0x52, 0x6f, 0x6c, 0x6c, 0x62,
0x61, 0x63, 0x6b, 0x65, 0x64, 0x10, 0x05, 0x2a, 0x6c, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f,
0x77, 0x6e, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4a, 0x6f, 0x62, 0x49,
0x44, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e,
0x61, 0x6d, 0x65, 0x10, 0x02, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x69,
0x6c, 0x76, 0x75, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x76, 0x32, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x65, 0x64,
0x5f, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03,
0x28, 0x03, 0x52, 0x11, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x65, 0x64, 0x53, 0x65, 0x67, 0x6d, 0x65,
0x6e, 0x74, 0x49, 0x64, 0x73, 0x22, 0x58, 0x0a, 0x17, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x43,
0x68, 0x61, 0x6e, 0x67, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x64, 0x79,
0x12, 0x3d, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x25, 0x2e, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x2e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x22,
0x3b, 0x0a, 0x18, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x45, 0x78,
0x74, 0x72, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73,
0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03,
0x52, 0x0a, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x22, 0x5a, 0x0a, 0x0a,
0x54, 0x78, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x74, 0x78,
0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x74, 0x78, 0x6e, 0x49,
0x64, 0x12, 0x35, 0x0a, 0x16, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x6d,
0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28,
0x03, 0x52, 0x15, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x4d, 0x69, 0x6c, 0x6c,
0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xc4, 0x01, 0x0a, 0x10, 0x52, 0x4d, 0x51,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x12, 0x18, 0x0a,
0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07,
0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x57, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65,
0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6d, 0x69,
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x2e, 0x52, 0x4d, 0x51, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x61,
0x79, 0x6f, 0x75, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45,
0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,
0x1a, 0x3d, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e,
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
0x9b, 0x01, 0x0a, 0x0f, 0x42, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x48, 0x65, 0x61,
0x64, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x72, 0x6f, 0x61, 0x64,
0x63, 0x61, 0x73, 0x74, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x76, 0x63, 0x68, 0x61, 0x6e, 0x6e,
0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x76, 0x63, 0x68, 0x61, 0x6e,
0x6e, 0x65, 0x6c, 0x73, 0x12, 0x47, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69,
0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52,
0x0c, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x5e, 0x0a,
0x0b, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x06,
0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x6d,
0x69, 0x6c, 0x76, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d,
0x61, 0x69, 0x6e, 0x52, 0x06, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x10, 0x0a, 0x03, 0x6b,
0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x88, 0x01,
0x0a, 0x0c, 0x43, 0x69, 0x70, 0x68, 0x65, 0x72, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x13,
0x0a, 0x05, 0x65, 0x7a, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65,
0x7a, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x61, 0x66, 0x65,
0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x61, 0x66, 0x65,
0x4b, 0x65, 0x79, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x62,
0x79, 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x70, 0x61, 0x79, 0x6c,
0x6f, 0x61, 0x64, 0x42, 0x79, 0x74, 0x65, 0x73, 0x2a, 0x9a, 0x02, 0x0a, 0x0b, 0x4d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e,
0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x54, 0x69, 0x6d, 0x65, 0x54, 0x69, 0x63,
0x6b, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x10, 0x02, 0x12,
0x0a, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x46,
0x6c, 0x75, 0x73, 0x68, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e,
0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x06,
0x12, 0x13, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74,
0x69, 0x6f, 0x6e, 0x10, 0x07, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x72, 0x6f, 0x70, 0x50, 0x61, 0x72,
0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x08, 0x12, 0x0f, 0x0a, 0x0b, 0x4d, 0x61, 0x6e, 0x75,
0x61, 0x6c, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x10, 0x09, 0x12, 0x11, 0x0a, 0x0d, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0x0a, 0x12, 0x0a, 0x0a, 0x06,
0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x63, 0x68, 0x65,
0x6d, 0x61, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x10, 0x0c, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x65,
0x67, 0x69, 0x6e, 0x54, 0x78, 0x6e, 0x10, 0x84, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x6d,
0x6d, 0x69, 0x74, 0x54, 0x78, 0x6e, 0x10, 0x85, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x52, 0x6f, 0x6c,
0x6c, 0x62, 0x61, 0x63, 0x6b, 0x54, 0x78, 0x6e, 0x10, 0x86, 0x07, 0x12, 0x08, 0x0a, 0x03, 0x54,
0x78, 0x6e, 0x10, 0xe7, 0x07, 0x2a, 0x74, 0x0a, 0x08, 0x54, 0x78, 0x6e, 0x53, 0x74, 0x61, 0x74,
0x65, 0x12, 0x0e, 0x0a, 0x0a, 0x54, 0x78, 0x6e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10,
0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x78, 0x6e, 0x49, 0x6e, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74,
0x10, 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x78, 0x6e, 0x4f, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69,
0x74, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x54, 0x78, 0x6e, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74,
0x74, 0x65, 0x64, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x78, 0x6e, 0x4f, 0x6e, 0x52, 0x6f,
0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x54, 0x78, 0x6e, 0x52,
0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x10, 0x05, 0x2a, 0x6c, 0x0a, 0x0e, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x19, 0x0a,
0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x55,
0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
0x4a, 0x6f, 0x62, 0x49, 0x44, 0x10, 0x01, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x10, 0x02, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2d, 0x69,
0x6f, 0x2f, 0x6d, 0x69, 0x6c, 0x76, 0x75, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x76, 0x32, 0x2f,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x70, 0x62,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@ -2368,7 +2391,8 @@ var file_messages_proto_goTypes = []interface{}{
nil, // 38: milvus.proto.messages.Message.PropertiesEntry
nil, // 39: milvus.proto.messages.ImmutableMessage.PropertiesEntry
nil, // 40: milvus.proto.messages.RMQMessageLayout.PropertiesEntry
(*schemapb.CollectionSchema)(nil), // 41: milvus.proto.schema.CollectionSchema
(datapb.SegmentLevel)(0), // 41: milvus.proto.data.SegmentLevel
(*schemapb.CollectionSchema)(nil), // 42: milvus.proto.schema.CollectionSchema
}
var file_messages_proto_depIdxs = []int32{
38, // 0: milvus.proto.messages.Message.properties:type_name -> milvus.proto.messages.Message.PropertiesEntry
@ -2377,15 +2401,16 @@ var file_messages_proto_depIdxs = []int32{
4, // 3: milvus.proto.messages.TxnMessageBody.messages:type_name -> milvus.proto.messages.Message
15, // 4: milvus.proto.messages.InsertMessageHeader.partitions:type_name -> milvus.proto.messages.PartitionSegmentAssignment
16, // 5: milvus.proto.messages.PartitionSegmentAssignment.segment_assignment:type_name -> milvus.proto.messages.SegmentAssignment
41, // 6: milvus.proto.messages.SchemaChangeMessageBody.schema:type_name -> milvus.proto.schema.CollectionSchema
40, // 7: milvus.proto.messages.RMQMessageLayout.properties:type_name -> milvus.proto.messages.RMQMessageLayout.PropertiesEntry
36, // 8: milvus.proto.messages.BroadcastHeader.Resource_keys:type_name -> milvus.proto.messages.ResourceKey
2, // 9: milvus.proto.messages.ResourceKey.domain:type_name -> milvus.proto.messages.ResourceDomain
10, // [10:10] is the sub-list for method output_type
10, // [10:10] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name
10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
41, // 6: milvus.proto.messages.CreateSegmentMessageHeader.level:type_name -> milvus.proto.data.SegmentLevel
42, // 7: milvus.proto.messages.SchemaChangeMessageBody.schema:type_name -> milvus.proto.schema.CollectionSchema
40, // 8: milvus.proto.messages.RMQMessageLayout.properties:type_name -> milvus.proto.messages.RMQMessageLayout.PropertiesEntry
36, // 9: milvus.proto.messages.BroadcastHeader.Resource_keys:type_name -> milvus.proto.messages.ResourceKey
2, // 10: milvus.proto.messages.ResourceKey.domain:type_name -> milvus.proto.messages.ResourceDomain
11, // [11:11] is the sub-list for method output_type
11, // [11:11] is the sub-list for method input_type
11, // [11:11] is the sub-list for extension type_name
11, // [11:11] is the sub-list for extension extendee
0, // [0:11] is the sub-list for field type_name
}
func init() { file_messages_proto_init() }

View File

@ -4,6 +4,7 @@ package milvus.proto.streaming;
option go_package = "github.com/milvus-io/milvus/pkg/v2/proto/streamingpb";
import "data_coord.proto";
import "messages.proto";
import "milvus.proto";
import "schema.proto";
@ -574,7 +575,7 @@ message SegmentAssignmentMeta {
string vchannel = 4;
SegmentAssignmentState state = 5;
SegmentAssignmentStat stat = 6;
int64 storage_version = 7;
int64 storage_version = 7; // only available if level is L1 or Legacy.
uint64 checkpoint_time_tick = 8; // The timetick of checkpoint, the meta already see the message at this timetick.
}
@ -587,12 +588,14 @@ enum SegmentAssignmentState {
// SegmentAssignmentStat is the stat of segment assignment.
message SegmentAssignmentStat {
uint64 max_binary_size = 1;
uint64 inserted_rows = 2;
uint64 inserted_binary_size = 3;
uint64 modified_rows = 2;
uint64 modified_binary_size = 3;
int64 create_timestamp = 4;
int64 last_modified_timestamp = 5;
uint64 binlog_counter = 6;
uint64 create_segment_time_tick = 7; // The timetick of create segment message in wal.
data.SegmentLevel level = 8; // The level of the segment, only L0 or L1.
uint64 max_rows = 9; // The max rows of the segment.
}
// The WALCheckpoint that is used to recovery the wal scanner.

File diff suppressed because it is too large Load Diff

View File

@ -107,6 +107,7 @@ func marshalSpecializedHeader(t MessageType, v Version, h string, enc zapcore.Ob
case *CreateSegmentMessageHeader:
enc.AddInt64("collectionID", header.GetCollectionId())
enc.AddInt64("segmentID", header.GetSegmentId())
enc.AddInt64("lv", int64(header.GetLevel()))
case *FlushMessageHeader:
enc.AddInt64("collectionID", header.GetCollectionId())
enc.AddInt64("segmentID", header.GetSegmentId())

View File

@ -5798,11 +5798,17 @@ type streamingConfig struct {
// logging
LoggingAppendSlowThreshold ParamItem `refreshable:"true"`
// memory usage control
FlushMemoryThreshold ParamItem `refreshable:"true"`
FlushGrowingSegmentBytesHwmThreshold ParamItem `refreshable:"true"`
FlushGrowingSegmentBytesLwmThreshold ParamItem `refreshable:"true"`
// Flush control
FlushL0MaxLifetime ParamItem `refreshable:"true"`
FlushL0MaxRowNum ParamItem `refreshable:"true"`
FlushL0MaxSize ParamItem `refreshable:"true"`
// recovery configuration.
WALRecoveryPersistInterval ParamItem `refreshable:"true"`
WALRecoveryMaxDirtyMessage ParamItem `refreshable:"true"`
@ -6039,6 +6045,36 @@ until the total bytes of growing segment is less than this threshold, 0.1 by def
}
p.FlushGrowingSegmentBytesLwmThreshold.Init(base.mgr)
p.FlushL0MaxLifetime = ParamItem{
Key: "streaming.flush.l0.maxLifetime",
Version: "2.6.0",
Doc: `The max lifetime of l0 segment, 10 minutes by default.
If the l0 segment is older than this time, it will be flushed.`,
DefaultValue: "10m",
Export: true,
}
p.FlushL0MaxLifetime.Init(base.mgr)
p.FlushL0MaxRowNum = ParamItem{
Key: "streaming.flush.l0.maxRowNum",
Version: "2.6.0",
Doc: `The max row num of l0 segment, 500000 by default.
If the row num of l0 segment is greater than this num, it will be flushed.`,
DefaultValue: "500000",
Export: true,
}
p.FlushL0MaxRowNum.Init(base.mgr)
p.FlushL0MaxSize = ParamItem{
Key: "streaming.flush.l0.maxSize",
Version: "2.6.0",
Doc: `The max size of l0 segment, 32m by default.
If the binary size of l0 segment is greater than this size, it will be flushed.`,
DefaultValue: "32m",
Export: true,
}
p.FlushL0MaxSize.Init(base.mgr)
p.WALRecoveryPersistInterval = ParamItem{
Key: "streaming.walRecovery.persistInterval",
Version: "2.6.0",

View File

@ -666,6 +666,9 @@ func TestComponentParam(t *testing.T) {
assert.Equal(t, float64(0.6), params.StreamingCfg.FlushMemoryThreshold.GetAsFloat())
assert.Equal(t, float64(0.2), params.StreamingCfg.FlushGrowingSegmentBytesHwmThreshold.GetAsFloat())
assert.Equal(t, float64(0.1), params.StreamingCfg.FlushGrowingSegmentBytesLwmThreshold.GetAsFloat())
assert.Equal(t, 10*time.Minute, params.StreamingCfg.FlushL0MaxLifetime.GetAsDurationByParse())
assert.Equal(t, 500000, params.StreamingCfg.FlushL0MaxRowNum.GetAsInt())
assert.Equal(t, int64(32*1024*1024), params.StreamingCfg.FlushL0MaxSize.GetAsSize())
assert.Equal(t, 30*time.Minute, params.StreamingCfg.WALTruncateSampleInterval.GetAsDurationByParse())
assert.Equal(t, 72*time.Hour, params.StreamingCfg.WALTruncateRetentionInterval.GetAsDurationByParse())