1. 首页 > 国产数据库教程 > OceanBase教程 > 正文

OceanBase教程FG179-OceanBase多租户资源隔离管控实战

本文档风哥主要介绍OceanBase数据库的多租户资源隔离管控实战,包括资源单元创建、资源池管理、租户创建与配置等。风哥教程参考OceanBase官方文档OceanBase多租户管理手册、OceanBase资源管理手册等。

通过本文的学习,您将了解如何实际配置OceanBase的多租户资源隔离,确保不同租户之间的资源隔离和性能稳定。

目录大纲

Part01-基础概念与理论知识

1.1 多租户资源隔离基本概念

多租户资源隔离是OceanBase的核心特性之一,通过资源单元和资源池的管理,实现不同租户之间的资源隔离。具有以下特点:

  • 资源隔离:不同租户之间的资源相互隔离,互不影响
  • 弹性伸缩:根据业务需求动态调整租户资源
  • 资源限制:对租户的资源使用进行限制,防止资源滥用
  • 资源监控:实时监控租户的资源使用情况

1.2 资源单元与资源池

资源单元(Resource Unit)是OceanBase中资源分配的基本单位,定义了CPU、内存等资源的配置。资源池(Resource Pool)是资源单元的集合,用于分配给租户。

  • 资源单元配置:包括CPU、内存、I/O等资源的配置
  • 资源池管理:资源池由多个资源单元组成,分布在不同的Zone中
  • 资源池分配:将资源池分配给租户,租户获得资源池中的所有资源

1.3 租户类型与特性

OceanBase支持多种租户类型,不同类型的租户具有不同的特性:

  • 系统租户:默认租户,用于管理整个集群
  • 普通租户:用户创建的租户,用于业务数据存储
  • MySQL租户:兼容MySQL语法的租户
  • Oracle租户:兼容Oracle语法的租户

风哥提示:多租户资源隔离是OceanBase的核心特性,通过合理配置资源单元和资源池,可以实现不同租户之间的资源隔离和性能稳定

Part02-生产环境规划与建议

2.1 多租户资源规划

多租户资源规划的建议:

  • 业务需求分析:根据业务类型和规模,分析资源需求
  • 资源预估:预估每个租户的CPU、内存、存储等资源需求
  • 资源分配:根据预估结果,分配合理的资源单元和资源池
  • 资源预留:预留一定的资源,用于应对业务增长
  • 资源监控:设置资源监控,及时发现资源使用异常

2.2 资源隔离管控建议

资源隔离管控的建议:

  • 合理设置资源限制:根据业务需求设置合理的资源限制
  • 定期调整资源:根据业务变化,定期调整租户资源
  • 监控资源使用:实时监控租户的资源使用情况
  • 优化资源配置:根据资源使用情况,优化资源配置
  • 防止资源滥用:设置资源使用上限,防止资源滥用

Part03-生产环境项目实施方案

3.1 资源单元创建

,风哥提示:。

资源单元创建的步骤:

# 1. 创建资源单元

-- 创建CPU为2核,内存为4GB的资源单元
CREATE RESOURCE UNIT fgedu_unit_2c4g
    MAX_CPU 2,
    MIN_CPU 2,
    MAX_MEMORY '4G',
    MIN_MEMORY '4G',
    MAX_IOPS 10000,
    MIN_IOPS 5000,
    MAX_DISK_SIZE '100G',
    MAX_SESSION_NUM 1000;

-- 创建CPU为4核,内存为8GB的资源单元
CREATE RESOURCE UNIT fgedu_unit_4c8g
    MAX_CPU 4,
    MIN_CPU 4,
    MAX_MEMORY '8G',
    MIN_MEMORY '8G',
    MAX_IOPS 20000,
    MIN_IOPS 10000,
    MAX_DISK_SIZE '200G',
    MAX_SESSION_NUM 2000;

