Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

DATAREDIS-803 - Work around Redis parameter limitation #326

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

Closed

Conversation

Copy link
Contributor

@christian-sahlmann christian-sahlmann commented Mar 30, 2018
edited
Loading

Redis has a limitation of 1024 * 1024 parameters for bulk operations.

To insert more than 1024 * 1024 / 2 - 1 entries with putAll(), they need to be split up in multiple HMSET commands.

To reveive more than 1024 * 1024 - 1 entries with entrySet(), we can directly use the HGETALL command instead of first fetching the keys with HKEYS and then fetching the values with HMGET.

Copy link
Member

mp911de commented Mar 30, 2018

Please create a ticket in our issue tracker so we can understand, what exactly you want to achieve.

@christian-sahlmann christian-sahlmann changed the title (削除) Use HGETALL instead of HMGET for DefaultRedisMap.entrySet() (削除ここまで) (追記) Work around Redis parameter limitation (追記ここまで) Mar 31, 2018
@christian-sahlmann christian-sahlmann changed the title (削除) Work around Redis parameter limitation (削除ここまで) (追記) DATAREDIS-803 Work around Redis parameter limitation (追記ここまで) Mar 31, 2018
@christian-sahlmann christian-sahlmann changed the title (削除) DATAREDIS-803 Work around Redis parameter limitation (削除ここまで) (追記) DATAREDIS-803 - Work around Redis parameter limitation (追記ここまで) Mar 31, 2018
Copy link
Contributor Author

Copy link
Member

@mp911de mp911de left a comment

Choose a reason for hiding this comment

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

Adding an optimization to fetch all entries with a single command is a good one. We should however not break command atomicity by introducing transparent partitioning if commands grow too big. This change hides Redis limitations and will cause surprises.
Such specifics rather belong into application code.

If you drop the mentioned change from your pull request, we can continue on the map access optimization.

byte[] rawKey = rawKey(key);

Map<byte[], byte[]> hashes = new LinkedHashMap<>(m.size());
int size = Math.min(RedisTemplate.REDIS_MAX_ARGS / 2 - 1, m.size());
Copy link
Member

@mp911de mp911de Apr 3, 2018

Choose a reason for hiding this comment

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

We can't change a single anticipated HMSET to multiple ones as we're losing atomicity. That's rather something to be handled in the application code.

Copy link
Contributor Author

@christian-sahlmann christian-sahlmann Apr 7, 2018

Choose a reason for hiding this comment

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

Good point. I didn't think about the atomicity. Removed it again and adapted the test accordingly.

*/
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {

public static final int REDIS_MAX_ARGS = 1024 * 1024;
Copy link
Member

@mp911de mp911de Apr 3, 2018

Choose a reason for hiding this comment

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

We should remove this one as there's no need for the constant (see comment above about atomicity).

Copy link
Contributor Author

@christian-sahlmann christian-sahlmann Apr 7, 2018

Choose a reason for hiding this comment

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

Yes, removed.

}

return entries;
return hashOps.entries().entrySet();
Copy link
Member

@mp911de mp911de Apr 3, 2018
edited
Loading

Choose a reason for hiding this comment

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

Nice optimization. We should retain the check for pipelining/transaction via checkResult(...) ending in something like:

entries = hashOps.entries();
checkResult(entries);
return entries.entrySet();

Copy link
Contributor Author

@christian-sahlmann christian-sahlmann Apr 7, 2018

Choose a reason for hiding this comment

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

Thanks. In the first place, I didn't intend this as an optimization, but as a fix to be able to fetch more than 1024*1024 -1 entries. But I agree, the optimization is a nice side effect ;)
I re-added the checkResult(...).

Redis has a [limitation of 1024 * 1024 parameters](https://github.com/antirez/redis/blob/4.0.9/src/networking.c#L1200) for bulk operations.
To insert more than 1024 * 1024 / 2 - 1 entries with putAll(), they need to be split up in multiple calls.
To reveive more than 1024 * 1024 - 1 entries with entrySet(), we can directly use the HGETALL command instead of first fetching the keys with HKEYS and then fetching the values with HMGET.
mp911de pushed a commit that referenced this pull request Apr 9, 2018
Redis has a limitation of 1024 * 1024 parameters]() for bulk operations.
To receive more than 1024 * 1024 - 1 entries with entrySet(), we can directly use the HGETALL command instead of first fetching the keys with HKEYS and then fetching the values with HMGET.
See also: https://github.com/antirez/redis/blob/4.0.9/src/networking.c#L1200
Original pull request: #326.
mp911de added a commit that referenced this pull request Apr 9, 2018
Remove DefaultRedisMapEntry as it's no longer required. Simplify test to unit test to reduce test scope and test run time.
Original pull request: #326.
mp911de pushed a commit that referenced this pull request Apr 9, 2018
Redis has a limitation of 1024 * 1024 parameters]() for bulk operations.
To receive more than 1024 * 1024 - 1 entries with entrySet(), we can directly use the HGETALL command instead of first fetching the keys with HKEYS and then fetching the values with HMGET.
See also: https://github.com/antirez/redis/blob/4.0.9/src/networking.c#L1200
Original pull request: #326.
mp911de added a commit that referenced this pull request Apr 9, 2018
Remove DefaultRedisMapEntry as it's no longer required. Simplify test to unit test to reduce test scope and test run time.
Original pull request: #326.
Copy link
Member

mp911de commented Apr 9, 2018

Thanks a lot. That's merged, polished, and backported to 2.0.x now.

christian-sahlmann reacted with hooray emoji

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Reviewers

@mp911de mp911de mp911de requested changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

AltStyle によって変換されたページ (->オリジナル) /