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
}
posted @   左扬  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源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发版)
levels of contents
点击右上角即可分享
微信分享提示