البرنامج التعليمي: تخزين البيانات على الحافة مع قواعد بيانات SQL Server

ينطبق على: علامة اختيار IoT Edge 1.5 IoT Edge 1.5 علامة اختيار IoT Edge 1.4 IoT Edge 1.4

هام

IoT Edge 1.5 LTS وIoT Edge 1.4 LTS هي إصدارات مدعومة. IoT Edge 1.4 LTS هو نهاية العمر الافتراضي في 12 نوفمبر 2024. إذا كنت تستخدم إصدارا سابقا، فشاهد تحديث IoT Edge.

نشر وحدة نمطية SQL Server لتخزين البيانات على جهاز يعمل بـ Azure IoT Edge باستخدام حاويات Linux.

استخدم Azure IoT Edge SQL Server وSQL Server لتخزين البيانات والاستعلام عنها على الحافة. لدى Azure IoT Edge قدرات تخزين أساسية لتخزين الرسائل مؤقتاً إذا كان الجهاز دون اتصال، ثم إعادة توجيهها عند إعادة إنشاء الاتصال. ومع ذلك، قد تحتاج إلى قدرات تخزين أكثر تقدماً، مثل القدرة على الاستعلام عن البيانات محلياً. يمكن لأجهزة IoT Edge استخدام قواعد البيانات المحلية لتنفيذ حوسبة أكثر تعقيداً دون الحاجة إلى الحفاظ على الاتصال بمركز IoT.

توفر هذه المقالة إرشادات لنشر قاعدة بيانات SQL Server إلى جهاز IoT Edge. دالات Azure، التي تعمل على جهاز IoT Edge، تقوم بتنظيم البيانات الواردة ثم ترسلها إلى قاعدة البيانات. يمكن تطبيق الخطوات الواردة في هذه المقالة أيضاً على قواعد البيانات الأخرى التي تعمل في حاويات، مثل MySQL أو PostgreSQL.

في هذا البرنامج التعليمي، تتعلم كيفية:

  • استخدام التعليمات البرمجية Visual Studio لإنشاء دالة Azure
  • نشر قاعدة بيانات SQL إلى جهاز IoT Edge
  • استخدام التعليمات البرمجية Visual Studio لإنشاء وحدات نمطية ونشرها على جهاز IoT Edge
  • عرض البيانات التي تم إنشاؤها

إذا لم يكن لديك اشتراك في Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.

المتطلبات الأساسية

قبل البدء في هذا البرنامج التعليمي، يجب أن تكون قد مررت بالبرنامج التعليمي السابق لإعداد بيئة التطوير الخاصة بك لتطوير حاويات Linux: تطوير وحدات Azure IoT Edge النمطية باستخدام Visual Studio Code. من خلال استكمال هذا البرنامج التعليمي، يجب أن تكون لديك المتطلبات الأساسية التالية في المكان:

  • مركز مجاني أو قياسي لـIoT في Azure.
  • جهاز AMD64 يقوم بتشغيل Azure IoT Edge مع حاويات Linux. يمكنك استخدام قوالب التشغيل السريع لإعداد جهاز Linux أو جهاز Windows.
    • لا يمكن لأجهزة ARM، مثل Raspberry Pis، تشغيل SQL Server. إذا كنت ترغب في استخدام SQL على جهاز ARM، فيمكنك استخدام Azure SQL Edge.
  • سجل حاوية، مثل Azure Container Registry .
  • تم تكوين Visual Studio Code باستخدام ملحقات Azure IoT Edge وAzure IoT Hub . أدوات Azure IoT Edge لملحق Visual Studio Code في وضع الصيانة.
  • قم بتنزيل وتثبيت نظام إدارة حاويات متوافق مع Docker على جهاز التطوير الخاص بك. قم بتكوينه لتشغيل حاويات Linux.

يستخدم هذا البرنامج التعليمي الوحدة النمطية دالات Azure لإرسال البيانات إلى SQL Server. لتطوير وحدة IoT Edge النمطية باستخدام دالات Azure، ثبت المتطلبات الأساسية الإضافية التالية على جهاز التطوير الخاص بك:

