Skip to content

docs:通过 RDS 读写分离提升数据库性能 #342

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
## Introduction

<!-- DOCS_DESCRIPTION_CN -->
本示例用于实现解决方案[RDS 通过代理组件实现读写分离](https://www.aliyun.com/solution/tech-solution/read-write-splitting-through-rds-proxy), 涉及到专有网络(VPC)、交换机(VSwitch)、云服务器(ECS)、云数据库(RDS MySQL) 等资源的创建。
<!-- DOCS_DESCRIPTION_CN -->

<!-- DOCS_DESCRIPTION_EN -->
This example demonstrates the implementation of the solution [Read write splitting through RDS proxy](https://www.aliyun.com/solution/tech-solution/read-write-splitting-through-rds-proxy). It involves the creation, and deployment of resources such as Virtual Private Cloud (VPC), VSwitch, Elastic Compute Service (ECS), and ApsaraDB RDS for MySQL.
<!-- DOCS_DESCRIPTION_EN -->

<!-- BEGIN_TF_DOCS -->
## Providers

| Name | Version |
|------|---------|
| <a name="provider_alicloud"></a> [alicloud](#provider\_alicloud) | n/a |
| <a name="provider_random"></a> [random](#provider\_random) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [alicloud_db_account.db_account](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_account) | resource |
| [alicloud_db_account_privilege.account_privilege](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_account_privilege) | resource |
| [alicloud_db_database.rds_database](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_database) | resource |
| [alicloud_db_instance.database](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_instance) | resource |
| [alicloud_db_readonly_instance.readonly_instance](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/db_readonly_instance) | resource |
| [alicloud_ecs_command.install_script](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_command) | resource |
| [alicloud_ecs_invocation.run_install](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/ecs_invocation) | resource |
| [alicloud_instance.ecs_instance](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/instance) | resource |
| [alicloud_rds_db_proxy.db_proxy](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/rds_db_proxy) | resource |
| [alicloud_security_group.security_group](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group) | resource |
| [alicloud_security_group_rule.allow_http](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/security_group_rule) | resource |
| [alicloud_vpc.vpc](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vpc) | resource |
| [alicloud_vswitch.vswitch1](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [alicloud_vswitch.vswitch2](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/resources/vswitch) | resource |
| [random_id.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
| [alicloud_db_instance_classes.example](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/db_instance_classes) | data source |
| [alicloud_db_zones.rds_zones](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/db_zones) | data source |
| [alicloud_images.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/images) | data source |
| [alicloud_instance_types.default](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/instance_types) | data source |
| [alicloud_regions.current](https://registry.terraform.io/providers/aliyun/alicloud/latest/docs/data-sources/regions) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_db_name"></a> [db\_name](#input\_db\_name) | 请输入数据库名称(由小写字母、数字及特殊字符 -\_ 组成,以字母开头,字母或数字结尾,最多64个字符)。 | `string` | `"db_test"` | no |
| <a name="input_db_password"></a> [db\_password](#input\_db\_password) | 请输入RDS数据库密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()\_+-=)。 | `string` | n/a | yes |
| <a name="input_db_user_name"></a> [db\_user\_name](#input\_db\_user\_name) | 请输入RDS数据库用户名(长度为2-16个字符,仅允许小写字母、数字和下划线,必须以字母开头,以字母或数字结尾)。 | `string` | `"testuser"` | no |
| <a name="input_ecs_instance_password"></a> [ecs\_instance\_password](#input\_ecs\_instance\_password) | 请输入服务器登录密码。密码长度为8-30位,必须包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*\_-+=\|{}[]:;'<>,.?/)。 | `string` | n/a | yes |
| <a name="input_region_id"></a> [region\_id](#input\_region\_id) | 请输入地域ID(例如:cn-hangzhou)。 | `string` | `"cn-hangzhou"` | no |
| <a name="input_vpc_cidr_block"></a> [vpc\_cidr\_block](#input\_vpc\_cidr\_block) | 请输入VPC的CIDR块(支持的值包括:192.168.0.0/16、172.16.0.0/12、10.0.0.0/8)。这是您的虚拟私有云的地址范围。 | `string` | `"192.168.0.0/16"` | no |
| <a name="input_vswitch1_cidr_block"></a> [vswitch1\_cidr\_block](#input\_vswitch1\_cidr\_block) | 请输入主交换机的CIDR块(例如:192.168.1.0/24)。这是您主虚拟交换机的地址范围。 | `string` | `"192.168.1.0/24"` | no |
| <a name="input_vswitch2_cidr_block"></a> [vswitch2\_cidr\_block](#input\_vswitch2\_cidr\_block) | 请输入备交换机的CIDR块(例如:192.168.2.0/24)。这是您备虚拟交换机的地址范围。 | `string` | `"192.168.2.0/24"` | no |
<!-- END_TF_DOCS -->
177 changes: 177 additions & 0 deletions solution/tech-solution/read-write-splitting-through-rds-proxy/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
provider "alicloud" {
region = var.region_id
}

resource "random_id" "suffix" {
byte_length = 8
}

locals {
zone_id_1 = data.alicloud_db_zones.rds_zones.zones[length(data.alicloud_db_zones.rds_zones.zones) - 1].id
zone_id_2 = data.alicloud_db_zones.rds_zones.zones[length(data.alicloud_db_zones.rds_zones.zones) - 2].id
common_name = random_id.suffix.id
install_script = <<SCRIPT
#!/bin/sh
export ROS_DEPLOY=true
curl -fsSL https://static-aliyun-doc.oss-cn-hangzhou.aliyuncs.com/install-script/read-write-splitting-for-databases/install.sh | bash

SCRIPT
}

data "alicloud_db_zones" "rds_zones" {
engine = "MySQL"
engine_version = "8.0"
instance_charge_type = "PostPaid"
category = "HighAvailability"
db_instance_storage_type = "cloud_essd"

}
data "alicloud_db_instance_classes" "example" {
zone_id = local.zone_id_1
engine = data.alicloud_db_zones.rds_zones.engine
engine_version = data.alicloud_db_zones.rds_zones.engine_version
category = data.alicloud_db_zones.rds_zones.category
db_instance_storage_type = data.alicloud_db_zones.rds_zones.db_instance_storage_type
instance_charge_type = data.alicloud_db_zones.rds_zones.instance_charge_type
}

data "alicloud_instance_types" "default" {
cpu_core_count = 4
system_disk_category = "cloud_essd"
image_id = data.alicloud_images.default.images[0].id
instance_type_family = "ecs.c6"
availability_zone = local.zone_id_1
}

data "alicloud_images" "default" {
name_regex = "^aliyun_3_x64_20G_alibase_*"
most_recent = true
owners = "system"
}

# VPC Resources
resource "alicloud_vpc" "vpc" {
vpc_name = "vpc"
cidr_block = var.vpc_cidr_block
}

# VSwitch Resources
resource "alicloud_vswitch" "vswitch1" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = var.vswitch1_cidr_block
zone_id = local.zone_id_1
vswitch_name = "vsw_001"
}

resource "alicloud_vswitch" "vswitch2" {
vpc_id = alicloud_vpc.vpc.id
cidr_block = var.vswitch2_cidr_block
zone_id = local.zone_id_2
vswitch_name = "vsw_002"
}

# Security Group
resource "alicloud_security_group" "security_group" {
vpc_id = alicloud_vpc.vpc.id
security_group_name = "sg"
security_group_type = "normal"
}

resource "alicloud_security_group_rule" "allow_http" {
type = "ingress"
ip_protocol = "tcp"
port_range = "80/80"
cidr_ip = "140.205.11.1/25"
security_group_id = alicloud_security_group.security_group.id
}

# ECS Resources
resource "alicloud_instance" "ecs_instance" {
instance_name = "ecs-${local.common_name}"
system_disk_category = data.alicloud_instance_types.default.system_disk_category
system_disk_size = 40
image_id = data.alicloud_images.default.images[0].id
vswitch_id = alicloud_vswitch.vswitch1.id
password = var.ecs_instance_password
instance_type = data.alicloud_instance_types.default.instance_types[0].id
internet_max_bandwidth_out = 5
security_groups = [alicloud_security_group.security_group.id]
}

# RDS Resources
resource "alicloud_db_instance" "database" {
engine = data.alicloud_db_instance_classes.example.engine
engine_version = data.alicloud_db_instance_classes.example.engine_version
instance_type = data.alicloud_db_instance_classes.example.instance_classes[0].instance_class
instance_storage = data.alicloud_db_instance_classes.example.instance_classes[0].storage_range.min
instance_name = "rds-${local.common_name}"
vswitch_id = alicloud_vswitch.vswitch1.id
monitoring_period = 60
zone_id = local.zone_id_1
zone_id_slave_a = local.zone_id_2
category = data.alicloud_db_instance_classes.example.category
security_group_ids = [alicloud_security_group.security_group.id]
}

resource "alicloud_db_database" "rds_database" {
instance_id = alicloud_db_instance.database.id
name = var.db_name
character_set = "utf8"
}

resource "alicloud_db_account" "db_account" {
db_instance_id = alicloud_db_instance.database.id
account_name = var.db_user_name
account_password = var.db_password
account_type = "Normal"
}

resource "alicloud_db_account_privilege" "account_privilege" {
instance_id = alicloud_db_instance.database.id
account_name = alicloud_db_account.db_account.account_name
privilege = "ReadWrite"
db_names = [alicloud_db_database.rds_database.name]
depends_on = [alicloud_db_database.rds_database]
}

# RDS DB Proxy
resource "alicloud_rds_db_proxy" "db_proxy" {
instance_id = alicloud_db_instance.database.id
db_proxy_instance_type = "common"
vpc_id = alicloud_vpc.vpc.id
vswitch_id = alicloud_vswitch.vswitch1.id
db_proxy_features = "ReadWriteSplitting"
instance_network_type = "VPC"
db_proxy_instance_num = 2
depends_on = [alicloud_db_account_privilege.account_privilege]
}

resource "alicloud_db_readonly_instance" "readonly_instance" {
master_db_instance_id = alicloud_db_instance.database.id
zone_id = local.zone_id_2
vswitch_id = alicloud_vswitch.vswitch2.id
instance_type = "mysqlro.n2.medium.1c"
instance_storage = alicloud_db_instance.database.instance_storage
instance_name = "readonly-${local.common_name}"
engine_version = alicloud_db_instance.database.engine_version
depends_on = [alicloud_rds_db_proxy.db_proxy]
}

# ECS Command
resource "alicloud_ecs_command" "install_script" {
name = "install-${local.common_name}"
command_content = base64encode(local.install_script)
description = "Install read-write splitting application"
type = "RunShellScript"
working_dir = "/root"
timeout = 3600
}

resource "alicloud_ecs_invocation" "run_install" {
command_id = alicloud_ecs_command.install_script.id
instance_id = [alicloud_instance.ecs_instance.id]
depends_on = [alicloud_db_readonly_instance.readonly_instance]
timeouts {
create = "15m"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Outputs
output "ecs_login_address_1" {
description = "ECS登录地址"
value = "https://ecs-workbench.aliyun.com/?from=EcsConsole&instanceType=ecs&regionId=${data.alicloud_regions.current.regions.0.id}&instanceId=${alicloud_instance.ecs_instance.id}"
}

data "alicloud_regions" "current" {
current = true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
variable "region_id" {
description = "请输入地域ID(例如:cn-hangzhou)。"
default = "cn-hangzhou"
}

variable "vpc_cidr_block" {
description = "请输入VPC的CIDR块(支持的值包括:192.168.0.0/16、172.16.0.0/12、10.0.0.0/8)。这是您的虚拟私有云的地址范围。"
default = "192.168.0.0/16"
validation {
condition = contains(["192.168.0.0/16", "172.16.0.0/12", "10.0.0.0/8"], var.vpc_cidr_block)
error_message = "无效的VPC CIDR块,请检查并重新输入。"
}
}

variable "vswitch1_cidr_block" {
description = "请输入主交换机的CIDR块(例如:192.168.1.0/24)。这是您主虚拟交换机的地址范围。"
default = "192.168.1.0/24"
}

variable "vswitch2_cidr_block" {
description = "请输入备交换机的CIDR块(例如:192.168.2.0/24)。这是您备虚拟交换机的地址范围。"
default = "192.168.2.0/24"
}

variable "ecs_instance_password" {
description = "请输入服务器登录密码。密码长度为8-30位,必须包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*_-+=|{}[]:;'<>,.?/)。"
type = string
sensitive = true
}

variable "db_name" {
description = "请输入数据库名称(由小写字母、数字及特殊字符 -_ 组成,以字母开头,字母或数字结尾,最多64个字符)。"
default = "db_test"
validation {
condition = regex("^[a-z][a-z0-9-_]{0,62}[a-z0-9]$", var.db_name) != ""
error_message = "数据库名称格式不正确。名称应由小写字母、数字及特殊字符 -_ 组成,以字母开头,字母或数字结尾,最多64个字符。"
}
}

variable "db_user_name" {
description = "请输入RDS数据库用户名(长度为2-16个字符,仅允许小写字母、数字和下划线,必须以字母开头,以字母或数字结尾)。"
type = string
default = "testuser"
validation {
condition = can(regex("^[a-zA-Z][a-zA-Z0-9_]{0,30}[a-zA-Z0-9]$", var.db_user_name))
error_message = "数据库用户名必须以字母开头,以字母或数字结尾,只能包含字母、数字和下划线。最多32个字符。"
}
}

variable "db_password" {
description = "请输入RDS数据库密码。密码长度为8-32位,需包含大写字母、小写字母、数字和特殊字符(如:!@#$%^&*()_+-=)。"
type = string
sensitive = true
}
Loading