github.com/pingcap/tiup@v1.15.1/components/playground/instance/tiflash.go (about) 1 // Copyright 2020 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 instance 15 16 import ( 17 "context" 18 "fmt" 19 "os/exec" 20 "path/filepath" 21 "strings" 22 23 "github.com/pingcap/errors" 24 tiupexec "github.com/pingcap/tiup/pkg/exec" 25 "github.com/pingcap/tiup/pkg/tidbver" 26 "github.com/pingcap/tiup/pkg/utils" 27 ) 28 29 // TiFlashRole is the role of TiFlash. 30 type TiFlashRole string 31 32 const ( 33 // TiFlashRoleNormal is used when TiFlash is not in disaggregated mode. 34 TiFlashRoleNormal TiFlashRole = "normal" 35 36 // TiFlashRoleDisaggWrite is used when TiFlash is in disaggregated mode and is the write node. 37 TiFlashRoleDisaggWrite TiFlashRole = "write" 38 // TiFlashRoleDisaggCompute is used when TiFlash is in disaggregated mode and is the compute node. 39 TiFlashRoleDisaggCompute TiFlashRole = "compute" 40 ) 41 42 // TiFlashInstance represent a running TiFlash 43 type TiFlashInstance struct { 44 instance 45 Role TiFlashRole 46 cseOpts CSEOptions 47 TCPPort int 48 ServicePort int 49 ProxyPort int 50 ProxyStatusPort int 51 pds []*PDInstance 52 dbs []*TiDBInstance 53 Process 54 } 55 56 // NewTiFlashInstance return a TiFlashInstance 57 func NewTiFlashInstance(role TiFlashRole, cseOptions CSEOptions, binPath, dir, host, configPath string, id int, pds []*PDInstance, dbs []*TiDBInstance, version string) *TiFlashInstance { 58 if role != TiFlashRoleNormal && role != TiFlashRoleDisaggWrite && role != TiFlashRoleDisaggCompute { 59 panic(fmt.Sprintf("Unknown TiFlash role %s", role)) 60 } 61 62 httpPort := 8123 63 if !tidbver.TiFlashNotNeedHTTPPortConfig(version) { 64 httpPort = utils.MustGetFreePort(host, httpPort) 65 } 66 return &TiFlashInstance{ 67 instance: instance{ 68 BinPath: binPath, 69 ID: id, 70 Dir: dir, 71 Host: host, 72 Port: httpPort, 73 StatusPort: utils.MustGetFreePort(host, 8234), 74 ConfigPath: configPath, 75 }, 76 Role: role, 77 cseOpts: cseOptions, 78 TCPPort: utils.MustGetFreePort(host, 9100), // 9000 for default object store port 79 ServicePort: utils.MustGetFreePort(host, 3930), 80 ProxyPort: utils.MustGetFreePort(host, 20170), 81 ProxyStatusPort: utils.MustGetFreePort(host, 20292), 82 pds: pds, 83 dbs: dbs, 84 } 85 } 86 87 // Addr return the address of tiflash 88 func (inst *TiFlashInstance) Addr() string { 89 return utils.JoinHostPort(AdvertiseHost(inst.Host), inst.ServicePort) 90 } 91 92 // StatusAddrs implements Instance interface. 93 func (inst *TiFlashInstance) StatusAddrs() (addrs []string) { 94 addrs = append(addrs, utils.JoinHostPort(inst.Host, inst.StatusPort)) 95 addrs = append(addrs, utils.JoinHostPort(inst.Host, inst.ProxyStatusPort)) 96 return 97 } 98 99 // Start calls set inst.cmd and Start 100 func (inst *TiFlashInstance) Start(ctx context.Context, version utils.Version) error { 101 if !tidbver.TiFlashPlaygroundNewStartMode(version.String()) { 102 return inst.startOld(ctx, version) 103 } 104 105 proxyConfigPath := filepath.Join(inst.Dir, "tiflash_proxy.toml") 106 if err := prepareConfig( 107 proxyConfigPath, 108 "", 109 inst.getProxyConfig(), 110 ); err != nil { 111 return err 112 } 113 114 configPath := filepath.Join(inst.Dir, "tiflash.toml") 115 if err := prepareConfig( 116 configPath, 117 inst.ConfigPath, 118 inst.getConfig(), 119 ); err != nil { 120 return err 121 } 122 123 endpoints := pdEndpoints(inst.pds, false) 124 125 args := []string{ 126 "server", 127 fmt.Sprintf("--config-file=%s", configPath), 128 "--", 129 } 130 runtimeConfig := [][]string{ 131 {"path", filepath.Join(inst.Dir, "data")}, 132 {"listen_host", inst.Host}, 133 {"logger.log", inst.LogFile()}, 134 {"logger.errorlog", filepath.Join(inst.Dir, "tiflash_error.log")}, 135 {"status.metrics_port", fmt.Sprintf("%d", inst.StatusPort)}, 136 {"flash.service_addr", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.ServicePort)}, 137 {"raft.pd_addr", strings.Join(endpoints, ",")}, 138 {"flash.proxy.addr", utils.JoinHostPort(inst.Host, inst.ProxyPort)}, 139 {"flash.proxy.advertise-addr", utils.JoinHostPort(AdvertiseHost(inst.Host), inst.ProxyPort)}, 140 {"flash.proxy.status-addr", utils.JoinHostPort(inst.Host, inst.ProxyStatusPort)}, 141 {"flash.proxy.data-dir", filepath.Join(inst.Dir, "proxy_data")}, 142 {"flash.proxy.log-file", filepath.Join(inst.Dir, "tiflash_tikv.log")}, 143 } 144 userConfig, err := unmarshalConfig(configPath) 145 if err != nil { 146 return errors.Trace(err) 147 } 148 for _, arg := range runtimeConfig { 149 // if user has set the config, skip it 150 if !isKeyPresentInMap(userConfig, arg[0]) { 151 args = append(args, fmt.Sprintf("--%s=%s", arg[0], arg[1])) 152 } 153 } 154 155 if inst.BinPath, err = tiupexec.PrepareBinary("tiflash", version, inst.BinPath); err != nil { 156 return err 157 } 158 inst.Process = &process{cmd: PrepareCommand(ctx, inst.BinPath, args, nil, inst.Dir)} 159 160 logIfErr(inst.Process.SetOutputFile(inst.LogFile())) 161 return inst.Process.Start() 162 } 163 164 func isKeyPresentInMap(m map[string]any, key string) bool { 165 keys := strings.Split(key, ".") 166 currentMap := m 167 168 for i := 0; i < len(keys); i++ { 169 if _, ok := currentMap[keys[i]]; !ok { 170 return false 171 } 172 173 // If the current value is a nested map, update the current map to the nested map 174 if innerMap, ok := currentMap[keys[i]].(map[string]any); ok { 175 currentMap = innerMap 176 } 177 } 178 179 return true 180 } 181 182 // Component return the component name. 183 func (inst *TiFlashInstance) Component() string { 184 return "tiflash" 185 } 186 187 // LogFile return the log file name. 188 func (inst *TiFlashInstance) LogFile() string { 189 return filepath.Join(inst.Dir, "tiflash.log") 190 } 191 192 // Cmd returns the internal Cmd instance 193 func (inst *TiFlashInstance) Cmd() *exec.Cmd { 194 return inst.Process.Cmd() 195 } 196 197 // StoreAddr return the store address of TiFlash 198 func (inst *TiFlashInstance) StoreAddr() string { 199 return utils.JoinHostPort(AdvertiseHost(inst.Host), inst.ServicePort) 200 }