إنشاء مشروع دالة

لإرسال البيانات إلى قاعدة بيانات، تحتاج إلى وحدة نمطية يمكنها تنظيم البيانات بشكل صحيح ثم تخزينها في جدول.

إنشاء مشروع جديد

توضح لك الخطوات التالية كيفية إنشاء دالة IoT Edge باستخدام Visual Studio Code وملحق Azure IoT Edge.

  1. فتح Visual Studio Code.

  2. افتح لوحة أوامر Visual Studio Code عن طريق تحديد عرض>لوحة الأوامر.

  3. في لوحة الأوامر، اكتب الأمر Azure IoT Edge: New IoT Edge solution وشغله. في لوحة الأوامر، قدم المعلومات التالية لإنشاء الحل الخاص بك:

    الحقل القيمة
    حدد مجلدًا اختر الموقع على جهاز التطوير الخاص بك ل Visual Studio Code لإنشاء ملفات الحل.
    تقديم اسم حل أدخل اسماً وصفياً للحل الخاص بك، مثل SqlSolution، أو اقبل استخدام الاسم الافتراضي.
    تحديد قالب الوحدة النمطية اختر Azure Functions - C#‎.
    تقديم اسم وحدة نمطية قم بتسمية الوحدة النمطية الخاصة بك sqlFunction.
    توفير مستودع صور Docker للوحدة النمطية يتضمن مستودع الصور اسم سجل الحاوية واسم صورة الحاوية الخاصة بك. تم ملء صورة الحاوية مسبقًا من الخطوة الأخيرة. استبدل localhost:5000 بقيمة خادم تسجيل الدخول من سجل حاوية Azure. يمكنك استرداد خادم تسجيل الدخول من صفحة النظرة العامة الخاصة بسجل الحاوية في مدخل Azure.

    تبدو السلسلة النهائية مثل <اسم> السجل.azurecr.io/sqlfunction.

    تقوم نافذة Visual Studio Code بتحميل مساحة العمل حل IoT Edge.

إضافة بيانات اعتماد التسجيل الخاصة بك

ملف البيئة يخزن بيانات الاعتماد الخاصة بسجل الحاوية ويشاركها مع وقت التشغيل IoT Edge. يحتاج وقت التشغيل إلى بيانات الاعتماد هذه لسحب الصور الخاصة بك إلى جهاز IoT Edge.

يحاول ملحق IoT Edge سحب بيانات اعتماد سجل الحاوية من Azure وتعبئتها في ملف البيئة. تحقق لمعرفة ما إذا كانت بيانات الاعتماد الخاصة بك مضمنة بالفعل. إذا لم يكن كذلك، فأضفها الآن:

  1. في مستكشف Visual Studio Code، افتح ملف .env.
  2. حدث الحقول باستخدام قيم اسم المستخدم وكلمة المرور التي نسختها من سجل حاوية Azure.
  3. احفظ هذا الملف.

إشعار

يستخدم هذا البرنامج التعليمي بيانات اعتماد تسجيل دخول المسؤول لسجل حاوية Azure، والتي تعتبر ملائمة لسيناريوهات التطوير والاختبار. عندما تكون جاهزًا لسيناريوهات الإنتاج، نوصي بخيار مصادقة أقل امتيازًا مثل أساسيات الخدمة. لمزيد من المعلومات، راجع إدارة الوصول إلى سجل الحاوية.

تحديد بنية الهدف

تحتاج إلى تحديد البنية التي تستهدفها مع كل حل، لأن الحاوية مبنية ويتم تشغيلها بشكل مختلف لكل نوع من أنواع البني. الافتراضي هو Linux AMD64.

  1. افتح لوحة الأوامر وابحث عن Azure IoT Edge: Set Default Target Platform for Edge Solution، أو حدد رمز الاختصار في الشريط الجانبي أسفل النافذة.

  2. في لوحة الأوامر، حدد بنية الهدف من قائمة الخيارات. في هذا البرنامج التعليمي، نستخدم جهاز Ubuntu الظاهري كجهاز IoT Edge، لذلك سنتخذ amd64 الافتراضي.

