SETEMBRO, 2010 | SÃO PAULO CÓDIGO DA SESSÃO: DEV301 Desenvolvendo para Azure Otavio Pecego Coelho Arquiteto Chefe Microsoft Brasil http://blogs.msdn.com/otavio [email protected] Agenda O que é o Windows Azure? Azure Storage Blob e Disk Table Filas CDN O que faltou? O que é o Windows Azure? EMPRESAS CONSUMIDORES INTERNET Provisionamento elástico e alta escalabilidade para empresas e consumidores finais. O que é o Windows Azure? Controlador da Malha de Servidores Aplicações no Windows Azure Dois tipos de Instâncias: Web Role & Worker Role Cada instância roda na sua própria VM e é replicada caso necessário Windows Azure Roles 4.0 • • • • Role Entry Point Diagnostics Intellitrace Local Drive 4.0 • • • • Role Entry Point Diagnostics Intellitrace Local Drive Desafio: HelloCloud Minha primeira aplicação na nuvem • • • • Construa e publique sua aplicação no Windows Azure Mostre sua aplicação no estande Windows Azure Preencha o formulário Concorra a 10 assinaturas MSDN Premium Visite o estande de Windows Azure e saiba todos os detalhes deste Desafio! Opções de Comunicação Internet LB Internet Windows Azure Queues WebSite Site Web Web Site (ASPX, ASMX, WCF) Worker Worker Worker Service Service Service (ASPX, ASMX, WCF) (ASPX, WCF, etc.) Tables Storage LB Blobs Controle do Tempo de Vida de uma Instância no Azure OnStart Busy Bootstrap Role Run Ready Loop de espera (worker) OnStop, Stopping Prepara para Shutdown 30 secs Stopping (Busy) RoleEnvironment.Changing, Changed Exemplo da Gerência de uma Role Azure Storage Tipos de Storages do Windows Azure BLOBS: TABELAS: Fornece uma interface Fornece simples para armazenar armazenamento arquivos nomeados, estruturado. Uma juntamente com tabela é um conjunto metadados do arquivo. de entidades que contém um conjunto de propriedades. FILAS: Fornece entrega de mensagens para uma aplicação e armazenamento confiáveis Drive: Um volume do sistema de arquivo NTFS durável, compartilhável entre as instâncias Conta Usuário cria nome globalmente único Conta Pode ser armazenado em qualquer datacenter do Azure Pode estar localizado em conjunto com os serviços de computação Usa uma chave secreta de 256 bits Cada Conta: Armazena até 100TB O limite padrão é de 5 Contas por subscrição Blob Blobs e Containers Guarda objetos (1TB p/ Page Blob e 200GB p/ Block Blob) Uma conta de Storage tem vários Blob Containers Container Contém uma coleção de blobs O compartilhamento de políticas é feita no nível do container Public READ ou Private Associa Metadados com o Container Metadado é um conjunto de pares <nome, valor> Até 8KB por container Account Container Blob IMG001.JPG Pictures http://<Account>.blob.core.windows.net/<Container>/<BlobName> IMG002.JPG Account Movies MOV1.AVI Blob + Blocos e/ou Página Conta Container pictures Blob IMG001. JPG Bloco /Página IMG002. JPG otavio Bloco/Pag 1 movies MOV1.AVI Bloco/Pag 2 Bloco/Pag 3 Escrevendo num Blob public static bool WriteFileToBlob( string configurationSettingName, string containerName, string blobName, string fileName) { CloudStorageAccount storageAccountInfo = CloudStorageAccount.FromConfigurationSetting( "DataConnectionString"); try { //cria classe de referência CloudBlobClient blobClient = storageAccountInfo.CreateCloudBlobClient(); // cria container CloudBlobContainer container = blobClient.GetContainerReference(containerName); container.CreateIfNotExist(); } // coloca array no container container.GetBlobReference(blobName).UploadFile(fileName); ... Lendo de um Blob protected string GetBlockBlobStream(String blobAddress) { String blobText; CloudStorageAccount cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient(); CloudBlockBlob cloudBlockBlob = cloudBlobClient.GetBlockBlobReference(blobAddress); using (MemoryStream memoryStream = new MemoryStream()) { cloudBlockBlob.DownloadToStream(memoryStream); Int64 streamSize = memoryStream.Length; memoryStream.Seek(0, SeekOrigin.Begin); using (StreamReader streamReader = new StreamReader(memoryStream)) { blobText = streamReader.ReadToEnd(); } } } return blobText; Upload de um Blob com Blocos Upload de um blob GRANDE Block Id N Block Id 1 Block Id 2 Block Id 3 10 GB Movie blobName = “TheBlob.wmv”; PutBlock(blobName, blockId1, block1Bits); PutBlock(blobName, blockId2, block2Bits); ………… PutBlock(blobName, blockIdN, blockNBits); PutBlockList(blobName, blockId1,…,blockIdN); TheBlob.wmv Windows Azure Storage Usando PutBlock – sobe um único bloco! protected void PutBlockFromStream( ref String blobText, String containerName, String blobName, Int32 blockId) { CloudStorageAccount cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName); CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(blobName); UTF8Encoding utf8Encoding = new UTF8Encoding(); using (MemoryStream memoryStream = new MemoryStream(utf8Encoding.GetBytes(blobText))) { } } cloudBlockBlob.PutBlock( Convert.ToBase64String( System.BitConverter.GetBytes(blockId)), memoryStream, null); Usando PutBlockList – (Commit de uma lista de Blocos) protected void PutBlockList(String containerName, String blobName, Int32 numBlocks ) { CloudStorageAccount cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient(); CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName); CloudBlockBlob cloudBlockBlob = cloudBlobContainer.GetBlockBlobReference(blobName); String[] blockIds = new String[numBlocks]; for (Int32 i = 0; i < numBlocks; i++) { blockIds[i] = Convert.ToBase64String( System.BitConverter.GetBytes(i) ); } } cloudBlockBlob.PutBlockList(blockIds); Page Blob (novo) – para Escrita e Leitura Randômica Cria MyBlob Especifica Tamanho do Blob = 10 GBytes 0 1024 1536 2048 2560 10 GB 10 GB Espaço de Endereçamento 512 Tamanho Fixo da Página = 512 bytes Operações de Acesso Randômicas PutPage[512, 2048) PutPage[0, 1024) ClearPage[512, 1536) PutPage[2048,2560) GetPageRange[0, 4096) retorna intervalos válidos: [0,512) , [1536,2560) GetBlob[1000, 2048) returna Zeros para os primeiros 536 bytes Próximos 512 bytes são os dados armazenados em [1536,2048) Escolhendo entre Block e Page Blob Block Blob Feito para cenários de streaming (leitura linear) Semântica de Update Upload de conjuntos de blocos para, então, dar commit. Concorrência: ETag Checks Page Blob Feito para cenários de leitura/escrita randômicas Semântica de Update Update imediato Concorrência: Leases Exemplo de “Snapshot” de um Blob Todas escritas aplicadas no base blob Somente deltas são mantidos entre snapshots MyBlob Exemplo de “Snapshot” de um Blob Todas escritas aplicadas tendo como referência o blob base Somente deltas são mantidos entre snapshots Volte a uma versão anterior via promoção de snapshot Pode usar ListBlobs para enumerar os snapshots de um blob MyBlob Promote Lease de um Blob Cenário Manter o blob “arrendado” para realizar updates exclusivos Operações de Lease Acquire, Renew, Release Acquire Retorna um Lease-ID, para ser usado nas próximas operações Políticas de Acesso Exclusive Modify – só quem fez lease pode modificar Read Access – qualquer um pode ler Renew lease Faça renew para continuar tendo acesso Exemplo: Acquire Lease public static string AcquireLease(this CloudBlob blob) { var creds = blob.ServiceClient.Credentials; var transformedUri = new Uri(creds.TransformUri(blob.Uri.ToString())); var req = BlobRequest.Lease(transformedUri, 90, // timeout (em segundos) LeaseAction.Acquire, // e não "break" //"release" ou "renew" null); // nome do lease existente (se algum) blob.ServiceClient.Credentials.SignRequest(req); using (var response = req.GetResponse()) { return response.Headers["x-ms-lease-id"]; } } Drive Windows Azure Drive (new) Implementa um volume NTFS durável para que os aplicativos Windows Azure façam uso Use a API do NTFS existente para acessar o drive Durabilidade e sobrevivência do dado no caso de failover Facilita a migração de aplicativos para o Azure Um Drive Windows Azure é um Page Blob Exemplo: montar um Page Blob com X:\ http://<accountname>.blob.core.windows.net/<containername>/<blobname> Todas as escritas no drive tornam-se duráveis via o Page Blob Cada Role suporta até 8 drives Como funciona o Windows Azure Drive Application Drive X: Local Cache Lease Windows Azure Blob Service Windows Azure Drives Lease Snapshot Exemplos de API do Drive public static void EnumerateDrives() { IDictionary<String, Uri> listDrives = CloudDrive.GetMountedDrives(); } foreach (KeyValuePair<String, Uri> drive in listDrives) { String driveInformation = String.Format("drive: {0} - uri: {1}", drive.Key, drive.Value.AbsoluteUri); Trace.WriteLine(driveInformation, "Information"); } public void WriteToDrive(Uri cloudDriveUri) { CloudStorageAccount cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString"); cloudDrive = cloudStorageAccount.CreateCloudDrive(cloudDriveUri.AbsoluteUri); String driveLetter = cloudDrive.Mount(CacheSizeInMegabytes, DriveMountOptions.None); String path = String.Format("{0}\\Pippo.txt", driveLetter); FileStream fileStream = new FileStream(path, FileMode.OpenOrCreate); StreamWriter streamWriter = new StreamWriter(fileStream); streamWriter.Write("that you have but slumbered here"); streamWriter.Close(); } cloudDrive.Unmount(); Carregando um Drive static public void UploadCloudDrive(CloudBlobClient cloudBlobClient, String containerName, String blobName, string path) { CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference(containerName); CloudPageBlob cloudPageBlob = cloudBlobContainer.GetPageBlobReference(blobName); cloudPageBlob.Properties.ContentType = "binary/octet-stream"; const const Int32 Int32 Int32 uploadSize = 0x100000; // 1MB Int32 numberFooterBytes = 0x200; //512B countBytesUploaded = 0; countBytesRead = 0; using (FileStream fileStream = new FileStream(path, FileMode.Open)) { Int32 blobSize = (Int32)fileStream.Length; Int32 offset = 0; cloudPageBlob.Create(blobSize); Int32 numberIterations = blobSize / uploadSize; for (Int32 i = 0; i < numberIterations; i++) { Byte[] bytes = new Byte[uploadSize]; countBytesRead += fileStream.Read(bytes, 0, uploadSize); } using (MemoryStream memoryStream = new MemoryStream(bytes)) { cloudPageBlob.WritePages(memoryStream, offset); offset += uploadSize; countBytesUploaded += uploadSize; } Byte[] footerBytes = new Byte[numberFooterBytes]; countBytesRead += fileStream.Read(footerBytes, 0, numberFooterBytes); } } using (MemoryStream memoryStream = new MemoryStream(footerBytes)) //Última Página { cloudPageBlob.WritePages(memoryStream, offset); offset += numberFooterBytes; countBytesUploaded += numberFooterBytes; } Table Windows Azure Table Fornece Storage Estruturado São Tabelas Massivamente Escaláveis Bilhões de Tabelas e Entidades (rows) Escala automaticamente até milhares de servidores quando o tráfego aumenta Altamente Disponível Pode acessar seu dado sempre Durável O dado é replicado pelo menos 3 vezes Interfaces de Programação Familiares e Simples WCF Data Services - .NET 3.5 SP1/ 4.0 Classes .NET e LINQ REST – com qualquer plataforma ou linguagem Modelo de Dados de uma Table • Table • Uma conta de Storage pode criar várias tables • O nome da Table pertence ao escopo de uma conta Tables armazenam Entidades Uma Table é um conjunto de Entidades (rows) Uma Entidade é um conjunto de Propriedades (columns) – máximo de 255 Chaves para Entidades Contém sempre duas propriedade “chaves” que junto têm o ID único da entidade na Table PartitionKey – permite a escalabilidade RowKey – identifica unicamente a entidade dentro da partição Exemplo de Particionamento Partition Key Nome do Documento Row Key Versão Property 3 Data/Hora da Modificação … Property N Descrição Example Doc V1.0 8/2/2007 … Committed version Example Doc V2.0.1 9/28/2007 Alice’s working version FAQ Doc V1.0 5/2/2007 Committed version FAQ Doc V1.0.1 7/6/2007 Alice’s working version FAQ Doc V1.0.2 8/1/2007 Sally’s working version Partição 1 Partição 2 Partição da Tabela – todas as entidades na tabela com a mesma Chave de Partição A aplicação controla a granularidade da partição Escalabilidade da Table: Load balance automático das partições; Entidades na mesma partição são armazenadas juntas => queries eficientes e garante a mesma localidade do cache Definindo uma Entidade public class Message : Microsoft.WindowsAzure.StorageClient. TableServiceEntity { public string Name { get; set; } public string Body { get; set; } } public Message() { PartitionKey = "a"; RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks DateTime.Now.Ticks, Guid.NewGuid()); } Definindo um Context public class MessageDataServiceContext : TableServiceContext { public IQueryable<Message> Messages { get { return this.CreateQuery<Message>("Messages"); } } public MessageDataServiceContext(string baseAddress, StorageCredentials credentials) : base(baseAddress, credentials) { } public void AddMessage(string name, string body) { this.AddObject( "Messages", new Message { Name = name, Body = body } ); } } this.SaveChanges(); Usando um Context var account = CloudStorageAccount.FromConfigurationSetting( "DataConnectionString"); // criação da tabela CloudTableClient.CreateTablesFromModel( typeof(MessageDataServiceContext), account.TableEndpoint.AbsoluteUri, account.Credentials ); // criação do contexto var context = new MessageDataServiceContext( account.TableEndpoint.ToString(), account.Credentials ); context.AddMessage(this.nameBox.Text, this.messageBox.Text); // !!! this.messageList.DataSource = context.Messages; this.messageList.DataBind(); Transações de Grupo de Entidades Suporta até 100 CUDs num único batch (máximo de 4M em tamanho) Todos comandos têm que se referir a uma única partição Comandos são executados na ordem de envio Pode haver colisões em caso de concorrência sobre uma mesma entidade Exemplo de Transação de um Grupo // loop de inserções for (int index = 0; index < newBlogs.Length; index++) { context.AddObject(newBlogs[index]); } // loop de deleções for (int index = 0; index < deletedBlogs.Length; index++) { context.DeleteObject(deletedBlogs[index]); } // loop de updates for (int index = 0; index < updatedBlogs.Length; index++) { updatedBlogs[index].Rating++; context.UpdateObject(updatedBlogs[index]); } // Operações CUD executadas num único batch. DataServiceResponse response = context.SaveChanges(SaveChangesOptions.Batch); Dicas para uso de Tabelas Esteja preparado para resultados parciais de suas queries Linq => use Take(N) Cuidado: DataServiceContext não é “thread safe” ! Ao armazenar tipos diferentes de entidades na mesma tabela Faça com que parte da sua RowKey identifique o tipo Uma query simples pode recuperar objetos de diferentes tipos Quando você usa Grupos de Entidades Você pode realizar transações entre tipos diferentes em uma mesma partição Você é responsável pela consistência entre múltiplas tabelas Use padrões adequados para tratar isto. Exemplo: Filas! Mais dicas em “Windows Azure Table – Programming Table Storage ” Queries em tabelas vazias -> crie entidades falsas para facilitar o tratamento de erros! Filas Filas no Windows Azure Provê a entrega confiável de mensagens Dispatch assíncrono e simples Semântica de programação que garante que uma mensagem possa ser processada pelo menos uma vez As filas são de alta disponibilidade, duráveis e com desempenho eficiente Conceitos da Fila do Azure Conta Fila Mensagem 128x128, http://… thumbnail jobs 256x256, http://… otavio http://… photo processing jobs http://… Conta, Fila e Mensagens Uma conta pode criar muitas filas Nome da fila está no escopo da conta Uma Fila contém mensagens Sem limite no número de mensagens armazenadas na fila Uma mensagem é armazenada na fila por até uma semana http://<Conta>.queue.core.windows.net/<NomeDaFila> Mensagens Tamanho da mensagem <= 8 KB Par armazenar dados maiores, guarde o conteúdo num blob ou entidade e envie seu nome no corpo da mensagem Adicionando Mensagens protected void btnSend_Click(object sender, EventArgs e) { // pega informação da conta no arq de config var storageAccount = CloudStorageAccount.FromConfigurationSetting( "DataConnectionString"); // encontra a referência para a fila var queueClient = storageAccount.CreateCloudQueueClient(); var queue = queueClient.GetQueueReference("messagequeue"); queue.CreateIfNotExist(); var msg = new CloudQueueMessage(txtMessage.Text); queue.AddMessage(msg); } txtMessage.Text = string.Empty; Loop de Leitura // pega dados da fila como no slide anterior ... while (true) { Thread.Sleep(10000); if (queue.Exists()) { var msg = queue.GetMessage(new TimeSpan(2000)); // 200.000 nanos if (msg != null) { // Trata a mensagem... Em menos de 200.000 nanos !!! } } } queue.DeleteMessage(msg); // mata a mensagem Dequeue e Delete de Mensagens Produtores Consumidores C1 P2 4 P1 3 2 1 C2 2. Dequeue(Q, 30 sec) msg 2 1. Dequeue(Q, 30 sec) msg 1 Dequeue e Delete de Mensagens Produtores Consumidores 1 P2 4 3 2 1 1. Dequeue(Q, 30 sec) msg 1 5. C1 crashed 6. msg1 visivel 30 segundos depois do Dequeue 2 P1 C1 C2 2. Dequeue(Q, 30 seg) msg 2 3. C2 consome msg 2 4. Delete(Q, msg 2) 7. Dequeue(Q, 30 seg) msg 1 Boa prática – Diminuindo o Polling Melhores Práticas para Filas Faça o processamento das mensagens idempotentes Com isto você não precisará lidar com falhas Não há ordem fixa para retirar mensagens Use o tamanho da fila para escalar seus workers CDN Windows Azure Content Delivery Network http://guid01.vo.msecnd.net/images/pic.1jpg Para habilitar o CDN: Registre CDN via Dev Portal Container público Não disponível! Localização do CDN Localização do CDN TTL Localização do CDN Content Delivery Network http://sally.blob.core.windows.net/ http://guid01.vo.msecnd.net/ pic1.jpg pic1.jpg pic1.jpg http://sally.blob.core.windows.net/images/pic1.jpg Windows Azure Blob Service O que faltou? Capacidades da plataforma Windows Azure COS303 | Movendo Aplicativos para a Nuvem COS304 | Projetando Aplicativos para a Escalabilidade - Tirando o melhor da Plataforma Windows Azure SIA305 | Segurança no Desenvolvimento para Windows Azure Application Services Frameworks “Dublin” Security Access Control Connectivity Service Bus COS201 | Plataforma Azure “Geneva” AppFabric - utilizando o Service Bus e o Access Control Services Project “Sydney” DBP308 | Sincronizando dados com a nuvem através do SQL Azure Data Sync e Sync Framework 2.0 COS302 | SQL Azure - Cenários SQL Azure de Uso, Migraçao e Operaçao Data Data Sync Compute Storage “Velocity” COS401 | Trace, Log, Provisionamento e Monitoraçao no Azure Table Storage Blob Storage Queue INT303 | Integrando Moodle com plataforma Microsoft Drive Content Delivery Network Resumo Azure é um Sistema Operacional feito para a Nuvem É projetado para utility computing Tem 4 metas principais: Gerenciamento Automático dos Serviços Um hospedeiro poderoso de Serviços Storage e Processamento na Nuvem Escalável e Disponível Uma experiência de desenvolvimento rica e familiar © 2008 Microsoft Corporation. Todos os direitos reservados. Microsoft, Windows, Windows Vista e outros nomes de produtos são ou podem ser marcas registradas e/ou marcas comerciais nos EUA e/ou outros países. Este documento é meramente informativo e representa a visão atual da Microsoft Corporation a partir da data desta apresentação. Como a Microsoft deve atender a condições de mercado em constante alteração, este documento não deve ser interpretado como um compromisso por parte da Microsoft, e a Microsoft não pode garantir a precisão de qualquer informação fornecida após a data desta apresentação. A MICROSOFT NÃO DÁ QUALQUER GARANTIA, SEJA ELA EXPRESSA, IMPLÍCITA OU ESTATUTÁRIA, REFERENTE ÀS INFORMAÇÕES DESTA APRESENTAÇÃO. Por favor preencha a avaliação