github.com/matrixorigin/matrixone@v1.2.0/pkg/logservice/config.go (about) 1 // Copyright 2021 - 2022 Matrix Origin 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 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package logservice 16 17 import ( 18 "fmt" 19 logservicepb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 20 "github.com/matrixorigin/matrixone/pkg/util" 21 "strconv" 22 "strings" 23 "time" 24 25 "github.com/google/uuid" 26 "github.com/lni/dragonboat/v4" 27 "github.com/lni/vfs" 28 "github.com/matrixorigin/matrixone/pkg/common/moerr" 29 "github.com/matrixorigin/matrixone/pkg/hakeeper" 30 "github.com/matrixorigin/matrixone/pkg/util/toml" 31 ) 32 33 const ( 34 defaultDeploymentID = 1 35 defaultDataDir = "mo-data/logservice" 36 defaultSnapshotExportDir = "exported-snapshot" 37 defaultRaftAddress = "0.0.0.0:32000" 38 defaultServiceAddress = "0.0.0.0:32001" 39 defaultGossipAddress = "0.0.0.0:32002" 40 defaultGossipSeedAddress = "127.0.0.1:32002" 41 defaultRaftPort = 32000 42 defaultGossipPort = 32002 43 44 defaultGossipProbeInterval = 5 * time.Second 45 defaultHeartbeatInterval = time.Second 46 defaultLogDBBufferSize = 768 * 1024 47 defaultTruncateInterval = 10 * time.Second 48 defaultMaxExportedSnapshot = 20 49 defaultMaxMessageSize = 1024 * 1024 * 100 50 // The default value for HAKeeper truncate interval. 51 defaultHAKeeperTruncateInterval = 24 * time.Hour 52 53 DefaultListenHost = "0.0.0.0" 54 DefaultServiceHost = "127.0.0.1" 55 DefaultLogServicePort = 32001 56 57 defaultRestoreFilePath = "hk_data" 58 ) 59 60 var ( 61 DefaultLogServiceServiceAddress = fmt.Sprintf("%s:%d", DefaultServiceHost, DefaultLogServicePort) 62 DefaultGossipServiceAddress = fmt.Sprintf("%s:%d", DefaultServiceHost, defaultGossipPort) 63 ) 64 65 // Config defines the Configurations supported by the Log Service. 66 type Config struct { 67 // FS is the underlying virtual FS used by the log service. Leave it as empty 68 // in production. 69 FS vfs.FS 70 // DeploymentID is basically the Cluster ID, nodes with different DeploymentID 71 // will not be able to communicate via raft. 72 DeploymentID uint64 `toml:"deployment-id"` 73 // UUID is the UUID of the log service node. UUID value must be set. 74 UUID string `toml:"uuid" user_setting:"basic"` 75 // RTTMillisecond is the average round trip time between log service nodes in 76 // milliseconds. 77 RTTMillisecond uint64 `toml:"rttmillisecond"` 78 // DataDir is the name of the directory for storing all log service data. It 79 // should a locally mounted partition with good write and fsync performance. 80 DataDir string `toml:"data-dir" user_setting:"basic"` 81 // SnapshotExportDir is the directory where the dragonboat snapshots are 82 // exported. 83 SnapshotExportDir string `toml:"snapshot-export-dir"` 84 // MaxExportedSnapshot is the max count of exported snapshots. If there are 85 // already MaxExportedSnapshot exported snapshots, no exported snapshot will 86 // be generated. 87 MaxExportedSnapshot int `toml:"max-exported-snapshot"` 88 // ServiceHost is the host name/IP for the service address of RPC request. There is 89 // no port value in it. 90 ServiceHost string `toml:"service-host"` 91 // ServiceAddress is log service's service address that can be reached by 92 // other nodes such as TN nodes. It is deprecated and will be removed. 93 ServiceAddress string `toml:"logservice-address" user_setting:"advanced"` 94 // ServiceListenAddress is the local listen address of the ServiceAddress. 95 // It is deprecated and will be removed. 96 ServiceListenAddress string `toml:"logservice-listen-address"` 97 // ServicePort is log service's service address port that can be reached by 98 // other nodes such as TN nodes. 99 LogServicePort int `toml:"logservice-port"` 100 // RaftAddress is the address that can be reached by other log service nodes 101 // via their raft layer. It is deprecated and will be removed. 102 RaftAddress string `toml:"raft-address" user_setting:"advanced"` 103 // RaftListenAddress is the local listen address of the RaftAddress. 104 // It is deprecated and will be removed. 105 RaftListenAddress string `toml:"raft-listen-address"` 106 // RaftPort is the address port that can be reached by other log service nodes 107 // via their raft layer. 108 RaftPort int `toml:"raft-port"` 109 // UseTeeLogDB enables the log service to use tee based LogDB which is backed 110 // by both a pebble and a tan based LogDB. This field should only be set to 111 // true during testing. 112 UseTeeLogDB bool `toml:"use-tee-logdb"` 113 // LogDBBufferSize is the size of the logdb buffer in bytes. 114 LogDBBufferSize uint64 `toml:"logdb-buffer-size"` 115 // GossipAddress is the address used for accepting gossip communication. 116 // It is deprecated and will be removed. 117 GossipAddress string `toml:"gossip-address" user_setting:"advanced"` 118 // GossipAddressV2 is the address used for accepting gossip communication. 119 // This is for domain name support. It is deprecated and will be removed. 120 GossipAddressV2 string `toml:"gossip-address-v2"` 121 // GossipListenAddress is the local listen address of the GossipAddress 122 // It is deprecated and will be removed. 123 GossipListenAddress string `toml:"gossip-listen-address"` 124 // GossipPort is the port address port used for accepting gossip communication. 125 GossipPort int `toml:"gossip-port"` 126 // GossipSeedAddresses is list of seed addresses that are used for 127 // introducing the local node into the gossip network. 128 GossipSeedAddresses []string `toml:"gossip-seed-addresses" user_setting:"advanced"` 129 // GossipProbeInterval how often gossip nodes probe each other. 130 GossipProbeInterval toml.Duration `toml:"gossip-probe-interval"` 131 // GossipAllowSelfAsSeed allow use self as gossip seed 132 GossipAllowSelfAsSeed bool `toml:"gossip-allow-self-as-seed"` 133 // HeartbeatInterval is the interval of how often log service node should be 134 // sending heartbeat message to the HAKeeper. 135 HeartbeatInterval toml.Duration `toml:"logservice-heartbeat-interval"` 136 // HAKeeperTickInterval is the interval of how often log service node should 137 // tick the HAKeeper. 138 HAKeeperTickInterval toml.Duration `toml:"hakeeper-tick-interval"` 139 // HAKeeperCheckInterval is the interval of how often HAKeeper should run 140 // cluster health checks. 141 HAKeeperCheckInterval toml.Duration `toml:"hakeeper-check-interval"` 142 // TruncateInterval is the interval of how often log service should 143 // process truncate for regular shards. 144 TruncateInterval toml.Duration `toml:"truncate-interval"` 145 // HAKeeperTruncateInterval is the interval of how often log service should 146 // process truncate for HAKeeper shard. 147 HAKeeperTruncateInterval toml.Duration `toml:"hakeeper-truncate-interval"` 148 // ExplicitHostname is the hostname used in draogboat. 149 ExplicitHostname string `toml:"explicit-hostname"` 150 151 RPC struct { 152 // MaxMessageSize is the max size for RPC message. The default value is 10MiB. 153 MaxMessageSize toml.ByteSize `toml:"max-message-size"` 154 // EnableCompress enable compress 155 EnableCompress bool `toml:"enable-compress"` 156 } 157 158 // BootstrapConfig is the configuration specified for the bootstrapping 159 // procedure. It only needs to be specified for Log Stores selected to host 160 // initial HAKeeper replicas during bootstrapping. 161 BootstrapConfig struct { 162 // BootstrapCluster indicates whether the cluster should be bootstrapped. 163 // Note the bootstrapping procedure will only be executed if BootstrapCluster 164 // is true and Config.UUID is found in Config.BootstrapConfig.InitHAKeeperMembers. 165 BootstrapCluster bool `toml:"bootstrap-cluster"` 166 // NumOfLogShards defines the number of Log shards in the initial deployment. 167 NumOfLogShards uint64 `toml:"num-of-log-shards"` 168 // NumOfTNShards defines the number of TN shards in the initial deployment. 169 // The count must be the same as NumOfLogShards in the current implementation. 170 NumOfTNShards uint64 `toml:"num-of-tn-shards"` 171 // NumOfLogShardReplicas is the number of replicas for each shard managed by 172 // Log Stores, including Log Service shards and the HAKeeper. 173 NumOfLogShardReplicas uint64 `toml:"num-of-log-shard-replicas"` 174 // InitHAKeeperMembers defines the initial members of the HAKeeper as a list 175 // of HAKeeper replicaID and UUID pairs. For example, 176 // when the initial HAKeeper members are 177 // replica with replica ID 101 running on Log Store uuid1 178 // replica with replica ID 102 running on Log Store uuid2 179 // replica with replica ID 103 running on Log Store uuid3 180 // the InitHAKeeperMembers string value should be 181 // []string{"101:uuid1", "102:uuid2", "103:uuid3"} 182 // Note that these initial HAKeeper replica IDs must be assigned by k8s 183 // from the range [K8SIDRangeStart, K8SIDRangeEnd) as defined in pkg/hakeeper. 184 // All uuid values are assigned by k8s, they are used to uniquely identify 185 // CN/DN/Log stores. 186 // Config.UUID and Config.BootstrapConfig values are considered together to 187 // figure out what is the replica ID of the initial HAKeeper replica. That 188 // is when Config.UUID is found in InitHAKeeperMembers, then the corresponding 189 // replica ID value will be used to launch a HAKeeper replica on the Log 190 // Service instance. 191 InitHAKeeperMembers []string `toml:"init-hakeeper-members" user_setting:"advanced"` 192 // Restore structure is used when the cluster needs to restore data. 193 Restore struct { 194 // FilePath is the path of the file, which contains the backup data. 195 // If is not set, nothing will be done for restore. 196 FilePath string `toml:"file-path"` 197 // Force means that we force to do restore even if RESTORED tag file 198 // already exists. 199 Force bool `toml:"force"` 200 } `toml:"restore"` 201 } 202 203 HAKeeperConfig struct { 204 // TickPerSecond indicates how many ticks every second. 205 // In HAKeeper, we do not use actual time to measure time elapse. 206 // Instead, we use ticks. 207 TickPerSecond int `toml:"tick-per-second"` 208 // LogStoreTimeout is the actual time limit between a log store's heartbeat. 209 // If HAKeeper does not receive two heartbeat within LogStoreTimeout, 210 // it regards the log store as down. 211 LogStoreTimeout toml.Duration `toml:"log-store-timeout"` 212 // TNStoreTimeout is the actual time limit between a tn store's heartbeat. 213 // If HAKeeper does not receive two heartbeat within TNStoreTimeout, 214 // it regards the tn store as down. 215 TNStoreTimeout toml.Duration `toml:"tn-store-timeout"` 216 // CNStoreTimeout is the actual time limit between a cn store's heartbeat. 217 // If HAKeeper does not receive two heartbeat within CNStoreTimeout, 218 // it regards the tn store as down. 219 CNStoreTimeout toml.Duration `toml:"cn-store-timeout"` 220 } 221 222 // HAKeeperClientConfig is the config for HAKeeperClient 223 HAKeeperClientConfig HAKeeperClientConfig 224 225 // DisableWorkers disables the HAKeeper ticker and HAKeeper client in tests. 226 // Never set this field to true in production 227 DisableWorkers bool 228 229 Ctl struct { 230 // ListenAddress ctl service listen address for receiving ctl requests 231 ListenAddress string `toml:"listen-address"` 232 // ServiceAddress service address for communication, if this address is not set, use 233 // ListenAddress as the communication address. 234 ServiceAddress string `toml:"service-address"` 235 } `toml:"ctl"` 236 } 237 238 func (c *Config) GetHAKeeperConfig() hakeeper.Config { 239 return hakeeper.Config{ 240 TickPerSecond: c.HAKeeperConfig.TickPerSecond, 241 LogStoreTimeout: c.HAKeeperConfig.LogStoreTimeout.Duration, 242 TNStoreTimeout: c.HAKeeperConfig.TNStoreTimeout.Duration, 243 CNStoreTimeout: c.HAKeeperConfig.CNStoreTimeout.Duration, 244 } 245 } 246 247 func (c *Config) GetHAKeeperClientConfig() HAKeeperClientConfig { 248 saddr := make([]string, 0) 249 saddr = append(saddr, c.HAKeeperClientConfig.ServiceAddresses...) 250 return HAKeeperClientConfig{ 251 DiscoveryAddress: c.HAKeeperClientConfig.DiscoveryAddress, 252 ServiceAddresses: saddr, 253 } 254 } 255 256 // returns replica ID of the HAKeeper replica and a boolean indicating whether 257 // we should run the bootstrap procedure. 258 func (c *Config) Bootstrapping() (uint64, bool) { 259 if !c.BootstrapConfig.BootstrapCluster { 260 return 0, false 261 } 262 members, err := c.GetInitHAKeeperMembers() 263 if err != nil { 264 return 0, false 265 } 266 for replicaID, uuid := range members { 267 if uuid == c.UUID { 268 return replicaID, true 269 } 270 } 271 return 0, false 272 } 273 274 func (c *Config) GetInitHAKeeperMembers() (map[uint64]dragonboat.Target, error) { 275 result := make(map[uint64]dragonboat.Target) 276 for _, pair := range c.BootstrapConfig.InitHAKeeperMembers { 277 pair = strings.TrimSpace(pair) 278 parts := strings.Split(pair, ":") 279 if len(parts) == 2 { 280 id := strings.TrimSpace(parts[0]) 281 target := strings.TrimSpace(parts[1]) 282 if _, err := uuid.Parse(target); err != nil { 283 return nil, moerr.NewBadConfigNoCtx("uuid %s", target) 284 } 285 idn, err := strconv.ParseUint(id, 10, 64) 286 if err != nil { 287 return nil, moerr.NewBadConfigNoCtx("replicateID '%v'", id) 288 } 289 if idn >= hakeeper.K8SIDRangeEnd || idn < hakeeper.K8SIDRangeStart { 290 return nil, moerr.NewBadConfigNoCtx("replicateID '%v'", id) 291 } 292 result[idn] = target 293 } else { 294 return nil, moerr.NewBadConfigNoCtx("replicaID:target %s", pair) 295 } 296 } 297 return result, nil 298 } 299 300 // Validate validates the configuration. 301 func (c *Config) Validate() error { 302 if len(c.UUID) == 0 { 303 return moerr.NewBadConfigNoCtx("uuid not set") 304 } 305 if c.DeploymentID == 0 { 306 return moerr.NewBadConfigNoCtx("deploymentID not set") 307 } 308 // when *ListenAddress is not empty and *Address is empty, consider it as an 309 // error 310 if len(c.ServiceAddress) == 0 && len(c.ServiceListenAddress) != 0 && c.LogServicePort == 0 { 311 return moerr.NewBadConfigNoCtx("ServiceAddress and LogServicePort not set") 312 } 313 if len(c.RaftAddress) == 0 && len(c.RaftListenAddress) != 0 && c.RaftPort == 0 { 314 return moerr.NewBadConfigNoCtx("RaftAddress and RaftPort not set") 315 } 316 if c.LogDBBufferSize == 0 { 317 return moerr.NewBadConfigNoCtx("LogDBBufferSize not set") 318 } 319 if len(c.GossipAddress) == 0 && len(c.GossipListenAddress) != 0 && c.GossipPort == 0 { 320 return moerr.NewBadConfigNoCtx("GossipAddress and GossipPort not set") 321 } 322 if len(c.GossipSeedAddresses) == 0 { 323 return moerr.NewBadConfigNoCtx("GossipSeedAddress not set") 324 } 325 if c.HAKeeperConfig.TickPerSecond == 0 { 326 return moerr.NewBadConfigNoCtx("TickPerSecond not set") 327 } 328 if c.HAKeeperConfig.LogStoreTimeout.Duration == 0 { 329 return moerr.NewBadConfigNoCtx("LogStoreTimeout not set") 330 } 331 if c.HAKeeperConfig.TNStoreTimeout.Duration == 0 { 332 return moerr.NewBadConfigNoCtx("DNStoreTimeout not set") 333 } 334 if c.GossipProbeInterval.Duration == 0 { 335 return moerr.NewBadConfigNoCtx("GossipProbeInterval not set") 336 } 337 if c.TruncateInterval.Duration == 0 { 338 return moerr.NewBadConfigNoCtx("TruncateInterval not set") 339 } 340 if c.HAKeeperTruncateInterval.Duration == 0 { 341 return moerr.NewBadConfigNoCtx("HAKeeperTruncateInterval not set") 342 } 343 if c.RPC.MaxMessageSize == 0 { 344 return moerr.NewBadConfigNoCtx("MaxMessageSize not set") 345 } 346 // validate BootstrapConfig 347 if c.BootstrapConfig.BootstrapCluster { 348 if c.BootstrapConfig.NumOfLogShards == 0 { 349 return moerr.NewBadConfigNoCtx("NumOfLogShards not set") 350 } 351 if c.BootstrapConfig.NumOfTNShards == 0 { 352 return moerr.NewBadConfigNoCtx("NumOfDNShards not set") 353 } 354 if c.BootstrapConfig.NumOfLogShardReplicas == 0 { 355 return moerr.NewBadConfigNoCtx("NumOfLogShardReplica not set") 356 } 357 if c.BootstrapConfig.NumOfTNShards != c.BootstrapConfig.NumOfLogShards { 358 return moerr.NewBadConfigNoCtx("NumOfDNShards does not match NumOfLogShards") 359 } 360 members, err := c.GetInitHAKeeperMembers() 361 if err != nil { 362 return err 363 } 364 if len(members) == 0 { 365 return moerr.NewBadConfigNoCtx("InitHAKeeperMembers not set") 366 } 367 if uint64(len(members)) != c.BootstrapConfig.NumOfLogShardReplicas { 368 return moerr.NewBadConfigNoCtx("InitHAKeeperMembers does not match NumOfLogShardReplicas") 369 } 370 } 371 372 return nil 373 } 374 375 func DefaultConfig() Config { 376 uid := "7c4dccb4-4d3c-41f8-b482-5251dc7a41bf" 377 return Config{ 378 FS: vfs.Default, 379 DeploymentID: defaultDeploymentID, 380 UUID: uid, 381 RTTMillisecond: 200, 382 DataDir: defaultDataDir, 383 SnapshotExportDir: defaultSnapshotExportDir, 384 MaxExportedSnapshot: defaultMaxExportedSnapshot, 385 ServiceAddress: defaultServiceAddress, 386 RaftAddress: defaultRaftAddress, 387 ServiceHost: DefaultServiceHost, 388 UseTeeLogDB: false, 389 LogDBBufferSize: defaultLogDBBufferSize, 390 GossipAddress: defaultGossipAddress, 391 GossipSeedAddresses: []string{DefaultGossipServiceAddress}, 392 GossipProbeInterval: toml.Duration{Duration: defaultGossipProbeInterval}, 393 GossipAllowSelfAsSeed: true, 394 HeartbeatInterval: toml.Duration{Duration: defaultHeartbeatInterval}, 395 HAKeeperTickInterval: toml.Duration{Duration: time.Second / hakeeper.DefaultTickPerSecond}, 396 HAKeeperCheckInterval: toml.Duration{Duration: hakeeper.CheckDuration}, 397 TruncateInterval: toml.Duration{Duration: defaultTruncateInterval}, 398 HAKeeperTruncateInterval: toml.Duration{Duration: defaultHAKeeperTruncateInterval}, 399 RPC: struct { 400 MaxMessageSize toml.ByteSize `toml:"max-message-size"` 401 EnableCompress bool `toml:"enable-compress"` 402 }(struct { 403 MaxMessageSize toml.ByteSize 404 EnableCompress bool 405 }{ 406 MaxMessageSize: toml.ByteSize(defaultMaxMessageSize), 407 EnableCompress: false, 408 }), 409 BootstrapConfig: struct { 410 BootstrapCluster bool `toml:"bootstrap-cluster"` 411 NumOfLogShards uint64 `toml:"num-of-log-shards"` 412 NumOfTNShards uint64 `toml:"num-of-tn-shards"` 413 NumOfLogShardReplicas uint64 `toml:"num-of-log-shard-replicas"` 414 InitHAKeeperMembers []string `toml:"init-hakeeper-members" user_setting:"advanced"` 415 Restore struct { 416 FilePath string `toml:"file-path"` 417 Force bool `toml:"force"` 418 } `toml:"restore"` 419 }(struct { 420 BootstrapCluster bool 421 NumOfLogShards uint64 422 NumOfTNShards uint64 423 NumOfLogShardReplicas uint64 424 InitHAKeeperMembers []string 425 Restore struct { 426 FilePath string 427 Force bool 428 } 429 }{ 430 BootstrapCluster: true, 431 NumOfLogShards: 1, 432 NumOfTNShards: 1, 433 NumOfLogShardReplicas: 1, 434 InitHAKeeperMembers: []string{"131072:" + uid}, 435 Restore: struct { 436 FilePath string 437 Force bool 438 }{ 439 FilePath: defaultRestoreFilePath, 440 Force: false, 441 }, 442 }), 443 HAKeeperConfig: struct { 444 TickPerSecond int `toml:"tick-per-second"` 445 LogStoreTimeout toml.Duration `toml:"log-store-timeout"` 446 TNStoreTimeout toml.Duration `toml:"tn-store-timeout"` 447 CNStoreTimeout toml.Duration `toml:"cn-store-timeout"` 448 }(struct { 449 TickPerSecond int 450 LogStoreTimeout toml.Duration 451 TNStoreTimeout toml.Duration 452 CNStoreTimeout toml.Duration 453 }{ 454 TickPerSecond: hakeeper.DefaultTickPerSecond, 455 LogStoreTimeout: toml.Duration{Duration: hakeeper.DefaultLogStoreTimeout}, 456 TNStoreTimeout: toml.Duration{Duration: hakeeper.DefaultTNStoreTimeout}, 457 CNStoreTimeout: toml.Duration{Duration: hakeeper.DefaultCNStoreTimeout}, 458 }), 459 HAKeeperClientConfig: HAKeeperClientConfig{ 460 DiscoveryAddress: "", 461 ServiceAddresses: []string{DefaultLogServiceServiceAddress}, 462 AllocateIDBatch: 100, 463 EnableCompress: false, 464 }, 465 DisableWorkers: false, 466 // Not used for now. 467 Ctl: struct { 468 ListenAddress string `toml:"listen-address"` 469 ServiceAddress string `toml:"service-address"` 470 }(struct { 471 ListenAddress string 472 ServiceAddress string 473 }{ListenAddress: "", ServiceAddress: ""}), 474 } 475 } 476 477 // Fill just fills the listen addresses. This function is deprecated and will be removed 478 // as the configurations are all deprecated. 479 func (c *Config) Fill() { 480 if len(c.ServiceAddress) == 0 { 481 c.ServiceAddress = defaultServiceAddress 482 c.ServiceListenAddress = defaultServiceAddress 483 } else if len(c.ServiceAddress) != 0 && len(c.ServiceListenAddress) == 0 { 484 c.ServiceListenAddress = c.ServiceAddress 485 } 486 if len(c.RaftAddress) == 0 { 487 c.RaftAddress = defaultRaftAddress 488 c.RaftListenAddress = defaultRaftAddress 489 } else if len(c.RaftAddress) != 0 && len(c.RaftListenAddress) == 0 { 490 c.RaftListenAddress = c.RaftAddress 491 } 492 // If GossipAddressV2 is set, we use it as gossip address, and GossipAddress 493 // will be overridden by it. 494 if len(c.GossipAddressV2) != 0 { 495 c.GossipAddress = c.GossipAddressV2 496 } 497 if len(c.GossipAddress) == 0 { 498 c.GossipAddress = defaultGossipAddress 499 c.GossipListenAddress = defaultGossipAddress 500 } else if len(c.GossipAddress) != 0 && len(c.GossipListenAddress) == 0 { 501 c.GossipListenAddress = c.GossipAddress 502 } 503 if len(c.GossipSeedAddresses) == 0 { 504 c.GossipSeedAddresses = []string{defaultGossipSeedAddress} 505 } 506 } 507 508 // HAKeeperClientConfig is the config for HAKeeper clients. 509 type HAKeeperClientConfig struct { 510 // DiscoveryAddress is the Log Service discovery address provided by k8s. 511 DiscoveryAddress string `toml:"discovery-address"` 512 // ServiceAddresses is a list of well known Log Services' service addresses. 513 ServiceAddresses []string `toml:"service-addresses"` 514 // AllocateIDBatch how many IDs are assigned from hakeeper each time. Default is 515 // 100. 516 AllocateIDBatch uint64 `toml:"allocate-id-batch"` 517 // EnableCompress enable compress 518 EnableCompress bool `toml:"enable-compress"` 519 } 520 521 // Validate validates the HAKeeperClientConfig. 522 func (c *HAKeeperClientConfig) Validate() error { 523 if len(c.DiscoveryAddress) == 0 && len(c.ServiceAddresses) == 0 { 524 c.ServiceAddresses = []string{DefaultLogServiceServiceAddress} 525 } 526 if c.AllocateIDBatch == 0 { 527 c.AllocateIDBatch = 100 528 } 529 return nil 530 } 531 532 // ClientConfig is the configuration for log service clients. 533 type ClientConfig struct { 534 // Tag client tag 535 Tag string 536 // ReadOnly indicates whether this is a read-only client. 537 ReadOnly bool 538 // LogShardID is the shard ID of the log service shard to be used. 539 LogShardID uint64 540 // TNReplicaID is the replica ID of the TN that owns the created client. 541 TNReplicaID uint64 542 // DiscoveryAddress is the Log Service discovery address provided by k8s. 543 DiscoveryAddress string 544 // LogService nodes service addresses. This field is provided for testing 545 // purposes only. 546 ServiceAddresses []string 547 // MaxMessageSize is the max message size for RPC. 548 MaxMessageSize int 549 // EnableCompress enable compress 550 EnableCompress bool 551 } 552 553 // Validate validates the ClientConfig. 554 func (c *ClientConfig) Validate() error { 555 if c.LogShardID == 0 { 556 return moerr.NewBadConfigNoCtx("LogShardID value cannot be 0") 557 } 558 if c.TNReplicaID == 0 { 559 return moerr.NewBadConfigNoCtx("DNReplicaID value cannot be 0") 560 } 561 if len(c.DiscoveryAddress) == 0 && len(c.ServiceAddresses) == 0 { 562 c.ServiceAddresses = []string{DefaultLogServiceServiceAddress} 563 } 564 return nil 565 } 566 567 func splitAddresses(v string) []string { 568 results := make([]string, 0) 569 parts := strings.Split(v, ";") 570 for _, v := range parts { 571 t := strings.TrimSpace(v) 572 if len(t) > 0 { 573 results = append(results, t) 574 } 575 } 576 return results 577 } 578 579 func (c *Config) LogServiceListenAddr() string { 580 if c.LogServicePort != 0 { 581 return fmt.Sprintf("%s:%d", DefaultListenHost, c.LogServicePort) 582 } 583 return c.ServiceListenAddress 584 } 585 586 func (c *Config) LogServiceServiceAddr() string { 587 if c.LogServicePort != 0 { 588 return fmt.Sprintf("%s:%d", c.ServiceHost, c.LogServicePort) 589 } 590 return c.ServiceAddress 591 } 592 593 func (c *Config) RaftListenAddr() string { 594 if c.RaftPort != 0 { 595 return fmt.Sprintf("%s:%d", DefaultListenHost, c.RaftPort) 596 } 597 return c.RaftListenAddress 598 } 599 600 func (c *Config) RaftServiceAddr() string { 601 if c.RaftPort != 0 { 602 return fmt.Sprintf("%s:%d", c.ServiceHost, c.RaftPort) 603 } 604 return c.RaftAddress 605 } 606 607 func (c *Config) GossipListenAddr() string { 608 if c.GossipPort != 0 { 609 return fmt.Sprintf("%s:%d", DefaultListenHost, c.GossipPort) 610 } 611 return c.GossipListenAddress 612 } 613 614 func (c *Config) GossipServiceAddr() string { 615 if c.GossipPort != 0 { 616 return fmt.Sprintf("%s:%d", c.ServiceHost, c.GossipPort) 617 } 618 return c.GossipAddress 619 } 620 621 func dumpLogConfig(cfg Config) (map[string]*logservicepb.ConfigItem, error) { 622 defCfg := Config{} 623 return util.DumpConfig(cfg, defCfg) 624 }