تحديث الوحدة النمطية باستخدام التعليمات البرمجية المخصصة

  1. في مستكشف Visual Studio Code، افتح الوحدات النمطية>sqlFunction>sqlFunction.csproj.

  2. ابحث عن مجموعة من مراجع الحزمة وأضف واحدة جديدة لتضمين SqlClient.

    <PackageReference Include="System.Data.SqlClient" Version="4.5.1"/>
    
  3. احفظ الملف sqlFunction.csproj.

  4. افتح الملف sqlFunction.cs.

  5. استبدل محتويات الملف بالكامل بالتعليمات البرمجية التالية:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Azure.Devices.Client;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.EdgeHub;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    using Newtonsoft.Json;
    using Sql = System.Data.SqlClient;
    
    namespace Functions.Samples
    {
        public static class sqlFunction
        {
            [FunctionName("sqlFunction")]
            public static async Task FilterMessageAndSendMessage(
                [EdgeHubTrigger("input1")] Message messageReceived,
                [EdgeHub(OutputName = "output1")] IAsyncCollector<Message> output,
                ILogger logger)
            {
                const int temperatureThreshold = 20;
                byte[] messageBytes = messageReceived.GetBytes();
                var messageString = System.Text.Encoding.UTF8.GetString(messageBytes);
    
                if (!string.IsNullOrEmpty(messageString))
                {
                    logger.LogInformation("Info: Received one non-empty message");
                    // Get the body of the message and deserialize it.
                    var messageBody = JsonConvert.DeserializeObject<MessageBody>(messageString);
    
                    //Store the data in SQL db
                    const string str = "<sql connection string>";
                    using (Sql.SqlConnection conn = new Sql.SqlConnection(str))
                    {
                        conn.Open();
                        var insertMachineTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'machine', " + messageBody.machine.temperature + ");";
                        var insertAmbientTemperature = "INSERT INTO MeasurementsDB.dbo.TemperatureMeasurements VALUES (CONVERT(DATETIME2,'" + messageBody.timeCreated + "', 127), 'ambient', " + messageBody.ambient.temperature + ");";
                        using (Sql.SqlCommand cmd = new Sql.SqlCommand(insertMachineTemperature + "\n" + insertAmbientTemperature, conn))
                        {
                            //Execute the command and log the # rows affected.
                            var rows = await cmd.ExecuteNonQueryAsync();
                            logger.LogInformation($"{rows} rows were updated");
                        }
                    }
    
                    if (messageBody != null && messageBody.machine.temperature > temperatureThreshold)
                    {
                        // Send the message to the output as the temperature value is greater than the threashold.
                        using (var filteredMessage = new Message(messageBytes))
                        {
                             // Copy the properties of the original message into the new Message object.
                             foreach (KeyValuePair<string, string> prop in messageReceived.Properties)
                             {filteredMessage.Properties.Add(prop.Key, prop.Value);}
                             // Add a new property to the message to indicate it is an alert.
                             filteredMessage.Properties.Add("MessageType", "Alert");
                             // Send the message.
                             await output.AddAsync(filteredMessage);
                             logger.LogInformation("Info: Received and transferred a message with temperature above the threshold");
                        }
                    }
                }
            }
        }
        //Define the expected schema for the body of incoming messages.
        class MessageBody
        {
            public Machine machine {get; set;}
            public Ambient ambient {get; set;}
            public string timeCreated {get; set;}
        }
        class Machine
        {
            public double temperature {get; set;}
            public double pressure {get; set;}
        }
        class Ambient
        {
            public double temperature {get; set;}
            public int humidity {get; set;}
        }
    }
    
  6. في السطر 35، استبدل سلسلة <sql سلسلة الاتصال> بالسلسلة التالية. تشير خاصية مصدر البيانات إلى حاوية SQL Server، وهي غير موجودة بعد. ستقوم بإنشائها باسم SQL في القسم التالي.

    Data Source=tcp:sql,1433;Initial Catalog=MeasurementsDB;User Id=SA;Password=Strong!Passw0rd;TrustServerCertificate=False;Connection Timeout=30;
    
  7. احفظ الملف sqlFunction.cs.

