Jump to: navigation, search

Difference between revisions of "Trove-Replication-And-Clustering-API"

Line 1: Line 1:
 +
=Instance Object Changes=
 +
Part of this proposal includes adding new properties to the json structure of an instance.
 +
The first would be to add a "nodes" property which would be list of refs back to the nova
 +
instance(s) that make up the trove instance.
 +
 +
The second would be a metadata storage that is of an open format to be used for storing
 +
critical data that is pertinent to the trove instance.
 +
 +
==INSTANCES==
 +
===Nodes===
 +
Because trove instances are a service type with an underlying nova resource(s) we can better
 +
display the nova resource(s) that make up the instance of a service type.  When looking at a
 +
singular trove instance of something like redis or mysql the knowledge of the instance
 +
resource isn't all that important.  Currently trove knows about the instance from a nova
 +
perspective but masks most of this information. This would look something like this:
 +
 +
'''GET''' /instances/{id}
 +
<pre>
 +
{
 +
    "instance": {
 +
        "created": "2013-05-08T22:43:34",
 +
        "hostname": "e09ad9a3f73309469cf1f43d11e79549caf9acf2.rackspaceclouddb.com",
 +
        "id": "dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
        "name": "json_rack_instance",
 +
        "status": "ACTIVE",
 +
        "updated": "2013-05-08T22:43:34",
 +
        "service_type": "mysql-5.1",
 +
        "nodes": [
 +
        {
 +
        "flavor": {
 +
            "id": "1",
 +
            "links": [
 +
                {
 +
                    "href": "https://service/v1.0/1234/flavors/1",
 +
                    "rel": "self"
 +
                },
 +
                {
 +
                    "href": "https://service/flavors/1",
 +
                    "rel": "bookmark"
 +
                }
 +
            ]
 +
        },
 +
        "links": [
 +
            {
 +
                "href": "https://service/v1.0/1234/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
                "rel": "self"
 +
            },
 +
            {
 +
                "href": "https://service/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
                "rel": "bookmark"
 +
            }
 +
        ],
 +
        "volume": {
 +
            "size": 2,
 +
            "used": 0.16368598397821188
 +
        },
 +
        },
 +
        ],
 +
    }
 +
}
 +
</pre>
 +
 +
===Metadata===
 +
The metadata looks much like our previous proposal.  It contains critical information to the
 +
configuration or topology of the cluster or replication agreement.  This should look something
 +
like this:
 +
 +
'''GET''' /instances/{id}
 +
