Add container objects counter #778

Merged
fyrchik merged 1 commit from dstepanov-yadro/frostfs-node:feat/container_objects_total_metric into master 2024-09-04 19:51:04 +00:00

Add container counter metric.

Object counter metric marked as deprecated as it can be replaced by new metric.

Closes #763

Add container counter metric. Object counter metric marked as deprecated as it can be replaced by new metric. Closes #763
dstepanov-yadro force-pushed feat/container_objects_total_metric from 745255d977 to fca3c3547c 2023-11-02 11:52:58 +00:00 Compare
dstepanov-yadro force-pushed feat/container_objects_total_metric from a45d638d7c to bf88665ee3 2023-11-02 13:50:06 +00:00 Compare
dstepanov-yadro reviewed 2023-11-02 13:54:42 +00:00
@ -0,0 +27,4 @@
}
}
func (u *metricUpdater) start() {
Author
Member

The metric is updated at interval, as it is easier to implement.

The metric is updated at interval, as it is easier to implement.
Owner

We update it during PUT and DELETE, what is the purpose of this thread?

We update it during PUT and DELETE, what is the purpose of this thread?
Author
Member

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

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
Owner

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.

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.
Author
Member

Ok, fixed.

Ok, fixed.
fyrchik marked this conversation as resolved
dstepanov-yadro changed title from WIP: Add container objects counter to Add container objects counter 2023-11-02 14:07:07 +00:00
dstepanov-yadro requested review from storage-core-committers 2023-11-02 14:07:16 +00:00
dstepanov-yadro requested review from storage-core-developers 2023-11-02 14:07:16 +00:00
fyrchik reviewed 2023-11-06 07:18:32 +00:00
@ -115,0 +250,4 @@
var counterKey []byte
switch typ {
case phy:
counterKey = containerCounterKey(cnrID, true)
Owner

It is always the same size, we can pre-allocate here.

It is always the same size, we can pre-allocate here.
Author
Member

done

done
fyrchik marked this conversation as resolved
@ -176,0 +425,4 @@
if len(buf) != cidSize+3 {
return cid.ID{}, false, fmt.Errorf("invalid key length")
}
typeStr := string(buf[cidSize:])
Owner

We do this just to compare with 2 constants, can we avoid allocations here if they are present?

We do this just to compare with 2 constants, can we avoid allocations here if they are present?
Author
Member

done

done
fyrchik marked this conversation as resolved
@ -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)
Owner

Can we avoid creating a map here?

Can we avoid creating a map here?
Author
Member

done

done
fyrchik marked this conversation as resolved
@ -197,0 +254,4 @@
for _, obj := range oo {
cnr, _ := obj.ContainerID()
expV, expOk := expectedLogCC[cnr.EncodeToString()]
v, ok := mm.getContainerCount(cnr.EncodeToString(), logical)
Owner

How about mm.checkContainerCount(t, cnr, logical, v) or require.Equal(t, expV, mm.getContainerCount(t, ...)?
To make the function smaller

How about `mm.checkContainerCount(t, cnr, logical, v)` or `require.Equal(t, expV, mm.getContainerCount(t, ...)`? To make the function smaller
Author
Member

Done, thx

Done, thx
fyrchik marked this conversation as resolved
@ -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.",
Owner

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.

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.
Author
Member

Deprecated metric (objects per shard) can be calculated from new one (objects per shard per container) with PromQL query. So it looks redundant.

Deprecated metric (objects per shard) can be calculated from new one (objects per shard per container) with PromQL query. So it looks redundant.
fyrchik marked this conversation as resolved
dstepanov-yadro force-pushed feat/container_objects_total_metric from bf88665ee3 to e4ee5f270d 2023-11-07 07:19:45 +00:00 Compare
dstepanov-yadro force-pushed feat/container_objects_total_metric from e4ee5f270d to a63a2af7c8 2023-11-07 08:16:44 +00:00 Compare
dstepanov-yadro force-pushed feat/container_objects_total_metric from a63a2af7c8 to 7cfb10aba1 2023-11-07 09:12:46 +00:00 Compare
dstepanov-yadro force-pushed feat/container_objects_total_metric from 7cfb10aba1 to 9f85720499 2023-11-07 09:13:55 +00:00 Compare
dstepanov-yadro force-pushed feat/container_objects_total_metric from 9f85720499 to 06ae40725c 2023-11-07 10:04:34 +00:00 Compare
dstepanov-yadro force-pushed feat/container_objects_total_metric from 06ae40725c to 1ca44a00be 2023-11-07 10:14:56 +00:00 Compare
fyrchik approved these changes 2023-11-07 10:36:45 +00:00
@ -79,0 +207,4 @@
return db.updateContainerCounter(tx, typ, delta, inc)
}
func (db *DB) incCounters(tx *bbolt.Tx, cnrID cid.ID) error {
Owner

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?

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?
Author
Member

Now both (phy and log) are stored with single key (CID).

Now both (`phy` and `log`) 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 {
Owner

This will break if we later have subbuckets here, but I doubt we will.
Anyway, wlll containerCounterInitialized := containerCounterB.Stats().KeyN != 0 suffice?

This will break if we later have subbuckets here, but I doubt we will. Anyway, wlll `containerCounterInitialized := containerCounterB.Stats().KeyN != 0` suffice?
Owner

Also, can bucket != nil check serve as a sign that we have initialized everything?

Also, can `bucket != nil` check serve as a sign that we have initialized everything?
Author
Member

Stats() will read all bucket pages, but we need only first.

`Stats()` will read all bucket pages, but we need only first.
Author
Member

Also, can bucket != nil check serve as a sign that we have initialized everything?

Yes, fixed

> Also, can bucket != nil check serve as a sign that we have initialized everything? Yes, fixed
fyrchik marked this conversation as resolved
dstepanov-yadro force-pushed feat/container_objects_total_metric from 1ca44a00be to a761948e1d 2023-11-07 10:51:34 +00:00 Compare
Owner

Failing test -- #788 , seems unrelated

Failing test -- https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/788 , seems unrelated
acid-ant approved these changes 2023-11-07 11:51:30 +00:00
dstepanov-yadro force-pushed feat/container_objects_total_metric from a761948e1d to d5951edc6c 2023-11-07 11:56:59 +00:00 Compare
fyrchik approved these changes 2023-11-07 12:08:30 +00:00
dstepanov-yadro force-pushed feat/container_objects_total_metric from d5951edc6c to 70ab1ebd54 2023-11-08 09:31:24 +00:00 Compare
fyrchik merged commit 70ab1ebd54 into master 2023-11-08 10:44:05 +00:00
Sign in to join this conversation.
No reviewers
TrueCloudLab/storage-core-developers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: TrueCloudLab/frostfs-node#778
No description provided.