إضافة الحاوية SQL Server

يظهر بيان النشر الوحدات النمطية التي سيقوم وقت التشغيل IoT بتثبيتها على جهاز IoT Edge. لقد قمت بتوفير التعليمات البرمجية لإنشاء وحدة نمطية مخصصة للدالة في القسم السابق، ولكن الوحدة النمطية SQL Server تم إنشاؤها بالفعل ومتاحة في Microsoft Artifact Registry. تحتاج فقط إلى إخبار وقت تشغيل IoT Edge لتضمينها، ثم تكوينها على جهازك.

  1. في Visual Studio Code، افتح لوحة الأوامر عن طريق تحديد View > Command Palette.

  2. في لوحة الأوامر، اكتب الأمر Azure IoT Edge: Add IoT Edge module وشغله. في لوحة الأوامر، قدم المعلومات التالية لإضافة وحدة نمطية جديدة:

    الحقل القيمة
    تحديد ملف قالب النشر تقوم لوحة الأوامر بتمييز الملف deployment.template.json في مجلد الحل الحالي. حدِّد هذا الملف.
    تحديد قالب الوحدة النمطية حدد الوحدة النمطية الموجودة (أدخل عنوان URL للصورة الكاملة).
    توفير اسم الوحدة النمطية أدخل sql. يطابق هذا الاسم اسم الحاوية الذي ظهر في سلسلة الاتصال في ملف sqlFunction.cs.
    توفير صورة Docker للوحدة النمطية أدخل URI التالي لسحب صورة حاوية SQL Server من Microsoft Artifact Registry. بالنسبة للصور المستندة إلى Ubuntu، استخدم mcr.microsoft.com/mssql/server:latest. بالنسبة للصور المستندة إلى Red Hat Enterprise Linux (RHEL)، استخدم mcr.microsoft.com/mssql/rhel/server:latest.

    صورة حاوية Azure SQL Edge هي إصدار خفيف الوزن ومزود بالحاويات من SQL Server يمكن تشغيله على أجهزة IoT Edge. تم تحسينه لسيناريوهات الحافة ويمكن تشغيله على أجهزة ARM وAMD64.

  3. في مجلد الحل، افتح الملف deployment.template.json.

  4. ابحث عن قسم الوحدات النمطية. يجب أن ترى ثلاث وحدات نمطية. يتم تضمين الوحدة النمطية SimulatedTemperatureSensor بشكل افتراضي في الحلول الجديدة، وتوفر بيانات الاختبار لاستخدامها مع الوحدات النمطية الأخرى. الوحدة النمطية sqlFunction هي الوحدة النمطية التي قمت بإنشائها أولاً وتحديثها باستخدام التعليمات البرمجية الجديدة. وأخيرا، تم استيراد الوحدة النمطية sql من Microsoft Artifact Registry.

    تلميح

    تأتي الوحدة النمطية SQL Server مع كلمة مرور افتراضية معينة في متغيرات بيئة بيان النشر. في أي وقت تقوم فيه بإنشاء حاوية SQL Server في بيئة إنتاج، يجب تغيير كلمة مرور مسؤول النظام الافتراضية.

  5. أغلق الملف deployment.template.json.

إنشاء حل IoT Edge الخاص بك

