البرنامج التعليمي: تنفيذ قاعدة بيانات موزعة جغرافياً (قاعدة بيانات Azure SQL)
ينطبق على: قاعدة بيانات Azure SQL
تكوين قاعدة بيانات في قاعدة بيانات SQL وتطبيق العميل من أجل تجاوز الفشل إلى منطقة بعيدة واختبار خطة تجاوز الفشل. ستتعرف على كيفية:
- إنشاء مجموعة تجاوز الفشل
- تشغيل تطبيق Java للاستعلام عن قاعدة بيانات في قاعدة بيانات SQL
- تجاوز الفشل التجريبي
إذا لم يكن لديك اشتراك في Azure، فأنشئ free account قبل البدء.
المتطلبات الأساسية
ملاحظة
تستخدم هذه المقالة الوحدة النمطية Azure Az PowerShell، وهي الوحدة النمطية PowerShell الموصى بها للتفاعل مع Azure. لبدء استخدام الوحدة النمطية Az PowerShell، راجع تثبيت Azure PowerShell. لمعرفة كيفية الترحيل إلى الوحدة النمطية Az PowerShell، راجع ترحيل Azure PowerShell من AzureRM إلى Az.
هام
لا تزال الوحدة النمطيةPowerShell Azure Resource Manager مدعومة من قبل قاعدة بيانات SQL Azure، ولكن جميع التطويرات المستقبلية تكون للوحدة النمطية Az.Sql. بالنسبة إلى أوامر cmdlets، راجع AzureRM.Sql. تتطابق وسائط الأوامر في الوحدة النمطية Az وفي الوحدات النمطية AzureRm بشكل كبير.
لإكمال البرنامج التعليمي، تأكد من تثبيت العناصر التالية:
قاعدة بيانات واحدة في قاعدة بيانات SQL Azure. لإنشاء استخدام واحد،
ملاحظة
يستخدم البرنامج التعليمي نموذج قاعدة بيانات AdventureWorksLT.
Java و Maven، راجع إنشاء تطبيق باستخدام SQL Server، مع تمييز Java وتحديد البيئة الخاصة بك، ثم اتبع الخطوات.
هام
تأكد من إعداد قواعد جدار الحماية لاستخدام عنوان IP العام للكمبيوتر الذي تقوم بتنفيذ الخطوات عليه في هذا البرنامج التعليمي. ستقوم قواعد جدار الحماية على مستوى قاعدة البيانات بإجراء نسخ متماثل تلقائياً إلى الخادم الثانوي.
للحصول على معلومات، راجع إنشاء قاعدة جدار حماية على مستوى قاعدة بيانات أو لتحديد عنوان IP المستخدم لقاعدة جدار الحماية على مستوى الخادم للكمبيوتر الخاص بك، راجع إنشاء جدار حماية على مستوى الخادم.
إنشاء مجموعة تجاوز أعطال
باستخدام Azure PowerShell، قم بإنشاء مجموعات تجاوز الفشل بين خادم موجود وخادم جديد في منطقة أخرى. ثم أضف نموذج قاعدة البيانات إلى مجموعة تجاوز الفشل.
هام
يتطلب هذا النموذج وجود Azure PowerShell Az 1.0 أو أي نسخة أحدث. اضغط Get-Module -ListAvailable Az
لمعرفة الإصدارات المثبتة.
إذا كنت بحاجة إلى التثبيت، راجع نموذجInstall Azure PowerShell.
قم بتشغيل Connect-AzAccountلتسجيل الدخول إلى Azure.
لإنشاء مجموعة تجاوز الفشل، قم بتشغيل البرنامج النصي التالي:
$admin = "<adminName>"
$password = "<password>"
$resourceGroup = "<resourceGroupName>"
$location = "<resourceGroupLocation>"
$server = "<serverName>"
$database = "<databaseName>"
$drLocation = "<disasterRecoveryLocation>"
$drServer = "<disasterRecoveryServerName>"
$failoverGroup = "<globallyUniqueFailoverGroupName>"
# create a backup server in the failover region
New-AzSqlServer -ResourceGroupName $resourceGroup -ServerName $drServer `
-Location $drLocation -SqlAdministratorCredentials $(New-Object -TypeName System.Management.Automation.PSCredential `
-ArgumentList $admin, $(ConvertTo-SecureString -String $password -AsPlainText -Force))
# create a failover group between the servers
New-AzSqlDatabaseFailoverGroup –ResourceGroupName $resourceGroup -ServerName $server `
-PartnerServerName $drServer –FailoverGroupName $failoverGroup –FailoverPolicy Automatic -GracePeriodWithDataLossHours 2
# add the database to the failover group
Get-AzSqlDatabase -ResourceGroupName $resourceGroup -ServerName $server -DatabaseName $database | `
Add-AzSqlDatabaseToFailoverGroup -ResourceGroupName $resourceGroup -ServerName $server -FailoverGroupName $failoverGroup
يمكن أيضاً تغيير إعدادات النسخ المتماثل الجغرافي في مدخل Azure، عن طريق تحديد قاعدة البيانات، ثم الإعدادات>النسخ المتماثل الجغرافي.
تشغيل مشروع العينة
في وحدة التحكم، قم بإنشاء مشروع Maven باستخدام الأمر التالي:
mvn archetype:generate "-DgroupId=com.sqldbsamples" "-DartifactId=SqlDbSample" "-DarchetypeArtifactId=maven-archetype-quickstart" "-Dversion=1.0.0"
اكتب Y واضغط على Enter.
تغيير الدلائل إلى المشروع الجديد.
cd SqlDbSample
باستخدام المحرر المفضل لديك، افتح ملف pom.xml في مجلد المشروع.
إضافة برنامج تشغيل Microsoft JDBC لتبعية SQL Server عن طريق إضافة المقطع
dependency
التالي. يجب لصق التبعية داخل المقطعdependencies
الأكبر.<dependency> <groupId>com.microsoft.sqlserver</groupId> <artifactId>mssql-jdbc</artifactId> <version>6.1.0.jre8</version> </dependency>
حدد إصدار Java بإضافة المقطع
properties
بعد المقطعdependencies
:<properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties>
دعم ملفات البيان بإضافة المقطع
build
بعد المقطعproperties
:<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.0.0</version> <configuration> <archive> <manifest> <mainClass>com.sqldbsamples.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build>
حفظ ملف pom.xml وإغلاقه.
افتح الملف app.java الموجود في ..\SqlDbSample\src\main\java\com\sqldbsamples واستبدال المحتويات بالرمز التالي:
package com.sqldbsamples; import java.sql.Connection; import java.sql.Statement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Timestamp; import java.sql.DriverManager; import java.util.Date; import java.util.concurrent.TimeUnit; public class App { private static final String FAILOVER_GROUP_NAME = "<your failover group name>"; // add failover group name private static final String DB_NAME = "<your database>"; // add database name private static final String USER = "<your admin>"; // add database user private static final String PASSWORD = "<your password>"; // add database password private static final String READ_WRITE_URL = String.format("jdbc:" + "sqlserver://%s.database.windows.net:1433;database=%s;user=%s;password=%s;encrypt=true;" + "hostNameInCertificate=*.database.windows.net;loginTimeout=30;", FAILOVER_GROUP_NAME, DB_NAME, USER, PASSWORD); private static final String READ_ONLY_URL = String.format("jdbc:" + "sqlserver://%s.secondary.database.windows.net:1433;database=%s;user=%s;password=%s;encrypt=true;" + "hostNameInCertificate=*.database.windows.net;loginTimeout=30;", FAILOVER_GROUP_NAME, DB_NAME, USER, PASSWORD); public static void main(String[] args) { System.out.println("#######################################"); System.out.println("## GEO DISTRIBUTED DATABASE TUTORIAL ##"); System.out.println("#######################################"); System.out.println(""); int highWaterMark = getHighWaterMarkId(); try { for(int i = 1; i < 1000; i++) { // loop will run for about 1 hour System.out.print(i + ": insert on primary " + (insertData((highWaterMark + i)) ? "successful" : "failed")); TimeUnit.SECONDS.sleep(1); System.out.print(", read from secondary " + (selectData((highWaterMark + i)) ? "successful" : "failed") + "\n"); TimeUnit.SECONDS.sleep(3); } } catch(Exception e) { e.printStackTrace(); } } private static boolean insertData(int id) { // Insert data into the product table with a unique product name so we can find the product again String sql = "INSERT INTO SalesLT.Product " + "(Name, ProductNumber, Color, StandardCost, ListPrice, SellStartDate) VALUES (?,?,?,?,?,?);"; try (Connection connection = DriverManager.getConnection(READ_WRITE_URL); PreparedStatement pstmt = connection.prepareStatement(sql)) { pstmt.setString(1, "BrandNewProduct" + id); pstmt.setInt(2, 200989 + id + 10000); pstmt.setString(3, "Blue"); pstmt.setDouble(4, 75.00); pstmt.setDouble(5, 89.99); pstmt.setTimestamp(6, new Timestamp(new Date().getTime())); return (1 == pstmt.executeUpdate()); } catch (Exception e) { return false; } } private static boolean selectData(int id) { // Query the data previously inserted into the primary database from the geo replicated database String sql = "SELECT Name, Color, ListPrice FROM SalesLT.Product WHERE Name = ?"; try (Connection connection = DriverManager.getConnection(READ_ONLY_URL); PreparedStatement pstmt = connection.prepareStatement(sql)) { pstmt.setString(1, "BrandNewProduct" + id); try (ResultSet resultSet = pstmt.executeQuery()) { return resultSet.next(); } } catch (Exception e) { return false; } } private static int getHighWaterMarkId() { // Query the high water mark id stored in the table to be able to make unique inserts String sql = "SELECT MAX(ProductId) FROM SalesLT.Product"; int result = 1; try (Connection connection = DriverManager.getConnection(READ_WRITE_URL); Statement stmt = connection.createStatement(); ResultSet resultSet = stmt.executeQuery(sql)) { if (resultSet.next()) { result = resultSet.getInt(1); } } catch (Exception e) { e.printStackTrace(); } return result; } }
وأخيراً، احفظ الملف App.java وأغلقه.
في وحدة تحكم الأمر، قم بتشغيل الأمر التالي:
mvn package
بدء تشغيل التطبيق الذي سيتم تشغيله لمدة ساعة واحدة حتى يتوقف يدوياً، ما يتيح لك الوقت لتشغيل اختبار تجاوز الفشل.
mvn -q -e exec:java "-Dexec.mainClass=com.sqldbsamples.App"
####################################### ## GEO DISTRIBUTED DATABASE TUTORIAL ## ####################################### 1. insert on primary successful, read from secondary successful 2. insert on primary successful, read from secondary successful 3. insert on primary successful, read from secondary successful ...
تجاوز الفشل التجريبي
تشغيل البرامج النصية التالية لمحاكاة تجاوز الفشل ومراقبة نتائج التطبيق. لاحظ كيف ستفشل بعض الإدراجات والتحديدات أثناء ترحيل قاعدة البيانات.
يمكنك التحقق من دور خادم التعافي من الكوارث أثناء الاختبار باستخدام الأمر التالي:
(Get-AzSqlDatabaseFailoverGroup -FailoverGroupName $failoverGroup `
-ResourceGroupName $resourceGroup -ServerName $drServer).ReplicationRole
لاختبار تجاوز الفشل:
بدء تجاوز فشل يدوي لمجموعة تجاوز الفشل:
Switch-AzSqlDatabaseFailoverGroup -ResourceGroupName $resourceGroup ` -ServerName $drServer -FailoverGroupName $failoverGroup
إعادة مجموعة تجاوز الفشل مرة أخرى إلى الخادم الأساسي:
Switch-AzSqlDatabaseFailoverGroup -ResourceGroupName $resourceGroup ` -ServerName $server -FailoverGroupName $failoverGroup
الخطوات التالية
في هذا البرنامج التعليمي، قمت بتكوين قاعدة بيانات في قاعدة بيانات Azure SQL وتطبيق تجاوز الفشل إلى منطقة نائية واختبار خطة تجاوز الفشل. تعلمت كيفية القيام بالتالي:
- إنشاء مجموعة تجاوز الفشل للنسخ المتماثل الجغرافي
- تشغيل تطبيق Java للاستعلام عن قاعدة بيانات في قاعدة بيانات SQL
- تجاوز الفشل التجريبي
انتقل إلى البرنامج التعليمي التالي حول كيفية إضافة مثيل Azure SQL Managed Instance إلى مجموعة تجاوز الفشل: