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  }