في المقاطع السابقة، قمت بإنشاء حل مع وحدة نمطية واحدة، ثم قمت بإضافة آخر إلى قالب بيان النشر. تتم استضافة الوحدة النمطية SQL Server بشكل عام من قبل Microsoft، ولكن تحتاج إلى احتواء التعليمات البرمجية في الوحدة النمطية Functions. في هذا القسم، يمكنك إنشاء الحل، إنشاء صور حاوية للوحدة النمطية sqlFunction، ودفع الصورة إلى سجل الحاوية.

  1. في Visual Studio Code، افتح "Integrated Terminal" عن طريق تحديد "View>Terminal".

  2. سجل الدخول إلى سجل الحاوية في Visual Studio Code بحيث يمكنك دفع الصور إلى السجل. استخدم نفس بيانات اعتماد سجل حاويات Azure (ACR) التي قمت بإضافتها إلى الملف .env. أدخل الأمر التالي في المحطة الطرفية المدمجة:

    docker login -u <ACR username> -p <ACR password> <ACR login server>
    

    قد تشاهد تحذير أمان يوصي باستخدام المعلمة --password-stdin. وبالرغم من أن استخدامه خارج نطاق هذه المقالة، إلا إننا نوصي باتباع هذه الممارسة الأفضل. لمزيد من المعلومات، راجع مرجع الأمر تسجيل الدخول إلى docker.

  3. في مستكشف Visual Studio Code، انقر بزر الماوس الأيمن فوق ملف deployment.template.json وحدد Build and Push IoT Edge solution.

    يبدأ أمر الإنشاء والدفع ثلاث عمليات. أولًا، يقوم بإنشاء مجلد جديد في الحل يُسمى config والذي يحتوي على بيان النشر الكامل، والذي تم إنشاؤه من المعلومات الموجودة في قالب النشر وملفات الحل الأخرى. ثانيًا، يقوم بتشغيل docker build لإنشاء صورة الحاوية بناءً على dockerfile المناسب للبنية المستهدفة. بعد ذلك، يتم تشغيل docker push لدفع مستودع الصور إلى سجل الحاوية الخاص بك.

    قد تستغرق هذه العملية عدة دقائق في المرة الأولى ولكن أسرع في المرة التالية التي تقوم بتشغيل الأوامر.

    يمكنك التحقق من أنه تم دفع الوحدة النمطية sqlFunction بنجاح إلى سجل الحاوية. في مدخل Microsoft Azure، انتقل إلى سجل الحاوية. حدد المستودعات وابحث عن sqlFunction. لن يتم دفع الوحدات النمطية الأخرى، SimulatedTemperatureSensor وsql، إلى سجل الحاوية لأن مستودعاتها موجودة بالفعل في سجلات Microsoft.

نشر الحل على جهاز

يمكنك تعيين وحدات نمطية على جهاز من خلال مركز IoT، ولكن يمكنك أيضاً الوصول إلى مركز وأجهزة IoT من خلال Visual Studio Code. في هذا القسم، يمكنك إعداد الوصول إلى IoT Hub ثم استخدام Visual Studio Code لنشر الحل الخاص بك على جهاز IoT Edge.

  1. في مستكشف Visual Studio Code، ضمن قسم Azure IoT Hub، قم بتوسيع Devices لمشاهدة قائمة أجهزة IoT الخاصة بك.

  2. انقر بزر الماوس الأيمن فوق الجهاز الذي تريد استهدافه بالنشر،‏ ثم حدد إنشاء نشر لجهاز واحد.

  3. افتح الملف deployment.amd64.json في المجلد config ثم انقر فوق Select Edge Deployment Manifest. لا تستخدم deployment.template.js في الملف.

  4. ضمن جهازك، قم بتوسيع Modules لمشاهدة قائمة بالوحدات النمطية التي تم نشرها وتشغيلها. انقر فوق الزر التحديث. من المفترض أن ترى الوحدات النمطية sql وsqlFunction تعمل جنباً إلى جنب مع الوحدة النمطية SimulatedTemperatureSensor و$edgeAgent و$edgeHub.

    يمكنك أيضا التحقق من أن جميع الوحدات نشطة وتعمل على جهازك. على جهاز IoT Edge، قم بتشغيل الأمر التالي لمشاهدة حالة الوحدات النمطية.

    iotedge list
    

    قد يستغرق الأمر بضع دقائق لبدء تشغيل الوحدات النمطية. يحتاج وقت تشغيل IoT Edge إلى استلام بيان النشر الجديد الخاص به، وسحب صور الوحدة النمطية من وقت تشغيل الحاوية، ثم بدء تشغيل كل وحدة نمطية جديدة.

إنشاء قاعدة بيانات SQL

عند تطبيق بيان التوزيع على جهازك، ستحصل على ثلاث وحدات نمطية قيد التشغيل. تقوم الوحدة النمطية SimulatedTemperatureSensor بإنشاء بيانات بيئة المحاكاة. تقوم الوحدة النمطية sqlFunction بأخذ البيانات وتنسيقها من أجل قاعدة بيانات. يرشدك هذا القسم من خلال إعداد قاعدة بيانات SQL لتخزين بيانات درجة الحرارة.

