# rds-rwsplit

Part of **RDS**

# ApsaraDB RDS Read/Write Splitting

## Capabilities Overview

| Sub-capability | Calling Mode | Description |
|----------------|--------------|-------------|
| Apply for a read/write splitting endpoint | Synchronous | Applies for a read/write splitting endpoint for an ApsaraDB RDS instance with configurable network type, port, latency threshold, and read weights. |
| Modify read weights and latency threshold | Synchronous | Updates the read weight distribution method, read weights, and latency threshold for an existing read/write splitting configuration. |
| Query system-assigned read weights | Synchronous | Retrieves the system-calculated read weights for the primary instance and its read-only instances when using automatic (Standard) distribution. |
| Release the read/write splitting endpoint | Synchronous | Releases (deletes) the read/write splitting endpoint associated with an RDS instance. |

## API Calling Patterns

### Authentication
Use **Alibaba Cloud AccessKey-based signature authentication** as the primary method.

- Include common request parameters in every API call: `AccessKeyId`, `Signature`, `SignatureMethod`, `SignatureVersion`, `Timestamp`, and `Format`.
- The `Signature` is computed using your `AccessKeySecret` following the [Alibaba Cloud signature algorithm](https://help.aliyun.com/document_detail/25492.html).
- Store credentials securely using environment variables:
  ```bash
  export ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
  export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret
  ```

> **Note**: While some examples show a Bearer token header, the official and recommended method for RDS APIs is signature-based authentication with common request parameters.

### Service Endpoint (Endpoint)
All Read/Write Splitting APIs use a single global endpoint:

- Base URL: `https://rds.aliyuncs.com`
- Method: `GET` (parameters passed as query string)
- Region: The endpoint is region-agnostic; specify the target RDS instance’s region via the `RegionId` common request parameter (e.g., `cn-hangzhou`, `cn-shanghai`, `cn-beijing`).

### Synchronous API Pattern
All operations follow a simple synchronous request-response flow:

1. Construct a GET request to `https://rds.aliyuncs.com` with:
   - Required action-specific parameters (e.g., `Action=AllocateReadWriteSplittingConnection`)
   - Common request parameters (`AccessKeyId`, `Signature`, etc.)
2. Send the request.
3. Receive an immediate JSON response with a `RequestId` (or `RequestID`) on success.
4. Handle errors using standard HTTP status codes and error messages.

No polling or streaming is involved—each call completes in one round trip.

## Parameter Reference

### Apply for a read/write splitting endpoint (`AllocateReadWriteSplittingConnection`)

| Parameter | Type | Required | Default | Constraints | Description |
|----------|------|----------|---------|-------------|-------------|
| Action | String | Yes | — | Must be `AllocateReadWriteSplittingConnection` | The API operation to perform. |
| DBInstanceId | String | Yes | — | Valid RDS instance ID | The ID of the primary RDS instance. |
| ConnectionStringPrefix | String | No | `<instance_name>-rw` | 1–30 chars, lowercase letters and hyphens only, starts with letter | Prefix for the read/write splitting endpoint. |
| Port | String | No | `1433` | Integer between 1000–5999 | Port number for the endpoint. |
| MaxDelayTime | String | No | `30` | Integer between 0–7200 (seconds) | Latency threshold for routing reads to replicas. |
| NetType | String | No | `Intranet` | `Internet` or `Intranet` | Network accessibility of the endpoint. |
| DistributionType | String | No | `Standard` | `Standard` or `Custom` | Weight assignment method: automatic or manual. |
| Weight | String | No | — | Multiples of 100, max 10000; JSON format | Read weights for instances (required if `DistributionType=Custom`). |

### Modify read weights and latency threshold (`ModifyReadWriteSplittingConnection`)

| Parameter | Type | Required | Default | Constraints | Description |
|----------|------|----------|---------|-------------|-------------|
| Action | String | Yes | — | Must be `ModifyReadWriteSplittingConnection` | The API operation to perform. |
| DBInstanceId | String | Yes | — | Valid RDS instance ID | The ID of the primary RDS instance. |
| ConnectionStringPrefix | String | No | — | Same as above | Endpoint prefix (if changing). |
| Port | String | No | `3306` | 1000–5999 | New port (if changing). |
| MaxDelayTime | String | No | — | 0–7200 seconds | New latency threshold. |
| DistributionType | String | No | — | `Standard` or `Custom` | New weight distribution method. |
| Weight | String | No | — | Multiples of 100, max 10000 | New read weights (if `Custom`). |

### Query system-assigned read weights (`CalculateDBInstanceWeight`)

| Parameter | Type | Required | Default | Constraints | Description |
|----------|------|----------|---------|-------------|-------------|
| Action | String | Yes | — | Must be `CalculateDBInstanceWeight` | The API operation to perform. |
| DBInstanceId | String | Yes | — | Valid RDS instance ID | The ID of the primary RDS instance. |

### Release the read/write splitting endpoint (`ReleaseReadWriteSplittingConnection`)

| Parameter | Type | Required | Default | Constraints | Description |
|----------|------|----------|---------|-------------|-------------|
| Action | String | Yes | — | Must be `ReleaseReadWriteSplittingConnection` | The API operation to perform. |
| DBInstanceId | String | Yes | — | Valid RDS instance ID | The ID of the primary RDS instance. |

## Code Examples

### Apply for Endpoint - Bash - All Regions

```bash
curl -X GET "https://rds.aliyuncs.com/?Action=AllocateReadWriteSplittingConnection&DBInstanceId=rm-uf6wjk5xxxxxxx&ConnectionStringPrefix=rr-m5exxxxx-rw&Port=1433&MaxDelayTime=30&NetType=Intranet&DistributionType=Standard&Weight=%7B%22rm-bp1**********%22%3A800%2C%22master%22%3A400%2C%22slave%22%3A400%7D&RegionId=cn-hangzhou&AccessKeyId=YOUR_ACCESS_KEY_ID&Signature=YOUR_SIGNATURE&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&Timestamp=2024-06-01T12%3A00%3A00Z&Format=JSON"
```

### Modify Weights - Python - cn-hangzhou

```python
from aliyunsdkcore.client import AcsClient
from aliyunsdkrds.request.v20140815 import ModifyReadWriteSplittingConnectionRequest

client = AcsClient(
    access_key_id='YOUR_ACCESS_KEY_ID',
    access_key_secret='YOUR_ACCESS_KEY_SECRET',
    region_id='cn-hangzhou'
)

request = ModifyReadWriteSplittingConnectionRequest.ModifyReadWriteSplittingConnectionRequest()
request.set_DBInstanceId('rm-uf6wjk5xxxxxxx')
request.set_DistributionType('Custom')
request.set_Weight('{"rm-bp1...": 1000, "master": 500}')

response = client.do_action_with_exception(request)
print(response)
```

### Query System Weights - Bash - All Regions

```bash
curl -X GET "https://rds.aliyuncs.com/?Action=CalculateDBInstanceWeight&DBInstanceId=rm-uf6wjk5xxxxxxx&RegionId=cn-shanghai&AccessKeyId=YOUR_ACCESS_KEY_ID&Signature=YOUR_SIGNATURE&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&Timestamp=2024-06-01T12%3A00%3A00Z&Format=JSON"
```

### Release Endpoint - Java - cn-beijing

```java
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.rds.model.v20140815.ReleaseReadWriteSplittingConnectionRequest;
import com.aliyuncs.rds.model.v20140815.ReleaseReadWriteSplittingConnectionResponse;

public class ReleaseRWSplitting {
    public static void main(String[] args) throws ClientException {
        DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", "YOUR_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_SECRET");
        IAcsClient client = new DefaultAcsClient(profile);

        ReleaseReadWriteSplittingConnectionRequest request = new ReleaseReadWriteSplittingConnectionRequest();
        request.setDBInstanceId("rm-uf6wjk5xxxxxxx");

        ReleaseReadWriteSplittingConnectionResponse response = client.getAcsResponse(request);
        System.out.println("RequestID: " + response.getRequestId());
    }
}
```

## Response Format

```json
{
  "RequestId": "4C467B38-3910-447D-87BC-AC049166F216"
}
```

**Key Fields**:
- `RequestId` — Unique identifier for the API request; useful for troubleshooting with Alibaba Cloud support.

For `CalculateDBInstanceWeight`, the response includes additional data:

```json
{
  "RequestId": "4139E1C3-0480-5A50-B327-23E6B1028906",
  "Items": {
    "DBInstanceWeight": [
      {
        "Role": "master",
        "DBInstanceId": "******",
        "DBInstanceType": "Readonly",
        "Weight": "400"
      },
      {
        "Role": "master",
        "DBInstanceId": "******",
        "DBInstanceType": "Master",
        "Weight": "0"
      }
    ]
  }
}
```

**Key Fields**:
- `Items.DBInstanceWeight[].Role` — Role of the instance (`master` or `slave`)
- `Items.DBInstanceWeight[].DBInstanceId` — Instance ID
- `Items.DBInstanceWeight[].DBInstanceType` — `Master` or `Readonly`
- `Items.DBInstanceWeight[].Weight` — Assigned read weight (string)

## Error Handling

| Error Code | Description | Recommended Action |
|------------|-------------|---------------------|
| 400 | Invalid parameter provided. Check the request parameters and ensure they are valid and correctly formatted. | Validate all parameters against constraints (e.g., port range, weight format). |
| 400 | ReadDBInstance.NotFound: No read-only instances are attached to the instance. | Ensure at least one read-only instance is linked to the primary before enabling read/write splitting. |
| 403 | Access denied. Ensure the user has sufficient permissions to perform this operation. | Attach the `AliyunRDSFullAccess` policy or a custom policy with required RDS actions. |
| 404 | Resource not found. Verify the DBInstanceId exists and is in the Running state. | Confirm the instance ID and that the instance is active. |
| 500 | Internal server error. Retry the request after a short delay. | Implement exponential backoff and retry up to 3 times. |

### Rate Limits & Retry
- `CalculateDBInstanceWeight`: 100 QPS per account.
- `ReleaseReadWriteSplittingConnection`: Up to 10 requests per second.
- General guidance: Use exponential backoff (e.g., 1s, 2s, 4s delays) on 5xx errors. No `Retry-After` header is used.

## Requirements

- Python SDK: `pip install aliyun-python-sdk-rds>=2.1.0`
- Java SDK: `com.aliyun:aliyun-java-sdk-rds:latest`
- Environment setup:
  ```bash
  export ALIBABA_CLOUD_ACCESS_KEY_ID=your_key_id
  export ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_key_secret
  ```

## FAQ

Q: Can I use read/write splitting without read-only instances?
A: No. You must have at least one read-only instance attached to the primary RDS instance before applying for a read/write splitting endpoint.

Q: What’s the difference between `Standard` and `Custom` distribution types?
A: `Standard` lets the system automatically assign read weights based on instance specifications. `Custom` allows you to manually define weights for each instance in JSON format.

Q: Why do I get a 400 error when setting `Weight`?
A: The `Weight` parameter must be a JSON string with values that are multiples of 100 (e.g., `"400"`), and the format varies by instance type. Ensure proper URL encoding when passing in GET requests.

Q: Is the endpoint region-specific?
A: The API endpoint (`rds.aliyuncs.com`) is global, but you must specify the RDS instance’s region using the `RegionId` common parameter.

Q: How long does it take for weight changes to take effect?
A: Changes made via `ModifyReadWriteSplittingConnection` take effect immediately; no restart or propagation delay is required.

## Pricing & Billing

### Billing Model
Per-request billing: Each API call counts as one request, regardless of success or failure.

### Price Reference

| Tier | Input Price | Output Price |
|------|-------------|--------------|
| standard | ¥0.001 per request | ¥0.001 per request |
| default (query) | ¥0.0001 per request | ¥0.0001 per request |

### Free Tier
- `CalculateDBInstanceWeight`: 1000 free requests per month for new accounts.
- Other operations: No free tier.

### Usage Limits
- `CalculateDBInstanceWeight`: 100 QPS per account.
- `ReleaseReadWriteSplittingConnection`: 10 requests per second.
- General: 100 requests per minute per account (as noted in pricing notes).

### Billing Notes
Each API call is billed individually. Charges apply even if the response contains an error or is empty. Monitor usage via the Alibaba Cloud billing console.