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

RED-134847 support for active defrag for RedisJSON. #1262

Merged
merged 12 commits into from
Sep 10, 2024

Conversation

MeirShpilraien
Copy link
Collaborator

@MeirShpilraien MeirShpilraien commented Sep 3, 2024

The PR adds support for active defrag on RedisJSON. A pre condition for this PR is that the following PR's will be megred:

The PR register defrag function on the json datatype and uses the new capability of ISON to defrag the key.

Notice:

  • Increamental defrag of the json key is not support. In order to support it we need to implement the free_effort callback. This is not trivial and even if it was it would have cause the json object to potentially be freed when the GIL is not hold, which violate the assumption of our shared string implementation (it is not thread safe). We leave it for future improvment.

  • If we run on a Redis version that do not support the defrag start callback, we can still partially support defrag. In that case the IJSON object will be defraged but the shared strings dictionatrywill not be reinitialize. This basically means that shared strings will not be defraged.

Tests were added to cover the new functionality.

  • Change deps once all the required PR's get merged

The PR adds support for active defrag on RedisJSON. A pre condition for this PR is that the following PR's will be megred:

* [Redis defrad module API extentions](redis/redis#13509)
* [redismodule-rs support for active defrag API](RedisLabsModules/redismodule-rs#387)
* [IJSON support for defrag](RedisJSON/ijson#1)

The PR register defrag function on the json datatype and uses the new capability of ISON to defrag the key.

**Notice**:

* that increamental defrag of the json key is **not** support. In order to support it we need to implement the free_effort callback. This is not trivial and even if it was it would have cause the json object to potentially be freed when the GIL is not hold, which violate the assumption of our shared string implementation (it is not thread safe). We leave it for future improvment.

* If we run on a Redis version that do not support the defrag start callback, we can still partially support defrag. In that case the IJSON object will be defraged but the shared strings dictionaty will not be reinitialize. This basically means that shared strings will not be defraged.

Tests were added to cover the new functionality.
Copy link

codecov bot commented Sep 3, 2024

Codecov Report

Attention: Patch coverage is 74.24242% with 17 lines in your changes missing coverage. Please review.

Project coverage is 78.37%. Comparing base (1e82622) to head (b223cc9).

Files with missing lines Patch % Lines
redis_json/src/defrag.rs 73.84% 17 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1262      +/-   ##
==========================================
- Coverage   78.44%   78.37%   -0.07%     
==========================================
  Files          14       15       +1     
  Lines        3938     4004      +66     
==========================================
+ Hits         3089     3138      +49     
- Misses        849      866      +17     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

ephraimfeldblum
ephraimfeldblum previously approved these changes Sep 3, 2024
env.cmd('CONFIG', 'SET', 'active-defrag-cycle-min', '99')

try:
env.cmd('CONFIG', 'SET', 'activedefrag', 'yes')
Copy link

Choose a reason for hiding this comment

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

@MeirShpilraien i understand that unlike the redis defrag tests, this one isn't actually creating fragmentation and waiting for it to go down, which is ok.
and i understand that it does test all sorts of various types of json objects, and watches for stats about callback cycles, but how does it make sure that the pointers were really moved? what if redis forgets to call the module api callback?

maybe in addition to these, add one test that create holes and waits for them to get filled?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Modify to tests to actually cause fragmentation and verify that defrag actually took place.

Copy link

Choose a reason for hiding this comment

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

if i read it correctly, you created a lot of jason fields, and then deleted all of them.
what i think you should do:

  1. disable active defrag
  2. create a lot of jason fields
  3. delete all the even ones (or alternatively when you create them, you can create two keys, and interchangeably add fields to both, and then delete one key)
  4. verify you managed to create fragmentation beyond a certain threshold.
  5. enable active defrag.
  6. wait for fragmentation levels to go down

see memefficiency.tcl in redis.
what i wanna see is that fields get actually re-located (not just that the callback is called)

# wait for fragmentation for go down for up to 30 seconds
frag = env.cmd('info', 'memory')['mem_fragmentation_ratio']
startTime = time.time()
while frag < 1.1:
Copy link

Choose a reason for hiding this comment

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

shouldn't it be >?
p.s. i think allocator_frag_ratio is safer to use.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

shouldn't it be >?

Don't we want the fragmentation ratio to go down?

p.s. i think allocator_frag_ratio is safer to use.

OK, will change it.

Copy link
Collaborator Author

@MeirShpilraien MeirShpilraien Sep 4, 2024

Choose a reason for hiding this comment

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

shouldn't it be >?

Ohh sorry right, and when I used the allocator_frag_ratio it actually failed (went down to fast?)

Copy link

Choose a reason for hiding this comment

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

maybe.. seems odd, but no reason to wonder about it too much

iddm
iddm previously approved these changes Sep 4, 2024
Copy link

@oranagra oranagra left a comment

Choose a reason for hiding this comment

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

test LGTM

@@ -110,12 +110,12 @@ def testDefragBigJsons(env):
# wait for fragmentation for up to 30 seconds
Copy link

Choose a reason for hiding this comment

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

you can say that stats are updated by cron (the fragmentation is already a fact, we just wait for it to be detected).
one second (or even 200ms) is enough, no need for 30 sec.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@oranagra we will not wait for 30 seconds, we will wait for up to 30 seconds to see fragmentation and if we do not see it by than we will fail the test.

Copy link

Choose a reason for hiding this comment

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

i know.. still saying that there's no need.
IMHO it's misleading, we're just waiting for cron to update stats..
anyway, i don't really care.

@MeirShpilraien MeirShpilraien merged commit 6539e1e into master Sep 10, 2024
10 of 12 checks passed
@MeirShpilraien MeirShpilraien deleted the active_defrag_support branch September 10, 2024 11:28
MeirShpilraien added a commit that referenced this pull request Sep 16, 2024
The PR adds support for active defrag on RedisJSON. A pre condition for this PR is that the following PR's will be megred:

* [Redis defrad module API extentions](redis/redis#13509)
* [redismodule-rs support for active defrag API](RedisLabsModules/redismodule-rs#387)
* [IJSON support for defrag](RedisJSON/ijson#1)

The PR register defrag function on the json datatype and uses the new capability of ISON to defrag the key.

**Notice**:

* Increamental defrag of the json key is **not** support. In order to support it we need to implement the free_effort callback. This is not trivial and even if it was it would have cause the json object to potentially be freed when the GIL is not hold, which violate the assumption of our shared string implementation (it is not thread safe). We leave it for future improvment.

* If we run on a Redis version that do not support the defrag start callback, we can still partially support defrag. In that case the IJSON object will be defraged but the shared strings dictionatrywill not be reinitialize. This basically means that shared strings will not be defraged.

Tests were added to cover the new functionality.

(cherry picked from commit 6539e1e)
MeirShpilraien added a commit that referenced this pull request Sep 16, 2024
The PR adds support for active defrag on RedisJSON. A pre condition for this PR is that the following PR's will be megred:

* [Redis defrad module API extentions](redis/redis#13509)
* [redismodule-rs support for active defrag API](RedisLabsModules/redismodule-rs#387)
* [IJSON support for defrag](RedisJSON/ijson#1)

The PR register defrag function on the json datatype and uses the new capability of ISON to defrag the key.

**Notice**:

* Increamental defrag of the json key is **not** support. In order to support it we need to implement the free_effort callback. This is not trivial and even if it was it would have cause the json object to potentially be freed when the GIL is not hold, which violate the assumption of our shared string implementation (it is not thread safe). We leave it for future improvment.

* If we run on a Redis version that do not support the defrag start callback, we can still partially support defrag. In that case the IJSON object will be defraged but the shared strings dictionatrywill not be reinitialize. This basically means that shared strings will not be defraged.

Tests were added to cover the new functionality.

(cherry picked from commit 6539e1e)
MeirShpilraien added a commit that referenced this pull request Sep 16, 2024
The PR adds support for active defrag on RedisJSON. A pre condition for this PR is that the following PR's will be megred:

* [Redis defrad module API extentions](redis/redis#13509)
* [redismodule-rs support for active defrag API](RedisLabsModules/redismodule-rs#387)
* [IJSON support for defrag](RedisJSON/ijson#1)

The PR register defrag function on the json datatype and uses the new capability of ISON to defrag the key.

**Notice**:

* Increamental defrag of the json key is **not** support. In order to support it we need to implement the free_effort callback. This is not trivial and even if it was it would have cause the json object to potentially be freed when the GIL is not hold, which violate the assumption of our shared string implementation (it is not thread safe). We leave it for future improvment.

* If we run on a Redis version that do not support the defrag start callback, we can still partially support defrag. In that case the IJSON object will be defraged but the shared strings dictionatrywill not be reinitialize. This basically means that shared strings will not be defraged.

Tests were added to cover the new functionality.

(cherry picked from commit 6539e1e)
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.

4 participants