Um algoritmo de roteamento permite que uma consulta com o campo de roteamento de uma tabela lógica localize diretamente o shard da tabela de destino, sem cálculo manual de rota. Este tópico aborda o formato da expressão, o procedimento de configuração, exemplos de expressões de roteamento e as funções integradas disponíveis para uso nas expressões.
Por que usar um algoritmo de roteamento
O algoritmo de roteamento reduz a sobrecarga de roteamento. Após configurar esse algoritmo para uma tabela lógica, qualquer consulta que inclua o campo de roteamento localiza rapidamente o shard especificado. Assim, você elimina a necessidade de calcular rotas manualmente ou alternar entre bancos de dados e tabelas físicas.
Para mais informações sobre algoritmos de roteamento, consulte routing algorithm.
Casos de uso
Consultar dados em shards específicos de tabela.
Modificar dados em shards específicos de tabela.
Exportar dados de shards específicos de tabela.
Pré-requisitos
Configure uma tabela lógica em um banco de dados lógico. Para obter instruções, consulte logical table.
Configurar um algoritmo de roteamento por módulo simples
O procedimento a seguir configura um algoritmo de roteamento baseado em uma operação de módulo simples. Antes de selecionar a operação, verifique os tipos de campo compatíveis com cada uma:
Operação de Módulo Simples — Compatível apenas com campos de tipo numérico.
Hash modular — Compatível com campos de tipo numérico ou string.
-
Acesse a página Global Search e clique em Query à direita do banco de dados lógico desejado para abrir a página SQL Console.
NotaVocê também pode escolher SQL Console > SQL Console na barra de menu superior.
No canto superior direito da página, clique no ícone
para acessar a página da lista de tabelas.Na linha correspondente à tabela lógica desejada, clique em Configure Algorithm.
Na página da lista de algoritmos, clique em Create.
-
Configure Algorithm Type, Modulo Operation, Table Partitioning Field e Modulus.
Neste exemplo, defina Algorithm Type como Modulo Operation on One Column, Modulo Operation como Simple Modulo Operation, Table Partitioning Field como
ide Modulus como 4. A expressão resultante é#id#%4. Clique em Save.
-
Consulte os dados da tabela ou execute instruções INSERT na tabela lógica para verificar o resultado do roteamento. O sistema calcula o resultado e insere os dados no shard da tabela com o índice correspondente.
Por exemplo, ao inserir uma linha de dados com ID 9, o resultado calculado será 1 e os dados serão inseridos no shard da tabela
logic_table_01.
Formato da expressão
No DMS, o algoritmo de roteamento de sharding de tabela é definido por uma expressão Groovy, semelhante aos algoritmos configurados no código da aplicação. Uma expressão referencia um campo de roteamento no formato # + campo de roteamento + #, por exemplo, #shardKey#. O campo de roteamento corresponde ao campo selecionado como Table Partitioning Field.
Exemplos de expressões de roteamento
Nas expressões abaixo, user_id representa um campo de tabela de exemplo. Os exemplos estão agrupados conforme o que a expressão determina: apenas o shard da tabela, tanto o shard do banco de dados quanto o da tabela, ou um destino derivado de uma data, de dígitos em uma string ou de uma função personalizada.
-
Roteamento por regra de tabela
-
Operação de módulo simples
Módulo em números:
#user_id#%100Módulo encadeado:
#user_id#%10000%100Módulo sobre o hash Java de um número:
Math.abs(#user_id#.hashCode())%100
-
Hash modular em strings
Hash de uma string numérica:
Math.abs(#user_id#.toString().hashCode())%100Hash de uma string:
Math.abs(#user_id#.hashCode())%100CobarHash:
Math.abs(cobarHash(#column#,start, end)).intdiv(8)CobarOldHash:
Math.abs(cobarOldHash(#column#, len)).intdiv(8)
-
-
Roteamento por regra de banco de dados
Regra com mesmo nome de banco de dados e tabela:
'schema_prefix_'+(#user_id#%10)+'.table_name'-
Nome do banco de dados e nome da tabela
'schema_prefix_'+(#user_id#%100)+'.table_name_prefix_'+(#user_id#%1000)Mesmo conjunto de shards de tabela em cada shard de banco de dados:
'schema_prefix_'+lastSwapZero(String.valueOf((#user_id#%1024).intdiv(128)),4)+'.table_name_prefix_'+lastSwapZero(String.valueOf((#user_id#%128)),4)Rotear para um shard de banco de dados dividindo os dígitos 16 e 17 da string por 2 e, para o shard de tabela, utilizar os dígitos 16 e 17 da string:
'schema_prefix_'+substring(#EXTEND_ID#,16,18).toLong().intdiv(2)+'.table_name_prefix_'+substring(#EXTEND_ID#,16,18)
-
Roteamento por data
Rotear para a mesma tabela no mesmo dia de cada mês:
dayOfMonth(#time#) -
Roteamento pelo antepenúltimo dígito de uma string
Como o nome da tabela incrementa em passos de 10, o dígito extraído é multiplicado por 10. Se o incremento for 1, não é necessária multiplicação:
Integer.valueOf(substring(#ip_id#,-3,-2))*10 -
Outros roteamentos complexos
Use uma função personalizada:
String func(String arg){ return arg.hashCode()%10;} 'table_name_'+func(#user_id#)+'_other_'+func(#user_id#)Adicione uma quebra de linha entre a função e a expressão.
O DMS oferece suporte a roteamento por meio da função
CRC32(java.util.zip.CRC32).
Funções integradas para expressões de roteamento
Você pode chamar as seguintes funções integradas diretamente em uma expressão de roteamento.
-
cobarOldHash — Algoritmo legado CobarHash.
public static long cobarOldHash(String s, int len) { long h = 0; int sLen = s.length(); for (int i = 0; (i < len && i < sLen); i++) { h = (h << 5) - h + s.charAt(i); } return h; } -
cobarHash — Novo algoritmo cobarHash.
public static long cobarHash(String s, int start, int end) { if (start < 0) { start = 0; } if (end > s.length()) { end = s.length(); } long h = 0; for (int i = start; i < end; ++i) { h = (h << 5) - h + s.charAt(i); } return h; } -
weekOfYear — Retorna a semana do ano.
public static int weekOfYear(String dateValue) { Date date = DateTimeUtils.getSomeDate(dateValue); if(date != null) { return DateTimeUtils.getWeekOfYear(date); } return 0; } -
dayOfYear — Retorna o dia do ano.
public static int dayOfYear(String dateValue) { Date date = DateTimeUtils.getSomeDate(dateValue); if(date != null) { return DateTimeUtils.getDayOfYear(date); } return 0; } -
dayOfMonth — Retorna o dia do mês.
public static int dayOfMonth(String dateValue) { Date date = DateTimeUtils.getSomeDate(dateValue); if (date != null) { return DateTimeUtils.getDayOfMonth(date); } return 0; } -
dayOfWeek — Retorna o dia da semana.
public static int dayOfWeek(String dateValue) { Date date = DateTimeUtils.getSomeDate(dateValue); if (date != null) { int dayOfWeek = DateTimeUtils.getDayOfWeek(date); if (dayOfWeek==1){ dayOfWeek=7; }else { dayOfWeek=dayOfWeek-1; } return dayOfWeek; } return 0; } -
substring — Extrai uma substring. As posições inicial e final aceitam valores negativos, que contam de trás para frente a partir do fim da string.
public static String substring(String value, int start, int end) { return StringUtils.substring(value, start, end); }public static String substring(String value, int start) { return StringUtils.substring(value, start); } -
last4swap — Retorna os últimos quatro caracteres de uma string. Se a string tiver menos de quatro caracteres, zeros são adicionados à esquerda. Em seguida, os últimos quatro caracteres são trocados em pares.
public static String last4swap(String value) { if(value.length() < 4) { value = StringUtils.leftPad(value, 4, '0'); } return StringUtils.substring(value, -2)+StringUtils.substring(value, -4, -2); } -
lastSwapZero — Retorna uma string com o comprimento mínimo especificado. Caso a string seja menor que o tamanho definido, zeros são preenchidos antes dos dígitos.
public static String lastSwapZero(String value, int length) { if (value.length() < length) { return StringUtils.leftPad(value, length, '0'); } return value; }