github.com/kubewharf/katalyst-core@v0.5.3/pkg/custom-metric/store/remote/sharding.go (about) 1 /* 2 Copyright 2022 The Katalyst Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package remote 18 19 import ( 20 "context" 21 "fmt" 22 "net/http" 23 24 "k8s.io/klog/v2" 25 26 katalystbase "github.com/kubewharf/katalyst-core/cmd/base" 27 metricconf "github.com/kubewharf/katalyst-core/pkg/config/metric" 28 "github.com/kubewharf/katalyst-core/pkg/custom-metric/store/local" 29 sd "github.com/kubewharf/katalyst-core/pkg/util/service-discovery" 30 ) 31 32 const httpMetricURL = "http://%v" 33 34 // ShardingController is responsible to separate the metric store into 35 // several sharding pieces to tolerant single node failure, as well as 36 // avoiding memory pressure in single node. 37 // 38 // todo: currently, it not really a valid 39 type ShardingController struct { 40 ctx context.Context 41 42 sdManager sd.ServiceDiscoveryManager 43 totalCount int 44 } 45 46 func NewShardingController(ctx context.Context, baseCtx *katalystbase.GenericContext, 47 storeConf *metricconf.StoreConfiguration, 48 ) (*ShardingController, error) { 49 sdManager, err := sd.GetSDManager(ctx, baseCtx, storeConf.ServiceDiscoveryConf) 50 if err != nil { 51 return nil, err 52 } 53 54 // since collector will define its own pod/node label selectors, so we will construct informer separately 55 s := &ShardingController{ 56 ctx: ctx, 57 totalCount: storeConf.StoreServerReplicaTotal, 58 sdManager: sdManager, 59 } 60 61 return s, nil 62 } 63 64 func (s *ShardingController) Start() error { 65 return s.sdManager.Run() 66 } 67 68 func (s *ShardingController) Stop() error { 69 return nil 70 } 71 72 // GetRWCount returns the quorum read/write counts 73 func (s *ShardingController) GetRWCount() (int, int) { 74 r := (s.totalCount + 1) / 2 75 w := s.totalCount - r + 1 76 return r, w 77 } 78 79 // GetRequests returns the pre-generated http requests 80 func (s *ShardingController) GetRequests(ctx context.Context, path string) ([]*http.Request, error) { 81 endpoints, err := s.sdManager.GetEndpoints() 82 if err != nil { 83 return nil, fmt.Errorf("failed get endpoints from serviceDiscoveryManager: %v", err) 84 } 85 klog.V(6).Infof("%v current endpoints is %v", s.sdManager.Name(), endpoints) 86 87 requests := make([]*http.Request, 0, len(endpoints)) 88 for _, endpoint := range endpoints { 89 req, err := s.generateRequest(ctx, endpoint, path) 90 if err != nil { 91 klog.Errorf("failed to generate request err: %v", err) 92 continue 93 } 94 requests = append(requests, req) 95 } 96 97 return requests, nil 98 } 99 100 func (s *ShardingController) generateRequest(ctx context.Context, endpoint, path string) (*http.Request, error) { 101 url := fmt.Sprintf(httpMetricURL, endpoint+path) 102 103 req, err := http.NewRequestWithContext(ctx, "GET", url, nil) 104 if err != nil { 105 return nil, fmt.Errorf("new http request for %v err: %v", url, err) 106 } 107 108 req.Header.Add("Accept-Encoding", "gzip") 109 req.Header.Set("User-Agent", "remote-store") 110 111 switch path { 112 case local.ServingGetPath: 113 req.Method = "GET" 114 case local.ServingSetPath: 115 req.Method = "POST" 116 case local.ServingListPath: 117 req.Method = "GET" 118 } 119 120 return req, nil 121 }