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

[core] Refactor how we store data in redis. #46861

Merged
merged 36 commits into from
Sep 18, 2024

Conversation

rynewang
Copy link
Contributor

@rynewang rynewang commented Jul 30, 2024

Ray GCS Fault Tolerance replies on an external Redis. We write all data for a Ray cluster into a single Redis HASH. Within the HASH, we use a Redis field prefix to represent a Ray table. This is OK for single field CRUD, but for "get all entries for a Ray table" we would have to do a full table HSCAN and filter out other Ray tables by key prefix. This slows things down and the call to get_all_node_info and get_all_actor_info are in fact fairly common.

Updates the Redis usage by creating multiple Redis HASHes, 1 for each Ray table. The single field CRUD are largely the same; but "get all" operations now become a simple HSCAN on the target HASH only. This saves lots of compute.

Closes #46706.

Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@rynewang
Copy link
Contributor Author

ping @rkooo567

@rkooo567
Copy link
Contributor

can you link the original issue?

@rynewang
Copy link
Contributor Author

There's no issue; it's from a community PR #46706

Copy link
Contributor

@rkooo567 rkooo567 left a comment

Choose a reason for hiding this comment

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

Looks good in general. many minor comments.

Besides, how do we test them now?

@@ -141,7 +141,7 @@ KEYS *
# 1) "864b004c-6305-42e3-ac46-adfa8eb6f752"

# Step 6.5: Check the value of the key.
HGETALL 864b004c-6305-42e3-ac46-adfa8eb6f752
SCAN 0 MATCH 864b004c-6305-42e3-ac46-adfa8eb6f752*
Copy link
Contributor

Choose a reason for hiding this comment

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

cc @kevin85421 this is breaking change for kuberay users I think. Would this be okay?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we expect users to directly operate ray redis?

Copy link
Member

Choose a reason for hiding this comment

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

I think this change is fine. My only concern is about cleaning up Redis. @rynewang will provide me with a Docker image, and I will manually test it.

Copy link
Contributor Author

@rynewang rynewang Aug 20, 2024

Choose a reason for hiding this comment

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

Kuberay cleans redis by calling cleanup_redis_storage which I reimplemented so should be OK. I'm giving @kevin85421 a docker image to test

Copy link
Member

Choose a reason for hiding this comment

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

It's not easy to get a Docker image. Let's merge it and then I will use the nightly image to test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also cc @edoakes we are using the function to clean up redis or the raw command?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yea, I checked with @edoakes before, we also use cleanup_redis_storage

src/ray/gcs/store_client/redis_store_client.cc Outdated Show resolved Hide resolved
src/ray/gcs/store_client/redis_store_client.cc Outdated Show resolved Hide resolved
src/ray/gcs/store_client/redis_store_client.cc Outdated Show resolved Hide resolved
src/ray/gcs/store_client/redis_store_client.cc Outdated Show resolved Hide resolved
match_pattern,
"COUNT",
std::to_string(batch_count)};
std::vector<std::string> args = {"HSCAN", table_name_, std::to_string(cursor_.value())};
Copy link
Contributor

Choose a reason for hiding this comment

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

why does it not use GenRedisKey?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ctor of RedisScanner accepts the table name, and all its callers uses GenRedisKey so we are fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you want a more typed set up, e.g. a struct represending the {external_storage_namespace, table_name} ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want a more typed set up, e.g. a struct represending the {external_storage_namespace, table_name} ?

Yeah this would be great. I am also confused why this doesn't include external_storage_namespace (that's why I was asking why we don't use GenRedisKey)?

src/ray/gcs/store_client/redis_store_client.cc Outdated Show resolved Hide resolved
@rkooo567 rkooo567 added the @author-action-required The PR author is responsible for the next step. Remove tag to send back to the reviewer. label Aug 14, 2024
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@rynewang rynewang removed the @author-action-required The PR author is responsible for the next step. Remove tag to send back to the reviewer. label Aug 20, 2024
@rynewang
Copy link
Contributor Author

@rkooo567 PTAL again

Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@rynewang rynewang changed the title [core] Refactor how we storage things in redis. [core] Refactor how we store things in redis. Aug 21, 2024
@rynewang rynewang changed the title [core] Refactor how we store things in redis. [core] Refactor how we store data in redis. Aug 21, 2024
@rynewang rynewang added the go add ONLY when ready to merge, run all tests label Aug 21, 2024
Copy link
Contributor

