Add container objects counter #778
Labels
No labels
P0
P1
P2
P3
badger
frostfs-adm
frostfs-cli
frostfs-ir
frostfs-lens
frostfs-node
good first issue
triage
Infrastructure
blocked
bug
config
discussion
documentation
duplicate
enhancement
go
help wanted
internal
invalid
kludge
observability
perfomance
question
refactoring
wontfix
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: TrueCloudLab/frostfs-node#778
Loading…
Reference in a new issue
No description provided.
Delete branch "dstepanov-yadro/frostfs-node:feat/container_objects_total_metric"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Add container counter metric.
Object counter metric marked as deprecated as it can be replaced by new metric.
Closes #763
745255d977
tofca3c3547c
a45d638d7c
tobf88665ee3
@ -0,0 +27,4 @@
}
}
func (u *metricUpdater) start() {
The metric is updated at interval, as it is easier to implement.
We update it during PUT and DELETE, what is the purpose of this thread?
We update counter in DB during PUT/DELETE, but metric values will be updated with interval.
Now, for example, metric object counter per shard updates on every PUT/DELETE, not with intreval. This lead to such complex return results: https://git.frostfs.info/TrueCloudLab/frostfs-node/src/branch/master/pkg/local_object_storage/metabase/delete.go#L28
The reason for such code is mostly that
delete
is a batch operation.May be we could make it non-batch or move metrics update closer to counter update?
I am afraid background process will consume more resources than it should, even when the node is idle.
Ok, fixed.
WIP: Add container objects counterto Add container objects counter@ -115,0 +250,4 @@
var counterKey []byte
switch typ {
case phy:
counterKey = containerCounterKey(cnrID, true)
It is always the same size, we can pre-allocate here.
done
@ -176,0 +425,4 @@
if len(buf) != cidSize+3 {
return cid.ID{}, false, fmt.Errorf("invalid key length")
}
typeStr := string(buf[cidSize:])
We do this just to compare with 2 constants, can we avoid allocations here if they are present?
done
@ -184,3 +184,3 @@
if !isParent {
err = db.updateCounter(tx, phy, 1, true)
err = db.updateCounter(tx, phy, map[cid.ID]uint64{cnr: 1}, true)
Can we avoid creating a map here?
done
@ -197,0 +254,4 @@
for _, obj := range oo {
cnr, _ := obj.ContainerID()
expV, expOk := expectedLogCC[cnr.EncodeToString()]
v, ok := mm.getContainerCount(cnr.EncodeToString(), logical)
How about
mm.checkContainerCount(t, cnr, logical, v)
orrequire.Equal(t, expV, mm.getContainerCount(t, ...)
?To make the function smaller
Done, thx
@ -51,2 +52,2 @@
writeCache: newWriteCacheMetrics(),
mode: newShardIDMode(engineSubsystem, "mode_info", "Shard mode"),
objectCounter: newEngineGaugeVector("objects_total",
"Objects counters per shards. DEPRECATED: Will be deleted in next releasese, use frostfs_node_engine_container_objects_total metric.",
Why is it deprecated? It just has different usage: we count object in the container to calculate quotas, we count objects per shards to calculate the amount of space.
Deprecated metric (objects per shard) can be calculated from new one (objects per shard per container) with PromQL query. So it looks redundant.
bf88665ee3
toe4ee5f270d
e4ee5f270d
toa63a2af7c8
a63a2af7c8
to7cfb10aba1
7cfb10aba1
to9f85720499
9f85720499
to06ae40725c
06ae40725c
to1ca44a00be
@ -79,0 +207,4 @@
return db.updateContainerCounter(tx, typ, delta, inc)
}
func (db *DB) incCounters(tx *bbolt.Tx, cnrID cid.ID) error {
In bbolt execution time is constrained by the number of keys we put (as values might be stored on different pages and it takes some time to find a key). How about grouping all container counters in 1 value?
Now both (
phy
andlog
) are stored with single key (CID
).@ -161,1 +375,3 @@
err = b.Put(objectPhyCounterKey, data)
func isContainerCounterInitialized(tx *bbolt.Tx, containerCounterB *bbolt.Bucket) (bool, error) {
containerCounterInitialized := false
if err := containerCounterB.ForEach(func(_, _ []byte) error {
This will break if we later have subbuckets here, but I doubt we will.
Anyway, wlll
containerCounterInitialized := containerCounterB.Stats().KeyN != 0
suffice?Also, can
bucket != nil
check serve as a sign that we have initialized everything?Stats()
will read all bucket pages, but we need only first.Yes, fixed
1ca44a00be
toa761948e1d
Failing test -- #788 , seems unrelated
a761948e1d
tod5951edc6c
d5951edc6c
to70ab1ebd54