شغل الأوامر التالية على جهاز IoT Edge. تتصل هذه الأوامر بوحدة sql التي تعمل على جهازك وتنشئ قاعدة بيانات وجدولاً للاحتفاظ ببيانات درجة الحرارة التي يتم إرسالها إليها.

  1. في أداة سطر الأوامر على جهاز IoT Edge، اتصل بقاعدة البيانات.

    sudo docker exec -it sql bash
    
  2. افتح أداة الأمر SQL.

    /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P 'Strong!Passw0rd'
    
  3. إنشاء قاعدة البيانات:

    CREATE DATABASE MeasurementsDB
    ON
    (NAME = MeasurementsDB, FILENAME = '/var/opt/mssql/measurementsdb.mdf')
    GO
    
  4. حدد جدولك.

    CREATE TABLE MeasurementsDB.dbo.TemperatureMeasurements (measurementTime DATETIME2, location NVARCHAR(50), temperature FLOAT)
    GO
    

يمكنك تخصيص ملف SQL Server docker لإعداد SQL Server ليتم نشرها على أجهزة IoT Edge متعددة تلقائيا. لمزيد من المعلومات، راجع المشروع التجريبي لحاوية Microsoft SQL Server.

عرض البيانات المحلية

بمجرد إنشاء الجدول الخاص بك، تبدأ الوحدة النمطية sqlFunction بتخزين البيانات في قاعدة بيانات محلية SQL Server 2017 على جهاز IoT Edge.

من داخل أداة الأمر SQL، شغل الأمر التالي لعرض بيانات الجدول المنسقة:

SELECT * FROM MeasurementsDB.dbo.TemperatureMeasurements
GO

عرض محتويات قاعدة البيانات المحلية

تنظيف الموارد

إذا كنت تخطط للمتابعة إلى المقالة التالية الموصى بها، يمكنك الاحتفاظ بالموارد والتكوينات التي قمت بإنشائها وإعادة استخدامها. يمكنك أيضا الاستمرار في استخدام نفس جهاز IoT Edge كجهاز اختبار.

وإلا، يمكنك حذف التكوينات المحلية وموارد Azure التي قمت بإنشائها في هذه المقالة لتجنب الرسوم.

قم بحذف موارد Azure.

حذف موارد Azure ومجموعات الموارد لا رجعة فيه. يُرجى التأكد من عدم حذف مجموعة الموارد أو الموارد غير الصحيحة عن طريق الخطأ. إذا قمت بإنشاء مركز IoT داخل مجموعة موارد موجودة لديها موارد تريد الاحتفاظ بها، فاحذف فقط مورد محور IoT نفسه، وليس مجموعة الموارد.

لحذف الموارد:

  1. سجل الدخول إلى مدخل Azure، وحدد "Resource groups".

  2. حدد اسم مجموعة الموارد التي تحتوي على موارد اختبار IoT Edge.

  3. راجع قائمة الموارد الموجودة في مجموعة الموارد الخاصة بك. إذا كنت تريد حذفها جميعاً، يمكنك تحديد Delete resource group. إذا كنت تريد حذف بعضها فقط، فيمكنك النقر فوق كل مورد لحذفها بشكل فردي.

في هذا البرنامج التعليمي، قمت بإنشاء وحدة Azure Functions النمطية التي تحتوي على تعليمات برمجية لتصفية البيانات الأولية التي تم إنشاؤها بواسطة جهاز IoT Edge. عندما تكون مستعدا لإنشاء وحداتك النمطية الخاصة، يمكنك معرفة المزيد حول كيفية تطوير وحدات Azure IoT Edge النمطية باستخدام Visual Studio Code.

الخطوات التالية

إذا كنت ترغب في تجربة أسلوب تخزين آخر على الحافة، فاقرأ حول كيفية استخدام مخزن البيانات الثنائية كبيرة الحجم لـ Azure على IoT Edge.