Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DONT MERGE] Draft query stat API #2148

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft

[DONT MERGE] Draft query stat API #2148

wants to merge 6 commits into from

Conversation

phoebusm
Copy link
Collaborator

@phoebusm phoebusm commented Jan 28, 2025

Reference Issues/PRs

What does this implement or fix?

Draft query stat API for discussion and as placeholder

If the columns stated below are checked, it mean the column will be used to group the corresponding entries

There are 3 kinds of entry in the stats:

  1. Physical keys
  • For illustrating the performance of actual key read/write at the storage
  • uncompressed size (GetObject and PutObject operation only)
  • compressed size (for tdata keys, GetObject and PutObject operation only )
  • bandwidth (GetObject and PutObject operation only )
  • stage
  • key_type
  • storage_op
  • [Counts of each logical keys stored] (only for physical reference key)
  • Storage-specific statistics - Pending
  1. arcticdb call
  • For logging the absolute time of arcticdb call take
  • The absolute time of arcticdb call is likely not the sum of time taken to read corresponding keys, as some operations are parallelized
  1. arcticdb stages
  • For logging the absolute time of arcticdb call stages take
  • The absolute time of stages is likely not the sum of time taken to read corresponding keys, as some operations are parallelized
  • stage

Columns that shared by all types of entry:

  • arcticdb_call
  • count
  • parallelized
  • latency histogram
Latency histogram
  • Time taken for respective operation will be grouped by 10ms windows, e.g. the amount of time taken for calling a particular API call 6 times:
  • 23ms
  • 31ms
  • 35ms
  • 40ms
  • 49ms
  • 50ms
    Result:
time_count_20 time_count_30 time_count_40  time_count_50
            1             2             2              1
Unit
  • time - ms
  • data - byte
  • bandwidth - byte/second
Risk of overflow
  • A long running query stats may risk overflowing size and the calculation of bandwidth
  • No measure to mitigate for now but possible measure could be limiting the duration of query stat could record

Output format

Pandas dataframe

  • As the output dataframe could be very wide due to latency histogram and storage-specific statistic (which will be added in future)

Sample use cases

