
# TaurusDB数据库代理简介
数据库代理是TaurusDB和应用服务之间的网络层服务，用于转发应用服务访问TaurusDB的所有请求。
创建TaurusDB实例后，您可以[开通数据库代理](https://support.huaweicloud.com/usermanual-taurusdb/taurusdb_11_0017.html)，通过代理地址实现读写请求的自动转发。写请求自动访问主节点，读请求按照数据库代理的路由模式分发到各个节点，降低主节点的负载。
**数据库代理服务暂不收费。**
#### 介绍视频
<video controls="controls" preload="none" id="object3321174494711" class="idp-external-video" src="https://res-video.hc-cdn.com/cloudbu-site/china/zh-cn/support/taurusdb-video/1729242716260846965.mp4" title="读写分离介绍" poster="https://support.huaweicloud.com/usermanual-taurusdb/figure/zh-cn_image_0000002310619000.jpg" style="width:100%;height:auto;max-width:600px"></video>
#### 基本概念
#### 代理地址
购买数据库代理后，可以从数据库代理中查看代理地址，连接该地址可以执行读写操作，数据库代理会通过代理地址自动将写请求发送到主节点，将读请求发送到只读节点，降低主节点的压力。
#### 代理模式
TaurusDB的代理模式支持读写模式、TP只读模式和AP只读模式，每种模式的读写属性处理逻辑不同，详情请参见[表1]。
- **读写模式：**所有写请求只发往主节点，所有读请求按照读权重配比或活跃连接数情况分发到已选节点。
- **TP只读模式：**所有读请求按照读权重配比或活跃连接数情况分发到已选只读节点，不会分发到主节点。
- **AP只读模式** （公测）：所有读请求按照读权重配比分发到已选只读节点和HTAP节点。
  ![](https://support.huaweicloud.com/usermanual-taurusdb/public_sys-resources/note_3.0-zh-cn.png)
  AP只读模式目前是公测阶段，如需使用，请[提交工单](https://console.huaweicloud.com/ticket/?locale=zh-cn#/ticketindex/createIndex)。
  
 表1数据库代理读写属性处理逻辑 
| 数据库代理模式    | 路由模式                                                                                                             | 主节点权重     | 正常情况                                                                    | 只读节点全部故障                                                             |
|:---|:---|:---|:---|:---|
| 读写模式       | 负载均衡 可用区就近负载                                                      | 系统分配      | 主节点：可读可写 代理地址：可读可写        | 主节点：可读可写 代理地址：可读可写    |
| 读写模式       | 权重负载                                                                                                             | \> 0      | 主节点：可读可写 代理地址：可读可写       | 主节点：可读可写 代理地址：可读可写     |
| 读写模式       | 权重负载                                                                                                             | = 0       | 主节点：不可读可写 代理地址：可读可写      | 主节点：可读可写 代理地址：可读可写   |
| TP只读模式     | 权重负载 负载均衡 可用区就近负载 | 主节点权重不可设置 | 主节点：不处理只读请求 代理地址：可读不可写   | 主节点：不处理只读请求 代理地址：连接报错   |
| AP只读模式（公测） | 权重负载                                                                                                             | 主节点权重不可设置 | 主节点：不处理只读请求 代理地址：可读不可写 | 主节点：不处理只读请求 代理地址：连接报错 |
   
#### 事务拆分
数据库代理提供事务拆分功能，能够将事务内写操作之前的读请求转发到只读节点，降低主节点负载。
更多关于事务拆分的内容请参见[开启TaurusDB代理的事务拆分功能](https://support.huaweicloud.com/usermanual-taurusdb/taurusdb_11_0030.html)。
#### 连接池
数据库代理提供会话级连接池功能，可减少短连接业务频繁建立连接导致数据库负载高的问题。
更多关于连接池的内容请参见[开启TaurusDB代理的连接池功能](https://support.huaweicloud.com/usermanual-taurusdb/taurusdb_11_0048.html)。
#### 路由模式
TaurusDB数据库代理支持权重负载、负载均衡和可用区就近负载的路由模式，可根据需要配置不同的路由模式。
- 权重负载：根据您设置的读权重比例分发读请求。
- 负载均衡：根据数据库节点的活跃连接数情况进行读请求分发，将读请求分发到活跃连接数较少的节点上。负载均衡模式不需要修改权重。
- 可用区就近负载：根据可用区匹配，代理节点将读请求优先分发到同一可用区的数据库节点。该模式下建议数据库代理与TaurusDB节点设置在同一可用区，降低分发延迟。
更多关于路由模式的内容请参见[路由模式](https://support.huaweicloud.com/usermanual-taurusdb/taurusdb_11_0053.html)。
#### 读写分离原理
TaurusDB支持开通一个或多个数据库代理。
- [单个数据库代理下的读写分离]
  一个TaurusDB实例下默认只有1个数据库代理实例，应用服务通过数据库代理地址连接到数据库代理实例，写请求通过数据库代理实例自动转发到主节点，读请求根据数据库代理实例的路由模式转发至主节点或只读节点。
  图1单个数据库代理读写分离原理图   
  ![](https://support.huaweicloud.com/usermanual-taurusdb/figure/zh-cn_image_0000002299596037.png)
- [多个数据库代理下的读写分离]
  一个TaurusDB实例下可以创建多个数据库代理实例，最多支持创建4个，主要适用于有隔离需求的复杂业务。不同的应用服务可以根据业务需要连接不同的数据库代理，数据库代理连接指定的只读节点，将不同应用服务之间的读请求最终转发到不同的只读节点上，实现业务隔离。
  图2多个数据库代理读写分离   
  ![](https://support.huaweicloud.com/usermanual-taurusdb/figure/zh-cn_image_0000002630087988.png "点击放大")
#### 读写分离优势
- 相比在应用程序内手动做读写分离，扩容灵活，维护成本低。
- 客户端读请求按权重分发至后端只读节点，数据库实例整体负载更加均衡，提升资源利用率。
- 通过代理将指定业务的读请求路由到选定的只读实例上，实现业务隔离，避免多个业务之间相互影响。
- 数据库代理默认提供过载保护功能，避免用户执行大结果集操作时，因压力过大引起服务端OOM。针对数据库内核过慢引起的压力，系统依赖数据库限流机制。
 
#### 请求路由规则
#### 只发往主节点的写请求
- INSERT、UPDATE、DELETE、SELECT FOR UPDATE。
- 所有DDL操作（建表/库、删表/库、变更表结构、权限等）。
- 所有事务中的请求（事务拆分开启时部分读请求可能发送至只读节点，详见[事务拆分](https://support.huaweicloud.com/usermanual-taurusdb/taurusdb_11_0030.html)）。
- 用户自定义函数。
- 存储过程。
- EXECUTE语句。
- Multi Statements。
- 使用到临时表的请求。
- 所有对用户变量的更改。
- SELECT LAST_INSERT_ID()。
- KILL（SQL语句中的KILL，非命令KILL）。
- Prepare协议的**set names**命令。
 
#### 发往主节点的读请求
- 如果查询语句被放在事务中，事务请求都会路由到主实例。如果在查询语句前设置**set autocommit=0，**也会当作事务处理并路由到主实例。
- 如果所有只读节点均异常或只读节点权重为0时，则查询会路由到主实例。对于成功开启读写分离功能的实例，您可以设置其主实例和只读实例的权重。
- 在执行SQL语句时：
  - 如果执行了Multi-Statements（如"**insert xxx;select xxx**"），当前连接的后续请求会全部路由到主节点，需断开当前连接并重新连接才能恢复读写分离。
  
  - 带锁的读操作（如SELECT for UPDATE）会被路由到主节点。
  
  - 当使用**/\*FORCE_MASTER\*/** 这个**Hint**语句时，会被路由到主实例。
  
  - 如果执行了[Handler语句](https://dev.mysql.com/doc/refman/8.0/en/handler.html)，后续请求默认会全部路由到主节点，需断开当前连接并重新连接才能恢复读写分离。
   
- SELECT LAST_INSERT_ID()。
- 使用用户自定义变量时，包含用户自定义变量的语句会路由到主节点。
 
#### 发往只读节点或主节点
- 非事务中的SELECT。
- COM_STMT_EXECUTE命令。
 
#### 总是发往所有节点
- 所有系统变量的更改。
- USE命令。
 