<pre>
 +
{
 +
    "instance": {
 +
        "created": "2013-05-08T22:43:34",
 +
        "id": "cfeccbf4-ac5b-494a-99b7-61593a6a71b0",
 +
        "name": "multi-master-hotness",
 +
        "status": "ACTIVE",
 +
        "updated": "2013-05-08T22:43:34",
 +
        "service_type": "mysql-5.5",
 +
        "nodes": [
 +
        {
 +
        "id": "dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
        "hostname": "master-n01.example.com",
 +
        "flavor": {
 +
            "id": "1",
 +
            "links": [
 +
                {
 +
                    "href": "https://service/v1.0/1234/flavors/1",
 +
                    "rel": "self"
 +
                },
 +
                {
 +
                    "href": "https://service/flavors/1",
 +
                    "rel": "bookmark"
 +
                }
 +
            ]
 +
        },
 +
        "links": [
 +
            {
 +
                "href": "https://service/v1.0/1234/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
                "rel": "self"
 +
            },
 +
            {
 +
                "href": "https://service/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
                "rel": "bookmark"
 +
            }
 +
        ],
 +
        "volume": {
 +
            "size": 2,
 +
            "used": 0.16368598397821188
 +
        },
 +
        },
 +
        {
 +
        "id": "4530736b-c1ff-4c07-9a9f-fa9bca418157",
 +
        "hostname": "master-n02.example.com",
 +
        "flavor": {
 +
            "id": "1",
 +
            "links": [
 +
                {
 +
                    "href": "https://service/v1.0/1234/flavors/1",
 +
                    "rel": "self"
 +
                },
 +
                {
 +
                    "href": "https://service/flavors/1",
 +
                    "rel": "bookmark"
 +
                }
 +
            ]
 +
        },
 +
        "links": [
 +
            {
 +
                "href": "https://service/v1.0/1234/instances/4530736b-c1ff-4c07-9a9f-fa9bca418157",
 +
                "rel": "self"
 +
            },
 +
            {
 +
                "href": "https://service/instances/4530736b-c1ff-4c07-9a9f-fa9bca418157",
 +
                "rel": "bookmark"
 +
            }
 +
        ],
 +
        "volume": {
 +
            "size": 2,
 +
            "used": 0.16368598397821188
 +
        },
 +
        },
 +
        {
 +
        "id": "736b9820-7e91-4775-84b0-78e71d60ce4c",
 +
        "hostname": "master-n03.example.com",
 +
        "flavor": {
 +
            "id": "1",
 +
            "links": [
 +
                {
 +
                    "href": "https://service/v1.0/1234/flavors/1",
 +
                    "rel": "self"
 +
                },
 +
                {
 +
                    "href": "https://service/flavors/1",
 +
                    "rel": "bookmark"
 +
                }
 +
            ]
 +
        },
 +
        "links": [
 +
            {
 +
                "href": "https://service/v1.0/1234/instances/736b9820-7e91-4775-84b0-78e71d60ce4c",
 +
                "rel": "self"
 +
            },
 +
            {
 +
                "href": "https://service/instances/736b9820-7e91-4775-84b0-78e71d60ce4c",
 +
                "rel": "bookmark"
 +
            }
 +
        ],
 +
        "volume": {
 +
            "size": 2,
 +
            "used": 0.16368598397821188
 +
        },
 +
        },
 +
        ],
 +
        "metadata": {
 +
        "replication_contract": {
 +
        // We should use something more clear than just nova instance
 +
        // ids here but lets just use them for now for example. Maybe
 +
        // links? names? not sure what works best yet.
 +
        "dcc5c518-73c7-4471-83e1-15fae67a98eb": {
 +
        "replicates_to": [
 +
        "4530736b-c1ff-4c07-9a9f-fa9bca418157",
 +
        ],
 +
        "replicates_from": [
 +
        "736b9820-7e91-4775-84b0-78e71d60ce4c",
 +
        ],
 +
        "readable": True,
 +
        "writeable": True,
 +
        },
 +
        "4530736b-c1ff-4c07-9a9f-fa9bca418157": {
 +
        "replicates_to": [
 +
        "736b9820-7e91-4775-84b0-78e71d60ce4c",
 +
        ],
 +
        "replicates_from": [
 +
        "dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
        ],
 +
        "readable": True,
 +
        "writeable": True,
 +
        },
 +
        "736b9820-7e91-4775-84b0-78e71d60ce4c": {
 +
        "replicates_to": [
 +
        "dcc5c518-73c7-4471-83e1-15fae67a98eb",
 +
        ],
 +
        "replicates_from": [
 +
        "4530736b-c1ff-4c07-9a9f-fa9bca418157",
 +
        ],
 +
        "readable": True,
 +
        "writeable": True
 +
        }
 +
        }
 +
        }
 +
    }
 +
}
 +
</pre>
 +
 
=Clustering and Replication=
 
=Clustering and Replication=
 
A cluster is an independent service type.
 
A cluster is an independent service type.
Line 45: Line 258:
 
<pre>
 
<pre>
 
