Thanos源码专题【左扬精讲】——Thanos Store 组件(release-0.26)源码阅读和分析(详解 cmd/store.go )
Thanos Strore 组件(release-0.26)源码阅读和分析(详解 cmd/store.go )
https://github.com/thanos-io/thanos/blob/v0.26.0/cmd/thanos/store.go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 | // Copyright (c) The Thanos Authors. // Licensed under the Apache License 2.0. package main import ( "context" // 提供上下文管理功能,用于控制请求的取消、超时和截止日期 "fmt" // 提供了格式化I/O函数 "time" // 提供了时间的测量和显示功能 "github.com/alecthomas/units" // 提供单位转换功能 "github.com/go-kit/log" // 提供结构化的日志记录 "github.com/go-kit/log/level" // 提供日志级别的控制 grpclogging "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" // 提供gRPC请求的日志拦截器 "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/tags" // 提供gRPC请求的标签功能 "github.com/oklog/run" // 提供协程管理功能,用于同时运行多个任务 "github.com/opentracing/opentracing-go" // 提供分布式追踪功能 "github.com/pkg/errors" // 提供增强的错误处理功能 "github.com/prometheus/client_golang/prometheus" // 提供Prometheus监控客户端 "github.com/prometheus/common/route" // 提供HTTP路由功能 commonmodel "github.com/prometheus/common/model" // 提供Prometheus模型类型 extflag "github.com/efficientgo/tools/extkingpin" // 提供扩展的kingpin命令行解析器 blocksAPI "github.com/thanos-io/thanos/pkg/api/blocks" // 提供Thanos块API接口 "github.com/thanos-io/thanos/pkg/block" // 提供Thanos块处理功能 "github.com/thanos-io/thanos/pkg/block/metadata" // 提供Thanos块元数据功能 "github.com/thanos-io/thanos/pkg/component" // 提供Thanos组件标识功能 hidden "github.com/thanos-io/thanos/pkg/extflag" // 提供隐藏的命令行标志 "github.com/thanos-io/thanos/pkg/extkingpin" // 提供Thanos扩展的kingpin命令行解析器 "github.com/thanos-io/thanos/pkg/extprom" // 提供Thanos扩展的Prometheus功能 extpromhttp "github.com/thanos-io/thanos/pkg/extprom/http" // 提供Thanos扩展的Prometheus HTTP功能 "github.com/thanos-io/thanos/pkg/gate" // 提供Thanos并发控制功能 "github.com/thanos-io/thanos/pkg/info" // 提供Thanos信息服务器功能 "github.com/thanos-io/thanos/pkg/info/infopb" // 提供Thanos信息服务的Protobuf定义 "github.com/thanos-io/thanos/pkg/logging" // 提供Thanos日志记录功能 "github.com/thanos-io/thanos/pkg/model" // 提供Thanos数据模型 "github.com/thanos-io/thanos/pkg/objstore/client" // 提供对象存储客户端功能 "github.com/thanos-io/thanos/pkg/prober" // 提供Thanos健康检查探针功能 "github.com/thanos-io/thanos/pkg/runutil" // 提供Thanos运行实用工具 grpcserver "github.com/thanos-io/thanos/pkg/server/grpc" // 提供Thanos gRPC服务器功能 httpserver "github.com/thanos-io/thanos/pkg/server/http" // 提供Thanos HTTP服务器功能 "github.com/thanos-io/thanos/pkg/store" // 提供Thanos存储功能 storecache "github.com/thanos-io/thanos/pkg/store/cache" // 提供Thanos存储缓存功能 "github.com/thanos-io/thanos/pkg/store/labelpb" // 提供Thanos存储标签的Protobuf定义 "github.com/thanos-io/thanos/pkg/tls" // 提供Thanos TLS配置功能 "github.com/thanos-io/thanos/pkg/ui" // 提供Thanos用户界面功能 ) // storeConfig 存储配置 type storeConfig struct { indexCacheConfigs extflag.PathOrContent // 索引缓存配置,可以是文件路径或内容 objStoreConfig extflag.PathOrContent // 对象存储配置,可以是文件路径或内容 dataDir string // 数据目录,用于缓存索引头、内存缓存项和meta.jsons grpcConfig grpcConfig // gRPC配置 httpConfig httpConfig // HTTP配置 indexCacheSizeBytes units.Base2Bytes // 索引缓存大小,以字节为单位 chunkPoolSize units.Base2Bytes // 块池大小,以字节为单位 maxSampleCount uint64 // 最大样本数,单个Series调用返回的最大样本数 maxTouchedSeriesCount uint64 // 最大触摸系列数,单个Series调用返回的最大系列数 maxConcurrency int // 最大并发数,最大并发Series调用数 component component.StoreAPI // 组件标识,标识此存储为Store API debugLogging bool // 调试日志,是否启用调试日志记录 syncInterval time.Duration // 同步间隔,重复同步本地和远程视图之间的块的间隔时间 blockSyncConcurrency int // 块同步并发数,用于构造index-cache.json块的goroutine数 blockMetaFetchConcurrency int // 块元数据获取并发数,用于获取块元数据的goroutine数 filterConf *store.FilterConfig // 过滤配置,用于限制返回的数据范围 selectorRelabelConf extflag.PathOrContent // 选择器重标签配置,用于重新标记选择器 advertiseCompatibilityLabel bool // 广告兼容性标签,是否广告特殊兼容性标签 consistencyDelay commonmodel.Duration // 一致性延迟,在读取之前所有块的最小年龄 ignoreDeletionMarksDelay commonmodel.Duration // 忽略删除标记延迟,在获取块时过滤掉标记为删除的块的延迟 webConfig webConfig // web配置,用于配置Web服务器的行为 postingOffsetsInMemSampling int // 内存中采样偏移量,控制倒排索引偏移量与postings的比率 cachingBucketConfig extflag.PathOrContent // 缓存桶配置,包含缓存桶的配置信息 reqLogConfig *extflag.PathOrContent // 请求日志配置,用于配置请求日志的行为 lazyIndexReaderEnabled bool // 懒惰索引读取器启用,是否启用懒惰索引读取器 lazyIndexReaderIdleTimeout time.Duration // 懒惰索引读取器空闲超时,内存映射的index-headers空闲超时时间 } // registerFlag 注册标志 func (sc *storeConfig) registerFlag(cmd extkingpin.FlagClause) { // 注册http配置 sc.httpConfig = *sc.httpConfig.registerFlag(cmd) // 注册grpc配置 sc.grpcConfig = *sc.grpcConfig.registerFlag(cmd) // 注册数据目录, 本地数据目录用于缓存目的(索引头、内存缓存项和meta.jsons)。如果删除,不会丢失数据,只是存储必须重新构建缓存。注意:将原始块放在这里不会导致存储读取它们。对于这种情况,请使用Prometheus + 边车。 cmd.Flag( "data-dir" , "Local data directory used for caching purposes (index-header, in-mem cache items and meta.jsons). If removed, no data will be lost, just store will have to rebuild the cache. NOTE: Putting raw blocks here will not cause the store to read them. For such use cases use Prometheus + sidecar." ). Default( "./data" ).StringVar(&sc.dataDir) // 注册索引缓存大小, 最大大小为内存中的索引缓存项。如果指定了--index-cache.config或--index-cache.config-file选项,则忽略。 cmd.Flag( "index-cache-size" , "Maximum size of items held in the in-memory index cache. Ignored if --index-cache.config or --index-cache.config-file option is specified." ). Default( "250MB" ).BytesVar(&sc.indexCacheSizeBytes) sc.indexCacheConfigs = *extflag.RegisterPathOrContent(cmd, "index-cache.config" , "YAML file that contains index cache configuration. See format details: https://thanos.io/tip/components/store.md/#index-cache" , extflag.WithEnvSubstitution(), ) // 注册缓存桶配置, 包含缓存桶配置。实验性功能,风险较高。请参阅格式详细信息:https://thanos.io/tip/components/store.md/#caching-bucket sc.cachingBucketConfig = *extflag.RegisterPathOrContent(hidden.HiddenCmdClause(cmd), "store.caching-bucket.config" , "YAML that contains configuration for caching bucket. Experimental feature, with high risk of changes. See format details: https://thanos.io/tip/components/store.md/#caching-bucket" , extflag.WithEnvSubstitution(), ) // 注册块池大小, 最大大小为内存中的块池。 cmd.Flag( "chunk-pool-size" , "Maximum size of concurrently allocatable bytes reserved strictly to reuse for chunks in memory." ). Default( "2GB" ).BytesVar(&sc.chunkPoolSize) // 注册系列样本限制, 单个Series调用返回的最大样本数。如果超过此限制,Series调用失败。0表示没有限制。注意:为了效率,限制在内部实现为“块限制”,考虑每个块包含120个样本(这是每个块可以包含的最大样本数),所以实际的样本数量可能会更低,即使最大值可能会被命中。 cmd.Flag( "store.grpc.series-sample-limit" , "Maximum amount of samples returned via a single Series call. The Series call fails if this limit is exceeded. 0 means no limit. NOTE: For efficiency the limit is internally implemented as 'chunks limit' considering each chunk contains 120 samples (it's the max number of samples each chunk can contain), so the actual number of samples might be lower, even though the maximum could be hit." ). Default( "0" ).Uint64Var(&sc.maxSampleCount) // 注册系列样本限制, 单个Series调用返回的最大系列数。如果超过此限制,Series调用失败。0表示没有限制。 cmd.Flag( "store.grpc.touched-series-limit" , "Maximum amount of touched series returned via a single Series call. The Series call fails if this limit is exceeded. 0 means no limit." ). Default( "0" ).Uint64Var(&sc.maxTouchedSeriesCount) // 注册系列样本限制, 最大并发Series调用数。 cmd.Flag( "store.grpc.series-max-concurrency" , "Maximum number of concurrent Series calls." ).Default( "20" ).IntVar(&sc.maxConcurrency) // 注册组件 sc.component = component.Store // 注册对象存储配置 sc.objStoreConfig = *extkingpin.RegisterCommonObjStoreFlags(cmd, "" , true) // 注册同步块持续时间, 重复间隔用于同步本地和远程视图之间的块。 cmd.Flag( "sync-block-duration" , "Repeat interval for syncing the blocks between local and remote view." ). Default( "3m" ).DurationVar(&sc.syncInterval) // 注册块同步并发数, 用于从对象存储中构造index-cache.json块的goroutine数。必须等于或大于1。 cmd.Flag( "block-sync-concurrency" , "Number of goroutines to use when constructing index-cache.json blocks from object storage. Must be equal or greater than 1." ). Default( "20" ).IntVar(&sc.blockSyncConcurrency) // 注册块元数据获取并发数, 用于从对象存储中获取块元数据的goroutine数。 cmd.Flag( "block-meta-fetch-concurrency" , "Number of goroutines to use when fetching block metadata from object storage." ). Default( "32" ).IntVar(&sc.blockMetaFetchConcurrency) // 注册过滤配置 sc.filterConf = &store.FilterConfig{} // 注册最小时间, 开始时间范围限制。Thanos Store将仅提供在指定时间之后发生的指标。选项可以是以RFC3339格式表示的常量时间或相对于当前时间的时间段,例如-1d或2h45m。有效的时间单位是ms、s、m、h、d、w、y。 cmd.Flag( "min-time" , "Start of time range limit to serve. Thanos Store will serve only metrics, which happened later than this value. Option can be a constant time in RFC3339 format or time duration relative to current time, such as -1d or 2h45m. Valid duration units are ms, s, m, h, d, w, y." ). Default( "0000-01-01T00:00:00Z" ).SetValue(&sc.filterConf.MinTime) // 注册最大时间, 结束时间范围限制。Thanos Store将仅提供在指定时间之前发生的指标。选项可以是以RFC3339格式表示的常量时间或相对于当前时间的时间段,例如-1d或2h45m。有效的时间单位是ms、s、m、h、d、w、y。 cmd.Flag( "max-time" , "End of time range limit to serve. Thanos Store will serve only blocks, which happened earlier than this value. Option can be a constant time in RFC3339 format or time duration relative to current time, such as -1d or 2h45m. Valid duration units are ms, s, m, h, d, w, y." ). Default( "9999-12-31T23:59:59Z" ).SetValue(&sc.filterConf.MaxTime) // 注册调试广告兼容性标签, 如果为true,Store Gateway除了其他标签外,还将广告特殊“@thanos_compatibility_store_type=store”标签集。这使得Store Gateway与0.8.0之前的Querier兼容。 cmd.Flag( "debug.advertise-compatibility-label" , "If true, Store Gateway in addition to other labels, will advertise special \"@thanos_compatibility_store_type=store\" label set. This makes store Gateway compatible with Querier before 0.8.0" ). Hidden().Default( "true" ).BoolVar(&sc.advertiseCompatibilityLabel) // 注册选择器重标签配置 sc.selectorRelabelConf = *extkingpin.RegisterSelectorRelabelFlags(cmd) // 注册索引头内存采样偏移量, 控制Store Gateway将保留在内存中的倒排索引偏移量与 postings 的比率。较大的值将保留较少的偏移量,这会增加查询触摸这些倒排索引所需的CPU周期数。它适用于希望低基线内存压力和预期较少流量的设置。相反,较小的值将增加基线内存使用量,但略微提高延迟。1将保留所有在内存中。 cmd.Flag( "store.index-header-posting-offsets-in-mem-sampling" , "Controls what is the ratio of postings offsets store will hold in memory. " + "Larger value will keep less offsets, which will increase CPU cycles needed for query touching those postings. It's meant for setups that want low baseline memory pressure and where less traffic is expected. " + "On the contrary, smaller value will increase baseline memory usage, but improve latency slightly. 1 will keep all in memory. Default value is the same as in Prometheus which gives a good balance." ). Hidden().Default(fmt.Sprintf( "%v" , store.DefaultPostingOffsetInMemorySampling)).IntVar(&sc.postingOffsetsInMemSampling) // 注册一致性延迟, 在读取之前所有块的最小年龄。如果您的对象存储是最终一致的,请将其设置为安全值(例如30m)。GCS和S3是(大致)强一致的。 cmd.Flag( "consistency-delay" , "Minimum age of all blocks before they are being read. Set it to safe value (e.g 30m) if your object storage is eventually consistent. GCS and S3 are (roughly) strongly consistent." ). Default( "0s" ).SetValue(&sc.consistencyDelay) // 注册忽略删除标记延迟, 在获取块时过滤掉标记为删除的块的延迟。 cmd.Flag( "ignore-deletion-marks-delay" , "Duration after which the blocks marked for deletion will be filtered out while fetching blocks. " + "The idea of ignore-deletion-marks-delay is to ignore blocks that are marked for deletion with some delay. This ensures store can still serve blocks that are meant to be deleted but do not have a replacement yet. " + "If delete-delay duration is provided to compactor or bucket verify component, it will upload deletion-mark.json file to mark after what duration the block should be deleted rather than deleting the block straight away. " + "If delete-delay is non-zero for compactor or bucket verify component, ignore-deletion-marks-delay should be set to (delete-delay)/2 so that blocks marked for deletion are filtered out while fetching blocks before being deleted from bucket. " + "Default is 24h, half of the default value for --delete-delay on compactor." ). Default( "24h" ).SetValue(&sc.ignoreDeletionMarksDelay) // 注册索引头懒惰读取器启用, 如果为true,Store Gateway将在查询需要时仅懒惰地内存映射index-header。 cmd.Flag( "store.enable-index-header-lazy-reader" , "If true, Store Gateway will lazy memory map index-header only once the block is required by a query." ). Default( "false" ).BoolVar(&sc.lazyIndexReaderEnabled) // 注册索引头懒惰读取器空闲超时, 如果索引头懒惰读取器启用且此空闲超时设置>0,则内存映射的index-headers将在“空闲超时”不活动后自动释放。 cmd.Flag( "store.index-header-lazy-reader-idle-timeout" , "If index-header lazy reader is enabled and this idle timeout setting is > 0, memory map-ed index-headers will be automatically released after 'idle timeout' inactivity." ). Hidden().Default( "5m" ).DurationVar(&sc.lazyIndexReaderIdleTimeout) // 注册web外部前缀, 所有HTML链接和重定向URL的静态前缀。实际端点仍在/或web.route-prefix上提供。这允许Thanos桶Web UI在反向代理后面提供,该反向代理剥离URL子路径。 cmd.Flag( "web.external-prefix" , "Static prefix for all HTML links and redirect URLs in the bucket web UI interface. Actual endpoints are still served on / or the web.route-prefix. This allows thanos bucket web UI to be served behind a reverse proxy that strips a URL sub-path." ). Default( "" ).StringVar(&sc.webConfig.externalPrefix) // 注册web前缀头, HTTP请求头用于动态前缀UI链接和重定向。如果设置了web.external-prefix参数,此选项将被忽略。安全风险:仅在反向代理前面有Thanos时启用此选项。如果Thanos UI通过具有PathPrefixStrip选项的Traefik反向代理提供,该选项在X-Forwarded-Prefix头中发送剥离的前缀值,则--web.prefix-header=X-Forwarded-Prefix选项非常有用。这允许Thanos UI在子路径上提供。 cmd.Flag( "web.prefix-header" , "Name of HTTP request header used for dynamic prefixing of UI links and redirects. This option is ignored if web.external-prefix argument is set. Security risk: enable this option only if a reverse proxy in front of thanos is resetting the header. The --web.prefix-header=X-Forwarded-Prefix option can be useful, for example, if Thanos UI is served via Traefik reverse proxy with PathPrefixStrip option enabled, which sends the stripped prefix value in X-Forwarded-Prefix header. This allows thanos UI to be served on a sub-path." ). Default( "" ).StringVar(&sc.webConfig.prefixHeaderName) // 注册web禁用CORS, 是否禁用Thanos设置的CORS头。默认情况下,Thanos设置CORS头以允许所有。 cmd.Flag( "web.disable-cors" , "Whether to disable CORS headers to be set by Thanos. By default Thanos sets CORS headers to be allowed by all." ). Default( "false" ).BoolVar(&sc.webConfig.disableCORS) // 注册请求日志配置 sc.reqLogConfig = extkingpin.RegisterRequestLoggingFlags(cmd) } // registerStore registers a store command. // registerStore 函数用于注册store命令,使得应用程序能够处理与对象存储桶的交互。现在支持GCS、S3、Azure、Swift、腾讯COS和阿里云OSS。 // 该函数接受一个指向extkingpin.App的指针作为参数,并在此应用程序中注册store命令。 // // 参数: // app - 指向extkingpin.App的指针,表示要注册store命令的应用程序。 func registerStore(app *extkingpin.App) { // 注册store命令, 存储节点提供对对象存储中的块的访问。现在支持GCS、S3、Azure、Swift、腾讯COS和阿里云OSS。 cmd := app.Command(component.Store.String(), "Store node giving access to blocks in a bucket provider. Now supported GCS, S3, Azure, Swift, Tencent COS and Aliyun OSS." ) // 创建store配置 conf := &storeConfig{} // 注册store命令标志 conf.registerFlag(cmd) // 设置store命令 cmd.Setup( func (g *run.Group, logger log.Logger, reg *prometheus.Registry, tracer opentracing.Tracer, _ <- chan struct {}, debugLogging bool) error { // 检查最小时间是否大于最大时间 if conf.filterConf.MinTime.PrometheusTimestamp() > conf.filterConf.MaxTime.PrometheusTimestamp() { return errors.Errorf( "invalid argument: --min-time '%s' can't be greater than --max-time '%s'" , conf.filterConf.MinTime, conf.filterConf.MaxTime) } // 解析HTTP请求日志配置 httpLogOpts, err := logging.ParseHTTPOptions( "" , conf.reqLogConfig) if err != nil { return errors.Wrap(err, "error while parsing config for request logging" ) } // 解析GRPC请求日志配置 tagOpts, grpcLogOpts, err := logging.ParsegRPCOptions( "" , conf.reqLogConfig) if err != nil { return errors.Wrap(err, "error while parsing config for request logging" ) } // 运行store return runStore(g, logger, reg, tracer, httpLogOpts, grpcLogOpts, tagOpts, *conf, getFlagsMap(cmd.Flags()), ) }) } // runStore starts a daemon that serves queries to cluster peers using data from an object store. // 运行store, 启动一个守护进程,使用对象存储中的数据为集群对等体提供查询。 // runStore 函数初始化并启动一个存储节点。 // // 参数: // g *run.Group: 运行组,用于添加任务。 // logger log.Logger: 日志记录器。 // reg *prometheus.Registry: Prometheus注册表。 // tracer opentracing.Tracer: 追踪器。 // httpLogOpts []logging.Option: HTTP请求日志选项。 // grpcLogOpts []grpclogging.Option: GRPC请求日志选项。 // tagOpts []tags.Option: 标签选项。 // conf storeConfig: 存储配置。 // flagsMap map[string]string: 标志映射。 // // 返回值: // error: 如果初始化或启动过程中发生错误,则返回该错误。 func runStore( g *run.Group, // 运行组 logger log.Logger, // 日志记录器 reg *prometheus.Registry, // 注册表 tracer opentracing.Tracer, // 追踪器 httpLogOpts []logging.Option, // HTTP请求日志选项 grpcLogOpts []grpclogging.Option, // GRPC请求日志选项 tagOpts []tags.Option, // 标签选项 conf storeConfig, flagsMap map [string]string, ) error { // 创建GRPC探针 grpcProbe := prober.NewGRPC() // 创建HTTP探针 httpProbe := prober.NewHTTP() // 创建状态探针 statusProber := prober.Combine( // 组合探针 httpProbe, // HTTP探针 grpcProbe, // GRPC探针 prober.NewInstrumentation(conf.component, logger, extprom.WrapRegistererWithPrefix( "thanos_" , reg)), // 探针 ) // 创建HTTP服务器 srv := httpserver.New(logger, reg, conf.component, httpProbe, httpserver.WithListen(conf.httpConfig.bindAddress), // 监听地址 httpserver.WithGracePeriod(time.Duration(conf.httpConfig.gracePeriod)), // 优雅期 httpserver.WithTLSConfig(conf.httpConfig.tlsConfig), // TLS配置 httpserver.WithEnableH2C(true), // 启用H2C ) g.Add( func () error { statusProber.Healthy() // 设置健康状态 return srv.ListenAndServe() // 监听并服务 }, func (err error) { statusProber.NotReady(err) // 设置非就绪状态 defer statusProber.NotHealthy(err) // 设置非健康状态 srv.Shutdown(err) // 关闭服务器 }) // 解析对象存储配置 confContentYaml, err := conf.objStoreConfig.Content() if err != nil { return err } // 创建对象存储客户端 bkt, err := client.NewBucket(logger, confContentYaml, reg, conf.component.String()) if err != nil { // 创建对象存储客户端失败 return errors.Wrap(err, "create bucket client" ) } // 获取缓存桶配置 cachingBucketConfigYaml, err := conf.cachingBucketConfig.Content() if err != nil { // 获取缓存桶配置失败 return errors.Wrap(err, "get caching bucket configuration" ) } r := route.New() if len(cachingBucketConfigYaml) > 0 { // 创建缓存桶 bkt, err = storecache.NewCachingBucketFromYaml(cachingBucketConfigYaml, bkt, logger, reg, r) if err != nil { // 创建缓存桶失败 return errors.Wrap(err, "create caching bucket" ) } } // 获取选择器重标签配置 relabelContentYaml, err := conf.selectorRelabelConf.Content() if err != nil { // 获取选择器重标签配置失败 return errors.Wrap(err, "get content of relabel configuration" ) } // 解析选择器重标签配置 relabelConfig, err := block.ParseRelabelConfig(relabelContentYaml, block.SelectorSupportedRelabelActions) if err != nil { // 解析选择器重标签配置失败 return err } // 获取索引缓存配置 indexCacheContentYaml, err := conf.indexCacheConfigs.Content() if err != nil { // 获取索引缓存配置失败 return errors.Wrap(err, "get content of index cache configuration" ) } // Create the index cache loading its config from config file, while keeping // backward compatibility with the pre-config file era. // 创建索引缓存 var indexCache storecache.IndexCache // 如果索引缓存配置不为空 if len(indexCacheContentYaml) > 0 { // 创建索引缓存 indexCache, err = storecache.NewIndexCache(logger, indexCacheContentYaml, reg) } else { // 创建内存索引缓存 indexCache, err = storecache.NewInMemoryIndexCacheWithConfig(logger, reg, storecache.InMemoryIndexCacheConfig{ // 最大大小 MaxSize: model.Bytes(conf.indexCacheSizeBytes), // 最大项目大小 MaxItemSize: storecache.DefaultInMemoryIndexCacheConfig.MaxItemSize, }) } if err != nil { // 创建索引缓存失败 return errors.Wrap(err, "create index cache" ) } // 创建忽略删除标记过滤器 ignoreDeletionMarkFilter := block.NewIgnoreDeletionMarkFilter(logger, bkt, time.Duration(conf.ignoreDeletionMarksDelay), conf.blockMetaFetchConcurrency) // 创建元数据获取器 metaFetcher, err := block.NewMetaFetcher(logger, conf.blockMetaFetchConcurrency, bkt, conf.dataDir, extprom.WrapRegistererWithPrefix( "thanos_" , reg), // 注册器 []block.MetadataFilter{ // 元数据过滤器 block.NewTimePartitionMetaFilter(conf.filterConf.MinTime, conf.filterConf.MaxTime), // 时间分区元数据过滤器 block.NewLabelShardedMetaFilter(relabelConfig), // 标签分片元数据过滤器 block.NewConsistencyDelayMetaFilter(logger, time.Duration(conf.consistencyDelay), extprom.WrapRegistererWithPrefix( "thanos_" , reg)), // 一致性延迟元数据过滤器 ignoreDeletionMarkFilter, // 忽略删除标记过滤器 block.NewDeduplicateFilter(conf.blockMetaFetchConcurrency), // 去重过滤器 }) if err != nil { return errors.Wrap(err, "meta fetcher" ) } // Limit the concurrency on queries against the Thanos store. // 限制对Thanos存储的查询并发 if conf.maxConcurrency < 0 { // 最大并发值不能小于0 return errors.Errorf( "max concurrency value cannot be lower than 0 (got %v)" , conf.maxConcurrency) } // 创建一个新的gate实例,用于限制并发查询的数量。 // 使用extprom库包装注册器,并添加前缀"thanos_bucket_store_series_"以便于监控。 // maxConcurrency是从配置中读取的最大并发量。 queriesGate := gate.New(extprom.WrapRegistererWithPrefix( "thanos_bucket_store_series_" , reg), int(conf.maxConcurrency)) chunkPool, err := store.NewDefaultChunkBytesPool(uint64(conf.chunkPoolSize)) // 创建默认的块字节池 if err != nil { // 创建块字节池失败 return errors.Wrap(err, "create chunk pool" ) } // 创建桶存储选项 options := []store.BucketStoreOption{ store.WithLogger(logger), // 日志记录器 store.WithRegistry(reg), // 注册器 store.WithIndexCache(indexCache), // 索引缓存 store.WithQueryGate(queriesGate), // 查询Gate限 store.WithChunkPool(chunkPool), // 块字节池 store.WithFilterConfig(conf.filterConf), // 过滤配置 } // 如果调试日志记录为真 if conf.debugLogging { options = append(options, store.WithDebugLogging()) // 添加调试日志记录选项 } // 创建桶存储 bs, err := store.NewBucketStore( bkt, // 对象存储客户端 metaFetcher, // 元数据获取器 conf.dataDir, // 数据目录 store.NewChunksLimiterFactory(conf.maxSampleCount/store.MaxSamplesPerChunk), // 样本限制是基于每个块的最大样本数。 store.NewSeriesLimiterFactory(conf.maxTouchedSeriesCount), // 样本限制是基于每个块的最大样本数。 store.NewGapBasedPartitioner(store.PartitionerMaxGapSize), // 样本限制是基于每个块的最大样本数。 conf.blockSyncConcurrency, // 块同步并发 conf.advertiseCompatibilityLabel, // 广告兼容性标签 conf.postingOffsetsInMemSampling, // 索引头内存采样偏移量 false, // conf.lazyIndexReaderEnabled, // 索引头懒惰读取器启用 conf.lazyIndexReaderIdleTimeout, // 索引头懒惰读取器空闲超时 options..., // 选项 ) if err != nil { // 创建桶存储失败 return errors.Wrap(err, "create object storage store" ) } // bucketStoreReady signals when bucket store is ready. // 桶存储就绪信号 bucketStoreReady := make( chan struct {}) { ctx, cancel := context.WithCancel(context.Background()) // 创建上下文 g.Add( func () error { defer runutil.CloseWithLogOnErr(logger, bkt, "bucket client" ) // 关闭对象存储客户端 level.Info(logger).Log( "msg" , "initializing bucket store" ) // 初始化桶存储 begin := time.Now() // 开始时间 if err := bs.InitialSync(ctx); err != nil { // 初始化同步 close(bucketStoreReady) // 关闭桶存储就绪信号 return errors.Wrap(err, "bucket store initial sync" ) // 初始化同步失败 } level.Info(logger).Log( "msg" , "bucket store ready" , "init_duration" , time.Since(begin).String()) // 桶存储就绪 close(bucketStoreReady) // 关闭桶存储就绪信号 err := runutil.Repeat(conf.syncInterval, ctx.Done(), func () error { // 重复同步 if err := bs.SyncBlocks(ctx); err != nil { // 同步块 level.Warn(logger).Log( "msg" , "syncing blocks failed" , "err" , err) // 同步块失败 } return nil }) runutil.CloseWithLogOnErr(logger, bs, "bucket store" ) // 关闭桶存储 return err }, func (error) { cancel() // 取消上下文 }) } // 创建信息服务器 infoSrv := info.NewInfoServer( component.Store.String(), // 组件名称 info.WithLabelSetFunc( func () []labelpb.ZLabelSet { // 标签设置函数 return bs.LabelSet() }), info.WithStoreInfoFunc( func () *infopb.StoreInfo { // 存储信息函数 if httpProbe.IsReady() { // 如果HTTP探针就绪 mint, maxt := bs.TimeRange() // 时间范围 return &infopb.StoreInfo{ // 存储信息 MinTime: mint, // 最小时间 MaxTime: maxt, // 最大时间 } } return nil // 返回nil }), ) // Start query (proxy) gRPC StoreAPI. // 启动查询(代理)gRPC StoreAPI。 { // 创建TLS配置 tlsCfg, err := tls.NewServerConfig(log.With(logger, "protocol" , "gRPC" ), conf.grpcConfig.tlsSrvCert, conf.grpcConfig.tlsSrvKey, conf.grpcConfig.tlsSrvClientCA) if err != nil { // 创建TLS配置失败 return errors.Wrap(err, "setup gRPC server" ) } s := grpcserver.New(logger, reg, tracer, grpcLogOpts, tagOpts, conf.component, grpcProbe, grpcserver.WithServer(info.RegisterInfoServer(infoSrv)), // 注册InfoServer grpcserver.WithListen(conf.grpcConfig.bindAddress), // 监听地址 grpcserver.WithGracePeriod(time.Duration(conf.grpcConfig.gracePeriod)), // 优雅期 grpcserver.WithTLSConfig(tlsCfg), // TLS配置 ) // 添加桶存储就绪信号 g.Add( func () error { <-bucketStoreReady // 等待桶存储就绪 statusProber.Ready() // 设置就绪状态 return s.ListenAndServe() // 监听并服务 }, func (err error) { // 错误处理 statusProber.NotReady(err) // 设置非就绪状态 s.Shutdown(err) // 关闭服务器 }) } // Add bucket UI for loaded blocks. // 添加桶UI用于加载的块。 { ins := extpromhttp.NewInstrumentationMiddleware(reg, nil) // 创建中间件 compactorView := ui.NewBucketUI(logger, conf.webConfig.externalPrefix, conf.webConfig.prefixHeaderName, conf.component) compactorView.Register(r, ins) // Configure Request Logging for HTTP calls. // 配置HTTP请求日志 logMiddleware := logging.NewHTTPServerMiddleware(logger, httpLogOpts...) // 创建BlocksAPI api := blocksAPI.NewBlocksAPI(logger, conf.webConfig.disableCORS, "" , flagsMap, bkt) // 注册BlocksAPI api.Register(r.WithPrefix( "/api/v1" ), tracer, logger, ins, logMiddleware) // 更新BlocksAPI metaFetcher.UpdateOnChange( func (blocks []metadata.Meta, err error) { api.SetLoaded(blocks, err) // 设置加载的块 }) // 处理HTTP请求 srv.Handle( "/" , r) } level.Info(logger).Log( "msg" , "starting store node" ) // 启动存储节点 return nil // 返回nil } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2023-02-06 Istio从入门到精通——Istio Getting Started
2023-02-06 Istio从入门到精通——介绍 Istio (version: 1.16.2, Jan 30, 2023发版)