Skip to content

Conversation

christian-sahlmann
Copy link
Contributor

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

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.

@mp911de
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 force-pushed the master branch 4 times, most recently from b45256e to d6ceec8 Compare March 31, 2018 10:09
@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
@christian-sahlmann
Copy link
Contributor Author

Ticket created: https://jira.spring.io/browse/DATAREDIS-803

@christian-sahlmann christian-sahlmann force-pushed the master branch 5 times, most recently from 82d1efc to fee3d47 Compare March 31, 2018 12:48
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

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

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

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

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

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

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.
@mp911de
Copy link
Member

mp911de commented Apr 9, 2018

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

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