Databricks: Cluster Policies

Anselmo Borges
Rescue Point
Published in
7 min readJul 27, 2023
Salve horas de dor de cabeça com isso rs

Que o Databricks funciona bem, quem já trabalhou com ele sabe, mas se seu time não tem um treinamento devido na ferramenta, você precisa urgentemente implementar policies e bloqueios. Porque?

  • Todo mundo admin dá abertura para a criação dos monstros mais diversos.
  • Cada um cria o cluster no size que deve e do jeito que acha.
  • Versões das bibliotecas não tem nenhum padrão.
  • Você sempre precisará customizar acesso a external storages manualmente na criação de novos cluster em workspaces.

Essas são só algumas das buchas que você terá se não tiver um Platform Admin do Databricks e restringir os acessos e criações indevidas que não são só um risco pros seus dados mas também um risco pro seu bolso.

No termino desse material você vai ter uma base de como criar policies que permitem limitar algumas paradas na criação de clusters como também setar padrões que visam economizar muito que você apague incendio o tempo todo.

você não quer isso cara!

O que são cluster Policies?

São políticas que regulam a forma como os usuários acessam os clusters e que permite que os Platform Admins controlem o que os usuários podem ou não fazer com os clusters durante a sua criação.

Essas politicas são definidas em um formato do tipo JSON tipo esse abaixo, que pode parecer confuso no inicio mas na real é bem simples.

{
"spark_conf.spark.databricks.cluster.profile": {
"type": "fixed",
"value": "singleNode",
"hidden": true
},
"instance_pool_id": {
"type": "forbidden",
"hidden": true
},
"spark_version": {
"type": "unlimited",
"pattern": "auto:latest-ml"
},
"node_type_id": {
"type": "allowlist",
"values": [
"i3.xlarge",
"i3.2xlarge",
"i3.4xlarge"
],
"defaultValue": "i3.2xlarge"
},
"driver_node_type_id": {
"type": "fixed",
"value": "i3.2xlarge",
"hidden": true
},
"autoscale.min_workers": {
"type": "fixed",
"value": 1,
"hidden": true
},
"autoscale.max_workers": {
"type": "range",
"maxValue": 25,
"defaultValue": 5
},
"enable_elastic_disk": {
"type": "fixed",
"value": true,
"hidden": true
},
"autotermination_minutes": {
"type": "fixed",
"value": 30,
"hidden": true
},
"custom_tags.team": {
"type": "fixed",
"value": "product"
}
}

Esse exemplo acima é uma policy General em um Workspace Databricks na AWS (basta ver os sizes dos nodes), baseado em policies tudo no esquema de chave e valor.

As policies

São as configurações de restrição ou liberação que eu quero setar, por exemplo, eu quero definir uma versão especifica de Spark, se liga ai em baixo:

{
"spark_version": { "type": "allowlist", "values": [ "11.3.x-scala2.12", "10.4.x-scala2.12" ] }
}

Nesse caso, a policyspark_version vem acompanhada dos elementos type que é allowlist como o nome já diz cria uma lista de permitidos e em values os valores das versões spark que vou permitir. Simples assim.

E não precisa decorar as policies e elementos, pois a documentação da Databricks já deixa tudo no esquema pra você. As policies no caso você pode encontrar nessa tabela no link abaixo.

E você pode ver alguns outros exemplos como esse, inclusive olhando outros elementos nesse link aqui.

Mas em resumo, vamos criar uma policy do zero, lembrando:

  • Policies só funcionam na versão Premium do Databricks
  • Somente Workspace Admins conseguem criar policies.

Gerenciando e criando policies

Logando no Workspace Databricks vamos na aba Compute do menu lateral e clicamos em policies.

Compute > Policies

Existem algumas policies já predefinidas (escrevi esse artigo em Jul/23 então são esses no momento).

  • Job Clusters: Uma policy atribuída a clusters que serão criados para a execução de jobs pontuais, que vivem enquanto o job estiver ativo.
  • Legacy Shared Compute: Compartilhado com equipes para exploração interativa de dados, análise de dados e aprendizado de máquina, porém com bibliotecas legadas de versões mais antigas.
  • Personal Compute: Use com dados ou bibliotecas de pequeno a médio porte, como pandas e scikit-learn. O Spark é executado no modo local.
  • Power User Compute: Execute projetos avançados e complexos de ciência de dados com recursos dedicados.
  • Shared Compute: Compartilhado com equipes para exploração interativa de dados, análise de dados e aprendizado de máquina, parecido com o segundo, mas esse voltado para as ultimas versões de bibliotecas e recursos.

Vou pegar a politica de Personal compute pra gente dar uma explorada, clique na policy e vai exibir o JSON abaixo:

{
"node_type_id": {
"type": "allowlist",
"values": [
"Standard_DS3_v2",
"Standard_DS4_v2",
"Standard_DS5_v2",
"Standard_NC4as_T4_v3"
],
"defaultValue": "Standard_DS3_v2"
},
"spark_version": {
"type": "unlimited",
"defaultValue": "auto:latest-ml"
},
"runtime_engine": {
"type": "fixed",
"value": "STANDARD",
"hidden": true
},
"num_workers": {
"type": "fixed",
"value": 0,
"hidden": true
},
"data_security_mode": {
"type": "allowlist",
"values": [
"SINGLE_USER",
"LEGACY_SINGLE_USER",
"LEGACY_SINGLE_USER_STANDARD"
],
"defaultValue": "SINGLE_USER",
"hidden": true
},
"driver_instance_pool_id": {
"type": "forbidden",
"hidden": true
},
"cluster_type": {
"type": "fixed",
"value": "all-purpose"
},
"instance_pool_id": {
"type": "forbidden",
"hidden": true
},
"azure_attributes.availability": {
"type": "fixed",
"value": "ON_DEMAND_AZURE",
"hidden": true
},
"spark_conf.spark.databricks.cluster.profile": {
"type": "fixed",
"value": "singleNode",
"hidden": true
},
"autotermination_minutes": {
"type": "unlimited",
"defaultValue": 4320,
"isOptional": true
}
}

A primeira das policies desse policie group é o node_type_id que me dá uma lista de possíveis nodes que posso usar pra esse cenário e um tamanho padrão caso eu não escolha nenhum que é o Standard_DS3_v2.

"node_type_id": {
"type": "allowlist",
"values": [
"Standard_DS3_v2",
"Standard_DS4_v2",
"Standard_DS5_v2",
"Standard_NC4as_T4_v3"
],
"defaultValue": "Standard_DS3_v2"
},

A segunda é a versão do spark que a policy é spark_version que ao usar o type do tipo Unlimited permite que você liste todas as versões possíveis para escolha e seta como padrão a versão mais recente em auto: latest-ml .

"spark_version": {
"type": "unlimited",
"defaultValue": "auto:latest-ml"
},

A terceira policy é a runtime_engine que determina se o cluster usa Photon ou não. Os valores possíveis são PHOTONou STANDARD. O type do tipo fixed indica que o único padrão possível nessa policy é o STANDARD e o elemento hidden setado para true indica que esse parâmetro não será exibido no UI de criação de cluster.

"runtime_engine": {
"type": "fixed",
"value": "STANDARD",
"hidden": true
},

A quarta policy é num_workers , se você conhece o funcionamento do Spark no Databricks vai saber que ele tem um master e os nodes, nesse caso como essa policy é para fins simples, ele coloca um valor ficado em 0 impossibilitando a criação de workers para o cluster, inclusive ocultando essa opção no UI, em resumo todo cluster criado será single node.

"num_workers": {
"type": "fixed",
"value": 0,
"hidden": true
},

