|
Навигация
|
Главная » Windows Миграция БД на Windows Azure SQL VM. BLOB Storage + RESTИсточник: habrahabr alexejs Теперь, когда мы имеем созданную в Облаке с установленным на нее SQL Server и умеем со стороны клиента с ним соединяться, как с локальным SQL Server, остается наполнить его данными. Предположим, в рамках гибридного сценария часть БД планируется перенести на Azure SQL VM. В этой статье будет рассматриваться сценарий, когда БД обособляется в виде файла (или нескольких файлов) посредством создания ее резервной копии, detach, data-tier application и т.д., файл доставляется на Azure SQL VM и превращается обратно в базу путем восстановления из бэкапа, attach, deploy/import data-tier application и т.д. Первое и последнее действие не вызывают вопросов у DBA. Осталось понять, как лучше доставить отчужденный файл с базой (.bak, .mdf, .bacpac, …) на облачную виртуалку с SQL Server.Для примера перенесем любимую базу данных AdventureWorks в виде ее резервной копии: backup database AdventureWorks2012 to disk = 'c:\Temp\AdventureWorks2012.bak' with init, compression, stats = 10 Скрипт 1 Файлы небольших размеров, как этот, можно, не мудрствуя лукаво, переносить обычным Copy/Paste на удаленный рабочий стол виртуальной машины SQL Server. Еще в голову приходит сделать на виртуалке папку общего доступа и скопировать туда, используя продвинутые средства копирования с возможностью распараллеливания, коррекции и взобновления в случае сбоев, а также передать файл по FTP. Эти способы очевидны. В данном посте мы задействуем иной способ: передадим файл бэкапа с локальной машины в Azure Storage в виде блоба и скачаем его оттуда внутрь облачной виртуалки. У нас уже имеется один Storage Account, созданный автоматически при создании виртуальной машины, в котором был автоматически контейнер по имени vhds, в котором в виде блоба хранится виртуальный диск нашей виртуальной машины. Для чистоты эксперимента создадим новый Storage Account под названием tststorage в том же центре обработки данных, что и облачная виртуалка, для сокращения накладных расходов. Внутри Azure Storage данные могут храниться в виде блобов или таблиц - см. Azure Data Management and Business Analytics в документации Windows Azure. Таблицы не являются таблицами в строгом реляционном понимании. Это просто слабо структурированные наборы пар ключ-значение подобно тому, что когда-то называлось SQL Data Services - см. Введение в SQL Azure. По сравнению с SDS нынешние таблицы могут партиционироваться по ключу. Разные партиции хранятся на разных машинах в Облаке, чем достигается горизонтальное масштабирование, как при шардинге в случае SQL Azure Database. Блобы бывают блочные и страничные. Структура блочных блобов оптимизирована для подокового доступа, страничных - для случайного чтения/записи. Страничная структура позволяет запсать в блоб диапазон байтов. Подробно разница между ними объясняется, например, здесь -blogs.msdn.com/b/windowsazurestorage/archive/2010/04/11/using-windows-azure-page-blobs-and-how-to-efficiently-upload-and-download-page-blobs.aspx. Виртуальные диски хранятся как страничные блобы. Хранение блобов осуществляется внутри контейнеров, которые создаются в рамках Storage Account. Создадим в эккаунте tststorage контейнер container1 под хранение AdventureWorks2012.bak. Публичный контейнер позволяет видеть любому желающему содержащиеся в нем блобы. Публичный блоб позволяет любому желающему доступаться к любому блобу, но содержание контейнера недоступно. Наконец, частный контейнер означает, что для доступа к блобу потребуется указывать ключ Storage Account. Изменить впоследствии уровень доступа к контейнеру можно при помощи кнопки Edit Container. Сделанную в Скрипте 1 резервную копию базы для простоты будем загружать в Azure Storage как блочный блоб. Для операций над блобами в Облаке (равно как и над таблицами, и очередями) можно использовать REST, что позволяет работать напрямую через Интернет (HTTP Request/Response), привлекая широкий диапазон средств разработки. REST API для работы с блобами описывается здесь - msdn.microsoft.com/en-us/library/dd135733.aspx. Так можно посмотреть, какие блобы лежат в публичном контейнере: tststorage.blob.core.windows.net/container1?restype=container&comp=list Контейнер container1 сейчас пуст. Чтобы загрузить в него AdventureWorks2012.bak, нужно использовать метод PUT: using System; using System.Net; using System.IO; using System.Security.Cryptography; using System.Text; using System.Globalization; class Program { static void Main(string[] args) { string fileFullName = @"c:\Temp\AdventureWorks2012.bak"; //@"c:\Temp\aaa.txt"; string storageAccount = "tststorage"; string containerName = "container1"; string accessKey = "xws7rilyLjqdw8t75EHZbsIjbtwYDvpZw790lda0L1PgzEqKHxGNIDdCdQlPEvW5LdGWK/qOZFTs5xE4P93A5A=="; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(String.Format("https://{0}.blob.core.windows.net/{1}/{2}", storageAccount, containerName, Path.GetFileName(fileFullName))); FileStream fs = File.OpenRead(fileFullName); byte[] fileContent = new byte[fs.Length]; fs.Read(fileContent, 0, fileContent.Length); fs.Close(); req.Method = "PUT"; req.ContentLength = fileContent.Length; req.Headers.Add("x-ms-blob-type", "BlockBlob"); req.Headers.Add("x-ms-date", DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture)); req.Headers.Add("x-ms-version", "2011-08-18"); string canonicalizedString = BuildCanonicalizedString(req, String.Format("/{0}/{1}/{2}", storageAccount, containerName, Path.GetFileName(fileFullName))); req.Headers["Authorization"] = CreateAuthorizationHeader(canonicalizedString, storageAccount, accessKey); req.Timeout = 100 * 60 * 1000; Stream s = req.GetRequestStream(); s.Write(fileContent, 0, fileContent.Length); DateTime dt = DateTime.Now; req.GetResponse(); System.Diagnostics.Debug.WriteLine(DateTime.Now - dt); } static string CreateAuthorizationHeader(string canonicalizedString, string storageAccount, string accessKey) { HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(accessKey)); byte[] dataToHMAC = Encoding.UTF8.GetBytes(canonicalizedString); string signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHMAC)); return "SharedKey " + storageAccount + ":" + signature; } static string BuildCanonicalizedString(HttpWebRequest req, string canonicalizedResource) { StringBuilder sb = new StringBuilder(); sb.Append(req.Method + "\n\n\n"); sb.Append(String.Format("{0}\n\n\n\n\n\n\n\n\n", req.ContentLength)); sb.Append("x-ms-blob-type:" + req.Headers["x-ms-blob-type"] + '\n'); sb.Append("x-ms-date:" + req.Headers["x-ms-date"] + '\n'); sb.Append("x-ms-version:" + req.Headers["x-ms-version"] + '\n'); sb.Append(canonicalizedResource); return sb.ToString(); } } Скрипт 2 В этом коде все достаточно очевидно за исключением, пожалуй, одного момента. Несмотря на то, что контейнер container1 был создан как публичный, запись блоба требует авторизации. Кто и какие операции может выполнять над блобами и контейнерами в зависимости от установленного уровня доступа описывается здесь -msdn.microsoft.com/en-us/library/dd179354.aspx. Вне зависимости от уровня доступа право на запись имеет владелец. Чтобы авторизоваться как владелец в HTTP Request требуется установить заголовок Authorization. Строка, записываемая в этот заголовок, в соответствии с требованиями схем аутентификации содержит подпись, которая представляет собой Hash-based Message Authentication Code (HMAC) канонизированной строки в кодировке UTF-8, где хэш вычисляется по алгоритму SHA256 на основе ключа доступа. Канонизированная строка складывается из метода доступа REST, размера загружаемого файла, типа блоба (x-ms-blob-type = блочный или страничный) даты/времени HTTP-запроса в формате UTC (x-ms-date), даты версии блобовского сервиса Azure, обслуживающего данный HTTP-запрос (x-ms-version) и др. Здесь не требуется блистать высоким программерским искусством, нужна лишь кропотливость и внимательность, т.к. малейшая неаккуратность при формировании канонизированной строки неумолимо влечет ошибку HTTP 403 Forbidden. Ключи доступа (основной и запасной) формируются на этапе создания Storage Account, их можно посмотреть в свойствах контейнера (Manage Keys). Любой из них можно задавать в качестве accessKey для создания цифровой подписи при авторизации - HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(accessKey)); Для более гранулярнного управления правами можно использовать подпись общего доступа (Shared Access Signature). Подпись общего доступа позволяет создать политику, позволяющую выполнять определенную операцию, например, запись внутри определенного контейнера в пределах отведенного промежутка времени. Человек, которому вручается подпись, будет способен действовать в рамках этой политики. Другая подпись, например, может уполномачивать читать из другого контейнера в течение другого периода. Прочие комментарии. • Если блоб с таким именем в контейнере существует, он молчаливо перетирается. • Имя контейнера чувствительно к регистру. • Время загрузки, очевидно, зависит от скорости сетки. Например, с работы данный 45-меговый бэкап залился со свистом за 00:01:07. Из дома получалось в разы медленнее. В данном демонстрационном примере бэкап имел достаточно "детский" размер. Блочные блобы ограничены размером в 200 ГБ. Блочный блоб размером менее 64 МБ может быть загружен одной операцией записи, как мы наблюдали в примере Скрипт 2. В противном случае следует разбивать его на куски и загружать поблочно с использованием методов Put Block / Put Block List. При заливке в Azure Storage крупных файлов следует применять страничные блобы. Страничный блоб состоит из 512-байтных страниц, его максимальный размер составляет 1 ТБ. Пример на запись/чтение диапазона страниц страничного блоба приводится здесь - blogs.msdn.com/b/windowsazurestorage/archive/2010/04/11/using-windows-azure-page-blobs-and-how-to-efficiently-upload-and-download-page-blobs.aspx. Системные требования к DOORS. Convergence 2012: Облачная ERP-система Microsoft появится в четвертом квартале. Развертывание Rational Change версии 5.2 и выше на Apache Tomcat. IBM Rational Perfomance Test Server. Все драйверы прошедшей недели (с 8 по 14 января 2007 года) (download). Главная » Windows |
© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено. |