@rkooo567 rkooo567 left a comment

Choose a reason for hiding this comment

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

Looks good. Last couple comments (please make sure to resolve)!

Regarding Redis, can you sync with @kevin85421 and make sure we recommend to use cleanup_redis_storage , not the raw Redis command? If we have any recommendation using raw Redis command, I think we should have a loud release note.

match_pattern,
"COUNT",
std::to_string(batch_count)};
std::vector<std::string> args = {"HSCAN", table_name_, std::to_string(cursor_.value())};
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want a more typed set up, e.g. a struct represending the {external_storage_namespace, table_name} ?

Yeah this would be great. I am also confused why this doesn't include external_storage_namespace (that's why I was asking why we don't use GenRedisKey)?

Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@rynewang
Copy link
Contributor Author

Rewrote most of the file to use typed RedisCommand, RedisKey and RedisMatchPattern. PTAL! @rkooo567

Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Copy link
Contributor

@rkooo567 rkooo567 left a comment

Choose a reason for hiding this comment

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

looks very good!

python/ray/_private/gcs_utils.py Outdated Show resolved Hide resolved
python/ray/_raylet.pyx Outdated Show resolved Hide resolved
python/ray/includes/global_state_accessor.pxd Outdated Show resolved Hide resolved
src/ray/gcs/store_client/redis_store_client.h Show resolved Hide resolved
src/ray/gcs/store_client/redis_store_client.cc Outdated Show resolved Hide resolved
@rynewang rynewang enabled auto-merge (squash) August 27, 2024 00:14
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@github-actions github-actions bot disabled auto-merge August 27, 2024 00:38
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@rynewang rynewang enabled auto-merge (squash) September 5, 2024 05:42
rynewang and others added 2 commits September 6, 2024 11:00
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
Signed-off-by: Jiajun Yao <jeromeyjj@gmail.com>
@jjyao
Copy link
Collaborator

jjyao commented Sep 12, 2024

I think the test failure is real (i.e. cannot be fixed by increasing timeout)

Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@rynewang
Copy link
Contributor Author

it IS real. It happens when you have a large BatchDelete, where a bad move on callback function makes the callback never called. fixed and reverted the test relaxings.

@@ -136,12 +136,22 @@ export REDIS_POD=$(kubectl get pods --selector=app=redis -o custom-columns=POD:m
kubectl exec -it $REDIS_POD -- redis-cli -a "5241590000000000"

# Step 6.4: Check the keys in Redis.
# Note: the schema changed in Ray 2.36.0. Previously we use a single HASH table,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs to be updated to 2.38.0.

Copy link
Contributor

@angelinalg angelinalg left a comment

Choose a reason for hiding this comment

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

stamp

Signed-off-by: Ruiyang Wang <56065503+rynewang@users.noreply.github.com>
python/ray/_private/gcs_utils.py Outdated Show resolved Hide resolved
python/ray/_private/gcs_utils.py Outdated Show resolved Hide resolved
rynewang and others added 4 commits September 18, 2024 11:31
Co-authored-by: Jiajun Yao <jeromeyjj@gmail.com>
Signed-off-by: Ruiyang Wang <56065503+rynewang@users.noreply.github.com>
Co-authored-by: Jiajun Yao <jeromeyjj@gmail.com>
Signed-off-by: Ruiyang Wang <56065503+rynewang@users.noreply.github.com>
Signed-off-by: Ruiyang Wang <rywang014@gmail.com>
@jjyao jjyao merged commit f298a75 into ray-project:master Sep 18, 2024
4 of 5 checks passed
@JoshKarpel
Copy link
Contributor

Hi, just spotted this - wondering if corresponding changes are being made to KubeRay to ensure that it is able to clean up all of these new tables in the GCS cleanup job that runs when a cluster is terminated?

Alternatively, it would be nice if these tables had expirations set (and regularly refreshed) internally so that KubeRay didn't need to clean them up.

See ray-project/kuberay#959

@rynewang
Copy link
Contributor Author

rynewang commented Sep 19, 2024 via email

@JoshKarpel
Copy link
Contributor

Awesome, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Issues that should be addressed in Ray Core core-gcs Ray core global control storage. enhancement Request for new feature and/or capability go add ONLY when ready to merge, run all tests P1 Issue that should be fixed within a few weeks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants