-
Notifications
You must be signed in to change notification settings - Fork 1.1k
DData-based cluster sharding #3199
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
DData-based cluster sharding #3199
Conversation
Looking forward to this! |
d346c77
to
6938078
Compare
6938078
to
2674e91
Compare
This one is done. The only downside when compared to existing persistence mode (which still is the default one) is that DData doesn't support remember-entities option (which is opt-in). The reason here is that ddata durable store is not yet ready, as it requires well-defined data format - so far we serialize ddata structures with Hyperion. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me; need to add some docs explaining how to enable DData-based sharding in another PR.
@@ -247,6 +248,7 @@ public ClusterSharding(ExtendedActorSystem system) | |||
_system = system; | |||
_system.Settings.InjectTopLevelFallback(DefaultConfig()); | |||
_system.Settings.InjectTopLevelFallback(ClusterSingletonManager.DefaultConfig()); | |||
_system.Settings.InjectTopLevelFallback(DistributedData.DistributedData.DefaultConfig()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
|
||
namespace Akka.Cluster.Sharding | ||
{ | ||
using ShardId = String; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wtb typedef
in C#
// The default maximum-frame-size is 256 KiB with Artery. | ||
// When using entity identifiers with 36 character strings (e.g. UUID.randomUUID). | ||
// By splitting the elements over 5 keys we can support 10000 entities per shard. | ||
// The Gossip message size of 5 ORSet with 2000 ids is around 200 KiB. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These values are the same in .NET Desktop, slightly smaller in .NET Core since strings are UTF-8 instead of Unicode there. But either way, we're still in the clear.
if (newGotKeys.Count == NrOfKeys) | ||
RecoveryCompleted(); | ||
else | ||
Context.Become(WaitingForState(newGotKeys)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a comment and asking because I don't know the answer, but what's the allocation impact of these delegate calls that rely on argument closures? Just a new delegate and a long-lived reference to the closure itself?
|
||
private readonly ImmutableArray<ORSetKey<EntryId>> _stateKeys; | ||
|
||
public DDataShard( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me; went through all of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Damn, found some changes with MNTR Discovery at the very end that need to be rolled back. Looks like debug lines that were left-inplace.
var configFields = configType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); | ||
var roleFields = configFields.Where(f => f.FieldType == roleType).Select(f => (RoleName)f.GetValue(configInstance)); | ||
var configProps = configType.GetProperties(BindingFlags.Instance | BindingFlags.Public); | ||
var roleProps = configProps.Where(p => p.PropertyType == roleType && p.Name != "Myself").Select(p => (RoleName)p.GetValue(configInstance)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Horusiath errp.... Looks like these were debug lines added when you were testing this stuff. Going to need to remove that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, actually those changes are valid. Without them you cannot make inherited role names i.e. if you defined roles First, Second in some base MultiNodeConfig
class, then inherit from it (like in the case of ClusterShardingSpecConfig
→PersistentClusterShardingSpecConfig
and ClusterShardingSpecConfig
→DDataClusterShardingSpecConfig
), then MNTK runner won't detect those role names in actual specs, making the test cluster empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about the p.Name != "Myself"
- that looks like a one-off to me? No?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, every MultiNodeConfig
contains a property called Myself, which is also a RoleName
. While we may want to spin test cluster nodes based on properties like Controller, First, Second, Third etc., I guess we don't want to spin a cluster node called Myself for every test ;) Especially since it has some specific meaning in context of a config.
I was thinking about excluding properties to be used as test cluster nodes by attaching some special attribute to them, but it seem to be too much ceremony - so far it's used only in one case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Horusiath got it. Ok then, objection overruled. This is good to go.
This is PR bringing DistributedData-based mode for Akka.Cluster.Sharding. On the Akka JVM it's already a default option for sharding actors. It allows to use sharding without need for persistent journals.