(Github render gets weird when it comes to wide markdown table like below so can't uncomment the tables)

Very slow list_symbools because of very outdated symbol list cache

In the situation where the library has frequent add/delete symbol, a lot of SymbolList keys will be added as journal.
The list of keys usually will be compacted by

  • list_symbols call if caller has write permission
  • Symbol list compaction job if there is any

Imagine if the above actions are not done, when users call list_symbols, those keys are needed to be iterated to create the symbol list. This could be very time consuming if the list is long.
With query stat, users can learn the cause by checking the count in the entry:

| arcticdb_call   | stage         | key_type | storage_op    | parallelized | count | time_count_140 | time_count_150 | time_count_160 | time_count_170 | time_count_180 |
|-----------------|---------------|----------|---------------|--------------|-------|----------------|----------------|----------------|----------------|----------------|
| list_symbols    | NaN           | NaN      | NaN           | NaN          | 562   | 20             | 200            | 200            | 100            | 42             |
| list_symbols    | list          | NaN      | NaN           | NaN          | 562   | 20             | 200            | 200            | 100            | 42             |
| list_symbols    | list          | sl       | ListObjectsV2 | False        | 562   | 20             | 200            | 200            | 100            | 42             |
Very slow s3 API call

In the situation when the s3 endpoint has poor performance, the latency in stats will be very helpful to allow user pinpoint the culprit of poor performance:

| arcticdb_call   | stage         | key_type | storage_op    | parallelized | count | time_count_16200 |
|-----------------|---------------|----------|---------------|--------------|-------|------------------|
| list_symbols    | NaN           | NaN      | NaN           | NaN          | 1     | 1                |
| list_symbols    | list          | NaN      | NaN           | NaN          | 1     | 1                |
| list_symbols    | list          | sl       | ListObjectsV2 | False        | 1     | 1                |

In this case, user can turn on s3 log to understand which exact step is slow.

Slow read due to fragmented segments

The library has very small setting for no. columns per segment. A simple read will require reading many segments.
It can be discovered by checking count in the stats. It can be verified with disproportional high ratio of tdata key count to vref key count. Below is the example of a simple read of 9 symbols with 1000 segments in each's latest version:

| arcticdb_call | stage         | key_type | storage_op | parallelized | count | tdata | tindex | ver | uncompressed_size | compressed_size | bandwidth | time_count_140 | time_count_150 | time_count_160 | time_count_40 | time_count_50 | time_count_60 | time_count_9000 | time_count_9050 |
|---------------|---------------|----------|------------|--------------|-------|-------|--------|-----|-------------------|-----------------|-----------|----------------|----------------|----------------|---------------|---------------|---------------|----------------|----------------|
| read          | NaN           | NaN      | NaN        | NaN          | NaN   | NaN   | NaN    | NaN | NaN               | NaN             | NaN       | NaN            | NaN            | NaN            | NaN           | NaN           | NaN           | NaN            | 9              |
| read          | find_version  | NaN      | NaN        | NaN          | NaN   | NaN   | NaN    | NaN | NaN               | NaN             | NaN       | NaN            | NaN            | NaN            | 2             | 4             | 3             | NaN            | NaN            |
| read          | find_version  | vref     | GetObject  | NaN           | 9     | NaN   | 9      | 9   | 135               | NaN             | 260       | NaN            | NaN            | NaN            | 2             | 4             | 3             | NaN            | NaN            |
| read          | read          | NaN      | NaN        | NaN          | NaN   | NaN   | NaN    | NaN | NaN               | NaN             | NaN       | NaN            | NaN            | NaN            | NaN           | NaN           | NaN           | 9              | NaN            |
| read          | read          | tindex   | GetObject  | NaN         | 9     | 9000  | NaN    | NaN | 144               | NaN             | 301       | NaN            | NaN            | NaN            | 3             | 3             | 3             | NaN            | NaN            |
| read          | read          | tdata    | GetObject  | True         | 9000  | NaN   | NaN    | NaN | 18000000          | 1800000         | 5714      | 4000           | 4000           | 1000           | NaN           | NaN           | NaN           | NaN            | NaN            |
Tranversing long version chain

In the situation when old versions being deleted, which makes more v keys are need to be tranversed, e.g. 10 versions are appended and the last 5 version are deleted, the v keys will be tranversed in this order (T = tombstone):

vref -> ver 5T -> ver 6T -> ver 7T -> ver 8T -> ver 9T -> ver 9 -> ver 8 -> ver 7 -> ver 6 -> ver 5 -> ver 4

It can be discovered with disproportional high ratio of tdata key count to vref key count, with the count of tomb keys highlighted in v key:

| arcticdb_call | stage         | key_type | storage_op    | parallelized | count | tdata | tindex | ver | tomb | uncompressed_size | compressed_size | bandwidth | time_count_50 | time_count_140 | time_count_150 | time_count_160 | time_count_170 | time_count_190 | time_count_1760 | time_count_1950 |
|---------------|---------------|----------|---------------|--------------|-------|-------|--------|-----|------|-------------------|-----------------|-----------|---------------|----------------|----------------|----------------|----------------|----------------|----------------|----------------|
| read          | NaN           | NaN      | NaN           | NaN          | NaN   | NaN   | NaN    | NaN | NaN  | NaN               | NaN             | NaN       | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            | NaN            | 1              |
| read          | find_version  | NaN      | NaN           | NaN          | NaN   | NaN   | NaN    | NaN | NaN  | NaN               | NaN             | NaN       | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            | 1              | NaN            |
| read          | find_version  | vref     | GetObject     | NaN          | 1     | NaN   | NaN    | 1   | 1    | NaN               | NaN             | 260       | 1             | NaN            | NaN            | NaN            | NaN            | NaN            | NaN            | NaN            |
| read          | find_version  | ver      | GetObject     | NaN          | 11    | NaN   | 6      | 11  | 5    | NaN               | NaN             | 301       | NaN           | 3              | 2              | 3              | 3              | NaN            | NaN            | NaN            |
| read          | read          | NaN      | NaN           | NaN          | NaN   | NaN   | NaN    | NaN | NaN  | NaN               | NaN             | NaN       | NaN           | NaN            | NaN            | NaN            | NaN            | 1              | NaN            | NaN            |
| read          | read          | tdata    | GetObject     | NaN          | 5     | NaN   | NaN    | NaN | NaN  | 10000             | 1000            | 5714      | NaN           | 1              | 2              | 1              | 1              | NaN            | NaN            | NaN            |
| read          | read          | tindex   | GetObject     | True         | 1     | 5     | NaN    | NaN | NaN  | NaN               | NaN             | 301       | 1             | NaN            | NaN            | NaN            | NaN            | NaN            | NaN            | NaN            |                                          
Slow response while trying to read tombstone/delete version of a symbol

In the situation when user tries to specifically read a tombstone/delete version of a symbol, the process will iterate all existing snapshots of the library. This is as last resort process to try to find the version but the process could be painstakingly long as all snapshots are needed to be iterated. Below is an example when user's trying to read a non-existting version larger then the latest version, with 100 snapshots in the library:

| arcticdb_call      | stage              | key_type | storage_op    | parallelized | count | tindex | uncompressed_size | compressed_size | bandwidth | time_count_30 | time_count_40 | time_count_50 | time_count_90 | time_count_100 | time_count_110 | time_count_170 | time_count_260 |
|--------------------|--------------------|----------|---------------|--------------|-------|--------|-------------------|-----------------|-----------|---------------|---------------|---------------|---------------|----------------|----------------|----------------|----------------|
| read               | NaN               | NaN      | NaN           | NaN          | NaN   | NaN    | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | NaN           | NaN            | NaN            | NaN            | 1              |
| read               | find_version       | NaN      | NaN           | NaN          | NaN   | NaN    | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | 1             | NaN            | NaN            | NaN            | NaN            |
| read               | find_version       | ver      | GetObject     | NaN          | 1     | NaN    | 15                | NaN             | 301       | NaN           | 1             | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            |
| read               | find_version       | vref     | GetObject     | NaN          | 1     | NaN    | 16                | NaN             | 260       | NaN           | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            |
| read               | iterate_snapshot   | NaN      | NaN           | NaN          | NaN   | NaN    | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | NaN           | NaN            | NaN            | 1              | NaN            |
| read               | iterate_snapshot   | tref     | ListObjectsV2 | NaN          | 1     | NaN    | NaN               | NaN             | NaN       | 1             | NaN           | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            |
| read               | iterate_snapshot   | snap     | ListObjectsV2 | NaN          | 1     | NaN    | NaN               | NaN             | NaN       | 1             | NaN           | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            |
| read               | iterate_snapshot   | tref     | GetObject     | True         | 100   | 100    | 1500              | NaN             | 260       | NaN           | NaN           | NaN           | 10            | 80             | 10             | NaN            | NaN            |
Analyzing why the script is slow

A very common request. With query stat, user can pinpoint which exact step is slow. Below is a common use case

  1. Check symbol exist
  2. Read symbol latest version
  3. Update symbol
| arcticdb_call   | stage           | key_type | storage_op    | parallelized | count | ver | tindex | tdata | tall | uncompressed_size | compressed_size | bandwidth | time_count_30 | time_count_50 | time_count_80 | time_count_100 | time_count_130 | time_count_300 | time_count_350 | time_count_780 |
|-----------------|-----------------|----------|---------------|--------------|-------|-----|--------|-------|------|-------------------|-----------------|-----------|---------------|---------------|---------------|----------------|----------------|----------------|----------------|----------------|
| list_symbols    | NaN             | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | 1             | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| list_symbols    | list            | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | 1             | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| list_symbols    | list            | sl       | ListObjectsV2 | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | 1             | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| read            | NaN             | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | 1              | NaN            | NaN            | NaN            | NaN            |
| read            | find_version    | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| read            | find_version    | vref     | GetObject     | NaN          | 1     | 1   | 1      | NaN   | NaN  | 15                | NaN             | 260       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| read            | read            | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | 1             | NaN            | NaN            | NaN            | NaN            | NaN            |
| read            | read            | tdata    | GetObject     | True         | 1     | NaN | NaN    | NaN   | NaN  | 2000              | 200             | 5714      | 1             | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| read            | read            | tindex   | GetObject     | NaN          | 1     | NaN | NaN    | 1     | NaN  | 16                | NaN             | 301       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | NaN             | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            | 1              |
| write           | find_version    | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | 1             | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | find_version    | vref     | GetObject     | NaN          | 1     | 1   | 1      | NaN   | NaN  | 15                | NaN             | 260       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | find_version    | ver      | GetObject     | NaN          | 1     | 1   | 1      | NaN   | NaN  | 16                | NaN             | 301       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write           | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | NaN            | 1              | NaN            | NaN            | NaN            |
| write           | write           | tdata    | PutObject     | True         | 1     | NaN | NaN    | NaN   | NaN  | 2000              | 200             | 5714      | 1             | NaN           | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write           | tindex   | PutObject     | NaN          | 1     | NaN | NaN    | 1     | NaN  | 16                | NaN             | 301       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write           | sl       | PutObject     | NaN          | 1     | NaN | NaN    | NaN   | NaN  | 16                | NaN             | 301       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write_version  | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | NaN            | NaN            | NaN            | 1              | NaN            |
| write           | write_version  | vref     | GetObject     | NaN          | 1     | 1   | 1      | NaN   | NaN  | 15                | NaN             | 260       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write_version  | ver      | GetObject     | NaN          | 3     | 3   | 2      | NaN   | 1    | 48                | NaN             | 301       | NaN           | 3             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write_version  | ver      | PutObject     | NaN          | 2     | 2   | 1      | NaN   | 1    | 32                | NaN             | 301       | NaN           | 2             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | write_version  | vref     | PutObject     | NaN          | 1     | 1   | 1      | NaN   | NaN  | 15                | NaN             | 260       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | delete         | NaN      | NaN           | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | NaN           | NaN           | NaN            | NaN            | 1              | NaN            | NaN            |
| write           | delete         | tref     | ListObjectsV2 | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | delete         | snap     | ListObjectsV2 | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | delete         | tref     | GetObject     | True         | 100   | NaN | 100    | NaN   | NaN  | 1500              | NaN             | 260       | 50            | 50            | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | delete         | cstats   | DeleteObjects | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | delete         | tindex   | DeleteObjects | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |
| write           | delete         | tdata    | DeleteObjects | NaN          | 1     | NaN | NaN    | NaN   | NaN  | NaN               | NaN             | NaN       | NaN           | 1             | NaN           | NaN            | NaN            | NaN            | NaN            | NaN            |

With above stats, user can tell the slowness of the script run is because the library has delay delete OFF. Therefore it requires to iterate all snapshots to find out whether the version being overwritten is safe to delete

@phoebusm phoebusm marked this pull request as draft January 28, 2025 10:27
@phoebusm phoebusm changed the title Draft query stat API [DONT MERGE] Draft query stat API Jan 29, 2025
'count': [1, 5],
'max_time': [1, 10],
'min_time': [1, 20],
'avg_time': [1, 15],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a histogram will be better than min max avg

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

'max_time': [1, 10],
'min_time': [1, 20],
'avg_time': [1, 15],
'uncompressed_size': [10, 1000],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does 10 mean for the list here? You need to give realistic output for anyone to understand this proposal

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update it with a slightly more realistic output

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants