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
Download

Desenvolvendo para Azure - Junior Galvão - MVP