Sharding: API Administration



Creating a Sharded Database

To create a sharded database:

  • Use CreateDatabaseOperation to create the database.
  • Define ShardingConfiguration in the database record.
    • The initial configuration can define just the database topologies for as many shards as needed.
    • Orchestrators and shards can be added and removed later on, after the database is created.

ShardingConfiguration

public class ShardingConfiguration
{
    // Orchestrator configuration
    public OrchestratorConfiguration Orchestrator;

    // A database topology per shard dictionary
    public Dictionary<int, DatabaseTopology> Shards;

    // Buckets distribution between the shards (filled by RavenDB)
    public List<ShardBucketRange> BucketRanges = new List<ShardBucketRange>();

    // Buckets that are currently being resharded (filled by RavenDB)
    public Dictionary<int, ShardBucketMigration> BucketMigrations;
}

Example

DatabaseRecord dbRecord = new DatabaseRecord("sampleDB");

dbRecord.Sharding = new ShardingConfiguration
{
    Shards = new Dictionary<int, DatabaseTopology>()
    {
        { 0, new DatabaseTopology() }, // Shard #0 database topology
        { 1, new DatabaseTopology() }, // Shard #1 database topology
        { 2, new DatabaseTopology() }  // Shard #2 database topology
    }
};

store.Maintenance.Server.Send(new CreateDatabaseOperation(dbRecord));

Orchestrator Administration

Prior to granting a cluster node an orchestrator functionality, we should make sure that the node is up for the task, with no other tasks contesting the orchestrator for system resources. E.g., it may be better to use as orchestrators nodes that host no shards.

Adding an Orchestrator

  • To add an orchestrator pass the database name and the node to be added as orchestrator to the AddNodeToOrchestratorTopologyOperation operation.

    public AddNodeToOrchestratorTopologyOperation(string databaseName, string node = null)
  • Parameters:

    Parameter Type Description
    databaseName string Database Name
    node string Node tag for the node to be made orchestrator
  • Return value: ModifyOrchestratorTopologyResult

    public class ModifyOrchestratorTopologyResult
    {
        public string Name; // Database Name
        public OrchestratorTopology OrchestratorTopology; // Database Topology
        public long RaftCommandIndex;
    }

Removing an Orchestrator

  • To stop a node from functioning as an orchestrator pass the database name and the node tag to the RemoveNodeFromOrchestratorTopologyOperation operation.

    public RemoveNodeFromOrchestratorTopologyOperation(string databaseName, string node)
  • Parameters:

    Parameter Type Description
    databaseName string Database Name
    node string The node to be removed as orchestrator
  • Return value: ModifyOrchestratorTopologyResult

    public class ModifyOrchestratorTopologyResult
    {
        public string Name; // Database Name
        public OrchestratorTopology OrchestratorTopology; // Database Topology
        public long RaftCommandIndex;
    }

Shard Administration

Adding a Shard

  • To add a new shard, use one of the AddDatabaseShardOperation operation overloads.

    public AddDatabaseShardOperation(string databaseName, int? shardNumber = null)
    public AddDatabaseShardOperation(string databaseName, string[] nodes, int? shardNumber = null)
    public AddDatabaseShardOperation(string databaseName, int? replicationFactor, int? shardNumber = null)
  • Parameters:

    Parameter Type Description
    databaseName string Database Name
    shardNumber int? Shard number
    If a shard number is not explicitly provided, the shard number will be the biggest existing shard number + 1
    replicationFactor int? The new shard's replication factor (see comment below)
    nodes string[] A list of nodes to replicate the shard to.
    If provided, the replication factor will be set by the number of nodes.

    replicationFactor, the new shard's replication factor, is determined as follows:

    • If replicationFactor is not provided explicitly, and a list of nodes is provided, the replication factor will be set by the number of nodes.
    • If neither replicationFactor and a nodes list are provided, the replication factor will be set as that of the first shard.
    • If both replicationFactor and a nodes list are provided:
      • If there are less nodes than set by replicationFactor, the new shard will be replicated on these nodes.
      • If there are more nodes than set by replicationFactor, only as many replications as set by replicationFactor will be carried out.

  • Return value: AddDatabaseShardResult

    public class AddDatabaseShardResult
    {
        public string Name { get; set; }
        public int ShardNumber { get; set; }
        public DatabaseTopology ShardTopology { get; set; }
        public long RaftCommandIndex { get; set; }
    }

Adding a Shard Replica

  • To add a replica to an existing shard pass the database name and a shard number to the AddDatabaseNodeOperation operation.

    The replication factor is updated automatically as replicas are added, there is no need to update it explicitly.

    public AddDatabaseNodeOperation(string databaseName, int shardNumber, string node = null)
  • Parameters:

    Parameter Type Description
    databaseName string Database Name
    shardNumber string Shard Number
    node string The node that the replica will be set on (optional).
    If not provided, RavenDB will select an available node.
  • Return value: DatabasePutResult

    public class DatabasePutResult
    {
        public long RaftCommandIndex { get; set; }
    
        public string Name { get; set; }
        public DatabaseTopology Topology { get; set; }
        public List<string> NodesAddedTo { get; set; }
    
        public bool ShardsDefined { get; set; }
    }

Promoting a Shard Replica

  • Shard replicas can be promoted as non-sharded databases can.

    To promote a shard, pass the database name, shard number and node tag to the PromoteDatabaseNodeOperation operation.
    This will help locate the exact shard instance we want to promote, leading to the database, then to the specific shard, and finally to the specific replica of that shard.

    public PromoteDatabaseNodeOperation(string databaseName, int shardNumber, string node)
  • Parameters:

    Parameter Type Description
    databaseName string Database Name
    shardNumber int Shard number
    node string Node tag
  • Return value: DatabasePutResult

    public class DatabasePutResult
    {
        public long RaftCommandIndex { get; set; }
    
        public string Name { get; set; }
        public DatabaseTopology Topology { get; set; }
        public List<string> NodesAddedTo { get; set; }
    
        public bool ShardsDefined { get; set; }
    }

Removing a Shard

  • A shard is removed when all its replicas have been deleted.
  • RavenDB will remove a shard only after verifying that its database is empty. If any buckets remain in the database the operation will be aborted.
  • To remove a shard use the designated DeleteDatabasesOperation overload.

    public DeleteDatabasesOperation(
        string databaseName, 
        int shardNumber, 
        bool hardDelete, 
        string fromNode, 
        TimeSpan? timeToWaitForConfirmation = null)
  • Parameters:

    Parameter Type Description
    databaseName string Database Name
    shardNumber int Shard number: number of the shard replica to be removed
    hardDelete bool If true, Hard Delete: stop replication to this node and delete the replica's database.
    If false, Soft Delete: stop replication to this node but do not delete the replica's database.
    fromNode string The node we want to remove the replica from
    timeToWaitForConfirmation TimeSpan?
  • Return value: DeleteDatabaseResult

    public class DeleteDatabaseResult
    {
        public long RaftCommandIndex { get; set; }
        public string[] PendingDeletes { get; set; }
    }