-- 创建CPU为8核,内存为16GB的资源单元
CREATE RESOURCE UNIT fgedu_unit_8c16g
    MAX_CPU 8,学习交流加群风哥微信: itpux-com。
    MIN_CPU 8,
    MAX_MEMORY '16G',
    MIN_MEMORY '16G',
    MAX_IOPS 40000,
    MIN_IOPS 20000,
    MAX_DISK_SIZE '500G',
    MAX_SESSION_NUM 4000;
                    

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

3.2 资源池管理

资源池管理的步骤:

# 1. 创建资源池

-- 创建使用fgedu_unit_2c4g资源单元的资源池
CREATE RESOURCE POOL fgedu_pool_2c4g
    UNIT 'fgedu_unit_2c4g',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');

-- 创建使用fgedu_unit_4c8g资源单元的资源池
CREATE RESOURCE POOL fgedu_pool_4c8g
    UNIT 'fgedu_unit_4c8g',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');

-- 创建使用fgedu_unit_8c16g资源单元的资源池
CREATE RESOURCE POOL fgedu_pool_8c16g
    UNIT 'fgedu_unit_8c16g',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');学习交流加群风哥QQ113257174。
                    

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.02 sec)

# 2. 查看资源池

-- 查看资源池信息
SELECT * FROM oceanbase.DBA_OB_RESOURCE_POOLS;
                    

+——————+——————+—————+———-+—————+——————+
| RESOURCE_POOL_ID | NAME | RESOURCE_UNIT | UNIT_NUM | ZONE_LIST | TENANT_ID |
+——————+——————+—————+———-+—————+——————+
| 1 | sys_pool | sys_unit | 1 | zone1,zone2,zone3 | 1 |
| 2 | fgedu_pool_2c4g | fgedu_unit_2c4g | 3 | zone1,zone2,zone3 | NULL |
| 3 | fgedu_pool_4c8g | fgedu_unit_4c8g | 3 | zone1,zone2,zone3 | NULL |
| 4 | fgedu_pool_8c16g | fgedu_unit_8c16g | 3 | zone1,zone2,zone3 | NULL |
+——————+——————+—————+———-+—————+——————+

3.3 租户创建与配置

租户创建与配置的步骤:

# 1. 创建MySQL租户

-- 创建MySQL租户,使用fgedu_pool_2c4g资源池
CREATE TENANT fgedu_tenant_mysql
    RESOURCE_POOL_LIST = ('fgedu_pool_2c4g'),
    PRIMARY_ZONE = 'zone1',
    LOCALITY = 'F@zone1, F@zone2, F@zone3',
    COMMENT 'MySQL租户';更多视频教程www.fgedu.net.cn。

-- 创建MySQL租户的管理员用户
CREATE USER 'fgedu'@'%' IDENTIFIED BY 'fgedu123';
GRANT ALL PRIVILEGES ON fgedu_tenant_mysql.* TO 'fgedu'@'%';
                    

