练习:保护、监视和优化已迁移的数据库

已完成

你是 AdventureWorks 组织中的一名数据库开发人员。 十多年来,AdventureWorks 始终直接向最终消费者和分销商销售自行车和自行车零件。 他们的系统将信息存储在以前迁移到 Azure Database for PostgreSQL 的数据库中。

执行迁移后,你想要确保系统正常运行。 你决定使用可用的 Azure 工具来监视服务器。 为了减轻争用和延迟导致响应时间变慢的可能性,你决定实现读取复制。 你需要监视生成的系统,并将结果与灵活服务器体系结构进行比较。

在本练习中,您将执行以下任务:

  1. 为 Azure Database for PostgreSQL 服务配置 Azure 指标。
  2. 运行示例应用程序来模拟多个用户查询数据库。
  3. 查看指标。

设置环境

在 Cloud Shell 中运行下列 Azure CLI 命令,以使用 adventureworks 数据库的副本创建适用于 PostgreSQL 的 Azure 数据库。 最后的命令将打印服务器名称。

SERVERNAME="adventureworks$((10000 + RANDOM % 99999))"
PUBLICIP=$(wget http://ipecho.net/plain -O - -q)
git clone https://github.com/MicrosoftLearning/DP-070-Migrate-Open-Source-Workloads-to-Azure.git workshop

az postgres server create \
    --resource-group <rgn>[sandbox resource group name]</rgn> \
    --name $SERVERNAME \
    --location westus \
    --admin-user awadmin \
    --admin-password Pa55w.rdDemo \
    --version 10 \
    --storage-size 5120

az postgres db create \
    --name azureadventureworks \
    --server-name $SERVERNAME \
    --resource-group <rgn>[sandbox resource group name]</rgn>

az postgres server firewall-rule create \
    --resource-group <rgn>[sandbox resource group name]</rgn> \
    --server $SERVERNAME \
    --name AllowMyIP \
    --start-ip-address $PUBLICIP --end-ip-address $PUBLICIP

PGPASSWORD=Pa55w.rdDemo psql -h $SERVERNAME.postgres.database.azure.com -U awadmin@$SERVERNAME -d postgres -f workshop/migration_samples/setup/postgresql/adventureworks/create_user.sql

PGPASSWORD=Pa55w.rd psql -h $SERVERNAME.postgres.database.azure.com -U azureuser@$SERVERNAME -d azureadventureworks -f workshop/migration_samples/setup/postgresql/adventureworks/adventureworks.sql 2> /dev/null

echo "Your PostgreSQL server name is:\n"
echo $SERVERNAME.postgres.database.azure.com

为 Azure Database for PostgreSQL 服务配置 Azure 指标

  1. 使用 Web 浏览器打开新的标签页,然后导航到 Azure 门户

  2. 在 Azure 门户中,选择“所有资源”。

  3. 选择以 adventureworks 开头的 Azure Database for PostgreSQL 服务器名称。

  4. 在“监视”下,选择“指标”。

  5. 在图表页上添加以下指标:

    属性
    范围 adventureworks[nnn]
    指标命名空间 PostgreSQL 服务器标准指标
    指标 活动连接数
    聚合 Avg

    此指标显示每分钟与服务器建立的平均连接数。

  6. 选择“添加指标”,并添加以下指标:

    属性
    范围 adventureworks[nnn]
    指标命名空间 PostgreSQL 服务器标准指标
    指标 CPU 百分比
    聚合 Avg
  7. 选择“添加指标”,并添加以下指标:

    属性
    范围 adventureworks[nnn]
    指标命名空间 PostgreSQL 服务器标准指标
    指标 内存百分比
    聚合 Avg
  8. 选择“添加指标”,并添加以下指标:

    属性
    范围 adventureworks[nnn]
    指标命名空间 PostgreSQL 服务器标准指标
    指标 IO 百分比
    聚合 Avg

    最后这三个指标显示了测试应用程序使用资源的方式。

  9. 将图表的时间范围设置为“过去 30 分钟”。

  10. 选择“固定到仪表板”,然后选择“固定”。

运行示例应用程序来模拟多个用户查询数据库

  1. 在 Azure 门户上 Azure Database for PostgreSQL 服务器页的“设置”下选择“连接字符串”。 将 ADO.NET 连接字符串复制到剪贴板。

  2. 移动到 ~/workshop/migration_samples/code/postgresql/AdventureWorksSoakTest 文件夹。

    cd ~/workshop/migration_samples/code/postgresql/AdventureWorksSoakTest
    
  3. 使用代码编辑器打开 App.config 文件:

    code App.config
    
  4. 将“数据库”的值替换为 azureadventureworks,并将“ConectionString0”替换为剪贴板中的连接字符串。 将“用户 ID”更改为 azureuser@adventureworks[nnn],并将“密码”设置为“Pa55w.rd”。 完整文件应类似于以下示例:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <appSettings>
            <add key="ConnectionString0" value="Server=adventureworks101.postgres.database.azure.com;Database=azureadventureworks;Port=5432;User Id=azureuser@adventureworks101;Password=Pa55w.rd;Ssl Mode=Require;" />
            <add key="ConnectionString1" value="INSERT CONNECTION STRING HERE" />
            <add key="ConnectionString2" value="INSERT CONNECTION STRING HERE" />
            <add key="NumClients" value="100" />
            <add key="NumReplicas" value="1"/>
        </appSettings>
    </configuration>
    

    注意

    暂时忽略 ConnectionString1 和 ConnectionString2 设置。 稍后在实验室中更新这些项。

  5. 保存更改并关闭编辑器。

  6. 在 Cloud Shell 提示符中,运行以下命令以生成并运行应用:

    dotnet run
    

    当应用启动时,它生成多个线程,每个线程模拟一个用户。 线程执行循环,运行一系列查询。 将看到开始出现如下所示的消息:

    Client 48 : SELECT * FROM purchasing.vendor
    Response time: 630 ms
    
    Client 48 : SELECT * FROM sales.specialoffer
    Response time: 702 ms
    
    Client 43 : SELECT * FROM purchasing.vendor
    Response time: 190 ms
    
    Client 57 : SELECT * FROM sales.salesorderdetail
    Client 68 : SELECT * FROM production.vproductanddescription
    Response time: 51960 ms
    
    Client 55 : SELECT * FROM production.vproductanddescription
    Response time: 160212 ms
    
    Client 59 : SELECT * FROM person.person
    Response time: 186026 ms
    
    Response time: 2191 ms
    
    Client 37 : SELECT * FROM person.person
    Response time: 168710 ms
    

    执行下一步时,请保持应用正常运行。

查看指标

  1. 返回到 Azure 门户。

  2. 在左侧窗格中,选择“仪表板”

    应看到显示 Azure Database for PostgreSQL 服务指标的图表。

  3. 在“指标”窗格中选择要打开的图表。

  4. 让应用运行几分钟(越长越好)。 随着时间推移,图表中的指标应类似于下图所示的模式:

    Image showing the metrics gathered while the sample app is running

    此图表突出显示以下几点:

    • CPU 以满负荷运行;利用率快速达到 100%。
    • 连接数量缓慢增加。 该示例应用程序旨在连续快速启动 101 个客户端,但服务器一次只能应对打开几个连接。 图表中每个“步骤”添加的连接数变得越来越小,“步骤”之间的时间不断增大。 大约 45 分钟后,系统只能建立 70 个客户端连接。
    • 随着时间的推移,内存利用率不断增大。
    • IO 利用率接近于零。 客户端应用程序所需的所有数据当前都缓存在内存中。

    如果使应用程序运行足够长的时间,会看到开始连不上,并显示下图所示的错误消息。

    Image showing the connection errors that can occur when the server has insufficient resources available

  5. 在 Cloud Shell 中按 Enter 以停止应用程序。

配置服务器以收集查询性能数据

  1. 在 Azure 门户上 Azure Database for PostgreSQL 服务器页的“设置”下选择“服务器参数”。

  2. 在“服务器参数”页上,将以下参数设置为下表中指定的值。

    参数
    pg_qs.max_query_text_length 6000
    pg_qs.query_capture_mode ALL
    pg_qs.replace_parameter_placeholders ON
    pg_qs.retention_period_in_days 7
    pg_qs.track_utility ON
    pg_stat_statements.track ALL
    pgms_wait_sampling.history_period 100
    pgms_wait_sampling.query_capture_mode ALL
  3. 选择“保存”。

使用查询存储检查应用程序运行的查询

  1. 返回 Cloud Shell,然后重新启动示例应用:

    dotnet run
    

    在继续操作之前先让应用运行 5 分钟。

  2. 让应用保持运行并切换到 Azure 门户

  3. 在 Azure Database for PostgreSQL 服务器页面的“智能性能”下选择“Query Performance Insight”。

  4. 在“Query Performance Insight”页面的“长时间运行的查询”选项卡上,将“查询数”设置为“10”,将“选择标准”设置为“平均值”,并将“时间段”设置为“过去 6 小时”。

  5. 在图表上方选择“放大”(带有“+”号的放大镜图标)几次,以重点关注最新数据。

    根据让应用程序运行的时间,会看到如下所示的图表。 查询存储每 15 分钟聚合一次查询的统计信息,因此每个条形显示每个查询在每 15 分钟内所使用的相对时间:

    Image showing the statistics for long running queries captured by using Query Store

  6. 依次将鼠标悬停在每个条形上,查看该时间段内查询的统计信息。 系统花费最多时间执行的三大查询是:

    SELECT * FROM sales.salesorderdetail
    SELECT * FROM sales.salesorderheader
    SELECT * FROM person.person
    

    此信息适用于监视系统的管理员。 通过深入了解用户和应用运行的查询,你可以了解正在执行的工作负荷,并向应用程序开发人员提供有关如何改进其代码的建议。 例如,应用程序是否确实需要从 sales.salesorderdetail 表中检索所有 121000+ 行?

使用查询存储检查发生的任何等待

  1. 选择“等待统计信息”选项卡。

  2. 将“时间段”设置为“过去 6 小时”,将“分组依据”设置为“事件”,并将“最大组数”设置为“5”。

    与“长时间运行的查询”选项卡一样,每 15 分钟聚合一次数据。 图表下方的表显示系统已成为两类等待事件的对象:

    • 客户端:ClientWrite。 当服务器将数据(结果)写回到客户端时,发生这种等待事件。 它不指示写入数据库时发生等待。
    • 客户端:ClientRead。 当服务器正在等待从客户端读取数据(查询请求或其他命令)时,发生这种等待事件。 它与从数据库中读取数据所花时间无关。

    Image showing the wait statistics captured by using Query Store

    注意

    对数据库的读取和写入由 IO 事件而不是 Client 事件指示。 首次读取后,示例应用程序不引发任何 IO 等待,因为它所需的所有数据都缓存在内存中。 如果指标显示内存不足,则可能会看到 IO 等待事件开始发生。

  3. 返回到 Cloud Shell,然后按 Enter 以停止示例应用程序。

将副本添加到 Azure Database for PostgreSQL 服务

  1. 在 Azure 门户上 Azure Database for PostgreSQL 服务器页的“设置”下选择“复制”。

  2. 在“复制”页上选择“+ 添加副本”。

  3. 在“PostgreSQL 服务器”页上的“服务器名称”框中键入 adventureworks[nnn]-replica1,然后选择“确定”。

  4. 创建第一个副本后(会花几分钟时间),请重复上一步并添加另一个名为 adventureworks[nnn]-replica2 的副本。

  5. 等待两个副本的状态从“正在部署”更改为“可用”后再继续。

    Image showing the Replication page for Azure Database for PostgreSQL. Two replicas have been added.

配置副本以启用客户端访问

  1. 选择 adventureworks[nnn]-replica1 副本的名称。 你将转到针对此副本的 Azure Database for PostgreSQL 页面。
  2. 在“设置”下,选择“连接安全性”
  3. 在“连接安全性”页上,将“允许访问 Azure 服务”设置为“开”,然后选择“保存”。 此设置让使用 Cloud Shell 运行的应用程序能够访问服务器。
  4. 保存设置后重复前面的步骤,并允许 Azure 服务访问 adventureworks[nnn]-replica2 副本。

重启每个服务器

注意

配置复制不需要重新启动服务器。 此任务的目的是清除内存以及每个服务器的任何无关连接,以便再次运行该应用程序时收集的指标是“干净”的。

  1. 转到 adventureworks[nnn] 服务器的页面。
  2. 在“概述”页上,选择“重启”
  3. 在“重启服务器”对话框中选择“是”。
  4. 等待服务器重新启动,然后再继续操作。
  5. 按照相同的过程,重新启动 adventureworks[nnn]-replica1 和 adventureworks[nnn]-replica2 服务器。

重新配置示例应用程序以使用副本

  1. 在 Cloud Shell 中,编辑 App.config 文件。

    code App.config
    
  2. 为“ConnectionString1”和“ConnectionString2”设置添加连接字符串。 这些值应该与 ConnectionString0 的相同,但“服务器”和“用户 ID”元素中 adventureworks[nnn] 文本替换为 adventureworks[nnn]-replica1 和 adventureworks[nnn]-replica2。

  3. 将“NumReplicas”设置设为 3。

    现在 App.config 文件应类似于:

    <configuration>
        <appSettings>
            <add key="ConnectionString0" value="Server=adventureworks101.postgres.database.azure.com;Database=azureadventureworks;Port=5432;User Id=azureuser@adventureworks101;Password=Pa55w.rd;Ssl Mode=Require;" />
            <add key="ConnectionString1" value="Server=adventureworks101-replica1.postgres.database.azure.com;Database=azureadventureworks;Port=5432;User Id=azureuser@adventureworks101-replica1;Password=Pa55w.rd;Ssl Mode=Require;" />
            <add key="ConnectionString2" value="Server=adventureworks101-replica2.postgres.database.azure.com;Database=azureadventureworks;Port=5432;User Id=azureuser@adventureworks101-replica2;Password=Pa55w.rd;Ssl Mode=Require;" />
            <add key="NumClients" value="100" />
            <add key="NumReplicas" value="3"/>
        </appSettings>
    </configuration>
    
  4. 保存文件并关闭编辑器。

  5. 再次开始运行应用:

    dotnet run
    

    应用程序将像以前一样运行。 但这一次,请求会分布在三个服务器上。

  6. 让应用运行几分钟,然后再继续。

监视应用并观察性能指标中的差异

  1. 让应用保持运行并返回到 Azure 门户。

  2. 在左侧窗格中,选择“仪表板”

  3. 在“指标”窗格中选择要打开的图表。

    请记住,此图表显示 adventureworks*[nnn]* 服务器的指标,而不是副本的指标。 每个副本的负载应大致相同。

    示例图表显示自启动时 30 分钟内开始收集的应用程序指标。 此图表显示 CPU 利用率仍很高,但内存利用率较低。 另外,大约 25 分钟后,系统为 30 个以上的连接建立了连接。 这似乎不比以前的配置更好,后者在 45 分钟后支持 70 个连接。 但是,工作负载现在分布在三个服务器上,它们都在同一级别执行,并且已建立所有 101 个连接。 此外,系统能够在不报告任何连接故障的情况下运行。

    Image showing the metrics for the Azure Database for PostgreSQL server while running the application, after replication was configured

    可以通过升级到具有更多的 CPU 核心的更高定价层来解决 CPU 利用率问题。 本实验室中使用的示例系统使用具有 2 个核心的“基本”定价层运行。 更改为“常规用途”定价层将为你带来多达 64 个核心。

  4. 返回到 Cloud Shell,然后按 Enter 以停止应用。

现在,你已了解如何使用 Azure 门户中提供的工具来监视服务器活动。 还了解了如何配置复制,以及如何在读取密集型数据方案中通过创建只读副本分配工作负荷。