github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/config/messages.go (about) 1 // Copyright 2021 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package config 15 16 import ( 17 "time" 18 19 cerrors "github.com/pingcap/tiflow/pkg/errors" 20 "github.com/pingcap/tiflow/pkg/p2p" 21 ) 22 23 const defaultMaxRecvMsgSize = 256 * 1024 * 1024 // 256MB 24 25 // MessagesConfig configs MessageServer and MessageClient. 26 type MessagesConfig struct { 27 ClientMaxBatchInterval TomlDuration `toml:"client-max-batch-interval" json:"client-max-batch-interval"` 28 ClientMaxBatchSize int `toml:"client-max-batch-size" json:"client-max-batch-size"` 29 ClientMaxBatchCount int `toml:"client-max-batch-count" json:"client-max-batch-count"` 30 ClientRetryRateLimit float64 `toml:"client-retry-rate-limit" json:"client-retry-rate-limit"` 31 32 ServerMaxPendingMessageCount int `toml:"server-max-pending-message-count" json:"server-max-pending-message-count"` 33 ServerAckInterval TomlDuration `toml:"server-ack-interval" json:"server-ack-interval"` 34 ServerWorkerPoolSize int `toml:"server-worker-pool-size" json:"server-worker-pool-size"` 35 36 // MaxRecvMsgSize is the maximum message size in bytes TiCDC can receive. 37 MaxRecvMsgSize int `toml:"max-recv-msg-size" json:"max-recv-msg-size"` 38 39 // After a duration of this time if the server doesn't see any activity it 40 // pings the client to see if the transport is still alive. 41 KeepAliveTime TomlDuration `toml:"keep-alive-time" json:"keep-alive-time"` 42 // After having pinged for keepalive check, the server waits for a duration 43 // of Timeout and if no activity is seen even after that the connection is 44 // closed. 45 KeepAliveTimeout TomlDuration `toml:"keep-alive-timeout" json:"keep-alive-timeout"` 46 } 47 48 // read only 49 var defaultMessageConfig = &MessagesConfig{ 50 // Note that ClientMaxBatchInterval may increase the checkpoint latency. 51 ClientMaxBatchInterval: TomlDuration(time.Millisecond * 10), 52 ClientMaxBatchSize: 8 * 1024 * 1024, // 8MB 53 ClientMaxBatchCount: 128, 54 ClientRetryRateLimit: 1.0, // Once per second 55 ServerMaxPendingMessageCount: 102400, 56 ServerAckInterval: TomlDuration(time.Millisecond * 100), 57 ServerWorkerPoolSize: 4, 58 MaxRecvMsgSize: defaultMaxRecvMsgSize, 59 KeepAliveTime: TomlDuration(time.Second * 30), 60 KeepAliveTimeout: TomlDuration(time.Second * 10), 61 } 62 63 const ( 64 // These values are advanced parameters to MessageServer and MessageClient, 65 // and it is not necessary for users to modify them. 66 67 // clientSendChannelSize represents the size of an internal channel used to buffer 68 // unsent messages. 69 clientSendChannelSize = 128 70 71 // clientDialTimeout represents the timeout given to gRPC to dial. 5 seconds seems reasonable 72 // because it is unlikely that the latency between TiCDC nodes is larger than 5 seconds. 73 clientDialTimeout = time.Second * 5 74 75 // maxTopicPendingCount is the max allowed number of unhandled message for a message topic 76 // ** if there is NO registered handler for it **. 77 maxTopicPendingCount = 256 78 79 // serverSendChannelSize is the size of a channel used to buffer messages to be sent back to 80 // the client. Note that the traffic from the server to the client is minimal, as it consists 81 // only of ACK messages. 82 serverSendChannelSize = 16 83 84 // maxPeerCount is the maximum number of peers that can be connected to the server. 85 // 1024 is reasonable given the current scalability of TiCDC. 86 maxPeerCount = 1024 87 88 // unregisterHandleTimeout is the time to wait for a message handler to unregister. 89 // Only in extreme situations can unregistering take more than a second. We use a timeout 90 // to make deadlocking more detectable. 91 unregisterHandleTimeout = time.Second * 10 92 93 // serverSendRateLimit is the rate limit of sending messages from the server to the client. 94 // Since ACK messages are batched, 1024 should be more than enough. 95 serverSendRateLimit = 1024.0 96 ) 97 98 // ValidateAndAdjust validates and adjusts the configs. 99 func (c *MessagesConfig) ValidateAndAdjust() error { 100 if c.ClientMaxBatchInterval == 0 { 101 c.ClientMaxBatchInterval = defaultMessageConfig.ClientMaxBatchInterval 102 } 103 if time.Duration(c.ClientMaxBatchInterval) > 10*time.Second { 104 return cerrors.ErrInvalidServerOption.GenWithStackByArgs("client-max-batch-interval is larger than 10s") 105 } 106 107 // We do not impose an upper limit on ClientMaxBatchSize and ClientMaxBatchCount 108 // to allow some flexibility in tuning and debugging. 109 if c.ClientMaxBatchSize <= 0 { 110 c.ClientMaxBatchSize = defaultMessageConfig.ClientMaxBatchSize 111 } 112 113 if c.ClientMaxBatchCount <= 0 { 114 c.ClientMaxBatchCount = defaultMessageConfig.ClientMaxBatchCount 115 } 116 117 if c.ClientRetryRateLimit <= 0.0 { 118 c.ClientRetryRateLimit = defaultMessageConfig.ClientRetryRateLimit 119 } 120 121 if c.ServerMaxPendingMessageCount <= 0 { 122 c.ServerMaxPendingMessageCount = defaultMessageConfig.ServerMaxPendingMessageCount 123 } 124 125 if c.ServerAckInterval == 0 { 126 c.ServerAckInterval = defaultMessageConfig.ServerAckInterval 127 } 128 if c.KeepAliveTime == 0 { 129 c.KeepAliveTime = defaultMessageConfig.KeepAliveTime 130 } 131 if c.KeepAliveTimeout == 0 { 132 c.KeepAliveTimeout = defaultMessageConfig.KeepAliveTimeout 133 } 134 if time.Duration(c.ServerAckInterval) > 10*time.Second { 135 return cerrors.ErrInvalidServerOption.GenWithStackByArgs("server-ack-interval is larger than 10s") 136 } 137 138 if c.ServerWorkerPoolSize <= 0 { 139 c.ServerWorkerPoolSize = defaultMessageConfig.ServerWorkerPoolSize 140 } 141 // We put an upper limit on ServerWorkerPoolSize to avoid having to create many goroutines. 142 if c.ServerWorkerPoolSize > 32 { 143 return cerrors.ErrInvalidServerOption.GenWithStackByArgs("server-worker-pool-size is larger than 32") 144 } 145 146 if c.MaxRecvMsgSize == 0 { 147 c.MaxRecvMsgSize = defaultMaxRecvMsgSize 148 } 149 if c.MaxRecvMsgSize < 0 { 150 return cerrors.ErrInvalidServerOption.GenWithStackByArgs( 151 "max-recv-msg-size must be larger than 0") 152 } 153 154 return nil 155 } 156 157 // Clone returns a deep copy of the configuration. 158 func (c *MessagesConfig) Clone() *MessagesConfig { 159 return &MessagesConfig{ 160 ClientMaxBatchInterval: c.ClientMaxBatchInterval, 161 ClientMaxBatchSize: c.ClientMaxBatchSize, 162 ClientMaxBatchCount: c.ClientMaxBatchCount, 163 ClientRetryRateLimit: c.ClientRetryRateLimit, 164 ServerMaxPendingMessageCount: c.ServerMaxPendingMessageCount, 165 ServerAckInterval: c.ServerAckInterval, 166 ServerWorkerPoolSize: c.ServerWorkerPoolSize, 167 MaxRecvMsgSize: c.MaxRecvMsgSize, 168 KeepAliveTime: c.KeepAliveTime, 169 KeepAliveTimeout: c.KeepAliveTimeout, 170 } 171 } 172 173 // ToMessageClientConfig converts the MessagesConfig to a MessageClientConfig. 174 func (c *MessagesConfig) ToMessageClientConfig() *p2p.MessageClientConfig { 175 return &p2p.MessageClientConfig{ 176 SendChannelSize: clientSendChannelSize, 177 BatchSendInterval: time.Duration(c.ClientMaxBatchInterval), 178 MaxBatchBytes: c.ClientMaxBatchSize, 179 MaxBatchCount: c.ClientMaxBatchCount, 180 RetryRateLimitPerSecond: c.ClientRetryRateLimit, 181 DialTimeout: clientDialTimeout, 182 MaxRecvMsgSize: c.MaxRecvMsgSize, 183 } 184 } 185 186 // ToMessageServerConfig returns a MessageServerConfig that can be used to create a MessageServer. 187 func (c *MessagesConfig) ToMessageServerConfig() *p2p.MessageServerConfig { 188 return &p2p.MessageServerConfig{ 189 MaxPendingMessageCountPerTopic: maxTopicPendingCount, 190 MaxPendingTaskCount: c.ServerMaxPendingMessageCount, 191 SendChannelSize: serverSendChannelSize, 192 AckInterval: time.Duration(c.ServerAckInterval), 193 WorkerPoolSize: c.ServerWorkerPoolSize, 194 MaxPeerCount: maxPeerCount, 195 WaitUnregisterHandleTimeoutThreshold: unregisterHandleTimeout, 196 SendRateLimitPerStream: serverSendRateLimit, 197 MaxRecvMsgSize: c.MaxRecvMsgSize, 198 KeepAliveTimeout: time.Duration(c.KeepAliveTimeout), 199 KeepAliveTime: time.Duration(c.KeepAliveTime), 200 } 201 }