A quinta policy data_security_mode que segundo a documentação define os recursos de segurança do cluster. Catálogo Unity requer SINGLE_USERou USER_ISOLATIONmodo. Os clusters de passagem requerem LEGACY_PASSTHROUGHe os clusters Table ACL exigem LEGACY_TABLE_ACL. O padrão é definido NONEcomo sem nenhum recurso de segurança ativado. No caso abaixo estou liberando os recursos de single user comum e legados.

"data_security_mode": {
"type": "allowlist",
"values": [
"SINGLE_USER",
"LEGACY_SINGLE_USER",
"LEGACY_SINGLE_USER_STANDARD"
],
"defaultValue": "SINGLE_USER",
"hidden": true

A sexta policy do grupo é a driver_instance_pool_id, que conforme vendo abaixo com o type: forbidden proibe que esse parâmetro seja setado e ainda oculta o conteúdo na UI.

"driver_instance_pool_id": {
"type": "forbidden",
"hidden": true

A sétima policy desse grupo é a cluster_type que define como all-purpose que diferencia de job para Job Clusters e dlt para Delta Live Tables.

"cluster_type": {
"type": "fixed",
"value": "all-purpose"
},

A oitava policy é instance_pool_id que segundo a documentação controla o conjunto usado pelos nós do trabalhador se driver_instance_pool_idtambém estiver definido ou, caso contrário, para todos os nós do cluster. Se você usar pools para nós do worker, também deverá usar pools para o nó do driver. Quando oculto, remove a seleção de pool da interface do usuário e no caso está.

"instance_pool_id": {
"type": "forbidden",
"hidden": true
},

A nona policy é azure_atributes.avaiability que desconheço e assim que souber volto aqui pra editar, aparentemente é o tipo de VM usada na Azure para os nodes do cluster, acredito que pode ser Spot tbm e fica oculto no UI.

"azure_attributes.availability": {
"type": "fixed",
"value": "ON_DEMAND_AZURE",
"hidden": true
},

A décima policy é uma configuração do Spark que como dito em parâmetros anteriores, força a criação de um singleNode sem o uso de workers.

"spark_conf.spark.databricks.cluster.profile": {
"type": "fixed",
"value": "singleNode",
"hidden": true
},

A 11a e última policy é o autotermination_minutes que define uma policy de valor ilimitado e dando um valor de 4320 minutos com um perfil opcional em ser setado.

"autotermination_minutes": {
"type": "unlimited",
"defaultValue": 4320,
"isOptional": true
}
}

Existem várias outras policies e entidades possíveis todas na documentação que comentei nos links anteriores.

Limitando o numero máximo de DBUs

Além dessas policies que vimos, essa de limitar o máximo de DBUs utilizado é incrível, pois posso definir um limite e economizar uma grana considerável não deixando o usuário rodar as paradas a bel prazer.

Basta na policy group entrar com a policy abaixo, que no exemplo limita em 100 nos cluster criados a partir dela:

  "dbus_per_hour": {
"type": "range",
"maxValue": 100
},

Criando uma policy customizada

Entrando na aba compute, clique em policies e clique na opção create policy. Isso vai abrir uma tela nova onde você pode criar seu JSON do jeito que achar conveniente e setar privilégios de quem pode ou não usa-la.

Criando uma policy customizada

Como disse podemos definir quem vai poder usar essa policy, no meu caso vou setar para all_users.

Setado para all Users

Agora só salvar e usar, note a diferença das opções disponíveis quando alterno entre a Unrestricted e a Minha Policy.

Se ligou?

Bom, no post de hoje é isso!

Como estou estudando a melhor forma de separar essas policies, por áreas, sizes, projetos e outros, ainda tenho uma caminhada por aqui, mas assim que concluído venho contar minha experiencia pra vocês.

Espero que ajude!
Anselmo Borges

--

--

Anselmo Borges
Rescue Point

Bigdata Engineer, Cloud Architect, Nerd, Alcoholic, Brazilian Jiujitsu Black belt and hide and seek World champion.