Query OK, 0 rows affected (1.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

# 2. 创建Oracle租户

-- 创建Oracle租户,使用fgedu_pool_4c8g资源池
CREATE TENANT fgedu_tenant_oracle
    RESOURCE_POOL_LIST = ('fgedu_pool_4c8g'),
    PRIMARY_ZONE = 'zone1',
    LOCALITY = 'F@zone1, F@zone2, F@zone3',
    COMMENT 'Oracle租户',
    TENANT_MODE = 'ORACLE';

-- 创建Oracle租户的管理员用户
CREATE USER fgedu IDENTIFIED BY 'fgedu123';
GRANT ALL PRIVILEGES TO fgedu;
                    

Query OK, 0 rows affected (1.02 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

# 3. 查看租户信息

,更多学习教程公众号风哥教程itpux_com。

-- 查看租户信息
SELECT * FROM oceanbase.DBA_OB_TENANTS;
                    

+———–+——————-+————-+————-+——————-+—————————-+—————————-+—————+———-+—————————-+—————————-+—————-+
| TENANT_ID | TENANT_NAME | TENANT_TYPE | TENANT_MODE | PRIMARY_ZONE | CREATE_TIME | MODIFY_TIME | LOCALITY | COMMENT | REPLICA_TYPE | READONLY_STATUS | SWITCHOVER_STATUS |
+———–+——————-+————-+————-+——————-+—————————-+—————————-+—————+———-+—————————-+—————————-+—————-+
| 1 | sys | SYS | MYSQL | zone1;zone2;zone3 | 2026-04-01 10:00:00.000000 | 2026-04-01 10:00:00.000000 | F@zone1, F@zone2, F@zone3 | System tenant | FULL | NORMAL | NORMAL |
| 2 | fgedu_tenant_mysql | USER | MYSQL | zone1 | 2026-04-09 10:00:00.000000 | 2026-04-09 10:00:00.000000 | F@zone1, F@zone2, F@zone3 | MySQL租户 | FULL | NORMAL | NORMAL |
| 3 | fgedu_tenant_oracle | USER | ORACLE | zone1 | 2026-04-09 10:05:00.000000 | 2026-04-09 10:05:00.000000 | F@zone1, F@zone2, F@zone3 | Oracle租户 | FULL | NORMAL | NORMAL |
+———–+——————-+————-+————-+——————-+—————————-+—————————-+—————+———-+—————————-+—————————-+—————-+

Part04-生产案例与实战讲解

4.1 多租户资源隔离管控实战

多租户资源隔离管控的实战案例:

场景描述

某电商平台需要在OceanBase中创建多个租户,分别用于不同业务系统,确保资源隔离和性能稳定。

实施步骤

  1. 创建资源单元
  2. 创建资源池
  3. ,from DB视频:www.itpux.com。

  4. 创建租户
  5. 配置租户资源
  6. 监控资源使用

# 1. 创建资源单元

-- 创建不同规格的资源单元
CREATE RESOURCE UNIT fgedu_unit_small
    MAX_CPU 2,
    MIN_CPU 2,
    MAX_MEMORY '4G',
    MIN_MEMORY '4G',
    MAX_IOPS 10000,
    MIN_IOPS 5000,
    MAX_DISK_SIZE '100G',
    MAX_SESSION_NUM 1000;

CREATE RESOURCE UNIT fgedu_unit_medium
    MAX_CPU 4,
    MIN_CPU 4,
    MAX_MEMORY '8G',
    MIN_MEMORY '8G',
    MAX_IOPS 20000,
    MIN_IOPS 10000,
    MAX_DISK_SIZE '200G',
    MAX_SESSION_NUM 2000;

CREATE RESOURCE UNIT fgedu_unit_large
    MAX_CPU 8,
    MIN_CPU 8,
    MAX_MEMORY '16G',
    MIN_MEMORY '16G',
    MAX_IOPS 40000,
    MIN_IOPS 20000,
    MAX_DISK_SIZE '500G',
    MAX_SESSION_NUM 4000;
                    

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

# 2. 创建资源池

-- 创建不同规格的资源池
CREATE RESOURCE POOL fgedu_pool_small
    UNIT 'fgedu_unit_small',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');

CREATE RESOURCE POOL fgedu_pool_medium
    UNIT 'fgedu_unit_medium',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');

CREATE RESOURCE POOL fgedu_pool_large
    UNIT 'fgedu_unit_large',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');
                    

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.02 sec)

# 3. 创建租户

-- 创建用户租户1(电商交易系统),使用fgedu_pool_large资源池
CREATE TENANT fgedu_tenant_trade
    RESOURCE_POOL_LIST = ('fgedu_pool_large'),
    PRIMARY_ZONE = 'zone1',
    LOCALITY = 'F@zone1, F@zone2, F@zone3',
    COMMENT '电商交易系统租户';

-- 创建用户租户2(用户管理系统),使用fgedu_pool_medium资源池
CREATE TENANT fgedu_tenant_user
    RESOURCE_POOL_LIST = ('fgedu_pool_medium'),
    PRIMARY_ZONE = 'zone1',
    LOCALITY = 'F@zone1, F@zone2, F@zone3',
    COMMENT '用户管理系统租户';

-- 创建用户租户3(商品管理系统),使用fgedu_pool_small资源池
CREATE TENANT fgedu_tenant_product
    RESOURCE_POOL_LIST = ('fgedu_pool_small'),
    PRIMARY_ZONE = 'zone1',
    LOCALITY = 'F@zone1, F@zone2, F@zone3',
    COMMENT '商品管理系统租户';
                    

Query OK, 0 rows affected (1.01 sec)

Query OK, 0 rows affected (1.02 sec)

Query OK, 0 rows affected (1.01 sec)

# 4. 配置租户资源

-- 为每个租户创建管理员用户
-- 电商交易系统租户
CREATE USER 'fgedu'@'%' IDENTIFIED BY 'fgedu123' TENANT fgedu_tenant_trade;
GRANT ALL PRIVILEGES ON fgedu_tenant_trade.* TO 'fgedu'@'%';

-- 用户管理系统租户
CREATE USER 'fgedu'@'%' IDENTIFIED BY 'fgedu123' TENANT fgedu_tenant_user;
GRANT ALL PRIVILEGES ON fgedu_tenant_user.* TO 'fgedu'@'%';

-- 商品管理系统租户
CREATE USER 'fgedu'@'%' IDENTIFIED BY 'fgedu123' TENANT fgedu_tenant_product;
GRANT ALL PRIVILEGES ON fgedu_tenant_product.* TO 'fgedu'@'%';
                    

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

# 5. 监控资源使用

-- 查看租户资源使用情况
SELECT * FROM oceanbase.GV$OB_TENANT_STAT;

-- 查看租户会话数
SELECT * FROM oceanbase.GV$OB_TENANT_SESSIONS;

-- 查看租户CPU使用情况
SELECT * FROM oceanbase.GV$OB_TENANT_CPU_STAT;

-- 查看租户内存使用情况
SELECT * FROM oceanbase.GV$OB_TENANT_MEMORY_STAT;
                    

— GV$OB_TENANT_STAT输出(部分)
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+—————+
| TENANT_ID | TENANT_NAME | SVR_IP | SVR_PORT | ACTIVE_SESSIONS | TOTAL_SESSIONS | CPU_USAGE_PERCENT | MEMORY_USAGE_PERCENT | IOPS | THROUGHPUT |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+—————+
| 2 | fgedu_tenant_trade | 192.168.1.1 | 2882 | 10 | 100 | 10 | 20 | 1000 | 10240 |
| 3 | fgedu_tenant_user | 192.168.1.1 | 2882 | 5 | 50 | 5 | 10 | 500 | 5120 |
| 4 | fgedu_tenant_product | 192.168.1.1 | 2882 | 2 | 20 | 2 | 5 | 200 | 2048 |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+—————+

— GV$OB_TENANT_SESSIONS输出(部分)
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+
| TENANT_ID | TENANT_NAME | SVR_IP | SVR_PORT | ACTIVE_SESSIONS | TOTAL_SESSIONS | SESSION_LIMIT | IDLE_SESSIONS | ABORTED_SESSIONS |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+
| 2 | fgedu_tenant_trade | 192.168.1.1 | 2882 | 10 | 100 | 1000 | 90 | 0 |
| 3 | fgedu_tenant_user | 192.168.1.1 | 2882 | 5 | 50 | 2000 | 195 | 0 |
| 4 | fgedu_tenant_product | 192.168.1.1 | 2882 | 2 | 20 | 1000 | 98 | 0 |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+

4.2 租户资源调整实战

租户资源调整的实战案例:

场景描述

某电商平台的交易系统租户(fgedu_tenant_trade)业务量增长,需要增加其资源配置。

实施步骤

  1. 创建新的资源单元
  2. 创建新的资源池
  3. 修改租户资源配置
  4. 验证资源调整结果

# 1. 创建新的资源单元

-- 创建CPU为16核,内存为32GB的资源单元
CREATE RESOURCE UNIT fgedu_unit_16c32g
    MAX_CPU 16,
    MIN_CPU 16,
    MAX_MEMORY '32G',
    MIN_MEMORY '32G',
    MAX_IOPS 80000,
    MIN_IOPS 40000,
    MAX_DISK_SIZE '1000G',
    MAX_SESSION_NUM 8000;
                    

Query OK, 0 rows affected (0.01 sec)

# 2. 创建新的资源池

-- 创建使用fgedu_unit_16c32g资源单元的资源池
CREATE RESOURCE POOL fgedu_pool_16c32g
    UNIT 'fgedu_unit_16c32g',
    UNIT_NUM 3,
    ZONE_LIST ('zone1', 'zone2', 'zone3');
                    

Query OK, 0 rows affected (0.02 sec)

# 3. 修改租户资源配置

-- 修改租户资源配置,使用新的资源池
ALTER TENANT fgedu_tenant_trade
    RESOURCE_POOL_LIST = ('fgedu_pool_16c32g');
                    

Query OK, 0 rows affected (0.03 sec)

# 4. 验证资源调整结果

-- 查看租户资源使用情况
SELECT * FROM oceanbase.GV$OB_TENANT_STAT WHERE TENANT_NAME = 'fgedu_tenant_trade';

-- 查看租户会话数
SELECT * FROM oceanbase.GV$OB_TENANT_SESSIONS WHERE TENANT_NAME = 'fgedu_tenant_trade';
                    

— GV$OB_TENANT_STAT输出(部分)
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+—————+
| TENANT_ID | TENANT_NAME | SVR_IP | SVR_PORT | ACTIVE_SESSIONS | TOTAL_SESSIONS | CPU_USAGE_PERCENT | MEMORY_USAGE_PERCENT | IOPS | THROUGHPUT |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+—————+
| 2 | fgedu_tenant_trade | 192.168.1.1 | 2882 | 15 | 150 | 15 | 25 | 1500 | 15360 |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+—————+

— GV$OB_TENANT_SESSIONS输出(部分)
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+
| TENANT_ID | TENANT_NAME | SVR_IP | SVR_PORT | ACTIVE_SESSIONS | TOTAL_SESSIONS | SESSION_LIMIT | IDLE_SESSIONS | ABORTED_SESSIONS |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+
| 2 | fgedu_tenant_trade | 192.168.1.1 | 2882 | 15 | 150 | 8000 | 135 | 0 |
+———–+——————-+—————+—————+—————+—————+—————+—————+—————+

Part05-风哥经验总结与分享

5.1 多租户资源隔离最佳实践

OceanBase多租户资源隔离的最佳实践:

  • 合理规划资源:根据业务需求和规模,合理规划资源配置
  • 资源单元标准化:创建标准化的资源单元,方便管理和调整
  • 资源池合理分配:根据租户的重要性和资源需求,合理分配资源池
  • 定期监控资源:定期监控租户的资源使用情况,及时发现问题
  • 动态调整资源:根据业务变化,动态调整租户资源
  • 设置资源限制:设置合理的资源使用限制,防止资源滥用
  • 租户隔离:确保不同租户之间的资源隔离,互不影响
  • 备份与恢复:为每个租户制定合理的备份与恢复策略

5.2 常见问题与解决方案

多租户资源隔离中常见的问题与解决方案:

# 1. 资源不足
- 症状:租户资源不足,导致性能下降
- 解决方案:增加租户资源,或优化业务逻辑

# 2. 资源浪费
- 症状:租户资源利用率低,造成资源浪费
- 解决方案:调整租户资源配置,提高资源利用率

# 3. 资源争用
- 症状:不同租户之间资源争用,影响性能
- 解决方案:合理分配资源,设置资源限制

# 4. 资源调整失败
- 症状:修改租户资源配置失败
- 解决方案:检查资源池状态,确保资源池有足够的资源

# 5. 监控不到位
- 症状:无法及时发现资源使用异常
- 解决方案:设置完善的监控和告警机制

# 6. 租户创建失败
- 症状:创建租户失败
- 解决方案:检查资源池状态,确保资源池有足够的资源

# 7. 权限管理
- 症状:租户权限管理混乱
- 解决方案:建立完善的权限管理体系
                

风哥提示:多租户资源隔离是OceanBase的核心特性,通过合理配置资源单元和资源池,可以实现不同租户之间的资源隔离和性能稳定

+———–+——————-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+———-+—

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息