Recuperação de desastres regionais para clusters do Azure Databricks
Este artigo descreve uma arquitetura de recuperação de desastres útil para clusters do Azure Databricks e as etapas para realizar esse design.
Arquitetura do Azure Databricks
Quando você cria um espaço de trabalho do Azure Databricks a partir do portal do Azure, um aplicativo gerenciado é implantado como um recurso do Azure em sua assinatura, na região do Azure escolhida (por exemplo, Oeste dos EUA). Este dispositivo é implementado numa Rede Virtual do Azure com um Grupo de Segurança de Rede e uma conta de Armazenamento do Azure, disponível na sua subscrição. A rede virtual fornece segurança de nível de perímetro para o espaço de trabalho Databricks e é protegida por meio do grupo de segurança de rede. Dentro do espaço de trabalho, você cria clusters Databricks fornecendo o tipo de VM de trabalho e driver e a versão de tempo de execução do Databricks. Os dados persistentes estão disponíveis na sua conta de armazenamento. Depois que o cluster é criado, você pode executar trabalhos por meio de blocos de anotações, APIs REST ou pontos de extremidade ODBC/JDBC, anexando-os a um cluster específico.
O plano de controle Databricks gerencia e monitora o ambiente de espaço de trabalho Databricks. Qualquer operação de gerenciamento, como criar cluster, será iniciada a partir do plano de controle. Todos os metadados, como trabalhos agendados, são armazenados em um Banco de Dados do Azure e os backups do banco de dados são replicados automaticamente geograficamente para regiões emparelhadas onde são implementados.
Uma das vantagens dessa arquitetura é que os usuários podem conectar o Azure Databricks a qualquer recurso de armazenamento em sua conta. Um benefício importante é que a computação (Azure Databricks) e o armazenamento podem ser dimensionados independentemente um do outro.
Como criar uma topologia regional de recuperação de desastres
Na descrição da arquitetura anterior, há vários componentes usados para um pipeline de Big Data com o Azure Databricks: Armazenamento do Azure, Banco de Dados do Azure e outras fontes de dados. O Azure Databricks é a computação para o pipeline de Big Data. É efêmero por natureza, o que significa que, enquanto seus dados ainda estão disponíveis no Armazenamento do Azure, a computação (cluster do Azure Databricks) pode ser encerrada para evitar pagar pela computação quando você não precisa dela. As fontes de computação (Azure Databricks) e armazenamento devem estar na mesma região para que os trabalhos não tenham alta latência.
Para criar sua própria topologia regional de recuperação de desastres, siga estes requisitos:
Provisione vários espaços de trabalho do Azure Databricks em regiões separadas do Azure. Por exemplo, crie o espaço de trabalho principal do Azure Databricks no Leste dos EUA. Crie o espaço de trabalho secundário de recuperação de desastres do Azure Databricks em uma região separada, como West US. Para obter uma lista de regiões do Azure emparelhadas, consulte Replicação entre regiões. Para obter detalhes sobre as regiões do Azure Databricks, consulte Regiões suportadas.
Use armazenamento com redundância geográfica. Por padrão, os dados associados ao Azure Databricks são armazenados no Armazenamento do Azure e os resultados dos trabalhos do Databricks são armazenados no Armazenamento de Blobs do Azure, para que os dados processados sejam duráveis e permaneçam altamente disponíveis após o término do cluster. O armazenamento de cluster e o armazenamento de tarefas estão localizados na mesma zona de disponibilidade. Para proteger contra indisponibilidade regional, os espaços de trabalho do Azure Databricks usam armazenamento com redundância geográfica por padrão. Com o armazenamento com redundância geográfica, os dados são replicados para uma região emparelhada do Azure. O Databricks recomenda que você mantenha o padrão de armazenamento com redundância geográfica, mas se precisar usar o armazenamento com redundância local, você pode definir
storageAccountSkuName
comoStandard_LRS
no modelo ARM para o espaço de trabalho.Depois que a região secundária for criada, você deverá migrar os usuários, pastas de usuário, blocos de anotações, configuração de cluster, configuração de trabalhos, bibliotecas, armazenamento, scripts de inicialização e reconfigurar o controle de acesso. Detalhes adicionais são descritos na seção a seguir.
Desastre regional
Para se preparar para desastres regionais, você precisa manter explicitamente outro conjunto de espaços de trabalho do Azure Databricks em uma região secundária. Consulte Recuperação de desastres.
Nossas ferramentas recomendadas para recuperação de desastres são principalmente Terraform (para replicação de infra) e Delta Deep Clone (para replicação de dados).
Passos de migração detalhados
Instalar a CLI do Databricks
Os exemplos neste artigo usam a interface de linha de comando (CLI) Databricks, que é um wrapper fácil de usar sobre a API REST do Azure Databricks.
Antes de executar qualquer etapa de migração, instale a CLI do Databricks em seu computador local ou máquina virtual. Para obter mais informações, consulte Instalar a CLI do Databricks.
Nota
Os scripts Python fornecidos neste artigo funcionam com Python 2.7 e superior.
Configure dois perfis.
Seguindo as etapas em _, configure dois perfis: um para o espaço de trabalho primário e outro para o espaço de trabalho secundário.
databricks configure --profile primary databricks configure --profile secondary
Os blocos de código neste artigo alternam entre perfis em cada etapa subsequente usando o comando de espaço de trabalho correspondente. Certifique-se de que os nomes dos perfis criados sejam substituídos em cada bloco de código.
EXPORT_PROFILE = "primary" IMPORT_PROFILE = "secondary"
Você pode alternar manualmente na linha de comando, se necessário:
databricks workspace list --profile primary databricks workspace list --profile secondary
Migrar usuários do Microsoft Entra ID (anteriormente Azure Ative Directory)
Adicione manualmente os mesmos usuários do Microsoft Entra ID (anteriormente Azure Ative Directory) ao espaço de trabalho secundário que existe no espaço de trabalho primário.
Migrar as pastas de usuário e blocos de anotações
Use o seguinte código python para migrar os ambientes de usuário em área restrita, que incluem a estrutura de pastas aninhadas e blocos de anotações por usuário.
Nota
As bibliotecas não são copiadas nesta etapa, pois a API subjacente não oferece suporte a elas.
Copie e salve o seguinte script python em um arquivo e execute-o na linha de comando. Por exemplo,
python scriptname.py
.import sys import os import subprocess from subprocess import call, check_output EXPORT_PROFILE = "primary" IMPORT_PROFILE = "secondary" # Get a list of all users user_list_out = check_output(["databricks", "workspace", "list", "/Users", "--profile", EXPORT_PROFILE]) user_list = (user_list_out.decode(encoding="utf-8")).splitlines() print (user_list) # Export sandboxed environment(folders, notebooks) for each user and import into new workspace. #Libraries are not included with these APIs / commands. for user in user_list: #print("Trying to migrate workspace for user ".decode() + user) print (("Trying to migrate workspace for user ") + user) subprocess.call(str("mkdir -p ") + str(user), shell = True) export_exit_status = call("databricks workspace export_dir /Users/" + str(user) + " ./" + str(user) + " --profile " + EXPORT_PROFILE, shell = True) if export_exit_status==0: print ("Export Success") import_exit_status = call("databricks workspace import_dir ./" + str(user) + " /Users/" + str(user) + " --profile " + IMPORT_PROFILE, shell=True) if import_exit_status==0: print ("Import Success") else: print ("Import Failure") else: print ("Export Failure") print ("All done")
Migrar as configurações de cluster
Depois que os blocos de anotações forem migrados, você poderá, opcionalmente, migrar as configurações de cluster para o novo espaço de trabalho. É quase uma etapa totalmente automatizada usando a CLI do Databricks, a menos que você queira fazer a migração seletiva de configuração de cluster.
Nota
Não há nenhum ponto de extremidade de configuração de cluster de criação, e esse script tenta criar cada cluster imediatamente. Se não houver núcleos suficientes disponíveis na sua assinatura, a criação do cluster poderá falhar. A falha pode ser ignorada, desde que a configuração seja transferida com êxito.
O script a seguir fornecido imprime um mapeamento de IDs de cluster antigas para novas, que podem ser usadas para migração de trabalho posteriormente (para trabalhos configurados para usar clusters existentes).
Copie e salve o seguinte script python em um arquivo e execute-o na linha de comando. Por exemplo,
python scriptname.py
.import sys import os import subprocess import json from subprocess import call, check_output EXPORT_PROFILE = "primary" IMPORT_PROFILE = "secondary" # Get all clusters info from old workspace clusters_out = check_output(["databricks", "clusters", "list", "--profile", EXPORT_PROFILE]) clusters_info_list = str(clusters_out.decode(encoding="utf-8")).splitlines() print("Printing Cluster info List") print(clusters_info_list) # Create a list of all cluster ids clusters_list = [] ##for cluster_info in clusters_info_list: clusters_list.append(cluster_info.split(None, 1)[0]) for cluster_info in clusters_info_list: if cluster_info != '': clusters_list.append(cluster_info.split(None, 1)[0]) # Optionally filter cluster ids out manually, so as to create only required ones in new workspace # Create a list of mandatory / optional create request elements cluster_req_elems = ["num_workers","autoscale","cluster_name","spark_version","spark_conf","node_type_id","driver_node_type_id","custom_tags","cluster_log_conf","spark_env_vars","autotermination_minutes","enable_elastic_disk"] print("Printing Cluster element List") print (cluster_req_elems) print(str(len(clusters_list)) + " clusters found in the primary site" ) print ("---------------------------------------------------------") # Try creating all / selected clusters in new workspace with same config as in old one. cluster_old_new_mappings = {} i = 0 for cluster in clusters_list: i += 1 print("Checking cluster " + str(i) + "/" + str(len(clusters_list)) + " : " +str(cluster)) cluster_get_out_f = check_output(["databricks", "clusters", "get", "--cluster-id", str(cluster), "--profile", EXPORT_PROFILE]) cluster_get_out=str(cluster_get_out_f.decode(encoding="utf-8")) print ("Got cluster config from old workspace") print (cluster_get_out) # Remove extra content from the config, as we need to build create request with allowed elements only cluster_req_json = json.loads(cluster_get_out) cluster_json_keys = cluster_req_json.keys() #Don't migrate Job clusters if cluster_req_json['cluster_source'] == u'JOB' : print ("Skipping this cluster as it is a Job cluster : " + cluster_req_json['cluster_id'] ) print ("---------------------------------------------------------") continue #cluster_req_json.pop(key, None) for key in cluster_json_keys: if key not in cluster_req_elems: print (cluster_req_json) #cluster_del_item=cluster_json_keys .keys() cluster_req_json.popitem(key, None) # Create the cluster, and store the mapping from old to new cluster ids #Create a temp file to store the current cluster info as JSON strCurrentClusterFile = "tmp_cluster_info.json" #delete the temp file if exists if os.path.exists(strCurrentClusterFile) : os.remove(strCurrentClusterFile) fClusterJSONtmp = open(strCurrentClusterFile,"w+") fClusterJSONtmp.write(json.dumps(cluster_req_json)) fClusterJSONtmp.close() #cluster_create_out = check_output(["databricks", "clusters", "create", "--json", json.dumps(cluster_req_json), "--profile", IMPORT_PROFILE]) cluster_create_out = check_output(["databricks", "clusters", "create", "--json-file", strCurrentClusterFile , "--profile", IMPORT_PROFILE]) cluster_create_out_json = json.loads(cluster_create_out) cluster_old_new_mappings[cluster] = cluster_create_out_json['cluster_id'] print ("Cluster create request sent to secondary site workspace successfully") print ("---------------------------------------------------------") #delete the temp file if exists if os.path.exists(strCurrentClusterFile) : os.remove(strCurrentClusterFile) print ("Cluster mappings: " + json.dumps(cluster_old_new_mappings)) print ("All done") print ("P.S. : Please note that all the new clusters in your secondary site are being started now!") print (" If you won't use those new clusters at the moment, please don't forget terminating your new clusters to avoid charges")
Migrar a configuração de trabalhos
Se você migrou configurações de cluster na etapa anterior, pode optar por migrar configurações de trabalho para o novo espaço de trabalho. É uma etapa totalmente automatizada usando a CLI do Databricks, a menos que você queira fazer a migração seletiva de configuração de trabalho em vez de fazê-lo para todos os trabalhos.
Nota
A configuração para um trabalho agendado também contém as informações de "agendamento", portanto, por padrão, começará a funcionar de acordo com o tempo configurado assim que for migrado. Assim, o bloco de código a seguir remove todas as informações de agendamento durante a migração (para evitar execuções duplicadas em espaços de trabalho antigos e novos). Configure as agendas para esses trabalhos assim que estiver pronto para a substituição.
A configuração do trabalho requer definições para um cluster novo ou existente. Se estiver usando um cluster existente, o script /código abaixo tentará substituir o ID de cluster antigo pelo novo ID de cluster.
Copie e salve o seguinte script python em um arquivo. Substitua o valor de
old_cluster_id
enew_cluster_id
, pela saída da migração de cluster feita na etapa anterior. Execute-o na linha de comando, por exemplo,python scriptname.py
.import sys import os import subprocess import json from subprocess import call, check_output EXPORT_PROFILE = "primary" IMPORT_PROFILE = "secondary" # Please replace the old to new cluster id mappings from cluster migration output cluster_old_new_mappings = {"0227-120427-tryst214": "0229-032632-paper88"} # Get all jobs info from old workspace try: jobs_out = check_output(["databricks", "jobs", "list", "--profile", EXPORT_PROFILE]) jobs_info_list = jobs_out.splitlines() except: print("No jobs to migrate") sys.exit(0) # Create a list of all job ids jobs_list = [] for jobs_info in jobs_info_list: jobs_list.append(jobs_info.split(None, 1)[0]) # Optionally filter job ids out manually, so as to create only required ones in new workspace # Create each job in the new workspace based on corresponding settings in the old workspace for job in jobs_list: print("Trying to migrate " + str(job)) job_get_out = check_output(["databricks", "jobs", "get", "--job-id", job, "--profile", EXPORT_PROFILE]) print("Got job config from old workspace") job_req_json = json.loads(job_get_out) job_req_settings_json = job_req_json['settings'] # Remove schedule information so job doesn't start before proper cutover job_req_settings_json.pop('schedule', None) # Replace old cluster id with new cluster id, if job configured to run against an existing cluster if 'existing_cluster_id' in job_req_settings_json: if job_req_settings_json['existing_cluster_id'] in cluster_old_new_mappings: job_req_settings_json['existing_cluster_id'] = cluster_old_new_mappings[job_req_settings_json['existing_cluster_id']] else: print("Mapping not available for old cluster id " + str(job_req_settings_json['existing_cluster_id'])) continue call(["databricks", "jobs", "create", "--json", json.dumps(job_req_settings_json), "--profile", IMPORT_PROFILE]) print("Sent job create request to new workspace successfully") print("All done")
Migrar bibliotecas
Atualmente, não há uma maneira simples de migrar bibliotecas de um espaço de trabalho para outro. Em vez disso, reinstale essas bibliotecas no novo espaço de trabalho manualmente. Você pode automatizar isso usando a CLI do Databricks para carregar bibliotecas personalizadas no espaço de trabalho.
Migrar o armazenamento de blob do Azure e as montagens do Armazenamento do Azure Data Lake
Remonte manualmente todos os pontos de montagem do armazenamento de Blob do Azure e do Armazenamento do Azure Data Lake (Gen 2) usando uma solução baseada em notebook. Os recursos de armazenamento teriam sido montados no espaço de trabalho primário e isso deve ser repetido no espaço de trabalho secundário. Não há API externa para montagens.
Migrar scripts de inicialização de cluster
Qualquer script de inicialização de cluster pode ser migrado do antigo para o novo espaço de trabalho usando a CLI do Databricks. Primeiro, copie os scripts necessários para sua área de trabalho local ou máquina virtual. Em seguida, copie esses scripts para o novo espaço de trabalho no mesmo caminho.
Nota
Se você tiver scripts de inicialização armazenados no DBFS, migre-os primeiro para um local suportado. Ver _.
// Primary to local databricks fs cp dbfs:/Volumes/my_catalog/my_schema/my_volume/ ./old-ws-init-scripts --profile primary // Local to Secondary workspace databricks fs cp old-ws-init-scripts dbfs:/Volumes/my_catalog/my_schema/my_volume/ --profile secondary
Reconfigure e reaplique manualmente o controle de acesso.
Se o espaço de trabalho principal existente estiver configurado para usar a camada Premium ou Enterprise (SKU), é provável que você também esteja usando o controle de acesso.
Se você usar o controle de acesso, reaplique manualmente o controle de acesso aos recursos (Blocos de Anotações, Clusters, Trabalhos, Tabelas).
Recuperação de desastres para seu ecossistema do Azure
Se você estiver usando outros serviços do Azure, certifique-se de implementar práticas recomendadas de recuperação de desastres para esses serviços também. Por exemplo, se você optar por usar uma instância externa do metastore do Hive, considere a recuperação de desastres para o Banco de Dados SQL do Azure, o Azure HDInsight e/ou o Banco de Dados do Azure para MySQL. Para obter informações gerais sobre recuperação de desastres, consulte Recuperação de desastres para aplicativos do Azure.
Próximos passos
Para obter mais informações, consulte a documentação do Azure Databricks.