{
 
{
"metadata" {
+
"metadata": {
 
"nodes": 3
 
"nodes": 3
 
}
 
}

Revision as of 00:31, 10 October 2013

Instance Object Changes

Part of this proposal includes adding new properties to the json structure of an instance. The first would be to add a "nodes" property which would be list of refs back to the nova instance(s) that make up the trove instance.

The second would be a metadata storage that is of an open format to be used for storing critical data that is pertinent to the trove instance.

INSTANCES

Nodes

Because trove instances are a service type with an underlying nova resource(s) we can better display the nova resource(s) that make up the instance of a service type. When looking at a singular trove instance of something like redis or mysql the knowledge of the instance resource isn't all that important. Currently trove knows about the instance from a nova perspective but masks most of this information. This would look something like this:

GET /instances/{id}

{
    "instance": {
        "created": "2013-05-08T22:43:34",
        "hostname": "e09ad9a3f73309469cf1f43d11e79549caf9acf2.rackspaceclouddb.com",
        "id": "dcc5c518-73c7-4471-83e1-15fae67a98eb",
        "name": "json_rack_instance",
        "status": "ACTIVE",
        "updated": "2013-05-08T22:43:34",
        "service_type": "mysql-5.1",
        "nodes": [
        	{
        		"flavor": {
            		"id": "1", 
            		"links": [
                		{
                    		"href": "https://service/v1.0/1234/flavors/1", 
                    		"rel": "self"
                		},
                		{
                    		"href": "https://service/flavors/1", 
                    		"rel": "bookmark"
                		}
            		]
        		},
        		"links": [
            		{
                		"href": "https://service/v1.0/1234/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb", 
                		"rel": "self"
            		}, 
            		{
                		"href": "https://service/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb", 
                		"rel": "bookmark"
            		}
        		],
        		"volume": {
            		"size": 2,
            		"used": 0.16368598397821188
        		},
        	},
        ],
    }
}

Metadata

The metadata looks much like our previous proposal. It contains critical information to the configuration or topology of the cluster or replication agreement. This should look something like this:

GET /instances/{id}

{
    "instance": {
        "created": "2013-05-08T22:43:34",
        "id": "cfeccbf4-ac5b-494a-99b7-61593a6a71b0",
        "name": "multi-master-hotness",
        "status": "ACTIVE",
        "updated": "2013-05-08T22:43:34",
        "service_type": "mysql-5.5",
        "nodes": [
        	{
        		"id": "dcc5c518-73c7-4471-83e1-15fae67a98eb",
        		"hostname": "master-n01.example.com",
        		"flavor": {
            		"id": "1", 
            		"links": [
                		{
                    		"href": "https://service/v1.0/1234/flavors/1", 
                    		"rel": "self"
                		},
                		{
                    		"href": "https://service/flavors/1", 
                    		"rel": "bookmark"
                		}
            		]
        		},
        		"links": [
            		{
                		"href": "https://service/v1.0/1234/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb", 
                		"rel": "self"
            		}, 
            		{
                		"href": "https://service/instances/dcc5c518-73c7-4471-83e1-15fae67a98eb", 
                		"rel": "bookmark"
            		}
        		],
        		"volume": {
            		"size": 2,
            		"used": 0.16368598397821188
        		},
        	},
        	{
        		"id": "4530736b-c1ff-4c07-9a9f-fa9bca418157",
        		"hostname": "master-n02.example.com",
        		"flavor": {
            		"id": "1", 
            		"links": [
                		{
                    		"href": "https://service/v1.0/1234/flavors/1", 
                    		"rel": "self"
                		},
                		{
                    		"href": "https://service/flavors/1", 
                    		"rel": "bookmark"
                		}
            		]
        		},
        		"links": [
            		{
                		"href": "https://service/v1.0/1234/instances/4530736b-c1ff-4c07-9a9f-fa9bca418157", 
                		"rel": "self"
            		}, 
            		{
                		"href": "https://service/instances/4530736b-c1ff-4c07-9a9f-fa9bca418157", 
                		"rel": "bookmark"
            		}
        		],
        		"volume": {
            		"size": 2,
            		"used": 0.16368598397821188
        		},
        	},
        	{
        		"id": "736b9820-7e91-4775-84b0-78e71d60ce4c",
        		"hostname": "master-n03.example.com",
        		"flavor": {
            		"id": "1", 
            		"links": [
                		{
                    		"href": "https://service/v1.0/1234/flavors/1", 
                    		"rel": "self"
                		},
                		{
                    		"href": "https://service/flavors/1", 
                    		"rel": "bookmark"
                		}
            		]
        		},
        		"links": [
            		{
                		"href": "https://service/v1.0/1234/instances/736b9820-7e91-4775-84b0-78e71d60ce4c", 
                		"rel": "self"
            		}, 
            		{
                		"href": "https://service/instances/736b9820-7e91-4775-84b0-78e71d60ce4c", 
                		"rel": "bookmark"
            		}
        		],
        		"volume": {
            		"size": 2,
            		"used": 0.16368598397821188
        		},
        	},
        ],
        "metadata": {
        	"replication_contract": {
        		// We should use something more clear than just nova instance
        		// ids here but lets just use them for now for example. Maybe
        		// links? names? not sure what works best yet.
        		"dcc5c518-73c7-4471-83e1-15fae67a98eb": {
        			"replicates_to": [
        				"4530736b-c1ff-4c07-9a9f-fa9bca418157",
        			],
        			"replicates_from": [
        				"736b9820-7e91-4775-84b0-78e71d60ce4c",
        			],
        			"readable": True,
        			"writeable": True,
        		},
        		"4530736b-c1ff-4c07-9a9f-fa9bca418157": {
        			"replicates_to": [
        				"736b9820-7e91-4775-84b0-78e71d60ce4c",
        			],
        			"replicates_from": [
        				"dcc5c518-73c7-4471-83e1-15fae67a98eb",
        			],
        			"readable": True,
        			"writeable": True,
        		},
        		"736b9820-7e91-4775-84b0-78e71d60ce4c": {
        			"replicates_to": [
        				"dcc5c518-73c7-4471-83e1-15fae67a98eb",
        			],
        			"replicates_from": [
        				"4530736b-c1ff-4c07-9a9f-fa9bca418157",
        			],
        			"readable": True,
        			"writeable": True
        		}
        	}
        }
    }
}

Clustering and Replication

A cluster is an independent service type.

  • This simplifies the configurations (ties to service_type)
  • The guest impl can be different for each service_type
  • We don't need cluster type and service_type when defining a cluster


Think: A instance is an instance is a cluster is an instance is NOT replication

CLUSTERING

Definition of cluster for purposes of Trove:
A cluster must provide

  • High Availablility
  • Fault Tolerance


A cluster object is represented as an instance with a metadata attribute containing node information. A node is a sub-resource of a cluster and has a limited number of actions that can be performed on them. A cluster is made of of equal sized nodes using all the same flavor/disk size.

Cluster Operations

Create cluster:

Create a cluster with flavor X and size Y. All nodes are of equal size.
POST /instance

{
	"name": "foobar",
	"flavor": "{flavor_id}",
	"service_type": "{service_type_id}",
	"size": 50,
	"metadata": {
		"nodes": 5,
	}
}

Delete cluster:

  • Deletes all nodes in the cluster and the cluster itself.

DELETE /instance/{id}

Downsize a cluster (Delete nodes): PATCH /instance/{id}

{
	"metadata": {
		"nodes": 3
	}
}

Restart a cluster:

POST /instance/{id}/restart

{
	"empty body?"
}

Resize a cluster:

POST /instance/{id}/resize

{
	"flavor": "flavor_id",
	"volume": {
		"size": 100
	}
}

Initialize cluster:

POST /instance/{id}/initialize

{
	"pertinent data should go here..."
}

Rebalance/restripe cluster:

POST /instance/{id}/rebalance

{
	"pertinent data goes here"
}

Node Operations:

Restart a node:

POST /instance/{id}/node/{id}/restart

{
	"empty body?"
}

Initialize a node:

POST /instance/{id}/node/{id}/initialize

{
	"empty body?"
}


REPLICATION

We think of replication as a capability of some service types. Not every service type will have this capability and it should be configurable via the service types capabilities feature.

What you cannot do: - create a master and slave in one call - one call per action means simplified workflow


Replication workflow: 1. Create an instance 2. Create an Nth instance with - metadata {"master_instance": "id from 1", "replication_type": "typeid from replication_types api"} - Caveat: adding a replicated slave will alter data on the master instance and will use the agent to create the replication.

Replication Operations

Create Replication:

POST /instance

{
	"name": "foobar",
	"flavor": "flavor_id",
	"service_type": "mysql-5.1",
	"size": 50,
	"metadata": {
		"replication_type": "replication_type_id",
		"replication_data": {
			"master_instance": "instance_uuid"
		}
	}
}