Andrey's answer above is the most correct - the 'load balancing' is just DNS randomly picking on of the servers in the cluster. This results in the connections being very lopsided most of the time, if you are using the RO-cluster endpoint in conjunction with connection pooling, which most people are.
I recently opened a ticket with AWS support center and was pointed towards this 'smart driver' solution. I think the original post was looking for a way to keep the connections load-balanced.
There is a table in Aurora INFORMATION_SCHEMA that you can use to get the servers in your readonly cluster. Then you can make a connection string with those servers, and do the round-robin yourself.
EDIT: I updated my 1-line sql with something similar to the C# function we use to implement this. It returns the updated connection string.
public static string UpdateReadOnlyConnectionString()
{
List<string> hostList = new List<string>();
string connectionStringOrig = "Data Source=cluster-ro-endpoint;Initial Catalog=mydb;";
builder = new MySqlConnectionStringBuilder(connectionStringOrig);
// MySqlHelper.GetPreparedStatement gets a command with the main RDS cluster connections string.
using (MySqlCommand cmd = MySqlHelper.GetPreparedStatement("SELECT rhs.SERVER_ID FROM INFORMATION_SCHEMA.REPLICA_HOST_STATUS rhs " +
"WHERE rhs.SESSION_ID <> 'MASTER_SESSION_ID'"))
{
// simplifying from my wrapper classes, you get the idea
using (MySqlConnector.MySqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
string host = reader.GetString("SERVER_ID");
// this is a map between the SERVER_ID and the endpoint
string server = AuroraEndpoints[host].ServerEndpoint;
hostList.Add(server);
}
}
}
builder.Server = string.Join(",", hostList);
return builder.ConnectionString;
}
this will give you a live snapshot of the servers in the read-only cluster. We are using MySqlConnector drivers that will take a list of endpoints in the connection string and balance connections between those. If your driver doesn't have this capability, you can just pick one at random for each connection. You will need to either construct the endpoints from the instance ID or map them manually, and use them in the connection string instead of the ro cluster endpoint (you still use the primary cluster endpoint for the writer node).
You need to continue to monitor the REPLICA_HOST_STATUS table. If the set of readers changes due to a failover, or any other reason, we clear the connection pool so any new commands get a connection from the current set of readers.
I have tried this and it does result in the number of connections being balanced. It does not balance the actual load, but in our case the number of web connections follow the load. You could use the IOS or CPU columns in that same table to add true performance load balancing, to taste.
I realize this is 5 years after OP question, but this seems the most relevant and recent post that I can find, and I was not able to find this solution easily until AWS pointed me to it. I also found these similar questions, older and not as concisely asked:
Amazon Aurora DB Cluster Not Auto Balancing Correctly and AWS Aurora - load balance read operation between read replica and writer instance.